@upbeat-works/edgecms-sdk 0.1.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/bin/edgecms.js ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ import '../dist/cli.js';
package/dist/api.d.ts ADDED
@@ -0,0 +1,46 @@
1
+ import type { EdgeCMSConfig } from './config.js';
2
+ export interface Language {
3
+ locale: string;
4
+ default: boolean;
5
+ }
6
+ export interface PullResponse {
7
+ languages: Language[];
8
+ defaultLocale: string | null;
9
+ translations: Record<string, Record<string, string>>;
10
+ }
11
+ export interface PushResponse {
12
+ success: boolean;
13
+ keysUpdated: number;
14
+ locale: string;
15
+ section: string | null;
16
+ }
17
+ export interface LanguagesResponse {
18
+ languages: Language[];
19
+ defaultLocale: string | null;
20
+ }
21
+ export interface ApiError {
22
+ error: string;
23
+ code: string;
24
+ }
25
+ /**
26
+ * API client for EdgeCMS i18n endpoints.
27
+ */
28
+ export declare class EdgeCMSClient {
29
+ private baseUrl;
30
+ private apiKey;
31
+ constructor(config: EdgeCMSConfig);
32
+ private fetch;
33
+ /**
34
+ * Pull all translations from the CMS.
35
+ */
36
+ pull(version?: 'draft' | 'live'): Promise<PullResponse>;
37
+ /**
38
+ * Push translations to the CMS.
39
+ */
40
+ push(locale: string, translations: Record<string, string>, section?: string): Promise<PushResponse>;
41
+ /**
42
+ * Get available languages.
43
+ */
44
+ getLanguages(): Promise<LanguagesResponse>;
45
+ }
46
+ //# sourceMappingURL=api.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAEjD,MAAM,WAAW,QAAQ;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,YAAY;IAC5B,SAAS,EAAE,QAAQ,EAAE,CAAC;IACtB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;CACrD;AAED,MAAM,WAAW,YAAY;IAC5B,OAAO,EAAE,OAAO,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB;AAED,MAAM,WAAW,iBAAiB;IACjC,SAAS,EAAE,QAAQ,EAAE,CAAC;IACtB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B;AAED,MAAM,WAAW,QAAQ;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;CACb;AAaD;;GAEG;AACH,qBAAa,aAAa;IACzB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,MAAM,CAAS;gBAEX,MAAM,EAAE,aAAa;YAKnB,KAAK;IAoCnB;;OAEG;IACG,IAAI,CAAC,OAAO,GAAE,OAAO,GAAG,MAAe,GAAG,OAAO,CAAC,YAAY,CAAC;IAIrE;;OAEG;IACG,IAAI,CACT,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EACpC,OAAO,CAAC,EAAE,MAAM,GACd,OAAO,CAAC,YAAY,CAAC;IAOxB;;OAEG;IACG,YAAY,IAAI,OAAO,CAAC,iBAAiB,CAAC;CAGhD"}
package/dist/api.js ADDED
@@ -0,0 +1,71 @@
1
+ class EdgeCMSApiError extends Error {
2
+ code;
3
+ status;
4
+ constructor(code, message, status) {
5
+ super(message);
6
+ this.code = code;
7
+ this.status = status;
8
+ this.name = 'EdgeCMSApiError';
9
+ }
10
+ }
11
+ /**
12
+ * API client for EdgeCMS i18n endpoints.
13
+ */
14
+ export class EdgeCMSClient {
15
+ baseUrl;
16
+ apiKey;
17
+ constructor(config) {
18
+ this.baseUrl = config.baseUrl;
19
+ this.apiKey = config.apiKey;
20
+ }
21
+ async fetch(path, options = {}) {
22
+ const url = `${this.baseUrl}${path}`;
23
+ const headers = {
24
+ 'x-api-key': this.apiKey,
25
+ ...options.headers,
26
+ };
27
+ if (options.body && typeof options.body === 'string') {
28
+ headers['Content-Type'] = 'application/json';
29
+ }
30
+ const response = await fetch(url, {
31
+ ...options,
32
+ headers,
33
+ });
34
+ if (!response.ok) {
35
+ let errorData;
36
+ try {
37
+ errorData = (await response.json());
38
+ }
39
+ catch {
40
+ errorData = {
41
+ error: `HTTP ${response.status}: ${response.statusText}`,
42
+ code: 'HTTP_ERROR',
43
+ };
44
+ }
45
+ throw new EdgeCMSApiError(errorData.code, errorData.error, response.status);
46
+ }
47
+ return response.json();
48
+ }
49
+ /**
50
+ * Pull all translations from the CMS.
51
+ */
52
+ async pull(version = 'live') {
53
+ return this.fetch(`/api/i18n/pull?version=${version}`);
54
+ }
55
+ /**
56
+ * Push translations to the CMS.
57
+ */
58
+ async push(locale, translations, section) {
59
+ return this.fetch('/api/i18n/push', {
60
+ method: 'POST',
61
+ body: JSON.stringify({ locale, translations, section }),
62
+ });
63
+ }
64
+ /**
65
+ * Get available languages.
66
+ */
67
+ async getLanguages() {
68
+ return this.fetch('/api/i18n/languages');
69
+ }
70
+ }
71
+ //# sourceMappingURL=api.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api.js","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"AA8BA,MAAM,eAAgB,SAAQ,KAAK;IAE1B;IAEA;IAHR,YACQ,IAAY,EACnB,OAAe,EACR,MAAc;QAErB,KAAK,CAAC,OAAO,CAAC,CAAC;QAJR,SAAI,GAAJ,IAAI,CAAQ;QAEZ,WAAM,GAAN,MAAM,CAAQ;QAGrB,IAAI,CAAC,IAAI,GAAG,iBAAiB,CAAC;IAC/B,CAAC;CACD;AAED;;GAEG;AACH,MAAM,OAAO,aAAa;IACjB,OAAO,CAAS;IAChB,MAAM,CAAS;IAEvB,YAAY,MAAqB;QAChC,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC;QAC9B,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;IAC7B,CAAC;IAEO,KAAK,CAAC,KAAK,CAAI,IAAY,EAAE,UAAuB,EAAE;QAC7D,MAAM,GAAG,GAAG,GAAG,IAAI,CAAC,OAAO,GAAG,IAAI,EAAE,CAAC;QACrC,MAAM,OAAO,GAA2B;YACvC,WAAW,EAAE,IAAI,CAAC,MAAM;YACxB,GAAI,OAAO,CAAC,OAAkC;SAC9C,CAAC;QAEF,IAAI,OAAO,CAAC,IAAI,IAAI,OAAO,OAAO,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YACtD,OAAO,CAAC,cAAc,CAAC,GAAG,kBAAkB,CAAC;QAC9C,CAAC;QAED,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;YACjC,GAAG,OAAO;YACV,OAAO;SACP,CAAC,CAAC;QAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YAClB,IAAI,SAAmB,CAAC;YACxB,IAAI,CAAC;gBACJ,SAAS,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAa,CAAC;YACjD,CAAC;YAAC,MAAM,CAAC;gBACR,SAAS,GAAG;oBACX,KAAK,EAAE,QAAQ,QAAQ,CAAC,MAAM,KAAK,QAAQ,CAAC,UAAU,EAAE;oBACxD,IAAI,EAAE,YAAY;iBAClB,CAAC;YACH,CAAC;YACD,MAAM,IAAI,eAAe,CACxB,SAAS,CAAC,IAAI,EACd,SAAS,CAAC,KAAK,EACf,QAAQ,CAAC,MAAM,CACf,CAAC;QACH,CAAC;QAED,OAAO,QAAQ,CAAC,IAAI,EAAgB,CAAC;IACtC,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,IAAI,CAAC,UAA4B,MAAM;QAC5C,OAAO,IAAI,CAAC,KAAK,CAAe,0BAA0B,OAAO,EAAE,CAAC,CAAC;IACtE,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,IAAI,CACT,MAAc,EACd,YAAoC,EACpC,OAAgB;QAEhB,OAAO,IAAI,CAAC,KAAK,CAAe,gBAAgB,EAAE;YACjD,MAAM,EAAE,MAAM;YACd,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,YAAY,EAAE,OAAO,EAAE,CAAC;SACvD,CAAC,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,YAAY;QACjB,OAAO,IAAI,CAAC,KAAK,CAAoB,qBAAqB,CAAC,CAAC;IAC7D,CAAC;CACD"}
package/dist/cli.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}
package/dist/cli.js ADDED
@@ -0,0 +1,40 @@
1
+ #!/usr/bin/env node
2
+ import { Command } from 'commander';
3
+ import { loadConfig } from './config.js';
4
+ import { pull } from './commands/pull.js';
5
+ import { push } from './commands/push.js';
6
+ const program = new Command();
7
+ program
8
+ .name('edgecms')
9
+ .description('CLI SDK for EdgeCMS i18n - pull and push translations')
10
+ .version('0.1.0');
11
+ program
12
+ .command('pull')
13
+ .description('Pull translations from EdgeCMS and generate TypeScript types')
14
+ .option('--from <from>', 'Pull from "draft" or "live"', 'live')
15
+ .action(async (options) => {
16
+ try {
17
+ const config = loadConfig();
18
+ await pull(config, { version: options.from });
19
+ }
20
+ catch (error) {
21
+ console.error('Error:', error.message);
22
+ process.exit(1);
23
+ }
24
+ });
25
+ program
26
+ .command('push')
27
+ .description('Push local translations to EdgeCMS (default locale only)')
28
+ .option('-s, --section <section>', 'Section to assign to new keys')
29
+ .action(async (options) => {
30
+ try {
31
+ const config = loadConfig();
32
+ await push(config, { section: options.section });
33
+ }
34
+ catch (error) {
35
+ console.error('Error:', error.message);
36
+ process.exit(1);
37
+ }
38
+ });
39
+ program.parse();
40
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAC;AAC1C,OAAO,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAC;AAE1C,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACL,IAAI,CAAC,SAAS,CAAC;KACf,WAAW,CAAC,uDAAuD,CAAC;KACpE,OAAO,CAAC,OAAO,CAAC,CAAC;AAEnB,OAAO;KACL,OAAO,CAAC,MAAM,CAAC;KACf,WAAW,CAAC,8DAA8D,CAAC;KAC3E,MAAM,CAAC,eAAe,EAAE,6BAA6B,EAAE,MAAM,CAAC;KAC9D,MAAM,CAAC,KAAK,EAAC,OAAO,EAAC,EAAE;IACvB,IAAI,CAAC;QACJ,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;QAC5B,MAAM,IAAI,CAAC,MAAM,EAAE,EAAE,OAAO,EAAE,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;IAC/C,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QAChB,OAAO,CAAC,KAAK,CAAC,QAAQ,EAAG,KAAe,CAAC,OAAO,CAAC,CAAC;QAClD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACjB,CAAC;AACF,CAAC,CAAC,CAAC;AAEJ,OAAO;KACL,OAAO,CAAC,MAAM,CAAC;KACf,WAAW,CAAC,0DAA0D,CAAC;KACvE,MAAM,CAAC,yBAAyB,EAAE,+BAA+B,CAAC;KAClE,MAAM,CAAC,KAAK,EAAC,OAAO,EAAC,EAAE;IACvB,IAAI,CAAC;QACJ,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;QAC5B,MAAM,IAAI,CAAC,MAAM,EAAE,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;IAClD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QAChB,OAAO,CAAC,KAAK,CAAC,QAAQ,EAAG,KAAe,CAAC,OAAO,CAAC,CAAC;QAClD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACjB,CAAC;AACF,CAAC,CAAC,CAAC;AAEJ,OAAO,CAAC,KAAK,EAAE,CAAC"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Generates TypeScript type definitions from translation keys.
3
+ */
4
+ export declare function generateTypes(keys: string[]): string;
5
+ //# sourceMappingURL=codegen.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codegen.d.ts","sourceRoot":"","sources":["../src/codegen.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,CA8BpD"}
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Generates TypeScript type definitions from translation keys.
3
+ */
4
+ export function generateTypes(keys) {
5
+ const sortedKeys = [...keys].sort();
6
+ const lines = [
7
+ '// Auto-generated by @edgecms/sdk - do not edit manually',
8
+ '// Run `edgecms pull` to regenerate this file',
9
+ '',
10
+ 'export interface TranslationKeys {',
11
+ ];
12
+ for (const key of sortedKeys) {
13
+ // Escape quotes in key names
14
+ const escapedKey = key.replace(/"/g, '\\"');
15
+ lines.push(` "${escapedKey}": string;`);
16
+ }
17
+ lines.push('}');
18
+ lines.push('');
19
+ lines.push('export type TranslationKey = keyof TranslationKeys;');
20
+ lines.push('');
21
+ lines.push('/**');
22
+ lines.push(' * Helper function to get a typed translation key.');
23
+ lines.push(' * This ensures the key exists at compile time.');
24
+ lines.push(' */');
25
+ lines.push('export function t<K extends TranslationKey>(key: K): K {');
26
+ lines.push(' return key;');
27
+ lines.push('}');
28
+ lines.push('');
29
+ return lines.join('\n');
30
+ }
31
+ //# sourceMappingURL=codegen.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codegen.js","sourceRoot":"","sources":["../src/codegen.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,UAAU,aAAa,CAAC,IAAc;IAC3C,MAAM,UAAU,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC;IAEpC,MAAM,KAAK,GAAG;QACb,0DAA0D;QAC1D,+CAA+C;QAC/C,EAAE;QACF,oCAAoC;KACpC,CAAC;IAEF,KAAK,MAAM,GAAG,IAAI,UAAU,EAAE,CAAC;QAC9B,6BAA6B;QAC7B,MAAM,UAAU,GAAG,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QAC5C,KAAK,CAAC,IAAI,CAAC,MAAM,UAAU,YAAY,CAAC,CAAC;IAC1C,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAChB,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACf,KAAK,CAAC,IAAI,CAAC,qDAAqD,CAAC,CAAC;IAClE,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACf,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAClB,KAAK,CAAC,IAAI,CAAC,oDAAoD,CAAC,CAAC;IACjE,KAAK,CAAC,IAAI,CAAC,iDAAiD,CAAC,CAAC;IAC9D,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAClB,KAAK,CAAC,IAAI,CAAC,0DAA0D,CAAC,CAAC;IACvE,KAAK,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;IAC5B,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAChB,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAEf,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACzB,CAAC"}
@@ -0,0 +1,10 @@
1
+ import type { EdgeCMSConfig } from '../config.js';
2
+ export interface PullOptions {
3
+ version?: 'draft' | 'live';
4
+ }
5
+ /**
6
+ * Pull translations from EdgeCMS and write to local files.
7
+ * Also generates TypeScript types.
8
+ */
9
+ export declare function pull(config: EdgeCMSConfig, options?: PullOptions): Promise<void>;
10
+ //# sourceMappingURL=pull.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pull.d.ts","sourceRoot":"","sources":["../../src/commands/pull.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAIlD,MAAM,WAAW,WAAW;IAC3B,OAAO,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;CAC3B;AAED;;;GAGG;AACH,wBAAsB,IAAI,CACzB,MAAM,EAAE,aAAa,EACrB,OAAO,GAAE,WAAgB,GACvB,OAAO,CAAC,IAAI,CAAC,CAkDf"}
@@ -0,0 +1,47 @@
1
+ import { writeFileSync, mkdirSync, existsSync } from 'node:fs';
2
+ import { resolve, dirname } from 'node:path';
3
+ import { EdgeCMSClient } from '../api.js';
4
+ import { generateTypes } from '../codegen.js';
5
+ /**
6
+ * Pull translations from EdgeCMS and write to local files.
7
+ * Also generates TypeScript types.
8
+ */
9
+ export async function pull(config, options = {}) {
10
+ const client = new EdgeCMSClient(config);
11
+ const version = options.version || 'live';
12
+ console.log(`Pulling translations (version: ${version})...`);
13
+ const response = await client.pull(version);
14
+ // Ensure locales directory exists
15
+ const localesDir = resolve(process.cwd(), config.localesDir);
16
+ if (!existsSync(localesDir)) {
17
+ mkdirSync(localesDir, { recursive: true });
18
+ console.log(`Created directory: ${config.localesDir}`);
19
+ }
20
+ // Write JSON files for each locale
21
+ let totalKeys = 0;
22
+ for (const [locale, translations] of Object.entries(response.translations)) {
23
+ const filePath = resolve(localesDir, `${locale}.json`);
24
+ const content = JSON.stringify(translations, null, 2);
25
+ writeFileSync(filePath, content + '\n', 'utf-8');
26
+ const keyCount = Object.keys(translations).length;
27
+ totalKeys = Math.max(totalKeys, keyCount);
28
+ console.log(` ${locale}.json (${keyCount} keys)`);
29
+ }
30
+ // Generate TypeScript types from default locale keys
31
+ const defaultTranslations = response.translations[config.defaultLocale] ||
32
+ response.translations[response.defaultLocale || ''] ||
33
+ Object.values(response.translations)[0] ||
34
+ {};
35
+ const keys = Object.keys(defaultTranslations);
36
+ const typesContent = generateTypes(keys);
37
+ // Ensure types output directory exists
38
+ const typesPath = resolve(process.cwd(), config.typesOutputPath);
39
+ const typesDir = dirname(typesPath);
40
+ if (!existsSync(typesDir)) {
41
+ mkdirSync(typesDir, { recursive: true });
42
+ }
43
+ writeFileSync(typesPath, typesContent, 'utf-8');
44
+ console.log(` ${config.typesOutputPath} (${keys.length} keys)`);
45
+ console.log(`\nPull complete! ${response.languages.length} locales, ${totalKeys} keys.`);
46
+ }
47
+ //# sourceMappingURL=pull.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pull.js","sourceRoot":"","sources":["../../src/commands/pull.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ import type { EdgeCMSConfig } from '../config.js';
2
+ export interface PushOptions {
3
+ section?: string;
4
+ }
5
+ /**
6
+ * Push local translations to EdgeCMS.
7
+ * Only pushes the default locale.
8
+ */
9
+ export declare function push(config: EdgeCMSConfig, options?: PushOptions): Promise<void>;
10
+ //# sourceMappingURL=push.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"push.d.ts","sourceRoot":"","sources":["../../src/commands/push.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAGlD,MAAM,WAAW,WAAW;IAC3B,OAAO,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;GAGG;AACH,wBAAsB,IAAI,CACzB,MAAM,EAAE,aAAa,EACrB,OAAO,GAAE,WAAgB,GACvB,OAAO,CAAC,IAAI,CAAC,CAwCf"}
@@ -0,0 +1,40 @@
1
+ import { readFileSync, existsSync } from 'node:fs';
2
+ import { resolve } from 'node:path';
3
+ import { EdgeCMSClient } from '../api.js';
4
+ /**
5
+ * Push local translations to EdgeCMS.
6
+ * Only pushes the default locale.
7
+ */
8
+ export async function push(config, options = {}) {
9
+ const client = new EdgeCMSClient(config);
10
+ const locale = config.defaultLocale;
11
+ // Read local translations file
12
+ const localesDir = resolve(process.cwd(), config.localesDir);
13
+ const filePath = resolve(localesDir, `${locale}.json`);
14
+ if (!existsSync(filePath)) {
15
+ throw new Error(`Translations file not found: ${filePath}\n` +
16
+ `Run 'edgecms pull' first to download translations.`);
17
+ }
18
+ let translations;
19
+ try {
20
+ const content = readFileSync(filePath, 'utf-8');
21
+ translations = JSON.parse(content);
22
+ }
23
+ catch (error) {
24
+ throw new Error(`Failed to parse ${filePath}: ${error.message}`);
25
+ }
26
+ const keyCount = Object.keys(translations).length;
27
+ console.log(`Pushing ${locale}.json (${keyCount} keys)...`);
28
+ if (options.section) {
29
+ console.log(` Section: ${options.section}`);
30
+ }
31
+ const response = await client.push(locale, translations, options.section);
32
+ if (response.success) {
33
+ console.log(`\nPush complete! ${response.keysUpdated} keys updated.`);
34
+ console.log('\nNote: Changes are saved as a draft. Publish from the CMS to make them live.');
35
+ }
36
+ else {
37
+ throw new Error('Push failed: unexpected response');
38
+ }
39
+ }
40
+ //# sourceMappingURL=push.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"push.js","sourceRoot":"","sources":["../../src/commands/push.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAM1C;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,IAAI,CACzB,MAAqB,EACrB,UAAuB,EAAE;IAEzB,MAAM,MAAM,GAAG,IAAI,aAAa,CAAC,MAAM,CAAC,CAAC;IACzC,MAAM,MAAM,GAAG,MAAM,CAAC,aAAa,CAAC;IAEpC,+BAA+B;IAC/B,MAAM,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,MAAM,CAAC,UAAU,CAAC,CAAC;IAC7D,MAAM,QAAQ,GAAG,OAAO,CAAC,UAAU,EAAE,GAAG,MAAM,OAAO,CAAC,CAAC;IAEvD,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC3B,MAAM,IAAI,KAAK,CACd,gCAAgC,QAAQ,IAAI;YAC3C,oDAAoD,CACrD,CAAC;IACH,CAAC;IAED,IAAI,YAAoC,CAAC;IACzC,IAAI,CAAC;QACJ,MAAM,OAAO,GAAG,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QAChD,YAAY,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IACpC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QAChB,MAAM,IAAI,KAAK,CAAC,mBAAmB,QAAQ,KAAM,KAAe,CAAC,OAAO,EAAE,CAAC,CAAC;IAC7E,CAAC;IAED,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,MAAM,CAAC;IAClD,OAAO,CAAC,GAAG,CAAC,WAAW,MAAM,UAAU,QAAQ,WAAW,CAAC,CAAC;IAE5D,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;QACrB,OAAO,CAAC,GAAG,CAAC,cAAc,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;IAC9C,CAAC;IAED,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,YAAY,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;IAE1E,IAAI,QAAQ,CAAC,OAAO,EAAE,CAAC;QACtB,OAAO,CAAC,GAAG,CAAC,oBAAoB,QAAQ,CAAC,WAAW,gBAAgB,CAAC,CAAC;QACtE,OAAO,CAAC,GAAG,CACV,+EAA+E,CAC/E,CAAC;IACH,CAAC;SAAM,CAAC;QACP,MAAM,IAAI,KAAK,CAAC,kCAAkC,CAAC,CAAC;IACrD,CAAC;AACF,CAAC"}
@@ -0,0 +1,18 @@
1
+ export interface EdgeCMSConfig {
2
+ /** Base URL of the EdgeCMS instance (e.g., "https://cms.example.com/edge-cms") */
3
+ baseUrl: string;
4
+ /** API key for authentication (can use ${ENV_VAR} syntax) */
5
+ apiKey: string;
6
+ /** Directory where locale JSON files are stored */
7
+ localesDir: string;
8
+ /** Default locale (e.g., "en") */
9
+ defaultLocale: string;
10
+ /** Path to output TypeScript types file */
11
+ typesOutputPath: string;
12
+ }
13
+ /**
14
+ * Loads the EdgeCMS configuration from the project root.
15
+ * Looks for edgecms.config.json in the current working directory.
16
+ */
17
+ export declare function loadConfig(cwd?: string): EdgeCMSConfig;
18
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,aAAa;IAC7B,kFAAkF;IAClF,OAAO,EAAE,MAAM,CAAC;IAChB,6DAA6D;IAC7D,MAAM,EAAE,MAAM,CAAC;IACf,mDAAmD;IACnD,UAAU,EAAE,MAAM,CAAC;IACnB,kCAAkC;IAClC,aAAa,EAAE,MAAM,CAAC;IACtB,2CAA2C;IAC3C,eAAe,EAAE,MAAM,CAAC;CACxB;AAqBD;;;GAGG;AACH,wBAAgB,UAAU,CAAC,GAAG,GAAE,MAAsB,GAAG,aAAa,CA8DrE"}
package/dist/config.js ADDED
@@ -0,0 +1,69 @@
1
+ import { readFileSync, existsSync } from 'node:fs';
2
+ import { resolve } from 'node:path';
3
+ const CONFIG_FILENAME = 'edgecms.config.json';
4
+ /**
5
+ * Resolves environment variable references in a string.
6
+ * Supports ${VAR_NAME} syntax.
7
+ */
8
+ function resolveEnvVars(value) {
9
+ return value.replace(/\$\{([^}]+)\}/g, (_, envVar) => {
10
+ const envValue = process.env[envVar];
11
+ if (!envValue) {
12
+ throw new Error(`Environment variable "${envVar}" is not set. ` +
13
+ `Please set it in your environment or .env file.`);
14
+ }
15
+ return envValue;
16
+ });
17
+ }
18
+ /**
19
+ * Loads the EdgeCMS configuration from the project root.
20
+ * Looks for edgecms.config.json in the current working directory.
21
+ */
22
+ export function loadConfig(cwd = process.cwd()) {
23
+ const configPath = resolve(cwd, CONFIG_FILENAME);
24
+ if (!existsSync(configPath)) {
25
+ throw new Error(`Configuration file not found: ${CONFIG_FILENAME}\n` +
26
+ `Please create a ${CONFIG_FILENAME} file in your project root.\n\n` +
27
+ `Example:\n` +
28
+ JSON.stringify({
29
+ baseUrl: 'https://your-cms.example.com/edge-cms',
30
+ apiKey: '${EDGECMS_API_KEY}',
31
+ localesDir: './src/locales',
32
+ defaultLocale: 'en',
33
+ typesOutputPath: './src/locales/types.ts',
34
+ }, null, 2));
35
+ }
36
+ let rawConfig;
37
+ try {
38
+ const content = readFileSync(configPath, 'utf-8');
39
+ rawConfig = JSON.parse(content);
40
+ }
41
+ catch (error) {
42
+ throw new Error(`Failed to parse ${CONFIG_FILENAME}: ${error.message}`);
43
+ }
44
+ // Validate required fields
45
+ const requiredFields = [
46
+ 'baseUrl',
47
+ 'apiKey',
48
+ 'localesDir',
49
+ 'defaultLocale',
50
+ 'typesOutputPath',
51
+ ];
52
+ for (const field of requiredFields) {
53
+ if (!rawConfig[field]) {
54
+ throw new Error(`Missing required field "${field}" in ${CONFIG_FILENAME}`);
55
+ }
56
+ }
57
+ // Resolve environment variables in apiKey
58
+ const apiKey = resolveEnvVars(rawConfig.apiKey);
59
+ // Normalize baseUrl (remove trailing slash)
60
+ const baseUrl = rawConfig.baseUrl.replace(/\/$/, '');
61
+ return {
62
+ baseUrl,
63
+ apiKey,
64
+ localesDir: rawConfig.localesDir,
65
+ defaultLocale: rawConfig.defaultLocale,
66
+ typesOutputPath: rawConfig.typesOutputPath,
67
+ };
68
+ }
69
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAepC,MAAM,eAAe,GAAG,qBAAqB,CAAC;AAE9C;;;GAGG;AACH,SAAS,cAAc,CAAC,KAAa;IACpC,OAAO,KAAK,CAAC,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE;QACpD,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACrC,IAAI,CAAC,QAAQ,EAAE,CAAC;YACf,MAAM,IAAI,KAAK,CACd,yBAAyB,MAAM,gBAAgB;gBAC9C,iDAAiD,CAClD,CAAC;QACH,CAAC;QACD,OAAO,QAAQ,CAAC;IACjB,CAAC,CAAC,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,UAAU,CAAC,MAAc,OAAO,CAAC,GAAG,EAAE;IACrD,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,EAAE,eAAe,CAAC,CAAC;IAEjD,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC7B,MAAM,IAAI,KAAK,CACd,iCAAiC,eAAe,IAAI;YACnD,mBAAmB,eAAe,iCAAiC;YACnE,YAAY;YACZ,IAAI,CAAC,SAAS,CACb;gBACC,OAAO,EAAE,uCAAuC;gBAChD,MAAM,EAAE,oBAAoB;gBAC5B,UAAU,EAAE,eAAe;gBAC3B,aAAa,EAAE,IAAI;gBACnB,eAAe,EAAE,wBAAwB;aACzC,EACD,IAAI,EACJ,CAAC,CACD,CACF,CAAC;IACH,CAAC;IAED,IAAI,SAAiC,CAAC;IACtC,IAAI,CAAC;QACJ,MAAM,OAAO,GAAG,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;QAClD,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IACjC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QAChB,MAAM,IAAI,KAAK,CACd,mBAAmB,eAAe,KAAM,KAAe,CAAC,OAAO,EAAE,CACjE,CAAC;IACH,CAAC;IAED,2BAA2B;IAC3B,MAAM,cAAc,GAA4B;QAC/C,SAAS;QACT,QAAQ;QACR,YAAY;QACZ,eAAe;QACf,iBAAiB;KACjB,CAAC;IAEF,KAAK,MAAM,KAAK,IAAI,cAAc,EAAE,CAAC;QACpC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC;YACvB,MAAM,IAAI,KAAK,CACd,2BAA2B,KAAK,QAAQ,eAAe,EAAE,CACzD,CAAC;QACH,CAAC;IACF,CAAC;IAED,0CAA0C;IAC1C,MAAM,MAAM,GAAG,cAAc,CAAC,SAAS,CAAC,MAAO,CAAC,CAAC;IAEjD,4CAA4C;IAC5C,MAAM,OAAO,GAAG,SAAS,CAAC,OAAQ,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IAEtD,OAAO;QACN,OAAO;QACP,MAAM;QACN,UAAU,EAAE,SAAS,CAAC,UAAW;QACjC,aAAa,EAAE,SAAS,CAAC,aAAc;QACvC,eAAe,EAAE,SAAS,CAAC,eAAgB;KAC3C,CAAC;AACH,CAAC"}
@@ -0,0 +1,6 @@
1
+ export { loadConfig, type EdgeCMSConfig } from './config.js';
2
+ export { EdgeCMSClient, type PullResponse, type PushResponse, type Language, } from './api.js';
3
+ export { generateTypes } from './codegen.js';
4
+ export { pull, type PullOptions } from './commands/pull.js';
5
+ export { push, type PushOptions } from './commands/push.js';
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,KAAK,aAAa,EAAE,MAAM,aAAa,CAAC;AAC7D,OAAO,EACN,aAAa,EACb,KAAK,YAAY,EACjB,KAAK,YAAY,EACjB,KAAK,QAAQ,GACb,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,EAAE,IAAI,EAAE,KAAK,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,EAAE,IAAI,EAAE,KAAK,WAAW,EAAE,MAAM,oBAAoB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,7 @@
1
+ // Re-export everything for programmatic usage
2
+ export { loadConfig } from './config.js';
3
+ export { EdgeCMSClient, } from './api.js';
4
+ export { generateTypes } from './codegen.js';
5
+ export { pull } from './commands/pull.js';
6
+ export { push } from './commands/push.js';
7
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,8CAA8C;AAC9C,OAAO,EAAE,UAAU,EAAsB,MAAM,aAAa,CAAC;AAC7D,OAAO,EACN,aAAa,GAIb,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,EAAE,IAAI,EAAoB,MAAM,oBAAoB,CAAC;AAC5D,OAAO,EAAE,IAAI,EAAoB,MAAM,oBAAoB,CAAC"}
package/package.json ADDED
@@ -0,0 +1,30 @@
1
+ {
2
+ "name": "@upbeat-works/edgecms-sdk",
3
+ "version": "0.1.0",
4
+ "description": "CLI SDK for EdgeCMS i18n - pull and push translations",
5
+ "type": "module",
6
+ "bin": {
7
+ "edgecms": "./bin/edgecms.js"
8
+ },
9
+ "main": "./dist/index.js",
10
+ "types": "./dist/index.d.ts",
11
+ "files": [
12
+ "dist",
13
+ "bin"
14
+ ],
15
+ "scripts": {
16
+ "build": "tsc",
17
+ "dev": "tsc --watch",
18
+ "typecheck": "tsc --noEmit"
19
+ },
20
+ "dependencies": {
21
+ "commander": "^12.1.0"
22
+ },
23
+ "devDependencies": {
24
+ "@types/node": "^20.19.9",
25
+ "typescript": "^5.8.3"
26
+ },
27
+ "engines": {
28
+ "node": ">=18"
29
+ }
30
+ }