@contentstorage/core 0.3.7 → 0.3.9

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/dist/index.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- import { AppConfig } from './lib/configLoader.js';
2
- export { AppConfig };
1
+ import { AppConfig, LanguageCode } from './types.js';
2
+ export { AppConfig, LanguageCode };
@@ -1,6 +1,2 @@
1
- export interface AppConfig {
2
- contentUrl: string;
3
- contentDir: string;
4
- typesOutputFile: string;
5
- }
1
+ import { AppConfig } from '../types.js';
6
2
  export declare function loadConfig(): Promise<AppConfig>;
@@ -1,6 +1,7 @@
1
1
  import path from 'path';
2
2
  import fs from 'fs';
3
3
  const DEFAULT_CONFIG = {
4
+ languageCodes: [],
4
5
  contentDir: path.join('src', 'assets', 'content'),
5
6
  typesOutputFile: path.join('src', 'generated', 'content-types.ts'),
6
7
  };
@@ -37,6 +38,7 @@ export async function loadConfig() {
37
38
  }
38
39
  // Resolve paths relative to the user's project root (process.cwd())
39
40
  const finalConfig = {
41
+ languageCodes: mergedConfig.languageCodes || [],
40
42
  contentUrl: mergedConfig.contentUrl,
41
43
  contentDir: path.resolve(process.cwd(), mergedConfig.contentDir),
42
44
  typesOutputFile: path.resolve(process.cwd(), mergedConfig.typesOutputFile),
@@ -6,59 +6,78 @@ import chalk from 'chalk';
6
6
  import { loadConfig } from '../lib/configLoader.js';
7
7
  export async function pullContent() {
8
8
  console.log(chalk.blue('Starting content pull...'));
9
+ // Load configuration (assuming this function is defined elsewhere and works)
9
10
  const config = await loadConfig();
10
- console.log(chalk.gray(`Getting content from: ${config.contentUrl}`));
11
+ console.log(chalk.gray(`Content base URL: ${config.contentUrl}`));
11
12
  console.log(chalk.gray(`Saving content to: ${config.contentDir}`));
12
13
  try {
13
- // Fetch data
14
- const response = await axios.get(config.contentUrl);
15
- const jsonData = response.data; // Assume axios parses JSON automatically
16
- if (!jsonData) {
17
- throw new Error('No data received from the URL.');
14
+ // Validate languageCodes array
15
+ if (!Array.isArray(config.languageCodes)) {
16
+ console.log(chalk.red(`Expected array from config.languageCodes, but received type ${typeof config.languageCodes}. Cannot pull files.`));
17
+ return; // Exit if languageCodes is not an array
18
18
  }
19
- // Ensure the output directory exists
20
- await fs.mkdir(config.contentDir, { recursive: true });
21
- // --- How to save the data? ---
22
- // Option 1: Save the entire response as one file (e.g., content.json)
23
- // const outputPath = path.join(config.contentDir, 'content.json');
24
- // await fs.writeFile(outputPath, JSON.stringify(jsonData, null, 2));
25
- // console.log(chalk.green(`Content saved successfully to ${outputPath}`));
26
- // Option 2: Assume the response is an ARRAY of objects, save each as a separate file
27
- // This matches the requirement "use the first file from the directory" later
28
- if (!Array.isArray(jsonData)) {
29
- throw new Error(`Expected an array of objects from ${config.contentUrl}, but received type ${typeof jsonData}. Cannot save individual files.`);
30
- }
31
- if (jsonData.length === 0) {
32
- console.log(chalk.yellow('Received empty array. No files to save.'));
33
- return;
19
+ if (config.languageCodes.length === 0) {
20
+ console.log(chalk.yellow('config.languageCodes array is empty. No files to pull.'));
21
+ return; // Exit if languageCodes array is empty
34
22
  }
35
- console.log(chalk.gray(`Received ${jsonData.length} items. Saving individually...`));
36
- let filesSavedCount = 0;
37
- for (let i = 0; i < jsonData.length; i++) {
38
- const item = jsonData[i];
39
- // Determine filename: use 'id' or 'slug' if available, otherwise use index
40
- const filename = `${item.id || item.slug || i}.json`;
23
+ // Ensure the output directory exists (create it once before the loop)
24
+ await fs.mkdir(config.contentDir, { recursive: true });
25
+ // Process each language code
26
+ for (const languageCode of config.languageCodes) {
27
+ const fileUrl = `${config.contentUrl}/${languageCode}.json`;
28
+ const filename = `${languageCode}.json`;
41
29
  const outputPath = path.join(config.contentDir, filename);
30
+ console.log(chalk.blue(`\nProcessing language: ${languageCode}`));
31
+ console.log(chalk.gray(`Workspaceing from: ${fileUrl}`));
42
32
  try {
43
- await fs.writeFile(outputPath, JSON.stringify(item, null, 2));
44
- filesSavedCount++;
33
+ // Fetch data for the current language
34
+ const response = await axios.get(fileUrl);
35
+ const jsonData = response.data;
36
+ // Basic check for data existence, although axios usually throws for non-2xx responses
37
+ if (jsonData === undefined || jsonData === null) {
38
+ throw new Error(`No data received from ${fileUrl} for language ${languageCode}.`);
39
+ }
40
+ // Validate that jsonData is a single, non-null JSON object (not an array)
41
+ // This check mirrors the original code's expectation for the content of a JSON file.
42
+ if (typeof jsonData !== 'object' ||
43
+ Array.isArray(jsonData) /* jsonData === null is already covered */) {
44
+ throw new Error(`Expected a single JSON object from ${fileUrl} for language ${languageCode}, but received type ${Array.isArray(jsonData) ? 'array' : typeof jsonData}. Cannot save the file.`);
45
+ }
46
+ console.log(chalk.green(`Received JSON for ${languageCode}. Saving to ${outputPath}`));
47
+ // Write the JSON data to the file
48
+ await fs.writeFile(outputPath, JSON.stringify(jsonData, null, 2));
49
+ console.log(chalk.green(`Successfully saved ${outputPath}`));
45
50
  }
46
- catch (writeError) {
47
- console.error(chalk.red(`Error saving file ${filename}:`), writeError.message);
48
- // Optionally decide whether to continue or stop on error
51
+ catch (error) {
52
+ // Catch errors related to fetching or saving a single language file
53
+ console.error(chalk.red(`\nError processing language ${languageCode} from ${fileUrl}:`));
54
+ if (axios.isAxiosError(error)) {
55
+ console.error(chalk.red(` Status: ${error.response?.status}`));
56
+ console.error(chalk.red(`Response Data: ${error.response?.data ? JSON.stringify(error.response.data) : 'N/A'}`));
57
+ console.error(chalk.red(` Message: ${error.message}`)); // Axios error message
58
+ }
59
+ else {
60
+ // For non-Axios errors (e.g., manually thrown errors, fs errors)
61
+ console.error(chalk.red(` Error: ${error.message}`));
62
+ }
63
+ // Re-throw the error to be caught by the outer try-catch block,
64
+ // which will then call process.exit(1), maintaining original exit behavior on error.
65
+ throw error;
49
66
  }
50
67
  }
51
- console.log(chalk.green(`Successfully saved ${filesSavedCount} files to ${config.contentDir}`));
68
+ console.log(chalk.green('\nAll content successfully pulled and saved.'));
52
69
  }
53
- catch (error) {
54
- console.error(chalk.red('Error fetching or saving content:'));
55
- if (axios.isAxiosError(error)) {
56
- console.error(chalk.red(`Status: ${error.response?.status}`));
57
- console.error(chalk.red(`Data: ${JSON.stringify(error.response?.data)}`));
58
- }
59
- else {
60
- console.error(chalk.red(error.message));
61
- }
70
+ catch {
71
+ // Outer catch for setup errors (like loadConfig) or re-thrown errors from the loop
72
+ // The specific error details for a file operation would have been logged by the inner catch.
73
+ // This block provides a general failure message and ensures the process exits with an error code.
74
+ console.error(chalk.red('\n-----------------------------------------------------'));
75
+ console.error(chalk.red('Content pull failed due to an error. See details above.'));
76
+ // error.message from the re-thrown error will be implicitly part of the error object logged by some environments,
77
+ // or if you add console.error(error) here.
78
+ // The original code logged error.message at this level:
79
+ // if (error.message) console.error(chalk.red(`Underlying error: ${error.message}`));
80
+ console.error(chalk.red('-----------------------------------------------------'));
62
81
  process.exit(1); // Exit with error code
63
82
  }
64
83
  }
@@ -0,0 +1,7 @@
1
+ export type AppConfig = {
2
+ languageCodes: LanguageCode[];
3
+ contentUrl: string;
4
+ contentDir: string;
5
+ typesOutputFile: string;
6
+ };
7
+ export type LanguageCode = 'SQ' | 'BE' | 'BS' | 'BG' | 'HR' | 'CS' | 'DA' | 'NL' | 'EN' | 'ET' | 'FI' | 'FR' | 'DE' | 'EL' | 'HU' | 'GA' | 'IT' | 'LV' | 'LT' | 'MK' | 'NO' | 'PL' | 'PT' | 'RO' | 'RU' | 'SR' | 'SK' | 'SL' | 'ES' | 'SV' | 'TR' | 'UK';
package/dist/types.js ADDED
@@ -0,0 +1 @@
1
+ export {};
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@contentstorage/core",
3
3
  "author": "Kaido Hussar <kaidohus@gmail.com>",
4
4
  "homepage": "https://contentstorage.app",
5
- "version": "0.3.7",
5
+ "version": "0.3.9",
6
6
  "type": "module",
7
7
  "description": "Fetch content from contentstorage and generate TypeScript types",
8
8
  "module": "dist/index.js",