langctl 0.1.0 → 0.1.2
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/.gitattributes +2 -0
- package/NEXT_PHASE.md +618 -0
- package/README.md +994 -115
- package/WORKING_INSTRUCTIONS.md +1389 -0
- package/dist/auth.d.ts +4 -0
- package/dist/auth.js +6 -0
- package/dist/commands/auth.js +1 -9
- package/dist/commands/config.js +4 -7
- package/dist/commands/debug.js +8 -14
- package/dist/commands/export.d.ts +14 -0
- package/dist/commands/export.js +115 -0
- package/dist/commands/import.d.ts +11 -0
- package/dist/commands/import.js +171 -0
- package/dist/commands/init.js +2 -8
- package/dist/commands/keys.d.ts +25 -0
- package/dist/commands/keys.js +396 -0
- package/dist/commands/org.d.ts +13 -0
- package/dist/commands/org.js +147 -0
- package/dist/commands/projects.d.ts +28 -0
- package/dist/commands/projects.js +369 -21
- package/dist/commands/team.d.ts +29 -0
- package/dist/commands/team.js +285 -0
- package/dist/config.d.ts +1 -3
- package/dist/config.js +2 -4
- package/dist/index.js +354 -3
- package/dist/supabase.d.ts +4 -4
- package/dist/supabase.js +8 -11
- package/package.json +52 -5
- package/NPM_PUBLISH_GUIDE.md +0 -293
- package/QUICK_PUBLISH.md +0 -64
package/dist/auth.d.ts
CHANGED
|
@@ -26,6 +26,10 @@ export declare function isAuthenticated(): boolean;
|
|
|
26
26
|
* Get current organization ID
|
|
27
27
|
*/
|
|
28
28
|
export declare function getOrganizationId(): string | undefined;
|
|
29
|
+
/**
|
|
30
|
+
* Get current API key
|
|
31
|
+
*/
|
|
32
|
+
export declare function getApiKey(): string | undefined;
|
|
29
33
|
/**
|
|
30
34
|
* Logout (clear authentication)
|
|
31
35
|
*/
|
package/dist/auth.js
CHANGED
|
@@ -94,6 +94,12 @@ export function isAuthenticated() {
|
|
|
94
94
|
export function getOrganizationId() {
|
|
95
95
|
return config.get('organizationId');
|
|
96
96
|
}
|
|
97
|
+
/**
|
|
98
|
+
* Get current API key
|
|
99
|
+
*/
|
|
100
|
+
export function getApiKey() {
|
|
101
|
+
return config.get('apiKey');
|
|
102
|
+
}
|
|
97
103
|
/**
|
|
98
104
|
* Logout (clear authentication)
|
|
99
105
|
*/
|
package/dist/commands/auth.js
CHANGED
|
@@ -3,16 +3,8 @@ import ora from 'ora';
|
|
|
3
3
|
import { authenticate, logout } from '../auth.js';
|
|
4
4
|
import { config } from '../config.js';
|
|
5
5
|
import { initializeSupabase } from '../supabase.js';
|
|
6
|
-
// Hardcoded Supabase credentials
|
|
7
|
-
const SUPABASE_URL = 'https://bcgnmvkgkbhbxzzflwdb.supabase.co';
|
|
8
|
-
const SUPABASE_ANON_KEY = 'sb_publishable_WCpKr-NwubrPtOj2E0cvAQ_TzvfXsNB';
|
|
9
6
|
export async function authCommand(apiKey) {
|
|
10
|
-
//
|
|
11
|
-
if (!config.get('supabaseUrl')) {
|
|
12
|
-
config.set('supabaseUrl', SUPABASE_URL);
|
|
13
|
-
config.set('supabaseAnonKey', SUPABASE_ANON_KEY);
|
|
14
|
-
}
|
|
15
|
-
// Initialize Supabase
|
|
7
|
+
// Initialize Supabase (with hardcoded credentials)
|
|
16
8
|
try {
|
|
17
9
|
initializeSupabase();
|
|
18
10
|
}
|
package/dist/commands/config.js
CHANGED
|
@@ -9,9 +9,11 @@ export function configCommand() {
|
|
|
9
9
|
}
|
|
10
10
|
// Display config with masked sensitive values
|
|
11
11
|
const displayConfig = {
|
|
12
|
-
...allConfig,
|
|
13
12
|
apiKey: allConfig.apiKey ? maskApiKey(allConfig.apiKey) : undefined,
|
|
14
|
-
|
|
13
|
+
organizationId: allConfig.organizationId,
|
|
14
|
+
organizationName: allConfig.organizationName,
|
|
15
|
+
defaultProject: allConfig.defaultProject,
|
|
16
|
+
defaultLanguage: allConfig.defaultLanguage
|
|
15
17
|
};
|
|
16
18
|
Object.entries(displayConfig).forEach(([key, value]) => {
|
|
17
19
|
if (value !== undefined) {
|
|
@@ -25,9 +27,4 @@ function maskApiKey(key) {
|
|
|
25
27
|
return '***';
|
|
26
28
|
return `${key.substring(0, 10)}...${key.substring(key.length - 4)}`;
|
|
27
29
|
}
|
|
28
|
-
function maskSensitive(value) {
|
|
29
|
-
if (value.length < 8)
|
|
30
|
-
return '***';
|
|
31
|
-
return `${value.substring(0, 8)}...`;
|
|
32
|
-
}
|
|
33
30
|
//# sourceMappingURL=config.js.map
|
package/dist/commands/debug.js
CHANGED
|
@@ -1,16 +1,13 @@
|
|
|
1
1
|
import chalk from 'chalk';
|
|
2
2
|
import ora from 'ora';
|
|
3
3
|
import { getSupabase, initializeSupabase } from '../supabase.js';
|
|
4
|
-
import { config } from '../config.js';
|
|
5
4
|
export async function debugListApiKeys() {
|
|
6
|
-
//
|
|
7
|
-
const url = config.get('supabaseUrl');
|
|
8
|
-
const key = config.get('supabaseAnonKey');
|
|
5
|
+
// Initialize supabase (with hardcoded credentials)
|
|
9
6
|
try {
|
|
10
|
-
initializeSupabase(
|
|
7
|
+
initializeSupabase();
|
|
11
8
|
}
|
|
12
9
|
catch (e) {
|
|
13
|
-
console.error(chalk.red('✗
|
|
10
|
+
console.error(chalk.red('✗ Failed to connect to Langctl servers.'));
|
|
14
11
|
return;
|
|
15
12
|
}
|
|
16
13
|
const supabase = getSupabase();
|
|
@@ -21,14 +18,12 @@ export async function debugListApiKeys() {
|
|
|
21
18
|
.limit(100);
|
|
22
19
|
if (error) {
|
|
23
20
|
spinner.fail(chalk.red(`Error fetching API keys: ${error.message}`));
|
|
24
|
-
console.log(chalk.yellow('Hint:
|
|
21
|
+
console.log(chalk.yellow('Hint: This is a debug command and may require elevated permissions.'));
|
|
25
22
|
return;
|
|
26
23
|
}
|
|
27
24
|
spinner.succeed(chalk.green(`Found ${data?.length || 0} API keys`));
|
|
28
25
|
if (!data || data.length === 0) {
|
|
29
|
-
console.log(chalk.yellow('No API keys visible with current
|
|
30
|
-
console.log(chalk.white(`Supabase URL: ${url}`));
|
|
31
|
-
console.log(chalk.white(`Anon key prefix: ${(key || '').substring(0, 12)}...`));
|
|
26
|
+
console.log(chalk.yellow('No API keys visible with current permissions.'));
|
|
32
27
|
return;
|
|
33
28
|
}
|
|
34
29
|
for (const row of data) {
|
|
@@ -36,13 +31,12 @@ export async function debugListApiKeys() {
|
|
|
36
31
|
}
|
|
37
32
|
}
|
|
38
33
|
export async function debugListOrganizations() {
|
|
39
|
-
|
|
40
|
-
const key = config.get('supabaseAnonKey');
|
|
34
|
+
// Initialize supabase (with hardcoded credentials)
|
|
41
35
|
try {
|
|
42
|
-
initializeSupabase(
|
|
36
|
+
initializeSupabase();
|
|
43
37
|
}
|
|
44
38
|
catch (e) {
|
|
45
|
-
console.error(chalk.red('✗
|
|
39
|
+
console.error(chalk.red('✗ Failed to connect to Langctl servers.'));
|
|
46
40
|
return;
|
|
47
41
|
}
|
|
48
42
|
const supabase = getSupabase();
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
type ExportFormat = 'i18n-json' | 'android-xml' | 'ios-strings' | 'flutter-arb' | 'flat-json' | 'nested-json';
|
|
2
|
+
interface ExportOptions {
|
|
3
|
+
language?: string;
|
|
4
|
+
format?: ExportFormat;
|
|
5
|
+
output?: string;
|
|
6
|
+
module?: string;
|
|
7
|
+
includeUnpublished?: boolean;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Export translations command
|
|
11
|
+
*/
|
|
12
|
+
export declare function exportCommand(projectSlug: string, options: ExportOptions): Promise<void>;
|
|
13
|
+
export {};
|
|
14
|
+
//# sourceMappingURL=export.d.ts.map
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import ora from 'ora';
|
|
3
|
+
import { writeFileSync, mkdirSync } from 'fs';
|
|
4
|
+
import { join, dirname } from 'path';
|
|
5
|
+
import { isAuthenticated, getApiKey } from '../auth.js';
|
|
6
|
+
const EDGE_FUNCTION_URL = 'https://bcgnmvkgkbhbxzzflwdb.supabase.co/functions/v1/export-translations';
|
|
7
|
+
const LIST_PROJECTS_URL = 'https://bcgnmvkgkbhbxzzflwdb.supabase.co/functions/v1/list-projects';
|
|
8
|
+
/**
|
|
9
|
+
* Get project by slug
|
|
10
|
+
*/
|
|
11
|
+
async function getProjectBySlug(apiKey, slug) {
|
|
12
|
+
try {
|
|
13
|
+
const response = await fetch(LIST_PROJECTS_URL, {
|
|
14
|
+
method: 'POST',
|
|
15
|
+
headers: {
|
|
16
|
+
'Content-Type': 'application/json',
|
|
17
|
+
'X-API-Key': apiKey
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
if (!response.ok) {
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
23
|
+
const data = await response.json();
|
|
24
|
+
if (!data.success || !data.projects) {
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
|
+
return data.projects.find((p) => p.slug === slug) || null;
|
|
28
|
+
}
|
|
29
|
+
catch (error) {
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Export translations command
|
|
35
|
+
*/
|
|
36
|
+
export async function exportCommand(projectSlug, options) {
|
|
37
|
+
// Check authentication
|
|
38
|
+
if (!isAuthenticated()) {
|
|
39
|
+
console.log(chalk.red('✗ Not authenticated. Please run "langctl auth <api-key>" first.\n'));
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
const apiKey = getApiKey();
|
|
43
|
+
if (!apiKey) {
|
|
44
|
+
console.log(chalk.red('✗ API key not found. Please run "langctl auth <api-key>" again.\n'));
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
const spinner = ora('Fetching project...').start();
|
|
48
|
+
try {
|
|
49
|
+
// Get project by slug
|
|
50
|
+
const project = await getProjectBySlug(apiKey, projectSlug);
|
|
51
|
+
if (!project) {
|
|
52
|
+
spinner.fail(chalk.red(`Project "${projectSlug}" not found`));
|
|
53
|
+
console.log(chalk.yellow('\nRun "langctl projects list" to see available projects.\n'));
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
spinner.text = 'Exporting translations...';
|
|
57
|
+
// Determine languages to export
|
|
58
|
+
const languages = options.language
|
|
59
|
+
? [options.language]
|
|
60
|
+
: project.languages;
|
|
61
|
+
// Validate language if specified
|
|
62
|
+
if (options.language && !project.languages.includes(options.language)) {
|
|
63
|
+
spinner.fail(chalk.red(`Language "${options.language}" not found in project`));
|
|
64
|
+
console.log(chalk.yellow(`Available languages: ${project.languages.join(', ')}\n`));
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
const format = options.format || 'flat-json';
|
|
68
|
+
const publishedOnly = !options.includeUnpublished;
|
|
69
|
+
// Export each language
|
|
70
|
+
for (const language of languages) {
|
|
71
|
+
spinner.text = `Exporting ${language}...`;
|
|
72
|
+
const response = await fetch(EDGE_FUNCTION_URL, {
|
|
73
|
+
method: 'POST',
|
|
74
|
+
headers: {
|
|
75
|
+
'Content-Type': 'application/json',
|
|
76
|
+
'X-API-Key': apiKey
|
|
77
|
+
},
|
|
78
|
+
body: JSON.stringify({
|
|
79
|
+
projectId: project.id,
|
|
80
|
+
language,
|
|
81
|
+
format,
|
|
82
|
+
publishedOnly,
|
|
83
|
+
module: options.module
|
|
84
|
+
})
|
|
85
|
+
});
|
|
86
|
+
if (!response.ok) {
|
|
87
|
+
const errorData = await response.json().catch(() => ({}));
|
|
88
|
+
throw new Error(errorData.error || `HTTP ${response.status}: ${response.statusText}`);
|
|
89
|
+
}
|
|
90
|
+
const data = await response.json();
|
|
91
|
+
if (!data.success || !data.content) {
|
|
92
|
+
throw new Error(data.error || 'Failed to export translations');
|
|
93
|
+
}
|
|
94
|
+
// Determine output path
|
|
95
|
+
const outputPath = options.output
|
|
96
|
+
? options.output
|
|
97
|
+
: join(process.cwd(), 'translations', data.filename || `${language}.json`);
|
|
98
|
+
// Ensure directory exists
|
|
99
|
+
mkdirSync(dirname(outputPath), { recursive: true });
|
|
100
|
+
// Write file
|
|
101
|
+
writeFileSync(outputPath, data.content, 'utf-8');
|
|
102
|
+
spinner.succeed(chalk.green(`Exported ${language} → ${outputPath}`));
|
|
103
|
+
// Show spinner again if there are more languages
|
|
104
|
+
if (languages.indexOf(language) < languages.length - 1) {
|
|
105
|
+
spinner.start();
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
console.log(chalk.blue(`\n✓ Exported ${languages.length} language(s) successfully\n`));
|
|
109
|
+
}
|
|
110
|
+
catch (error) {
|
|
111
|
+
spinner.fail(chalk.red('Failed to export translations'));
|
|
112
|
+
console.error(chalk.red(`Error: ${error.message}\n`));
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
//# sourceMappingURL=export.js.map
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
interface ImportOptions {
|
|
2
|
+
language: string;
|
|
3
|
+
overwrite?: boolean;
|
|
4
|
+
publish?: boolean;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Import translations command
|
|
8
|
+
*/
|
|
9
|
+
export declare function importCommand(projectSlug: string, filePath: string, options: ImportOptions): Promise<void>;
|
|
10
|
+
export {};
|
|
11
|
+
//# sourceMappingURL=import.d.ts.map
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import ora from 'ora';
|
|
3
|
+
import { readFileSync } from 'fs';
|
|
4
|
+
import { resolve } from 'path';
|
|
5
|
+
import { isAuthenticated, getApiKey } from '../auth.js';
|
|
6
|
+
const PUSH_TRANSLATIONS_URL = 'https://bcgnmvkgkbhbxzzflwdb.supabase.co/functions/v1/push-translations';
|
|
7
|
+
const LIST_PROJECTS_URL = 'https://bcgnmvkgkbhbxzzflwdb.supabase.co/functions/v1/list-projects';
|
|
8
|
+
/**
|
|
9
|
+
* Get project by slug
|
|
10
|
+
*/
|
|
11
|
+
async function getProjectBySlug(apiKey, slug) {
|
|
12
|
+
try {
|
|
13
|
+
const response = await fetch(LIST_PROJECTS_URL, {
|
|
14
|
+
method: 'POST',
|
|
15
|
+
headers: {
|
|
16
|
+
'Content-Type': 'application/json',
|
|
17
|
+
'X-API-Key': apiKey
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
if (!response.ok) {
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
23
|
+
const data = await response.json();
|
|
24
|
+
if (!data.success || !data.projects) {
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
|
+
return data.projects.find((p) => p.slug === slug) || null;
|
|
28
|
+
}
|
|
29
|
+
catch (error) {
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Parse translation file based on extension
|
|
35
|
+
*/
|
|
36
|
+
function parseTranslationFile(filePath) {
|
|
37
|
+
const content = readFileSync(filePath, 'utf-8');
|
|
38
|
+
const ext = filePath.split('.').pop()?.toLowerCase();
|
|
39
|
+
if (ext === 'json') {
|
|
40
|
+
const parsed = JSON.parse(content);
|
|
41
|
+
// Check if it's nested JSON and flatten it
|
|
42
|
+
if (isNestedObject(parsed)) {
|
|
43
|
+
return flattenObject(parsed);
|
|
44
|
+
}
|
|
45
|
+
return parsed;
|
|
46
|
+
}
|
|
47
|
+
throw new Error(`Unsupported file format: .${ext}. Only JSON files are currently supported.`);
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Check if object has nested objects
|
|
51
|
+
*/
|
|
52
|
+
function isNestedObject(obj) {
|
|
53
|
+
return Object.values(obj).some(value => typeof value === 'object' && value !== null && !Array.isArray(value));
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Flatten nested object to dot-notation keys
|
|
57
|
+
*/
|
|
58
|
+
function flattenObject(obj, prefix = '') {
|
|
59
|
+
const result = {};
|
|
60
|
+
Object.entries(obj).forEach(([key, value]) => {
|
|
61
|
+
const fullKey = prefix ? `${prefix}.${key}` : key;
|
|
62
|
+
if (typeof value === 'string') {
|
|
63
|
+
result[fullKey] = value;
|
|
64
|
+
}
|
|
65
|
+
else if (typeof value === 'object' && value !== null) {
|
|
66
|
+
Object.assign(result, flattenObject(value, fullKey));
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
return result;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Import translations command
|
|
73
|
+
*/
|
|
74
|
+
export async function importCommand(projectSlug, filePath, options) {
|
|
75
|
+
// Check authentication
|
|
76
|
+
if (!isAuthenticated()) {
|
|
77
|
+
console.log(chalk.red('✗ Not authenticated. Please run "langctl auth <api-key>" first.\n'));
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
const apiKey = getApiKey();
|
|
81
|
+
if (!apiKey) {
|
|
82
|
+
console.log(chalk.red('✗ API key not found. Please run "langctl auth <api-key>" again.\n'));
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
const spinner = ora('Loading file...').start();
|
|
86
|
+
try {
|
|
87
|
+
// Resolve file path
|
|
88
|
+
const resolvedPath = resolve(filePath);
|
|
89
|
+
// Parse translation file
|
|
90
|
+
spinner.text = 'Parsing translation file...';
|
|
91
|
+
const translations = parseTranslationFile(resolvedPath);
|
|
92
|
+
const keyCount = Object.keys(translations).length;
|
|
93
|
+
if (keyCount === 0) {
|
|
94
|
+
spinner.warn(chalk.yellow('No translations found in file'));
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
spinner.text = 'Fetching project...';
|
|
98
|
+
// Get project by slug
|
|
99
|
+
const project = await getProjectBySlug(apiKey, projectSlug);
|
|
100
|
+
if (!project) {
|
|
101
|
+
spinner.fail(chalk.red(`Project "${projectSlug}" not found`));
|
|
102
|
+
console.log(chalk.yellow('\nRun "langctl projects list" to see available projects.\n'));
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
// Validate language
|
|
106
|
+
if (!project.languages.includes(options.language)) {
|
|
107
|
+
spinner.fail(chalk.red(`Language "${options.language}" not found in project`));
|
|
108
|
+
console.log(chalk.yellow(`Available languages: ${project.languages.join(', ')}\n`));
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
spinner.text = `Importing ${keyCount} translations...`;
|
|
112
|
+
// Push translations
|
|
113
|
+
const response = await fetch(PUSH_TRANSLATIONS_URL, {
|
|
114
|
+
method: 'POST',
|
|
115
|
+
headers: {
|
|
116
|
+
'Content-Type': 'application/json',
|
|
117
|
+
'X-API-Key': apiKey
|
|
118
|
+
},
|
|
119
|
+
body: JSON.stringify({
|
|
120
|
+
projectId: project.id,
|
|
121
|
+
language: options.language,
|
|
122
|
+
translations,
|
|
123
|
+
publish: options.publish || false,
|
|
124
|
+
createMissing: true
|
|
125
|
+
})
|
|
126
|
+
});
|
|
127
|
+
if (!response.ok) {
|
|
128
|
+
const errorData = await response.json().catch(() => ({}));
|
|
129
|
+
throw new Error(errorData.error || `HTTP ${response.status}: ${response.statusText}`);
|
|
130
|
+
}
|
|
131
|
+
const data = await response.json();
|
|
132
|
+
if (!data.success && data.errors.length > 0) {
|
|
133
|
+
spinner.fail(chalk.red('Import completed with errors'));
|
|
134
|
+
console.log(chalk.green(`\n✓ Created: ${data.created}`));
|
|
135
|
+
console.log(chalk.blue(`✓ Updated: ${data.updated}`));
|
|
136
|
+
console.log(chalk.yellow(`⊘ Skipped: ${data.skipped}`));
|
|
137
|
+
console.log(chalk.red(`✗ Errors: ${data.errors.length}\n`));
|
|
138
|
+
if (data.errors.length > 0) {
|
|
139
|
+
console.log(chalk.red('Errors:'));
|
|
140
|
+
data.errors.slice(0, 5).forEach(err => {
|
|
141
|
+
console.log(chalk.red(` - ${err.key}: ${err.error}`));
|
|
142
|
+
});
|
|
143
|
+
if (data.errors.length > 5) {
|
|
144
|
+
console.log(chalk.gray(` ... and ${data.errors.length - 5} more errors\n`));
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
spinner.succeed(chalk.green('Import completed successfully'));
|
|
150
|
+
console.log(chalk.green(`\n✓ Created: ${data.created}`));
|
|
151
|
+
console.log(chalk.blue(`✓ Updated: ${data.updated}`));
|
|
152
|
+
console.log(chalk.yellow(`⊘ Skipped: ${data.skipped}`));
|
|
153
|
+
if (options.publish) {
|
|
154
|
+
console.log(chalk.green('✓ Keys published'));
|
|
155
|
+
}
|
|
156
|
+
console.log('');
|
|
157
|
+
}
|
|
158
|
+
catch (error) {
|
|
159
|
+
spinner.fail(chalk.red('Failed to import translations'));
|
|
160
|
+
if (error.code === 'ENOENT') {
|
|
161
|
+
console.error(chalk.red(`Error: File not found: ${filePath}\n`));
|
|
162
|
+
}
|
|
163
|
+
else if (error instanceof SyntaxError) {
|
|
164
|
+
console.error(chalk.red(`Error: Invalid JSON file\n`));
|
|
165
|
+
}
|
|
166
|
+
else {
|
|
167
|
+
console.error(chalk.red(`Error: ${error.message}\n`));
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
//# sourceMappingURL=import.js.map
|
package/dist/commands/init.js
CHANGED
|
@@ -5,9 +5,6 @@ import { config } from '../config.js';
|
|
|
5
5
|
import { authenticate } from '../auth.js';
|
|
6
6
|
import { initializeSupabase } from '../supabase.js';
|
|
7
7
|
import { showLogo } from '../utils/banner.js';
|
|
8
|
-
// Hardcoded Supabase credentials - users don't need to know about our backend
|
|
9
|
-
const SUPABASE_URL = 'https://bcgnmvkgkbhbxzzflwdb.supabase.co';
|
|
10
|
-
const SUPABASE_ANON_KEY = 'sb_publishable_WCpKr-NwubrPtOj2E0cvAQ_TzvfXsNB';
|
|
11
8
|
export async function initCommand() {
|
|
12
9
|
// Show logo
|
|
13
10
|
showLogo();
|
|
@@ -28,12 +25,9 @@ export async function initCommand() {
|
|
|
28
25
|
return;
|
|
29
26
|
}
|
|
30
27
|
}
|
|
31
|
-
//
|
|
32
|
-
config.set('supabaseUrl', SUPABASE_URL);
|
|
33
|
-
config.set('supabaseAnonKey', SUPABASE_ANON_KEY);
|
|
34
|
-
// Initialize Supabase client
|
|
28
|
+
// Initialize Supabase client (with hardcoded credentials - user doesn't need to know)
|
|
35
29
|
try {
|
|
36
|
-
initializeSupabase(
|
|
30
|
+
initializeSupabase();
|
|
37
31
|
}
|
|
38
32
|
catch (error) {
|
|
39
33
|
console.error(chalk.red('✗ Failed to connect to Langctl servers'));
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* List translation keys
|
|
3
|
+
*/
|
|
4
|
+
export declare function listKeysCommand(projectSlug: string, options: any): Promise<void>;
|
|
5
|
+
/**
|
|
6
|
+
* Get single key
|
|
7
|
+
*/
|
|
8
|
+
export declare function getKeyCommand(projectSlug: string, keyName: string): Promise<void>;
|
|
9
|
+
/**
|
|
10
|
+
* Create translation key
|
|
11
|
+
*/
|
|
12
|
+
export declare function createKeyCommand(projectSlug: string, keyName: string, options: any): Promise<void>;
|
|
13
|
+
/**
|
|
14
|
+
* Delete translation key
|
|
15
|
+
*/
|
|
16
|
+
export declare function deleteKeyCommand(projectSlug: string, keyName: string): Promise<void>;
|
|
17
|
+
/**
|
|
18
|
+
* Update single translation
|
|
19
|
+
*/
|
|
20
|
+
export declare function translateKeyCommand(projectSlug: string, keyName: string, options: any): Promise<void>;
|
|
21
|
+
/**
|
|
22
|
+
* Publish/unpublish keys
|
|
23
|
+
*/
|
|
24
|
+
export declare function publishKeysCommand(projectSlug: string, keys: string[], options: any): Promise<void>;
|
|
25
|
+
//# sourceMappingURL=keys.d.ts.map
|