@contentstorage/core 1.1.1 → 1.2.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/README.md CHANGED
@@ -1 +1,349 @@
1
- # contentstorage-core
1
+ # @contentstorage/core
2
+
3
+ > A key-value based CMS core library that fetches content from ContentStorage and generates TypeScript types
4
+
5
+ [![npm version](https://img.shields.io/npm/v/@contentstorage/core.svg)](https://www.npmjs.com/package/@contentstorage/core)
6
+ [![License](https://img.shields.io/npm/l/@contentstorage/core.svg)](https://github.com/kaidohussar/contentstorage-core/blob/master/LICENSE)
7
+
8
+ ## Features
9
+
10
+ - **Key-Value Storage** - Organize content with hierarchical dot-notation paths
11
+ - **Multi-Language Support** - Built-in support for 40+ languages
12
+ - **TypeScript First** - Automatic type generation from your content
13
+ - **Type Safety** - Full autocompletion and type checking for content access
14
+ - **Live Editor Integration** - Real-time content editing without page reload
15
+ - **Special Content Types** - Support for text, images, and variations
16
+ - **Variable Substitution** - Dynamic content with template variables
17
+ - **CLI Tools** - Easy content management with professional CLI
18
+
19
+ ## Installation
20
+
21
+ ```bash
22
+ npm install @contentstorage/core
23
+ ```
24
+
25
+ or
26
+
27
+ ```bash
28
+ yarn add @contentstorage/core
29
+ ```
30
+
31
+ ## Quick Start
32
+
33
+ ### 1. Create Configuration File
34
+
35
+ Create `contentstorage.config.js` in your project root:
36
+
37
+ ```javascript
38
+ export default {
39
+ contentKey: 'your-content-key',
40
+ languageCodes: ['EN', 'FR', 'DE'],
41
+ contentDir: 'src/content/json',
42
+ typesOutputFile: 'src/content/content-types.d.ts'
43
+ };
44
+ ```
45
+
46
+ ### 2. Pull Content & Generate Types
47
+
48
+ ```bash
49
+ # Pull content from ContentStorage CDN
50
+ npx contentstorage pull
51
+
52
+ # Generate TypeScript type definitions
53
+ npx contentstorage generate-types
54
+ ```
55
+
56
+ ### 3. Initialize and Use in Your App
57
+
58
+ ```typescript
59
+ import { initContentStorage, fetchContent, getText, getImage } from '@contentstorage/core';
60
+
61
+ // Initialize
62
+ initContentStorage({
63
+ contentKey: 'your-content-key',
64
+ languageCodes: ['EN', 'FR', 'DE']
65
+ });
66
+
67
+ // Fetch content for a language
68
+ await fetchContent('EN');
69
+
70
+ // Access content with full type safety
71
+ const title = getText('HomePage.title');
72
+ // → { contentId: 'HomePage.title', text: 'Welcome!' }
73
+
74
+ const heroImage = getImage('HomePage.hero');
75
+ // → { contentId: 'HomePage.hero', data: { url: '...', altText: '...' } }
76
+
77
+ // Use variables in text
78
+ const greeting = getText('HomePage.greeting', { name: 'John' });
79
+ // → { contentId: 'HomePage.greeting', text: 'Hello John!' }
80
+ ```
81
+
82
+ ## CLI Commands
83
+
84
+ ### `contentstorage pull`
85
+
86
+ Pull content from ContentStorage CDN
87
+
88
+ ```bash
89
+ npx contentstorage pull [options]
90
+ ```
91
+
92
+ **Options:**
93
+ - `--content-key <key>` - Content key for your project
94
+ - `--content-dir <dir>` - Directory to save content files
95
+ - `--lang <code>` - Language code (e.g., EN, FR)
96
+ - `--pending-changes` - Fetch pending/draft content
97
+
98
+ **Examples:**
99
+ ```bash
100
+ npx contentstorage pull --content-key abc123
101
+ npx contentstorage pull --lang EN --pending-changes
102
+ npx contentstorage pull --content-dir src/content
103
+ ```
104
+
105
+ ### `contentstorage generate-types`
106
+
107
+ Generate TypeScript type definitions from content
108
+
109
+ ```bash
110
+ npx contentstorage generate-types [options]
111
+ ```
112
+
113
+ **Options:**
114
+ - `--output <file>` - Output file for generated types
115
+ - `--content-key <key>` - Content key for your project
116
+ - `--lang <code>` - Language code (e.g., EN, FR)
117
+ - `--pending-changes` - Use pending/draft content
118
+
119
+ **Examples:**
120
+ ```bash
121
+ npx contentstorage generate-types --output src/types.ts
122
+ npx contentstorage generate-types --content-key abc123 --lang EN
123
+ ```
124
+
125
+ ### `contentstorage --help`
126
+
127
+ Show all available commands and options
128
+
129
+ ```bash
130
+ npx contentstorage --help
131
+ npx contentstorage pull --help
132
+ npx contentstorage generate-types --help
133
+ ```
134
+
135
+ ## Configuration
136
+
137
+ ### Configuration File (`contentstorage.config.js`)
138
+
139
+ ```javascript
140
+ export default {
141
+ // Required: Unique content identifier
142
+ contentKey: 'your-content-key',
143
+
144
+ // Required: Array of language codes
145
+ languageCodes: ['EN', 'FR', 'DE', 'ES'],
146
+
147
+ // Optional: Local storage path (default: src/content/json)
148
+ contentDir: 'src/content/json',
149
+
150
+ // Optional: Types file path (default: src/content/content-types.ts)
151
+ typesOutputFile: 'src/content/content-types.d.ts',
152
+
153
+ // Optional: Fetch draft content
154
+ pendingChanges: false
155
+ };
156
+ ```
157
+
158
+ ### Supported Languages
159
+
160
+ The library supports 40+ languages including:
161
+ EN, FR, DE, ES, IT, PT, NL, PL, RU, TR, SV, NO, DA, FI, CS, SK, HU, RO, BG, HR, SL, SR, and more.
162
+
163
+ ## API Reference
164
+
165
+ ### Initialization
166
+
167
+ #### `initContentStorage(config)`
168
+
169
+ Initialize the content storage system.
170
+
171
+ ```typescript
172
+ initContentStorage({
173
+ contentKey: string,
174
+ languageCodes: LanguageCode[]
175
+ });
176
+ ```
177
+
178
+ #### `setContentLanguage(config)`
179
+
180
+ Set content for a specific language.
181
+
182
+ ```typescript
183
+ setContentLanguage({
184
+ languageCode: LanguageCode,
185
+ contentJson: object
186
+ });
187
+ ```
188
+
189
+ ### Content Retrieval
190
+
191
+ #### `getText<Path>(contentId, variables?)`
192
+
193
+ Get localized text with optional variable substitution.
194
+
195
+ ```typescript
196
+ const result = getText('HomePage.title');
197
+ // → { contentId: 'HomePage.title', text: 'Welcome!' }
198
+
199
+ const greeting = getText('HomePage.greeting', { name: 'John', count: 5 });
200
+ // → { contentId: 'HomePage.greeting', text: 'Hello John, you have 5 items' }
201
+ ```
202
+
203
+ **Returns:** `{ contentId: string, text: string }`
204
+
205
+ #### `getImage(contentId)`
206
+
207
+ Get image content with CDN URL.
208
+
209
+ ```typescript
210
+ const image = getImage('HomePage.hero');
211
+ // → {
212
+ // contentId: 'HomePage.hero',
213
+ // data: {
214
+ // contentstorage_type: 'image',
215
+ // url: 'https://cdn.contentstorage.app/...',
216
+ // altText: 'Hero image'
217
+ // }
218
+ // }
219
+ ```
220
+
221
+ **Returns:** `{ contentId: string, data: ImageObject } | undefined`
222
+
223
+ #### `getVariation(contentId, variationKey?, variables?)`
224
+
225
+ Get content variation for A/B testing.
226
+
227
+ ```typescript
228
+ const cta = getVariation('HomePage.cta', 'mobile');
229
+ // → { contentId: 'HomePage.cta', text: 'Tap Now' }
230
+
231
+ // Defaults to 'default' variation if not specified
232
+ const ctaDefault = getVariation('HomePage.cta');
233
+ ```
234
+
235
+ **Returns:** `{ contentId: string, text: string }`
236
+
237
+ ### Content Fetching
238
+
239
+ #### `fetchContent(languageCode)`
240
+
241
+ Fetch content from ContentStorage CDN.
242
+
243
+ ```typescript
244
+ await fetchContent('EN');
245
+ ```
246
+
247
+ ## TypeScript Integration
248
+
249
+ The library uses interface augmentation for type-safe content access:
250
+
251
+ ```typescript
252
+ // After running: npx contentstorage generate-types
253
+ // The generated types augment the ContentStructure interface
254
+
255
+ import { getText } from '@contentstorage/core';
256
+
257
+ // TypeScript knows all available content paths
258
+ const title = getText('HomePage.title'); // ✅ Autocomplete works
259
+ const invalid = getText('Invalid.path'); // ❌ TypeScript error
260
+ ```
261
+
262
+ ## Content Structure
263
+
264
+ Content is organized in a hierarchical key-value structure:
265
+
266
+ ```json
267
+ {
268
+ "HomePage": {
269
+ "title": "Welcome to Our App",
270
+ "greeting": "Hello {name}, you have {count} items",
271
+ "hero": {
272
+ "contentstorage_type": "image",
273
+ "url": "hero.jpg",
274
+ "altText": "Hero image"
275
+ },
276
+ "cta": {
277
+ "contentstorage_type": "variation",
278
+ "data": {
279
+ "default": "Click Here",
280
+ "mobile": "Tap Now",
281
+ "desktop": "Click to Continue"
282
+ }
283
+ }
284
+ }
285
+ }
286
+ ```
287
+
288
+ **Access with dot notation:**
289
+ - `getText('HomePage.title')` → "Welcome to Our App"
290
+ - `getText('HomePage.greeting', { name: 'John', count: 5 })` → "Hello John, you have 5 items"
291
+ - `getImage('HomePage.hero')` → Image object with CDN URL
292
+ - `getVariation('HomePage.cta', 'mobile')` → "Tap Now"
293
+
294
+ ## Package.json Scripts
295
+
296
+ Add these scripts to your `package.json` for convenience:
297
+
298
+ ```json
299
+ {
300
+ "scripts": {
301
+ "content:pull": "contentstorage pull",
302
+ "content:types": "contentstorage generate-types",
303
+ "content:sync": "npm run content:pull && npm run content:types",
304
+ "prebuild": "npm run content:sync"
305
+ }
306
+ }
307
+ ```
308
+
309
+ Then run:
310
+
311
+ ```bash
312
+ npm run content:pull # Pull content
313
+ npm run content:types # Generate types
314
+ npm run content:sync # Pull and generate in one command
315
+ ```
316
+
317
+ ## Integration with React
318
+
319
+ For React integration, use [@contentstorage/react](https://www.npmjs.com/package/@contentstorage/react) which builds on top of this core library and provides React-specific components and hooks.
320
+
321
+ ## Live Editor Mode
322
+
323
+ When running in an iframe with live editor parameters, the library automatically:
324
+ - Loads the live editor script from CDN
325
+ - Tracks content usage via `window.memoryMap`
326
+ - Enables real-time content updates without page reload
327
+
328
+ ## Requirements
329
+
330
+ - Node.js >= 18.0.0
331
+ - TypeScript >= 5.0.0 (for type generation)
332
+
333
+ ## License
334
+
335
+ MIT
336
+
337
+ ## Author
338
+
339
+ Kaido Hussar - [kaidohus@gmail.com](mailto:kaidohus@gmail.com)
340
+
341
+ ## Links
342
+
343
+ - [Homepage](https://contentstorage.app)
344
+ - [GitHub](https://github.com/kaidohussar/contentstorage-core)
345
+ - [npm](https://www.npmjs.com/package/@contentstorage/core)
346
+
347
+ ## Support
348
+
349
+ For issues and questions, please [open an issue](https://github.com/kaidohussar/contentstorage-core/issues) on GitHub.
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
@@ -0,0 +1,96 @@
1
+ #!/usr/bin/env node
2
+ import chalk from 'chalk';
3
+ import { pullContent } from './pull-content.js';
4
+ import { generateTypes } from './generate-types.js';
5
+ const COMMANDS = {
6
+ pull: {
7
+ name: 'pull',
8
+ description: 'Pull content from Contentstorage CDN',
9
+ usage: 'contentstorage pull [options]',
10
+ options: [
11
+ ' --content-key <key> Content key for your project',
12
+ ' --content-dir <dir> Directory to save content files',
13
+ ' --lang <code> Language code (e.g., EN, FR)',
14
+ ' --pending-changes Fetch pending/draft content',
15
+ ],
16
+ },
17
+ 'generate-types': {
18
+ name: 'generate-types',
19
+ description: 'Generate TypeScript type definitions from content',
20
+ usage: 'contentstorage generate-types [options]',
21
+ options: [
22
+ ' --output <file> Output file for generated types',
23
+ ' --content-key <key> Content key for your project',
24
+ ' --lang <code> Language code (e.g., EN, FR)',
25
+ ' --pending-changes Use pending/draft content',
26
+ ],
27
+ },
28
+ };
29
+ function showHelp() {
30
+ console.log(chalk.bold('\nContentStorage CLI'));
31
+ console.log(chalk.dim('Manage content and generate TypeScript types\n'));
32
+ console.log(chalk.bold('Usage:'));
33
+ console.log(' contentstorage <command> [options]\n');
34
+ console.log(chalk.bold('Commands:'));
35
+ Object.values(COMMANDS).forEach((cmd) => {
36
+ console.log(` ${chalk.cyan(cmd.name.padEnd(20))} ${cmd.description}`);
37
+ });
38
+ console.log(chalk.bold('\nOptions:'));
39
+ console.log(' --help Show help for a command\n');
40
+ console.log(chalk.dim('Examples:'));
41
+ console.log(chalk.dim(' contentstorage pull --content-key abc123'));
42
+ console.log(chalk.dim(' contentstorage generate-types --output types.ts'));
43
+ console.log(chalk.dim(' contentstorage pull --help # Show help for pull command\n'));
44
+ }
45
+ function showCommandHelp(commandName) {
46
+ const cmd = COMMANDS[commandName];
47
+ if (!cmd) {
48
+ console.error(chalk.red(`Unknown command: ${commandName}`));
49
+ process.exit(1);
50
+ }
51
+ console.log(chalk.bold(`\n${cmd.name}`));
52
+ console.log(chalk.dim(cmd.description + '\n'));
53
+ console.log(chalk.bold('Usage:'));
54
+ console.log(` ${cmd.usage}\n`);
55
+ if (cmd.options.length > 0) {
56
+ console.log(chalk.bold('Options:'));
57
+ cmd.options.forEach((opt) => console.log(opt));
58
+ console.log('');
59
+ }
60
+ }
61
+ async function main() {
62
+ const args = process.argv.slice(2);
63
+ // No arguments - show help
64
+ if (args.length === 0) {
65
+ showHelp();
66
+ process.exit(0);
67
+ }
68
+ const command = args[0];
69
+ // Global --help flag
70
+ if (command === '--help' || command === '-h') {
71
+ showHelp();
72
+ process.exit(0);
73
+ }
74
+ // Command-specific --help
75
+ if (args.includes('--help') || args.includes('-h')) {
76
+ showCommandHelp(command);
77
+ process.exit(0);
78
+ }
79
+ // Route to commands
80
+ switch (command) {
81
+ case 'pull':
82
+ await pullContent();
83
+ break;
84
+ case 'generate-types':
85
+ await generateTypes();
86
+ break;
87
+ default:
88
+ console.error(chalk.red(`Unknown command: ${command}\n`));
89
+ console.log(chalk.dim('Run "contentstorage --help" for usage'));
90
+ process.exit(1);
91
+ }
92
+ }
93
+ main().catch((error) => {
94
+ console.error(chalk.red('Unexpected error:'), error);
95
+ process.exit(1);
96
+ });
@@ -172,4 +172,3 @@ export async function generateTypes() {
172
172
  process.exit(1);
173
173
  }
174
174
  }
175
- generateTypes();
@@ -135,4 +135,3 @@ export async function pullContent() {
135
135
  process.exit(1); // Exit with error code
136
136
  }
137
137
  }
138
- pullContent();
package/package.json CHANGED
@@ -2,14 +2,14 @@
2
2
  "name": "@contentstorage/core",
3
3
  "author": "Kaido Hussar <kaidohus@gmail.com>",
4
4
  "homepage": "https://contentstorage.app",
5
- "version": "1.1.1",
5
+ "version": "1.2.0",
6
6
  "type": "module",
7
7
  "description": "Fetch content from contentstorage and generate TypeScript types",
8
+ "license": "MIT",
8
9
  "module": "dist/index.js",
9
10
  "types": "dist/index.d.ts",
10
11
  "bin": {
11
- "pull-content": "dist/scripts/pull-content.js",
12
- "generate-types": "dist/scripts/generate-types.js"
12
+ "contentstorage": "dist/scripts/cli.js"
13
13
  },
14
14
  "repository": {
15
15
  "type": "git",