@togglely/sdk-core 1.1.11 → 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 +243 -50
- package/dist/cli.d.ts +10 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +157 -0
- package/dist/cli.js.map +1 -0
- package/dist/index.d.ts +58 -8
- package/dist/index.d.ts.map +1 -1
- package/dist/index.esm.js +105 -53
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +105 -53
- package/dist/index.js.map +1 -1
- package/package.json +8 -3
package/README.md
CHANGED
|
@@ -1,8 +1,15 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Togglely Core SDK
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Framework-agnostic core SDK for [Togglely](https://togglely.io) feature flag management with offline support and multi-brand/tenant capabilities.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- 🚀 **Real-time flag evaluation** - Fetch flags from your Togglely instance
|
|
8
|
+
- 💾 **Offline-first support** - JSON file, environment variables, or inline fallback
|
|
9
|
+
- 🏢 **Multi-brand/tenant** - Support for multi-tenant projects
|
|
10
|
+
- 🔒 **Type-safe** - Full TypeScript support
|
|
11
|
+
- ⚡ **Lightweight** - Minimal bundle size
|
|
12
|
+
- 🔧 **CLI tool** - Build-time JSON generation for offline deployment
|
|
6
13
|
|
|
7
14
|
## Installation
|
|
8
15
|
|
|
@@ -10,89 +17,275 @@ No automatic polling - fetch once on init (configurable) and refresh manually or
|
|
|
10
17
|
npm install @togglely/sdk-core
|
|
11
18
|
```
|
|
12
19
|
|
|
13
|
-
##
|
|
20
|
+
## Quick Start
|
|
14
21
|
|
|
15
22
|
```typescript
|
|
16
23
|
import { TogglelyClient } from '@togglely/sdk-core';
|
|
17
24
|
|
|
18
25
|
const client = new TogglelyClient({
|
|
19
26
|
apiKey: 'your-api-key',
|
|
27
|
+
project: 'my-project',
|
|
20
28
|
environment: 'production',
|
|
21
|
-
baseUrl: 'https://
|
|
29
|
+
baseUrl: 'https://togglely.io',
|
|
22
30
|
});
|
|
23
31
|
|
|
24
|
-
// Check if feature is enabled
|
|
25
|
-
const isEnabled = await client.isEnabled('new-feature'
|
|
32
|
+
// Check if a feature is enabled
|
|
33
|
+
const isEnabled = await client.isEnabled('new-feature');
|
|
34
|
+
if (isEnabled) {
|
|
35
|
+
// Show new feature
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// Get typed values
|
|
39
|
+
const message = await client.getString('welcome-message', 'Hello!');
|
|
40
|
+
const timeout = await client.getNumber('api-timeout', 5000);
|
|
41
|
+
const config = await client.getJSON('app-config', { theme: 'dark' });
|
|
42
|
+
```
|
|
26
43
|
|
|
27
|
-
|
|
28
|
-
|
|
44
|
+
## Configuration
|
|
45
|
+
|
|
46
|
+
```typescript
|
|
47
|
+
interface TogglelyConfig {
|
|
48
|
+
apiKey: string; // Your API key from Togglely dashboard
|
|
49
|
+
project: string; // Project key
|
|
50
|
+
environment: string; // Environment key (e.g., 'development', 'production')
|
|
51
|
+
baseUrl: string; // Your Togglely instance URL
|
|
52
|
+
timeout?: number; // Request timeout in ms (default: 5000)
|
|
53
|
+
offlineFallback?: boolean; // Enable offline fallback (default: true)
|
|
54
|
+
offlineJsonPath?: string; // Path to offline JSON file
|
|
55
|
+
offlineToggles?: object; // Inline offline toggles
|
|
56
|
+
brandKey?: string; // Brand key for multi-brand projects
|
|
57
|
+
tenantId?: string; // Tenant ID (alias for brandKey)
|
|
58
|
+
context?: object; // Initial targeting context
|
|
59
|
+
}
|
|
60
|
+
```
|
|
29
61
|
|
|
30
|
-
|
|
31
|
-
const limit = await client.getNumber('max-items', 10);
|
|
62
|
+
## Multi-Brand / Multi-Tenant Support
|
|
32
63
|
|
|
33
|
-
|
|
34
|
-
const config = await client.getJSON('app-config', {});
|
|
64
|
+
For projects with multiple brands or tenants:
|
|
35
65
|
|
|
36
|
-
|
|
37
|
-
client
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
66
|
+
```typescript
|
|
67
|
+
const client = new TogglelyClient({
|
|
68
|
+
apiKey: 'your-api-key',
|
|
69
|
+
project: 'my-project',
|
|
70
|
+
environment: 'production',
|
|
71
|
+
baseUrl: 'https://togglely.io',
|
|
72
|
+
tenantId: 'brand-a', // or brandKey: 'brand-a'
|
|
41
73
|
});
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## Offline Fallback
|
|
77
|
+
|
|
78
|
+
The SDK supports multiple offline fallback methods (in priority order):
|
|
42
79
|
|
|
43
|
-
|
|
44
|
-
const isPremiumFeature = await client.isEnabled('premium-feature', false);
|
|
80
|
+
### 1. Inline Toggles (Config)
|
|
45
81
|
|
|
46
|
-
|
|
47
|
-
client
|
|
48
|
-
|
|
82
|
+
```typescript
|
|
83
|
+
const client = new TogglelyClient({
|
|
84
|
+
apiKey: 'your-api-key',
|
|
85
|
+
project: 'my-project',
|
|
86
|
+
environment: 'production',
|
|
87
|
+
baseUrl: 'https://togglely.io',
|
|
88
|
+
offlineToggles: {
|
|
89
|
+
'new-feature': { value: true, enabled: true },
|
|
90
|
+
'api-timeout': { value: 5000, enabled: true, flagType: 'NUMBER' },
|
|
91
|
+
},
|
|
92
|
+
});
|
|
49
93
|
```
|
|
50
94
|
|
|
51
|
-
|
|
95
|
+
### 2. JSON File
|
|
52
96
|
|
|
53
|
-
|
|
97
|
+
Generate a JSON file at build time (see CLI section below):
|
|
98
|
+
|
|
99
|
+
```typescript
|
|
100
|
+
const client = new TogglelyClient({
|
|
101
|
+
apiKey: 'your-api-key',
|
|
102
|
+
project: 'my-project',
|
|
103
|
+
environment: 'production',
|
|
104
|
+
baseUrl: 'https://togglely.io',
|
|
105
|
+
offlineJsonPath: '/toggles.json', // Will be fetched if API fails
|
|
106
|
+
});
|
|
107
|
+
```
|
|
54
108
|
|
|
55
|
-
### Environment Variables
|
|
109
|
+
### 3. Environment Variables (Node.js)
|
|
56
110
|
|
|
57
111
|
```bash
|
|
58
112
|
TOGGLELY_NEW_FEATURE=true
|
|
59
|
-
|
|
113
|
+
TOGGLELY_API_TIMEOUT=5000
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
```typescript
|
|
117
|
+
const client = new TogglelyClient({
|
|
118
|
+
apiKey: 'your-api-key',
|
|
119
|
+
project: 'my-project',
|
|
120
|
+
environment: 'production',
|
|
121
|
+
baseUrl: 'https://togglely.io',
|
|
122
|
+
envPrefix: 'TOGGLELY_', // Default prefix
|
|
123
|
+
});
|
|
60
124
|
```
|
|
61
125
|
|
|
62
|
-
### Browser
|
|
126
|
+
### 4. Window Object (Browser)
|
|
63
127
|
|
|
64
128
|
```html
|
|
65
129
|
<script>
|
|
66
130
|
window.__TOGGLELY_TOGGLES = {
|
|
67
|
-
'new-feature': true,
|
|
68
|
-
'
|
|
131
|
+
'new-feature': { value: true, enabled: true },
|
|
132
|
+
'api-timeout': { value: 5000, enabled: true },
|
|
69
133
|
};
|
|
70
134
|
</script>
|
|
71
135
|
```
|
|
72
136
|
|
|
73
|
-
##
|
|
137
|
+
## Build-Time JSON Generation (CLI)
|
|
138
|
+
|
|
139
|
+
Install the CLI tool globally or use npx:
|
|
140
|
+
|
|
141
|
+
```bash
|
|
142
|
+
# Install globally
|
|
143
|
+
npm install -g @togglely/sdk-core
|
|
144
|
+
|
|
145
|
+
# Or use with npx
|
|
146
|
+
npx @togglely/sdk-core togglely-pull --apiKey=xxx --project=xxx --environment=xxx
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
### CLI Usage
|
|
150
|
+
|
|
151
|
+
```bash
|
|
152
|
+
# Basic usage
|
|
153
|
+
togglely-pull \
|
|
154
|
+
--apiKey=tk_your_api_key \
|
|
155
|
+
--project=my-project \
|
|
156
|
+
--environment=production \
|
|
157
|
+
--output=./public/toggles.json
|
|
158
|
+
|
|
159
|
+
# With tenant/brand
|
|
160
|
+
togglely-pull \
|
|
161
|
+
--apiKey=tk_your_api_key \
|
|
162
|
+
--project=my-project \
|
|
163
|
+
--environment=production \
|
|
164
|
+
--tenantId=brand-a \
|
|
165
|
+
--output=./toggles.json
|
|
166
|
+
|
|
167
|
+
# Different output formats
|
|
168
|
+
togglely-pull --format=json # JSON file (default)
|
|
169
|
+
togglely-pull --format=env # .env file
|
|
170
|
+
togglely-pull --format=js # JavaScript module
|
|
171
|
+
|
|
172
|
+
# Using environment variables
|
|
173
|
+
export TOGGLELY_APIKEY=tk_your_api_key
|
|
174
|
+
export TOGGLELY_PROJECT=my-project
|
|
175
|
+
export TOGGLELY_ENVIRONMENT=production
|
|
176
|
+
togglely-pull --output=./toggles.json
|
|
177
|
+
|
|
178
|
+
# Using config file
|
|
179
|
+
togglely-pull --config=./togglely.config.js
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
### Config File (togglely.config.js)
|
|
183
|
+
|
|
184
|
+
```javascript
|
|
185
|
+
module.exports = {
|
|
186
|
+
apiKey: process.env.TOGGLELY_APIKEY,
|
|
187
|
+
project: 'my-project',
|
|
188
|
+
environment: 'production',
|
|
189
|
+
baseUrl: 'https://togglely.io',
|
|
190
|
+
tenantId: process.env.BRAND_KEY,
|
|
191
|
+
output: './public/toggles.json',
|
|
192
|
+
format: 'json',
|
|
193
|
+
};
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
### Build Script Integration
|
|
197
|
+
|
|
198
|
+
Add to your build process:
|
|
199
|
+
|
|
200
|
+
```json
|
|
201
|
+
{
|
|
202
|
+
"scripts": {
|
|
203
|
+
"build": "togglely-pull && vite build",
|
|
204
|
+
"build:staging": "togglely-pull --environment=staging && vite build",
|
|
205
|
+
"build:prod": "togglely-pull --environment=production && vite build"
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
## Targeting Context
|
|
211
|
+
|
|
212
|
+
Set user context for advanced targeting rules:
|
|
213
|
+
|
|
214
|
+
```typescript
|
|
215
|
+
const client = new TogglelyClient({
|
|
216
|
+
apiKey: 'your-api-key',
|
|
217
|
+
project: 'my-project',
|
|
218
|
+
environment: 'production',
|
|
219
|
+
baseUrl: 'https://togglely.io',
|
|
220
|
+
context: {
|
|
221
|
+
userId: 'user-123',
|
|
222
|
+
email: 'user@example.com',
|
|
223
|
+
country: 'DE',
|
|
224
|
+
region: 'EU',
|
|
225
|
+
},
|
|
226
|
+
});
|
|
227
|
+
|
|
228
|
+
// Or update context later
|
|
229
|
+
client.setContext({
|
|
230
|
+
userId: 'user-456',
|
|
231
|
+
country: 'US',
|
|
232
|
+
});
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
## Events
|
|
236
|
+
|
|
237
|
+
Listen to SDK events:
|
|
238
|
+
|
|
239
|
+
```typescript
|
|
240
|
+
// When flags are first loaded
|
|
241
|
+
client.on('ready', (state) => {
|
|
242
|
+
console.log('Togglely is ready!');
|
|
243
|
+
});
|
|
244
|
+
|
|
245
|
+
// When flags are updated
|
|
246
|
+
client.on('update', (state) => {
|
|
247
|
+
console.log('Flags updated!');
|
|
248
|
+
});
|
|
74
249
|
|
|
75
|
-
|
|
250
|
+
// When going offline
|
|
251
|
+
client.on('offline', (state) => {
|
|
252
|
+
console.log('Using offline mode');
|
|
253
|
+
});
|
|
76
254
|
|
|
77
|
-
|
|
255
|
+
// When coming back online
|
|
256
|
+
client.on('online', (state) => {
|
|
257
|
+
console.log('Back online!');
|
|
258
|
+
});
|
|
259
|
+
|
|
260
|
+
// On error
|
|
261
|
+
client.on('error', (state) => {
|
|
262
|
+
console.error('Error:', state.lastError);
|
|
263
|
+
});
|
|
264
|
+
```
|
|
78
265
|
|
|
79
|
-
|
|
80
|
-
- `apiKey` (string, required): Your API key
|
|
81
|
-
- `environment` (string, required): Environment name
|
|
82
|
-
- `baseUrl` (string, required): Togglely instance URL
|
|
83
|
-
- `timeout` (number, default: 5000): Request timeout in ms
|
|
84
|
-
- `offlineFallback` (boolean, default: true): Enable offline mode
|
|
85
|
-
- `envPrefix` (string, default: 'TOGGLELY_'): Environment variable prefix
|
|
86
|
-
- `autoFetch` (boolean, default: true): Fetch toggles on init
|
|
266
|
+
## API Reference
|
|
87
267
|
|
|
88
268
|
### Methods
|
|
89
269
|
|
|
90
|
-
- `isEnabled(key, defaultValue)
|
|
91
|
-
- `getString(key, defaultValue)
|
|
92
|
-
- `getNumber(key, defaultValue)
|
|
93
|
-
- `getJSON(key, defaultValue)
|
|
94
|
-
- `
|
|
95
|
-
- `
|
|
96
|
-
- `
|
|
97
|
-
- `
|
|
98
|
-
- `
|
|
270
|
+
- `isEnabled(key, defaultValue?)` - Check boolean flag
|
|
271
|
+
- `getString(key, defaultValue?)` - Get string value
|
|
272
|
+
- `getNumber(key, defaultValue?)` - Get number value
|
|
273
|
+
- `getJSON(key, defaultValue?)` - Get JSON value
|
|
274
|
+
- `getValue(key)` - Get raw toggle value
|
|
275
|
+
- `getAllToggles()` - Get all cached toggles
|
|
276
|
+
- `setContext(context)` - Set targeting context
|
|
277
|
+
- `getContext()` - Get current context
|
|
278
|
+
- `refresh()` - Manually refresh flags
|
|
279
|
+
- `on(event, handler)` - Subscribe to events
|
|
280
|
+
- `off(event, handler)` - Unsubscribe from events
|
|
281
|
+
- `destroy()` - Cleanup
|
|
282
|
+
|
|
283
|
+
### State
|
|
284
|
+
|
|
285
|
+
- `isReady()` - Check if initial load completed
|
|
286
|
+
- `isOffline()` - Check if in offline mode
|
|
287
|
+
- `getState()` - Get full state object
|
|
288
|
+
|
|
289
|
+
## License
|
|
290
|
+
|
|
291
|
+
MIT
|
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Togglely CLI - Build-time JSON generator
|
|
4
|
+
*
|
|
5
|
+
* Usage:
|
|
6
|
+
* togglely-pull --apiKey=xxx --project=xxx --environment=xxx --output=./toggles.json
|
|
7
|
+
* togglely-pull --config=./togglely.config.js
|
|
8
|
+
*/
|
|
9
|
+
export {};
|
|
10
|
+
//# sourceMappingURL=cli.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAEA;;;;;;GAMG"}
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Togglely CLI - Build-time JSON generator
|
|
4
|
+
*
|
|
5
|
+
* Usage:
|
|
6
|
+
* togglely-pull --apiKey=xxx --project=xxx --environment=xxx --output=./toggles.json
|
|
7
|
+
* togglely-pull --config=./togglely.config.js
|
|
8
|
+
*/
|
|
9
|
+
import * as fs from 'fs';
|
|
10
|
+
import * as path from 'path';
|
|
11
|
+
function parseArgs() {
|
|
12
|
+
const args = process.argv.slice(2);
|
|
13
|
+
const config = {};
|
|
14
|
+
for (const arg of args) {
|
|
15
|
+
if (arg.startsWith('--apiKey=')) {
|
|
16
|
+
config.apiKey = arg.split('=')[1];
|
|
17
|
+
}
|
|
18
|
+
else if (arg.startsWith('--project=')) {
|
|
19
|
+
config.project = arg.split('=')[1];
|
|
20
|
+
}
|
|
21
|
+
else if (arg.startsWith('--environment=')) {
|
|
22
|
+
config.environment = arg.split('=')[1];
|
|
23
|
+
}
|
|
24
|
+
else if (arg.startsWith('--baseUrl=')) {
|
|
25
|
+
config.baseUrl = arg.split('=')[1];
|
|
26
|
+
}
|
|
27
|
+
else if (arg.startsWith('--tenantId=')) {
|
|
28
|
+
config.tenantId = arg.split('=')[1];
|
|
29
|
+
}
|
|
30
|
+
else if (arg.startsWith('--output=')) {
|
|
31
|
+
config.output = arg.split('=')[1];
|
|
32
|
+
}
|
|
33
|
+
else if (arg.startsWith('--format=')) {
|
|
34
|
+
config.format = arg.split('=')[1];
|
|
35
|
+
}
|
|
36
|
+
else if (arg.startsWith('--config=')) {
|
|
37
|
+
const configPath = arg.split('=')[1];
|
|
38
|
+
if (fs.existsSync(configPath)) {
|
|
39
|
+
const fileConfig = require(path.resolve(configPath));
|
|
40
|
+
Object.assign(config, fileConfig);
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
console.error(`Config file not found: ${configPath}`);
|
|
44
|
+
process.exit(1);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
return config;
|
|
49
|
+
}
|
|
50
|
+
function loadEnvFile() {
|
|
51
|
+
const envConfig = {};
|
|
52
|
+
// Try to load from .env file
|
|
53
|
+
const envPaths = ['.env', '.env.local', '.env.production', '.env.development'];
|
|
54
|
+
for (const envPath of envPaths) {
|
|
55
|
+
if (fs.existsSync(envPath)) {
|
|
56
|
+
const content = fs.readFileSync(envPath, 'utf-8');
|
|
57
|
+
const lines = content.split('\n');
|
|
58
|
+
for (const line of lines) {
|
|
59
|
+
const match = line.match(/^TOGGLELY_(\w+)=(.+)$/);
|
|
60
|
+
if (match) {
|
|
61
|
+
const key = match[1].toLowerCase();
|
|
62
|
+
const value = match[2].replace(/^["']|["']$/g, '');
|
|
63
|
+
if (key === 'apikey')
|
|
64
|
+
envConfig.apiKey = value;
|
|
65
|
+
if (key === 'project')
|
|
66
|
+
envConfig.project = value;
|
|
67
|
+
if (key === 'environment')
|
|
68
|
+
envConfig.environment = value;
|
|
69
|
+
if (key === 'baseurl')
|
|
70
|
+
envConfig.baseUrl = value;
|
|
71
|
+
if (key === 'tenantid')
|
|
72
|
+
envConfig.tenantId = value;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
return envConfig;
|
|
78
|
+
}
|
|
79
|
+
async function fetchToggles(config) {
|
|
80
|
+
const params = new URLSearchParams();
|
|
81
|
+
params.set('apiKey', config.apiKey);
|
|
82
|
+
if (config.tenantId)
|
|
83
|
+
params.set('tenantId', config.tenantId);
|
|
84
|
+
const url = `${config.baseUrl}/sdk/flags/${config.project}/${config.environment}?${params.toString()}`;
|
|
85
|
+
console.log(`Fetching toggles from: ${url.replace(config.apiKey, '***')}`);
|
|
86
|
+
const response = await fetch(url);
|
|
87
|
+
if (!response.ok) {
|
|
88
|
+
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
|
89
|
+
}
|
|
90
|
+
return response.json();
|
|
91
|
+
}
|
|
92
|
+
function generateOutput(data, format) {
|
|
93
|
+
switch (format) {
|
|
94
|
+
case 'env':
|
|
95
|
+
return Object.entries(data)
|
|
96
|
+
.map(([key, value]) => {
|
|
97
|
+
const envKey = `TOGGLELY_${key.toUpperCase().replace(/-/g, '_')}`;
|
|
98
|
+
const envValue = typeof value === 'object' ? JSON.stringify(value) : String(value);
|
|
99
|
+
return `${envKey}=${envValue}`;
|
|
100
|
+
})
|
|
101
|
+
.join('\n');
|
|
102
|
+
case 'js':
|
|
103
|
+
return `// Auto-generated by Togglely CLI
|
|
104
|
+
module.exports = ${JSON.stringify(data, null, 2)};
|
|
105
|
+
`;
|
|
106
|
+
case 'json':
|
|
107
|
+
default:
|
|
108
|
+
return JSON.stringify(data, null, 2);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
async function main() {
|
|
112
|
+
console.log('🚀 Togglely CLI - Build-time JSON Generator\n');
|
|
113
|
+
const argsConfig = parseArgs();
|
|
114
|
+
const envConfig = loadEnvFile();
|
|
115
|
+
// Merge configs (args > env > defaults)
|
|
116
|
+
const config = {
|
|
117
|
+
baseUrl: 'https://togglely.io',
|
|
118
|
+
output: './togglely-toggles.json',
|
|
119
|
+
format: 'json',
|
|
120
|
+
...envConfig,
|
|
121
|
+
...argsConfig,
|
|
122
|
+
};
|
|
123
|
+
// Validate required fields
|
|
124
|
+
if (!config.apiKey || !config.project || !config.environment) {
|
|
125
|
+
console.error('❌ Missing required parameters:');
|
|
126
|
+
console.error(' --apiKey=<key>');
|
|
127
|
+
console.error(' --project=<project-key>');
|
|
128
|
+
console.error(' --environment=<environment-key>');
|
|
129
|
+
console.error('\nOr use environment variables:');
|
|
130
|
+
console.error(' TOGGLELY_APIKEY, TOGGLELY_PROJECT, TOGGLELY_ENVIRONMENT');
|
|
131
|
+
console.error('\nOr use a config file:');
|
|
132
|
+
console.error(' --config=./togglely.config.js');
|
|
133
|
+
process.exit(1);
|
|
134
|
+
}
|
|
135
|
+
try {
|
|
136
|
+
const data = await fetchToggles(config);
|
|
137
|
+
const output = generateOutput(data, config.format);
|
|
138
|
+
// Ensure directory exists
|
|
139
|
+
const dir = path.dirname(config.output);
|
|
140
|
+
if (!fs.existsSync(dir)) {
|
|
141
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
142
|
+
}
|
|
143
|
+
fs.writeFileSync(config.output, output);
|
|
144
|
+
console.log(`✅ Successfully saved ${Object.keys(data).length} toggles to: ${config.output}`);
|
|
145
|
+
console.log(`\nToggles found:`);
|
|
146
|
+
Object.entries(data).forEach(([key, value]) => {
|
|
147
|
+
const status = value.enabled ? '✅' : '❌';
|
|
148
|
+
console.log(` ${status} ${key}: ${JSON.stringify(value.value)}`);
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
catch (error) {
|
|
152
|
+
console.error(`❌ Error: ${error.message}`);
|
|
153
|
+
process.exit(1);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
main();
|
|
157
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Togglely Core SDK - Framework agnostic
|
|
2
|
+
* Togglely Core SDK - Framework agnostic feature flag management
|
|
3
3
|
*
|
|
4
|
-
*
|
|
4
|
+
* Features:
|
|
5
|
+
* - Real-time feature flag evaluation
|
|
6
|
+
* - Offline fallback via JSON file, environment variables, or window object
|
|
7
|
+
* - Multi-brand/tenant support
|
|
8
|
+
* - Type-safe flag access
|
|
9
|
+
* - Build-time JSON generation for offline-first deployment
|
|
5
10
|
*/
|
|
6
11
|
export interface TogglelyConfig {
|
|
7
12
|
/** API Key from your Togglely dashboard */
|
|
@@ -14,8 +19,12 @@ export interface TogglelyConfig {
|
|
|
14
19
|
baseUrl: string;
|
|
15
20
|
/** Request timeout in milliseconds (default: 5000) */
|
|
16
21
|
timeout?: number;
|
|
17
|
-
/** Enable offline
|
|
22
|
+
/** Enable offline fallback (default: true) */
|
|
18
23
|
offlineFallback?: boolean;
|
|
24
|
+
/** Path to offline JSON file for fallback (optional) */
|
|
25
|
+
offlineJsonPath?: string;
|
|
26
|
+
/** Inline offline toggles data (optional) */
|
|
27
|
+
offlineToggles?: Record<string, ToggleValue>;
|
|
19
28
|
/** Prefix for environment variables (default: 'TOGGLELY_') */
|
|
20
29
|
envPrefix?: string;
|
|
21
30
|
/** Auto-fetch toggles on init (default: true) */
|
|
@@ -37,6 +46,7 @@ export interface ToggleContext {
|
|
|
37
46
|
export interface ToggleValue {
|
|
38
47
|
value: any;
|
|
39
48
|
enabled: boolean;
|
|
49
|
+
flagType?: 'BOOLEAN' | 'STRING' | 'NUMBER' | 'JSON';
|
|
40
50
|
}
|
|
41
51
|
export interface AllTogglesResponse {
|
|
42
52
|
[key: string]: ToggleValue;
|
|
@@ -49,9 +59,6 @@ export interface TogglelyState {
|
|
|
49
59
|
}
|
|
50
60
|
export type TogglelyEventType = 'ready' | 'update' | 'error' | 'offline' | 'online';
|
|
51
61
|
export type TogglelyEventHandler = (state: TogglelyState) => void;
|
|
52
|
-
/**
|
|
53
|
-
* Core Togglely Client
|
|
54
|
-
*/
|
|
55
62
|
export declare class TogglelyClient {
|
|
56
63
|
private config;
|
|
57
64
|
private toggles;
|
|
@@ -69,19 +76,62 @@ export declare class TogglelyClient {
|
|
|
69
76
|
getState(): TogglelyState;
|
|
70
77
|
isReady(): boolean;
|
|
71
78
|
isOffline(): boolean;
|
|
79
|
+
/**
|
|
80
|
+
* Check if a boolean feature flag is enabled
|
|
81
|
+
* @param key - The flag key
|
|
82
|
+
* @param defaultValue - Default value if flag not found
|
|
83
|
+
* @returns Promise<boolean>
|
|
84
|
+
*/
|
|
72
85
|
isEnabled(key: string, defaultValue?: boolean): Promise<boolean>;
|
|
86
|
+
/**
|
|
87
|
+
* Get a string feature flag value
|
|
88
|
+
* @param key - The flag key
|
|
89
|
+
* @param defaultValue - Default value if flag not found or disabled
|
|
90
|
+
* @returns Promise<string>
|
|
91
|
+
*/
|
|
73
92
|
getString(key: string, defaultValue?: string): Promise<string>;
|
|
93
|
+
/**
|
|
94
|
+
* Get a number feature flag value
|
|
95
|
+
* @param key - The flag key
|
|
96
|
+
* @param defaultValue - Default value if flag not found or disabled
|
|
97
|
+
* @returns Promise<number>
|
|
98
|
+
*/
|
|
74
99
|
getNumber(key: string, defaultValue?: number): Promise<number>;
|
|
100
|
+
/**
|
|
101
|
+
* Get a JSON feature flag value
|
|
102
|
+
* @param key - The flag key
|
|
103
|
+
* @param defaultValue - Default value if flag not found or disabled
|
|
104
|
+
* @returns Promise<T>
|
|
105
|
+
*/
|
|
75
106
|
getJSON<T = any>(key: string, defaultValue?: T): Promise<T>;
|
|
107
|
+
/**
|
|
108
|
+
* Get raw toggle value
|
|
109
|
+
* @param key - The flag key
|
|
110
|
+
* @returns Promise<ToggleValue | null>
|
|
111
|
+
*/
|
|
76
112
|
getValue(key: string): Promise<ToggleValue | null>;
|
|
113
|
+
/**
|
|
114
|
+
* Get all toggles
|
|
115
|
+
* @returns Record<string, ToggleValue>
|
|
116
|
+
*/
|
|
77
117
|
getAllToggles(): Record<string, ToggleValue>;
|
|
78
118
|
/**
|
|
79
|
-
* Load toggles from
|
|
80
|
-
*
|
|
119
|
+
* Load offline toggles from multiple sources (in priority order):
|
|
120
|
+
* 1. Inline offlineToggles from config
|
|
121
|
+
* 2. JSON file (if offlineJsonPath is set)
|
|
122
|
+
* 3. window.__TOGGLELY_TOGGLES (browser)
|
|
123
|
+
* 4. Environment variables (Node.js)
|
|
81
124
|
*/
|
|
82
125
|
private loadOfflineToggles;
|
|
126
|
+
/**
|
|
127
|
+
* Load offline toggles from JSON file (async)
|
|
128
|
+
*/
|
|
129
|
+
private loadOfflineJsonFile;
|
|
83
130
|
private getOfflineToggle;
|
|
84
131
|
private parseOfflineValue;
|
|
132
|
+
/**
|
|
133
|
+
* Refresh all toggles from the server
|
|
134
|
+
*/
|
|
85
135
|
refresh(): Promise<void>;
|
|
86
136
|
forceOfflineMode(): void;
|
|
87
137
|
forceOnlineMode(): void;
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|