@contentstorage/core 1.0.2 → 1.1.1

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.
@@ -1,3 +1,4 @@
1
1
  export declare const CONTENTSTORAGE_CONFIG: {
2
2
  BASE_URL: string;
3
+ API_URL: string;
3
4
  };
@@ -1,3 +1,4 @@
1
1
  export const CONTENTSTORAGE_CONFIG = {
2
2
  BASE_URL: 'https://cdn.contentstorage.app',
3
+ API_URL: 'https://api.contentstorage.app',
3
4
  };
package/dist/index.js CHANGED
@@ -1,3 +1,4 @@
1
+ import { CONTENTSTORAGE_CONFIG } from './contentstorage-config.js';
1
2
  import { setContentLanguage, getText, getImage, getVariation, initContentStorage, } from './lib/contentManagement.js';
2
3
  import { fetchContent } from './lib/functions/fetchContent.js';
3
4
  export { initContentStorage, fetchContent, setContentLanguage, getText, getImage, getVariation, liveEditorReady, };
@@ -24,7 +25,7 @@ function liveEditorReady(retries = 2, delay = 3000) {
24
25
  resolve(false);
25
26
  return;
26
27
  }
27
- const cdnScriptUrl = `https://cdn.contentstorage.app/live-editor.js?contentstorage-live-editor=true`;
28
+ const cdnScriptUrl = `${CONTENTSTORAGE_CONFIG.BASE_URL}/live-editor.js?contentstorage-live-editor=true`;
28
29
  const loadScript = (attempt = 1) => {
29
30
  console.log(`Attempting to load Contentstorage live editor script (attempt ${attempt}/${retries})`);
30
31
  const scriptElement = document.createElement('script');
@@ -1,6 +1,6 @@
1
1
  import { AppConfig, ContentStructure, GetImageReturn, GetTextReturn, GetVariationReturn, LanguageCode } from '../types.js';
2
2
  export declare let activeContent: object | null;
3
- export declare let appConfig: Pick<AppConfig, 'contentKey' | 'languageCodes'> | null;
3
+ export declare let appConfig: Pick<AppConfig, 'contentKey' | 'languageCodes' | 'pendingChanges'> | null;
4
4
  /**
5
5
  * Loads and sets the content for a specific language.
6
6
  * It will internally ensure the application configuration (for contentDir) is loaded.
@@ -1,2 +1,7 @@
1
1
  import { LanguageCode } from '../../types.js';
2
- export declare function fetchContent(language?: LanguageCode): Promise<void>;
2
+ interface FetchContentOptions {
3
+ withPendingChanges?: boolean;
4
+ contentKey?: string;
5
+ }
6
+ export declare function fetchContent(language?: LanguageCode, options?: FetchContentOptions): Promise<void>;
7
+ export {};
@@ -1,8 +1,10 @@
1
1
  import axios from 'axios';
2
2
  import { CONTENTSTORAGE_CONFIG } from '../../contentstorage-config.js';
3
3
  import { appConfig, setContentLanguage } from '../contentManagement.js';
4
- export async function fetchContent(language) {
4
+ export async function fetchContent(language, options = {}) {
5
+ const { withPendingChanges, contentKey } = options;
5
6
  const languageToFetch = language || appConfig?.languageCodes?.[0];
7
+ const usePendingChangesToFetch = withPendingChanges || appConfig?.pendingChanges;
6
8
  console.log(`Starting content fetch for language ${language}...`);
7
9
  if (!languageToFetch) {
8
10
  throw Error(`No language found`);
@@ -10,11 +12,29 @@ export async function fetchContent(language) {
10
12
  if (!appConfig) {
11
13
  throw Error(`No app config found`);
12
14
  }
13
- const fileUrl = `${CONTENTSTORAGE_CONFIG.BASE_URL}/${appConfig.contentKey}/content/${languageToFetch}.json`;
15
+ const effectiveContentKey = contentKey || appConfig.contentKey;
16
+ let fileUrl;
17
+ let requestConfig = {};
18
+ if (usePendingChangesToFetch) {
19
+ if (!effectiveContentKey) {
20
+ throw Error(`No contentKey found`);
21
+ }
22
+ fileUrl = `${CONTENTSTORAGE_CONFIG.API_URL}/pending-changes/get-json?languageCode=${languageToFetch}`;
23
+ requestConfig.headers = {
24
+ 'X-Content-Key': effectiveContentKey,
25
+ };
26
+ }
27
+ else {
28
+ fileUrl = `${CONTENTSTORAGE_CONFIG.BASE_URL}/${effectiveContentKey}/content/${languageToFetch}.json`;
29
+ }
14
30
  try {
15
31
  // Fetch data for the current language
16
- const response = await axios.get(fileUrl);
17
- const jsonData = response.data;
32
+ const response = await axios.get(fileUrl, requestConfig);
33
+ let jsonData = response.data;
34
+ // Handle API response structure - only for pending changes API
35
+ if (usePendingChangesToFetch && jsonData && typeof jsonData === 'object' && 'data' in jsonData) {
36
+ jsonData = jsonData.data;
37
+ }
18
38
  if (jsonData === undefined || jsonData === null) {
19
39
  throw new Error(`No data received from ${fileUrl} for language ${languageToFetch}.`);
20
40
  }
@@ -17,7 +17,10 @@ export async function generateTypes() {
17
17
  if (arg.startsWith('--')) {
18
18
  const key = arg.substring(2);
19
19
  const value = args[i + 1];
20
- if (value && !value.startsWith('--')) {
20
+ if (key === 'pending-changes') {
21
+ cliConfig.pendingChanges = true;
22
+ }
23
+ else if (value && !value.startsWith('--')) {
21
24
  if (key === 'lang') {
22
25
  cliConfig.languageCodes = [value.toUpperCase()];
23
26
  }
@@ -103,12 +106,26 @@ export async function generateTypes() {
103
106
  if (!config.contentKey) {
104
107
  throw new Error('Cannot generate types: contentKey is missing');
105
108
  }
106
- const fileUrl = `${CONTENTSTORAGE_CONFIG.BASE_URL}/${config.contentKey}/content/${firstLanguageCode}.json`; // Adjust URL construction if necessary
109
+ let fileUrl;
110
+ const requestConfig = { responseType: 'json' };
111
+ if (config.pendingChanges) {
112
+ fileUrl = `${CONTENTSTORAGE_CONFIG.API_URL}/pending-changes/get-json?languageCode=${firstLanguageCode}`;
113
+ requestConfig.headers = {
114
+ 'X-Content-Key': config.contentKey,
115
+ };
116
+ }
117
+ else {
118
+ fileUrl = `${CONTENTSTORAGE_CONFIG.BASE_URL}/${config.contentKey}/content/${firstLanguageCode}.json`;
119
+ }
107
120
  dataSourceDescription = `remote URL (${fileUrl})`;
108
121
  console.log(chalk.blue(`Attempting to fetch JSON from: ${fileUrl}`));
109
122
  try {
110
- const response = await axios.get(fileUrl, { responseType: 'json' });
111
- const jsonResponse = response.data;
123
+ const response = await axios.get(fileUrl, requestConfig);
124
+ let jsonResponse = response.data;
125
+ // Handle API response structure - API returns { data: actualContent }
126
+ if (config.pendingChanges && jsonResponse && typeof jsonResponse === 'object' && 'data' in jsonResponse) {
127
+ jsonResponse = jsonResponse.data;
128
+ }
112
129
  console.log(chalk.blue('Flattening JSON for type generation'));
113
130
  jsonObject = flattenJson(jsonResponse);
114
131
  if (typeof jsonObject !== 'object' || jsonObject === null) {
@@ -7,13 +7,48 @@ import { loadConfig } from '../lib/configLoader.js';
7
7
  import { CONTENTSTORAGE_CONFIG } from '../contentstorage-config.js';
8
8
  export async function pullContent() {
9
9
  console.log(chalk.blue('Starting content pull...'));
10
- // Load configuration (assuming this function is defined elsewhere and works)
11
- const config = await loadConfig();
10
+ const args = process.argv.slice(2);
11
+ const cliConfig = {};
12
+ for (let i = 0; i < args.length; i++) {
13
+ const arg = args[i];
14
+ if (arg.startsWith('--')) {
15
+ const key = arg.substring(2);
16
+ const value = args[i + 1];
17
+ if (key === 'pending-changes') {
18
+ cliConfig.pendingChanges = true;
19
+ }
20
+ else if (value && !value.startsWith('--')) {
21
+ if (key === 'lang') {
22
+ cliConfig.languageCodes = [value.toUpperCase()];
23
+ }
24
+ else if (key === 'content-key') {
25
+ cliConfig.contentKey = value;
26
+ }
27
+ else if (key === 'content-dir') {
28
+ cliConfig.contentDir = value;
29
+ }
30
+ // Skip the value in the next iteration
31
+ i++;
32
+ }
33
+ }
34
+ }
35
+ let fileConfig = {};
36
+ try {
37
+ fileConfig = await loadConfig();
38
+ }
39
+ catch {
40
+ console.log(chalk.yellow('Could not load a configuration file. Proceeding with CLI arguments.'));
41
+ }
42
+ const config = { ...fileConfig, ...cliConfig };
12
43
  // Validate required fields
13
44
  if (!config.contentKey) {
14
45
  console.error(chalk.red('Error: Configuration is missing the required "contentKey" property.'));
15
46
  process.exit(1);
16
47
  }
48
+ if (!config.contentDir) {
49
+ console.error(chalk.red('Error: Configuration is missing the required "contentDir" property.'));
50
+ process.exit(1);
51
+ }
17
52
  console.log(chalk.blue(`Content key: ${config.contentKey}`));
18
53
  console.log(chalk.blue(`Saving content to: ${config.contentDir}`));
19
54
  try {
@@ -30,15 +65,29 @@ export async function pullContent() {
30
65
  await fs.mkdir(config.contentDir, { recursive: true });
31
66
  // Process each language code
32
67
  for (const languageCode of config.languageCodes) {
33
- const fileUrl = `${CONTENTSTORAGE_CONFIG.BASE_URL}/${config.contentKey}/content/${languageCode}.json`;
68
+ let fileUrl;
69
+ const requestConfig = {};
70
+ if (config.pendingChanges) {
71
+ fileUrl = `${CONTENTSTORAGE_CONFIG.API_URL}/pending-changes/get-json?languageCode=${languageCode}`;
72
+ requestConfig.headers = {
73
+ 'X-Content-Key': config.contentKey
74
+ };
75
+ }
76
+ else {
77
+ fileUrl = `${CONTENTSTORAGE_CONFIG.BASE_URL}/${config.contentKey}/content/${languageCode}.json`;
78
+ }
34
79
  const filename = `${languageCode}.json`;
35
80
  const outputPath = path.join(config.contentDir, filename);
36
81
  console.log(chalk.blue(`\nProcessing language: ${languageCode}`));
37
82
  console.log(chalk.blue(`Using following contentKey to fetch json: ${config.contentKey}`));
38
83
  try {
39
84
  // Fetch data for the current language
40
- const response = await axios.get(fileUrl);
41
- const jsonData = response.data;
85
+ const response = await axios.get(fileUrl, requestConfig);
86
+ let jsonData = response.data;
87
+ // Handle API response structure - only for pending changes API
88
+ if (config.pendingChanges && jsonData && typeof jsonData === 'object' && 'data' in jsonData) {
89
+ jsonData = jsonData.data;
90
+ }
42
91
  // Basic check for data existence, although axios usually throws for non-2xx responses
43
92
  if (jsonData === undefined || jsonData === null) {
44
93
  throw new Error(`No data received from ${fileUrl} for language ${languageCode}.`);
package/dist/types.d.ts CHANGED
@@ -3,6 +3,7 @@ export type AppConfig = {
3
3
  contentKey: string;
4
4
  contentDir: string;
5
5
  typesOutputFile: string;
6
+ pendingChanges?: boolean;
6
7
  };
7
8
  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';
8
9
  /**
@@ -11,14 +12,6 @@ export type LanguageCode = 'SQ' | 'BE' | 'BS' | 'BG' | 'HR' | 'CS' | 'DA' | 'NL'
11
12
  * consumers enable type-safe autocompletion for localization path strings
12
13
  * used with functions like `getText`.
13
14
  *
14
- * @example
15
- * // In consumer's project (e.g., in a .d.ts file):
16
- * import 'your-library-name'; // Your library's package name
17
- * import type { RootContentItem as AppSpecificRootItem } from './generated_content_types';
18
- *
19
- * declare module 'your-library-name' {
20
- * export interface ContentStructure extends AppSpecificRootItem {}
21
- * }
22
15
  */
23
16
  export interface ContentStructure {
24
17
  }
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": "1.0.2",
5
+ "version": "1.1.1",
6
6
  "type": "module",
7
7
  "description": "Fetch content from contentstorage and generate TypeScript types",
8
8
  "module": "dist/index.js",
@@ -45,6 +45,9 @@
45
45
  "engines": {
46
46
  "node": ">=18.0.0"
47
47
  },
48
+ "sideEffects": [
49
+ "./dist/index.js"
50
+ ],
48
51
  "publishConfig": {
49
52
  "access": "public"
50
53
  },