shipos 0.0.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 +225 -0
- package/dist/cache.d.ts +29 -0
- package/dist/cache.d.ts.map +1 -0
- package/dist/client.d.ts +53 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/index.d.ts +31 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +1 -0
- package/dist/modules/configs.d.ts +56 -0
- package/dist/modules/configs.d.ts.map +1 -0
- package/dist/modules/customers.d.ts +76 -0
- package/dist/modules/customers.d.ts.map +1 -0
- package/dist/modules/feature-flags.d.ts +66 -0
- package/dist/modules/feature-flags.d.ts.map +1 -0
- package/dist/react/components.d.ts +85 -0
- package/dist/react/components.d.ts.map +1 -0
- package/dist/react/hooks.d.ts +115 -0
- package/dist/react/hooks.d.ts.map +1 -0
- package/dist/react/index.d.ts +25 -0
- package/dist/react/index.d.ts.map +1 -0
- package/dist/react/index.js +1 -0
- package/dist/react/provider.d.ts +61 -0
- package/dist/react/provider.d.ts.map +1 -0
- package/dist/types.d.ts +69 -0
- package/dist/types.d.ts.map +1 -0
- package/package.json +53 -0
package/README.md
ADDED
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
# @shipos/sdk
|
|
2
|
+
|
|
3
|
+
Official SDK for ShipOS feature flags, global configs, and customer identification.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
bun add @shipos/sdk
|
|
9
|
+
# or
|
|
10
|
+
npm install @shipos/sdk
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Quick Start
|
|
14
|
+
|
|
15
|
+
### Basic Usage (Vanilla JS/TS)
|
|
16
|
+
|
|
17
|
+
```typescript
|
|
18
|
+
import { createShipOS } from '@shipos/sdk';
|
|
19
|
+
|
|
20
|
+
const shipos = createShipOS({
|
|
21
|
+
apiKey: 'your-api-key',
|
|
22
|
+
environment: 'production', // optional, defaults to 'production'
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
// Identify a customer
|
|
26
|
+
await shipos.customers.signIn({
|
|
27
|
+
externalId: 'user-123',
|
|
28
|
+
metadata: { name: 'Jane', plan: 'pro' },
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
// Get all feature flags
|
|
32
|
+
const flags = await shipos.featureFlags.getAll();
|
|
33
|
+
console.log(flags); // { 'new-feature': true, 'beta-mode': false }
|
|
34
|
+
|
|
35
|
+
// Get a single flag with default value
|
|
36
|
+
const isEnabled = await shipos.featureFlags.get('new-feature', false);
|
|
37
|
+
|
|
38
|
+
// Get a typed config
|
|
39
|
+
interface PricingConfig {
|
|
40
|
+
plans: Array<{ name: string; price: number }>;
|
|
41
|
+
}
|
|
42
|
+
const pricing = await shipos.configs.get<PricingConfig>('pricing');
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### React Integration
|
|
46
|
+
|
|
47
|
+
```tsx
|
|
48
|
+
import { ShipOSProvider, useFlag, useCustomer, Feature } from '@shipos/sdk/react';
|
|
49
|
+
|
|
50
|
+
// Wrap your app with the provider
|
|
51
|
+
function App() {
|
|
52
|
+
return (
|
|
53
|
+
<ShipOSProvider config={{ apiKey: 'your-api-key' }}>
|
|
54
|
+
<MyApp />
|
|
55
|
+
</ShipOSProvider>
|
|
56
|
+
);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// Identify users with useCustomer
|
|
60
|
+
function MyApp() {
|
|
61
|
+
const { signIn } = useCustomer();
|
|
62
|
+
|
|
63
|
+
useEffect(() => {
|
|
64
|
+
signIn({ externalId: 'user-123', metadata: { plan: 'pro' } });
|
|
65
|
+
}, []);
|
|
66
|
+
|
|
67
|
+
return <Dashboard />;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// Use hooks in your components
|
|
71
|
+
function Dashboard() {
|
|
72
|
+
const { enabled, isLoading } = useFlag('new-feature');
|
|
73
|
+
|
|
74
|
+
if (isLoading) return <div>Loading...</div>;
|
|
75
|
+
|
|
76
|
+
return enabled ? <NewFeature /> : <OldFeature />;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// Or use the Feature component
|
|
80
|
+
function AnotherComponent() {
|
|
81
|
+
return (
|
|
82
|
+
<Feature flag="new-dashboard" fallback={<OldDashboard />}>
|
|
83
|
+
<NewDashboard />
|
|
84
|
+
</Feature>
|
|
85
|
+
);
|
|
86
|
+
}
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## API Reference
|
|
90
|
+
|
|
91
|
+
### Core Client
|
|
92
|
+
|
|
93
|
+
#### `createShipOS(config)`
|
|
94
|
+
|
|
95
|
+
Creates a new ShipOS client instance.
|
|
96
|
+
|
|
97
|
+
```typescript
|
|
98
|
+
const shipos = createShipOS({
|
|
99
|
+
apiKey: string; // Required: Your API key
|
|
100
|
+
baseUrl?: string; // Optional: API base URL
|
|
101
|
+
environment?: string; // Optional: Environment (default: 'production')
|
|
102
|
+
cacheTTL?: number; // Optional: Cache TTL in ms (default: 60000)
|
|
103
|
+
debug?: boolean; // Optional: Enable debug logging
|
|
104
|
+
});
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### Customers
|
|
108
|
+
|
|
109
|
+
- `customers.signIn({ externalId, metadata? })` - Identify a customer
|
|
110
|
+
- `customers.signOut()` - Clear customer context
|
|
111
|
+
- `customers.get()` - Get current customer or null
|
|
112
|
+
|
|
113
|
+
### Feature Flags
|
|
114
|
+
|
|
115
|
+
- `featureFlags.getAll()` - Get all feature flags
|
|
116
|
+
- `featureFlags.get(key, defaultValue?)` - Get a single flag
|
|
117
|
+
- `featureFlags.refresh()` - Refresh flags (bypass cache)
|
|
118
|
+
|
|
119
|
+
### Global Configs
|
|
120
|
+
|
|
121
|
+
- `configs.get<T>(slug)` - Get a config by slug
|
|
122
|
+
- `configs.refresh<T>(slug)` - Refresh a config (bypass cache)
|
|
123
|
+
|
|
124
|
+
### Utilities
|
|
125
|
+
|
|
126
|
+
- `clearCache()` - Clear the cache
|
|
127
|
+
- `setEnvironment(env)` - Change environment
|
|
128
|
+
- `getEnvironment()` - Get current environment
|
|
129
|
+
|
|
130
|
+
### React Hooks
|
|
131
|
+
|
|
132
|
+
#### `useCustomer()`
|
|
133
|
+
|
|
134
|
+
Manage customer identification.
|
|
135
|
+
|
|
136
|
+
```typescript
|
|
137
|
+
const { customer, signIn, signOut } = useCustomer();
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
#### `useFlags()`
|
|
141
|
+
|
|
142
|
+
Get all feature flags.
|
|
143
|
+
|
|
144
|
+
```typescript
|
|
145
|
+
const { flags, isLoading, error, refreshFlags } = useFlags();
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
#### `useFlag(key, defaultValue?)`
|
|
149
|
+
|
|
150
|
+
Get a single feature flag.
|
|
151
|
+
|
|
152
|
+
```typescript
|
|
153
|
+
const { enabled, isLoading, error } = useFlag('my-feature', false);
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
#### `useConfig<T>(slug)`
|
|
157
|
+
|
|
158
|
+
Get a configuration by slug.
|
|
159
|
+
|
|
160
|
+
```typescript
|
|
161
|
+
const { config, isLoading, error, refresh } = useConfig<MyConfig>('my-config');
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
### React Components
|
|
165
|
+
|
|
166
|
+
#### `<Feature>`
|
|
167
|
+
|
|
168
|
+
Conditionally render based on a flag.
|
|
169
|
+
|
|
170
|
+
```tsx
|
|
171
|
+
<Feature flag="my-feature" fallback={<Fallback />} loading={<Loading />}>
|
|
172
|
+
<EnabledContent />
|
|
173
|
+
</Feature>
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
#### `<FeatureEnabled>`
|
|
177
|
+
|
|
178
|
+
Render only when flag is enabled.
|
|
179
|
+
|
|
180
|
+
```tsx
|
|
181
|
+
<FeatureEnabled flag="my-feature">
|
|
182
|
+
<EnabledContent />
|
|
183
|
+
</FeatureEnabled>
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
#### `<FeatureDisabled>`
|
|
187
|
+
|
|
188
|
+
Render only when flag is disabled.
|
|
189
|
+
|
|
190
|
+
```tsx
|
|
191
|
+
<FeatureDisabled flag="my-feature">
|
|
192
|
+
<DisabledContent />
|
|
193
|
+
</FeatureDisabled>
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
## Configuration
|
|
197
|
+
|
|
198
|
+
### Environment Variables
|
|
199
|
+
|
|
200
|
+
You can configure the SDK using environment variables:
|
|
201
|
+
|
|
202
|
+
```bash
|
|
203
|
+
SHIPOS_API_KEY=your-api-key
|
|
204
|
+
SHIPOS_ENVIRONMENT=production
|
|
205
|
+
SHIPOS_BASE_URL=https://api.shipos.app
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
### Server-Side Rendering (SSR)
|
|
209
|
+
|
|
210
|
+
For SSR, you can pass initial flags to avoid loading states:
|
|
211
|
+
|
|
212
|
+
```tsx
|
|
213
|
+
// In your server component or getServerSideProps
|
|
214
|
+
const shipos = createShipOS({ apiKey: process.env.SHIPOS_API_KEY });
|
|
215
|
+
const initialFlags = await shipos.featureFlags.getAll();
|
|
216
|
+
|
|
217
|
+
// Pass to provider
|
|
218
|
+
<ShipOSProvider config={config} initialFlags={initialFlags}>
|
|
219
|
+
<App />
|
|
220
|
+
</ShipOSProvider>
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
## License
|
|
224
|
+
|
|
225
|
+
MIT
|
package/dist/cache.d.ts
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Simple in-memory cache for SDK responses
|
|
3
|
+
*/
|
|
4
|
+
export declare class Cache {
|
|
5
|
+
private store;
|
|
6
|
+
private defaultTTL;
|
|
7
|
+
constructor(defaultTTL?: number);
|
|
8
|
+
/**
|
|
9
|
+
* Get a value from the cache
|
|
10
|
+
*/
|
|
11
|
+
get<T>(key: string): T | null;
|
|
12
|
+
/**
|
|
13
|
+
* Set a value in the cache
|
|
14
|
+
*/
|
|
15
|
+
set<T>(key: string, data: T): void;
|
|
16
|
+
/**
|
|
17
|
+
* Delete a value from the cache
|
|
18
|
+
*/
|
|
19
|
+
delete(key: string): void;
|
|
20
|
+
/**
|
|
21
|
+
* Clear all cached values
|
|
22
|
+
*/
|
|
23
|
+
clear(): void;
|
|
24
|
+
/**
|
|
25
|
+
* Update the default TTL
|
|
26
|
+
*/
|
|
27
|
+
setTTL(ttl: number): void;
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=cache.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../src/cache.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,qBAAa,KAAK;IAChB,OAAO,CAAC,KAAK,CAA+C;IAC5D,OAAO,CAAC,UAAU,CAAS;gBAEf,UAAU,GAAE,MAAc;IAItC;;OAEG;IACH,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,GAAG,IAAI;IAgB7B;;OAEG;IACH,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,GAAG,IAAI;IAOlC;;OAEG;IACH,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAIzB;;OAEG;IACH,KAAK,IAAI,IAAI;IAIb;;OAEG;IACH,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;CAG1B"}
|
package/dist/client.d.ts
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ShipOS SDK Client
|
|
3
|
+
*
|
|
4
|
+
* Main client for interacting with the ShipOS API.
|
|
5
|
+
* Methods are organized into namespaced modules:
|
|
6
|
+
* - `featureFlags` - Feature flag operations
|
|
7
|
+
* - `configs` - Global config operations
|
|
8
|
+
* - `customers` - Customer identification
|
|
9
|
+
*/
|
|
10
|
+
import { FeatureFlagsModule } from "./modules/feature-flags";
|
|
11
|
+
import { ConfigsModule } from "./modules/configs";
|
|
12
|
+
import { CustomersModule } from "./modules/customers";
|
|
13
|
+
import type { ShipOSConfig } from "./types";
|
|
14
|
+
export declare class ShipOS {
|
|
15
|
+
private apiKey;
|
|
16
|
+
private baseUrl;
|
|
17
|
+
private environment;
|
|
18
|
+
private cache;
|
|
19
|
+
private debug;
|
|
20
|
+
private customerId;
|
|
21
|
+
/** Feature flag operations */
|
|
22
|
+
readonly featureFlags: FeatureFlagsModule;
|
|
23
|
+
/** Global config operations */
|
|
24
|
+
readonly configs: ConfigsModule;
|
|
25
|
+
/** Customer identification */
|
|
26
|
+
readonly customers: CustomersModule;
|
|
27
|
+
constructor(config: ShipOSConfig);
|
|
28
|
+
/**
|
|
29
|
+
* Log debug messages
|
|
30
|
+
*/
|
|
31
|
+
private log;
|
|
32
|
+
/**
|
|
33
|
+
* Make an authenticated request to the API
|
|
34
|
+
*/
|
|
35
|
+
private request;
|
|
36
|
+
/**
|
|
37
|
+
* Clear the cache
|
|
38
|
+
*/
|
|
39
|
+
clearCache(): void;
|
|
40
|
+
/**
|
|
41
|
+
* Update the environment
|
|
42
|
+
*/
|
|
43
|
+
setEnvironment(environment: string): void;
|
|
44
|
+
/**
|
|
45
|
+
* Get current environment
|
|
46
|
+
*/
|
|
47
|
+
getEnvironment(): string;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Create a new ShipOS client instance
|
|
51
|
+
*/
|
|
52
|
+
export declare function createShipOS(config: ShipOSConfig): ShipOS;
|
|
53
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAClD,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,KAAK,EAAE,YAAY,EAAY,MAAM,SAAS,CAAC;AAMtD,qBAAa,MAAM;IACjB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,KAAK,CAAQ;IACrB,OAAO,CAAC,KAAK,CAAU;IACvB,OAAO,CAAC,UAAU,CAAuB;IAEzC,8BAA8B;IAC9B,QAAQ,CAAC,YAAY,EAAE,kBAAkB,CAAC;IAC1C,+BAA+B;IAC/B,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAC;IAChC,8BAA8B;IAC9B,QAAQ,CAAC,SAAS,EAAE,eAAe,CAAC;gBAExB,MAAM,EAAE,YAAY;IA2BhC;;OAEG;IACH,OAAO,CAAC,GAAG;IAMX;;OAEG;YACW,OAAO;IAsCrB;;OAEG;IACH,UAAU,IAAI,IAAI;IAKlB;;OAEG;IACH,cAAc,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI;IAMzC;;OAEG;IACH,cAAc,IAAI,MAAM;CAGzB;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM,CAEzD"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ShipOS SDK
|
|
3
|
+
*
|
|
4
|
+
* Official SDK for ShipOS feature flags, global configs, and customer identification.
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* ```typescript
|
|
8
|
+
* import { createShipOS } from '@shipos/sdk';
|
|
9
|
+
*
|
|
10
|
+
* const shipos = createShipOS({
|
|
11
|
+
* apiKey: 'your-api-key',
|
|
12
|
+
* environment: 'production',
|
|
13
|
+
* });
|
|
14
|
+
*
|
|
15
|
+
* // Identify a customer
|
|
16
|
+
* await shipos.customers.signIn({ externalId: 'user-123', metadata: { plan: 'pro' } });
|
|
17
|
+
*
|
|
18
|
+
* // Get all flags
|
|
19
|
+
* const flags = await shipos.featureFlags.getAll();
|
|
20
|
+
*
|
|
21
|
+
* // Get a single flag
|
|
22
|
+
* const isEnabled = await shipos.featureFlags.get('new-feature', false);
|
|
23
|
+
*
|
|
24
|
+
* // Get a config
|
|
25
|
+
* const pricing = await shipos.configs.get('pricing');
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
28
|
+
export { ShipOS, createShipOS } from "./client";
|
|
29
|
+
export { Cache } from "./cache";
|
|
30
|
+
export type { ShipOSConfig, FlagsResponse, ConfigResponse, ApiError, CacheEntry, Result, CustomerInfo, SignInOptions, } from "./types";
|
|
31
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAChD,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC,YAAY,EACV,YAAY,EACZ,aAAa,EACb,cAAc,EACd,QAAQ,EACR,UAAU,EACV,MAAM,EACN,YAAY,EACZ,aAAa,GACd,MAAM,SAAS,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
class b{store=new Map;defaultTTL;constructor(S=60000){this.defaultTTL=S}get(S){let O=this.store.get(S);if(!O)return null;if(Date.now()-O.timestamp>this.defaultTTL)return this.store.delete(S),null;return O.data}set(S,O){this.store.set(S,{data:O,timestamp:Date.now()})}delete(S){this.store.delete(S)}clear(){this.store.clear()}setTTL(S){this.defaultTTL=S}}class j{ctx;constructor(S){this.ctx=S}async getAll(){let S=`flags:${this.ctx.getEnvironment()}`,O=this.ctx.cache.get(S);if(O)return this.ctx.log("Returning cached flags"),O;let w=await this.ctx.request("/v1/flags");return this.ctx.cache.set(S,w),w}async get(S,O=!1){return(await this.getAll())[S]??O}async refresh(){let S=`flags:${this.ctx.getEnvironment()}`;return this.ctx.cache.delete(S),this.getAll()}}class q{ctx;constructor(S){this.ctx=S}async get(S){let O=`config:${this.ctx.getEnvironment()}:${S}`,w=this.ctx.cache.get(O);if(w)return this.ctx.log(`Returning cached config: ${S}`),w;let G=await this.ctx.request(`/v1/config/${S}`);return this.ctx.cache.set(O,G),G}async refresh(S){let O=`config:${this.ctx.getEnvironment()}:${S}`;return this.ctx.cache.delete(O),this.get(S)}}class z{ctx;customer=null;constructor(S){this.ctx=S}async signIn(S){if(!S.externalId)throw Error("ShipOS: externalId is required for signIn");return this.ctx.log(`Signing in customer: ${S.externalId}`),this.customer={externalId:S.externalId,metadata:S.metadata},this.ctx.setCustomerId(S.externalId),await this.ctx.request("/v1/customers/identify",{method:"POST",body:{externalId:S.externalId,metadata:S.metadata??{}}}),this.ctx.log(`Customer signed in: ${S.externalId}`),this.customer}signOut(){this.ctx.log("Signing out customer"),this.customer=null,this.ctx.setCustomerId(null)}get(){return this.customer}}var Y="https://api.shipos.app",Z=60000,B="0.1.0";class J{apiKey;baseUrl;environment;cache;debug;customerId=null;featureFlags;configs;customers;constructor(S){if(!S.apiKey)throw Error("ShipOS: apiKey is required");this.apiKey=S.apiKey,this.baseUrl=S.baseUrl||Y,this.environment=S.environment||"production",this.cache=new b(S.cacheTTL||Z),this.debug=S.debug||!1;let O={request:this.request.bind(this),cache:this.cache,getEnvironment:this.getEnvironment.bind(this),log:this.log.bind(this),setCustomerId:(w)=>{this.customerId=w}};this.featureFlags=new j(O),this.configs=new q(O),this.customers=new z(O)}log(...S){if(this.debug)console.log("[ShipOS]",...S)}async request(S,O={}){let w=`${this.baseUrl}${S}`,G=O.method||"GET";this.log(`${G} ${w}`);let Q={"x-shipos-key":this.apiKey,"x-shipos-env":this.environment,"x-shipos-sdk-version":B,"Content-Type":"application/json"};if(this.customerId)Q["x-shipos-customer-id"]=this.customerId;let W={method:G,headers:Q};if(O.body&&G!=="GET")W.body=JSON.stringify(O.body);let I=await fetch(w,W);if(!I.ok){let X=await I.json().catch(()=>({error:`HTTP ${I.status}`,code:"HTTP_ERROR"}));throw Error(X.error||`Request failed: ${I.status}`)}return I.json()}clearCache(){this.cache.clear(),this.log("Cache cleared")}setEnvironment(S){this.environment=S,this.cache.clear(),this.log(`Environment changed to: ${S}`)}getEnvironment(){return this.environment}}function D(S){return new J(S)}export{D as createShipOS,J as ShipOS,b as Cache};
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Configs Module
|
|
3
|
+
*
|
|
4
|
+
* Provides namespaced access to global configuration operations.
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* ```typescript
|
|
8
|
+
* const pricing = await shipos.configs.get<PricingConfig>('pricing');
|
|
9
|
+
* ```
|
|
10
|
+
*/
|
|
11
|
+
import type { Cache } from "../cache";
|
|
12
|
+
import type { ConfigResponse } from "../types";
|
|
13
|
+
/**
|
|
14
|
+
* Internal context shared by the parent ShipOS client
|
|
15
|
+
*/
|
|
16
|
+
export interface ConfigsContext {
|
|
17
|
+
request: <T>(endpoint: string, options?: {
|
|
18
|
+
method?: string;
|
|
19
|
+
body?: unknown;
|
|
20
|
+
}) => Promise<T>;
|
|
21
|
+
cache: Cache;
|
|
22
|
+
getEnvironment: () => string;
|
|
23
|
+
log: (...args: unknown[]) => void;
|
|
24
|
+
}
|
|
25
|
+
export declare class ConfigsModule {
|
|
26
|
+
private ctx;
|
|
27
|
+
constructor(ctx: ConfigsContext);
|
|
28
|
+
/**
|
|
29
|
+
* Get a configuration by slug
|
|
30
|
+
*
|
|
31
|
+
* @param slug - The config slug
|
|
32
|
+
* @returns The config data
|
|
33
|
+
*
|
|
34
|
+
* @example
|
|
35
|
+
* ```typescript
|
|
36
|
+
* interface PricingConfig {
|
|
37
|
+
* plans: Array<{ name: string; price: number }>;
|
|
38
|
+
* }
|
|
39
|
+
* const pricing = await shipos.configs.get<PricingConfig>('pricing');
|
|
40
|
+
* ```
|
|
41
|
+
*/
|
|
42
|
+
get<T = Record<string, unknown>>(slug: string): Promise<ConfigResponse<T>>;
|
|
43
|
+
/**
|
|
44
|
+
* Refresh a config (bypass cache)
|
|
45
|
+
*
|
|
46
|
+
* @param slug - The config slug
|
|
47
|
+
* @returns Fresh config from the API
|
|
48
|
+
*
|
|
49
|
+
* @example
|
|
50
|
+
* ```typescript
|
|
51
|
+
* const freshConfig = await shipos.configs.refresh<PricingConfig>('pricing');
|
|
52
|
+
* ```
|
|
53
|
+
*/
|
|
54
|
+
refresh<T = Record<string, unknown>>(slug: string): Promise<ConfigResponse<T>>;
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=configs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"configs.d.ts","sourceRoot":"","sources":["../../src/modules/configs.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AACtC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAE/C;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,OAAO,CAAA;KAAE,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC;IAC5F,KAAK,EAAE,KAAK,CAAC;IACb,cAAc,EAAE,MAAM,MAAM,CAAC;IAC7B,GAAG,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;CACnC;AAED,qBAAa,aAAa;IACxB,OAAO,CAAC,GAAG,CAAiB;gBAEhB,GAAG,EAAE,cAAc;IAI/B;;;;;;;;;;;;;OAaG;IACG,GAAG,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC;IAchF;;;;;;;;;;OAUG;IACG,OAAO,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC;CAKrF"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Customers Module
|
|
3
|
+
*
|
|
4
|
+
* Provides customer identification (sign-in) for the ShipOS SDK.
|
|
5
|
+
* When a customer is signed in, their external ID is sent with
|
|
6
|
+
* subsequent API requests for targeting and analytics.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```typescript
|
|
10
|
+
* await shipos.customers.signIn({ externalId: 'user-123', metadata: { plan: 'pro' } });
|
|
11
|
+
* const customer = shipos.customers.get();
|
|
12
|
+
* shipos.customers.signOut();
|
|
13
|
+
* ```
|
|
14
|
+
*/
|
|
15
|
+
import type { CustomerInfo, SignInOptions } from "../types";
|
|
16
|
+
/**
|
|
17
|
+
* Internal context shared by the parent ShipOS client
|
|
18
|
+
*/
|
|
19
|
+
export interface CustomersContext {
|
|
20
|
+
request: <T>(endpoint: string, options?: {
|
|
21
|
+
method?: string;
|
|
22
|
+
body?: unknown;
|
|
23
|
+
}) => Promise<T>;
|
|
24
|
+
log: (...args: unknown[]) => void;
|
|
25
|
+
setCustomerId: (id: string | null) => void;
|
|
26
|
+
}
|
|
27
|
+
export declare class CustomersModule {
|
|
28
|
+
private ctx;
|
|
29
|
+
private customer;
|
|
30
|
+
constructor(ctx: CustomersContext);
|
|
31
|
+
/**
|
|
32
|
+
* Sign in a customer
|
|
33
|
+
*
|
|
34
|
+
* Identifies the customer by their external ID and optional metadata.
|
|
35
|
+
* The customer context is stored locally and sent to the API for
|
|
36
|
+
* tracking and future flag targeting.
|
|
37
|
+
*
|
|
38
|
+
* @param options - Sign-in options with externalId and optional metadata
|
|
39
|
+
*
|
|
40
|
+
* @example
|
|
41
|
+
* ```typescript
|
|
42
|
+
* await shipos.customers.signIn({
|
|
43
|
+
* externalId: 'user-123',
|
|
44
|
+
* metadata: { name: 'John', plan: 'pro' },
|
|
45
|
+
* });
|
|
46
|
+
* ```
|
|
47
|
+
*/
|
|
48
|
+
signIn(options: SignInOptions): Promise<CustomerInfo>;
|
|
49
|
+
/**
|
|
50
|
+
* Sign out the current customer
|
|
51
|
+
*
|
|
52
|
+
* Clears the local customer context. Subsequent API requests
|
|
53
|
+
* will no longer include customer identification.
|
|
54
|
+
*
|
|
55
|
+
* @example
|
|
56
|
+
* ```typescript
|
|
57
|
+
* shipos.customers.signOut();
|
|
58
|
+
* ```
|
|
59
|
+
*/
|
|
60
|
+
signOut(): void;
|
|
61
|
+
/**
|
|
62
|
+
* Get the current signed-in customer
|
|
63
|
+
*
|
|
64
|
+
* @returns The current customer info, or null if no customer is signed in
|
|
65
|
+
*
|
|
66
|
+
* @example
|
|
67
|
+
* ```typescript
|
|
68
|
+
* const customer = shipos.customers.get();
|
|
69
|
+
* if (customer) {
|
|
70
|
+
* console.log(`Signed in as: ${customer.externalId}`);
|
|
71
|
+
* }
|
|
72
|
+
* ```
|
|
73
|
+
*/
|
|
74
|
+
get(): CustomerInfo | null;
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=customers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"customers.d.ts","sourceRoot":"","sources":["../../src/modules/customers.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAE5D;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,OAAO,CAAA;KAAE,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC;IAC5F,GAAG,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;IAClC,aAAa,EAAE,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;CAC5C;AAED,qBAAa,eAAe;IAC1B,OAAO,CAAC,GAAG,CAAmB;IAC9B,OAAO,CAAC,QAAQ,CAA6B;gBAEjC,GAAG,EAAE,gBAAgB;IAIjC;;;;;;;;;;;;;;;;OAgBG;IACG,MAAM,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,YAAY,CAAC;IA6B3D;;;;;;;;;;OAUG;IACH,OAAO,IAAI,IAAI;IAMf;;;;;;;;;;;;OAYG;IACH,GAAG,IAAI,YAAY,GAAG,IAAI;CAG3B"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Feature Flags Module
|
|
3
|
+
*
|
|
4
|
+
* Provides namespaced access to feature flag operations.
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* ```typescript
|
|
8
|
+
* const flags = await shipos.featureFlags.getAll();
|
|
9
|
+
* const isEnabled = await shipos.featureFlags.get('new-feature', false);
|
|
10
|
+
* ```
|
|
11
|
+
*/
|
|
12
|
+
import type { Cache } from "../cache";
|
|
13
|
+
import type { FlagsResponse } from "../types";
|
|
14
|
+
/**
|
|
15
|
+
* Internal context shared by the parent ShipOS client
|
|
16
|
+
*/
|
|
17
|
+
export interface FeatureFlagsContext {
|
|
18
|
+
request: <T>(endpoint: string, options?: {
|
|
19
|
+
method?: string;
|
|
20
|
+
body?: unknown;
|
|
21
|
+
}) => Promise<T>;
|
|
22
|
+
cache: Cache;
|
|
23
|
+
getEnvironment: () => string;
|
|
24
|
+
log: (...args: unknown[]) => void;
|
|
25
|
+
}
|
|
26
|
+
export declare class FeatureFlagsModule {
|
|
27
|
+
private ctx;
|
|
28
|
+
constructor(ctx: FeatureFlagsContext);
|
|
29
|
+
/**
|
|
30
|
+
* Get all feature flags
|
|
31
|
+
*
|
|
32
|
+
* @returns Record of flag keys to boolean values
|
|
33
|
+
*
|
|
34
|
+
* @example
|
|
35
|
+
* ```typescript
|
|
36
|
+
* const flags = await shipos.featureFlags.getAll();
|
|
37
|
+
* // => { "new-dashboard": true, "beta-features": false }
|
|
38
|
+
* ```
|
|
39
|
+
*/
|
|
40
|
+
getAll(): Promise<FlagsResponse>;
|
|
41
|
+
/**
|
|
42
|
+
* Get a single feature flag value
|
|
43
|
+
*
|
|
44
|
+
* @param key - The flag key
|
|
45
|
+
* @param defaultValue - Default value if flag is not found (defaults to false)
|
|
46
|
+
* @returns The flag value or default
|
|
47
|
+
*
|
|
48
|
+
* @example
|
|
49
|
+
* ```typescript
|
|
50
|
+
* const isEnabled = await shipos.featureFlags.get('new-dashboard', false);
|
|
51
|
+
* ```
|
|
52
|
+
*/
|
|
53
|
+
get(key: string, defaultValue?: boolean): Promise<boolean>;
|
|
54
|
+
/**
|
|
55
|
+
* Refresh flags (bypass cache)
|
|
56
|
+
*
|
|
57
|
+
* @returns Fresh flags from the API
|
|
58
|
+
*
|
|
59
|
+
* @example
|
|
60
|
+
* ```typescript
|
|
61
|
+
* const freshFlags = await shipos.featureFlags.refresh();
|
|
62
|
+
* ```
|
|
63
|
+
*/
|
|
64
|
+
refresh(): Promise<FlagsResponse>;
|
|
65
|
+
}
|
|
66
|
+
//# sourceMappingURL=feature-flags.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"feature-flags.d.ts","sourceRoot":"","sources":["../../src/modules/feature-flags.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AACtC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAE9C;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,OAAO,CAAA;KAAE,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC;IAC5F,KAAK,EAAE,KAAK,CAAC;IACb,cAAc,EAAE,MAAM,MAAM,CAAC;IAC7B,GAAG,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;CACnC;AAED,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,GAAG,CAAsB;gBAErB,GAAG,EAAE,mBAAmB;IAIpC;;;;;;;;;;OAUG;IACG,MAAM,IAAI,OAAO,CAAC,aAAa,CAAC;IActC;;;;;;;;;;;OAWG;IACG,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,YAAY,GAAE,OAAe,GAAG,OAAO,CAAC,OAAO,CAAC;IAKvE;;;;;;;;;OASG;IACG,OAAO,IAAI,OAAO,CAAC,aAAa,CAAC;CAKxC"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import type { ReactNode } from "react";
|
|
2
|
+
/**
|
|
3
|
+
* Feature Component Props
|
|
4
|
+
*/
|
|
5
|
+
interface FeatureProps {
|
|
6
|
+
/** The feature flag key */
|
|
7
|
+
flag: string;
|
|
8
|
+
/** Content to render when the flag is enabled */
|
|
9
|
+
children: ReactNode;
|
|
10
|
+
/** Content to render when the flag is disabled (optional) */
|
|
11
|
+
fallback?: ReactNode;
|
|
12
|
+
/** Content to render while loading (optional) */
|
|
13
|
+
loading?: ReactNode;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Feature Component
|
|
17
|
+
*
|
|
18
|
+
* Conditionally renders content based on a feature flag.
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* ```tsx
|
|
22
|
+
* // Basic usage
|
|
23
|
+
* <Feature flag="new-dashboard">
|
|
24
|
+
* <NewDashboard />
|
|
25
|
+
* </Feature>
|
|
26
|
+
*
|
|
27
|
+
* // With fallback
|
|
28
|
+
* <Feature flag="new-dashboard" fallback={<OldDashboard />}>
|
|
29
|
+
* <NewDashboard />
|
|
30
|
+
* </Feature>
|
|
31
|
+
*
|
|
32
|
+
* // With loading state
|
|
33
|
+
* <Feature flag="new-dashboard" loading={<Skeleton />}>
|
|
34
|
+
* <NewDashboard />
|
|
35
|
+
* </Feature>
|
|
36
|
+
* ```
|
|
37
|
+
*/
|
|
38
|
+
export declare function Feature({ flag, children, fallback, loading, }: FeatureProps): import("react/jsx-runtime").JSX.Element;
|
|
39
|
+
/**
|
|
40
|
+
* FeatureEnabled Component Props
|
|
41
|
+
*/
|
|
42
|
+
interface FeatureEnabledProps {
|
|
43
|
+
/** The feature flag key */
|
|
44
|
+
flag: string;
|
|
45
|
+
/** Content to render when the flag is enabled */
|
|
46
|
+
children: ReactNode;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* FeatureEnabled Component
|
|
50
|
+
*
|
|
51
|
+
* Only renders children when the flag is enabled.
|
|
52
|
+
* Simpler alternative to Feature when you don't need fallback.
|
|
53
|
+
*
|
|
54
|
+
* @example
|
|
55
|
+
* ```tsx
|
|
56
|
+
* <FeatureEnabled flag="beta-features">
|
|
57
|
+
* <BetaBanner />
|
|
58
|
+
* </FeatureEnabled>
|
|
59
|
+
* ```
|
|
60
|
+
*/
|
|
61
|
+
export declare function FeatureEnabled({ flag, children }: FeatureEnabledProps): import("react/jsx-runtime").JSX.Element | null;
|
|
62
|
+
/**
|
|
63
|
+
* FeatureDisabled Component Props
|
|
64
|
+
*/
|
|
65
|
+
interface FeatureDisabledProps {
|
|
66
|
+
/** The feature flag key */
|
|
67
|
+
flag: string;
|
|
68
|
+
/** Content to render when the flag is disabled */
|
|
69
|
+
children: ReactNode;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* FeatureDisabled Component
|
|
73
|
+
*
|
|
74
|
+
* Only renders children when the flag is disabled.
|
|
75
|
+
*
|
|
76
|
+
* @example
|
|
77
|
+
* ```tsx
|
|
78
|
+
* <FeatureDisabled flag="maintenance-mode">
|
|
79
|
+
* <MainContent />
|
|
80
|
+
* </FeatureDisabled>
|
|
81
|
+
* ```
|
|
82
|
+
*/
|
|
83
|
+
export declare function FeatureDisabled({ flag, children }: FeatureDisabledProps): import("react/jsx-runtime").JSX.Element | null;
|
|
84
|
+
export {};
|
|
85
|
+
//# sourceMappingURL=components.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"components.d.ts","sourceRoot":"","sources":["../../src/react/components.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAGvC;;GAEG;AACH,UAAU,YAAY;IACpB,2BAA2B;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,iDAAiD;IACjD,QAAQ,EAAE,SAAS,CAAC;IACpB,6DAA6D;IAC7D,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,iDAAiD;IACjD,OAAO,CAAC,EAAE,SAAS,CAAC;CACrB;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,OAAO,CAAC,EACtB,IAAI,EACJ,QAAQ,EACR,QAAe,EACf,OAAc,GACf,EAAE,YAAY,2CAQd;AAED;;GAEG;AACH,UAAU,mBAAmB;IAC3B,2BAA2B;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,iDAAiD;IACjD,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,cAAc,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,mBAAmB,kDAQrE;AAED;;GAEG;AACH,UAAU,oBAAoB;IAC5B,2BAA2B;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,kDAAkD;IAClD,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,eAAe,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,oBAAoB,kDAQvE"}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import type { CustomerInfo, SignInOptions } from "../types";
|
|
2
|
+
/**
|
|
3
|
+
* Hook to get all feature flags
|
|
4
|
+
*
|
|
5
|
+
* @example
|
|
6
|
+
* ```tsx
|
|
7
|
+
* function MyComponent() {
|
|
8
|
+
* const { flags, isLoading, error } = useFlags();
|
|
9
|
+
*
|
|
10
|
+
* if (isLoading) return <div>Loading...</div>;
|
|
11
|
+
* if (error) return <div>Error: {error.message}</div>;
|
|
12
|
+
*
|
|
13
|
+
* return (
|
|
14
|
+
* <div>
|
|
15
|
+
* {flags['new-feature'] && <NewFeature />}
|
|
16
|
+
* </div>
|
|
17
|
+
* );
|
|
18
|
+
* }
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
21
|
+
export declare function useFlags(): {
|
|
22
|
+
flags: import("..").FlagsResponse;
|
|
23
|
+
isLoading: boolean;
|
|
24
|
+
error: Error | null;
|
|
25
|
+
refreshFlags: () => Promise<void>;
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
* Hook to get a single feature flag
|
|
29
|
+
*
|
|
30
|
+
* @param key - The flag key
|
|
31
|
+
* @param defaultValue - Default value if flag is not found
|
|
32
|
+
*
|
|
33
|
+
* @example
|
|
34
|
+
* ```tsx
|
|
35
|
+
* function MyComponent() {
|
|
36
|
+
* const { enabled, isLoading } = useFlag('new-feature', false);
|
|
37
|
+
*
|
|
38
|
+
* if (isLoading) return <div>Loading...</div>;
|
|
39
|
+
*
|
|
40
|
+
* return enabled ? <NewFeature /> : <OldFeature />;
|
|
41
|
+
* }
|
|
42
|
+
* ```
|
|
43
|
+
*/
|
|
44
|
+
export declare function useFlag(key: string, defaultValue?: boolean): {
|
|
45
|
+
enabled: boolean;
|
|
46
|
+
isLoading: boolean;
|
|
47
|
+
error: Error | null;
|
|
48
|
+
};
|
|
49
|
+
/**
|
|
50
|
+
* Hook to get a configuration by slug
|
|
51
|
+
*
|
|
52
|
+
* @param slug - The config slug
|
|
53
|
+
*
|
|
54
|
+
* @example
|
|
55
|
+
* ```tsx
|
|
56
|
+
* interface PricingConfig {
|
|
57
|
+
* plans: Array<{ name: string; price: number }>;
|
|
58
|
+
* }
|
|
59
|
+
*
|
|
60
|
+
* function PricingPage() {
|
|
61
|
+
* const { config, isLoading, error, refresh } = useConfig<PricingConfig>('pricing');
|
|
62
|
+
*
|
|
63
|
+
* if (isLoading) return <div>Loading...</div>;
|
|
64
|
+
* if (error) return <div>Error: {error.message}</div>;
|
|
65
|
+
*
|
|
66
|
+
* return (
|
|
67
|
+
* <div>
|
|
68
|
+
* {config?.plans.map(plan => (
|
|
69
|
+
* <div key={plan.name}>{plan.name}: ${plan.price}</div>
|
|
70
|
+
* ))}
|
|
71
|
+
* </div>
|
|
72
|
+
* );
|
|
73
|
+
* }
|
|
74
|
+
* ```
|
|
75
|
+
*/
|
|
76
|
+
export declare function useConfig<T = Record<string, unknown>>(slug: string): {
|
|
77
|
+
config: T | null;
|
|
78
|
+
isLoading: boolean;
|
|
79
|
+
error: Error | null;
|
|
80
|
+
refresh: () => Promise<void>;
|
|
81
|
+
};
|
|
82
|
+
/**
|
|
83
|
+
* Hook to manage customer identification
|
|
84
|
+
*
|
|
85
|
+
* @example
|
|
86
|
+
* ```tsx
|
|
87
|
+
* function UserProfile() {
|
|
88
|
+
* const { customer, signIn, signOut } = useCustomer();
|
|
89
|
+
*
|
|
90
|
+
* useEffect(() => {
|
|
91
|
+
* // Sign in when user is authenticated
|
|
92
|
+
* signIn({ externalId: 'user-123', metadata: { plan: 'pro' } });
|
|
93
|
+
* }, []);
|
|
94
|
+
*
|
|
95
|
+
* return (
|
|
96
|
+
* <div>
|
|
97
|
+
* {customer ? (
|
|
98
|
+
* <>
|
|
99
|
+
* <p>Signed in as: {customer.externalId}</p>
|
|
100
|
+
* <button onClick={signOut}>Sign Out</button>
|
|
101
|
+
* </>
|
|
102
|
+
* ) : (
|
|
103
|
+
* <p>Not signed in</p>
|
|
104
|
+
* )}
|
|
105
|
+
* </div>
|
|
106
|
+
* );
|
|
107
|
+
* }
|
|
108
|
+
* ```
|
|
109
|
+
*/
|
|
110
|
+
export declare function useCustomer(): {
|
|
111
|
+
customer: CustomerInfo | null;
|
|
112
|
+
signIn: (options: SignInOptions) => Promise<CustomerInfo>;
|
|
113
|
+
signOut: () => void;
|
|
114
|
+
};
|
|
115
|
+
//# sourceMappingURL=hooks.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../../src/react/hooks.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAkB,YAAY,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAE5E;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,QAAQ;;;;;EAGvB;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,YAAY,GAAE,OAAe;;;;EAKjE;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,SAAS,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,IAAI,EAAE,MAAM;;;;;EA0ClE;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAgB,WAAW,IAUpB;IACH,QAAQ,EAAE,YAAY,GAAG,IAAI,CAAC;IAC9B,MAAM,EAAE,CAAC,OAAO,EAAE,aAAa,KAAK,OAAO,CAAC,YAAY,CAAC,CAAC;IAC1D,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB,CACF"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ShipOS SDK React Integration
|
|
3
|
+
*
|
|
4
|
+
* React hooks and components for ShipOS feature flags, configs, and customer identification.
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* ```tsx
|
|
8
|
+
* import { ShipOSProvider, useFlag, useCustomer, Feature } from '@shipos/sdk/react';
|
|
9
|
+
*
|
|
10
|
+
* function App() {
|
|
11
|
+
* return (
|
|
12
|
+
* <ShipOSProvider config={{ apiKey: 'your-api-key' }}>
|
|
13
|
+
* <Feature flag="new-feature">
|
|
14
|
+
* <NewFeature />
|
|
15
|
+
* </Feature>
|
|
16
|
+
* </ShipOSProvider>
|
|
17
|
+
* );
|
|
18
|
+
* }
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
21
|
+
export { ShipOSProvider, useShipOS } from "./provider";
|
|
22
|
+
export { useFlags, useFlag, useConfig, useCustomer } from "./hooks";
|
|
23
|
+
export { Feature, FeatureEnabled, FeatureDisabled } from "./components";
|
|
24
|
+
export type { ShipOSConfig, FlagsResponse, ConfigResponse, CustomerInfo, SignInOptions, } from "../types";
|
|
25
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/react/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAGH,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAGvD,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAGpE,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAGxE,YAAY,EACV,YAAY,EACZ,aAAa,EACb,cAAc,EACd,YAAY,EACZ,aAAa,GACd,MAAM,UAAU,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
class P{store=new Map;defaultTTL;constructor(G=60000){this.defaultTTL=G}get(G){let q=this.store.get(G);if(!q)return null;if(Date.now()-q.timestamp>this.defaultTTL)return this.store.delete(G),null;return q.data}set(G,q){this.store.set(G,{data:q,timestamp:Date.now()})}delete(G){this.store.delete(G)}clear(){this.store.clear()}setTTL(G){this.defaultTTL=G}}class _{ctx;constructor(G){this.ctx=G}async getAll(){let G=`flags:${this.ctx.getEnvironment()}`,q=this.ctx.cache.get(G);if(q)return this.ctx.log("Returning cached flags"),q;let z=await this.ctx.request("/v1/flags");return this.ctx.cache.set(G,z),z}async get(G,q=!1){return(await this.getAll())[G]??q}async refresh(){let G=`flags:${this.ctx.getEnvironment()}`;return this.ctx.cache.delete(G),this.getAll()}}class I{ctx;constructor(G){this.ctx=G}async get(G){let q=`config:${this.ctx.getEnvironment()}:${G}`,z=this.ctx.cache.get(q);if(z)return this.ctx.log(`Returning cached config: ${G}`),z;let J=await this.ctx.request(`/v1/config/${G}`);return this.ctx.cache.set(q,J),J}async refresh(G){let q=`config:${this.ctx.getEnvironment()}:${G}`;return this.ctx.cache.delete(q),this.get(G)}}class j{ctx;customer=null;constructor(G){this.ctx=G}async signIn(G){if(!G.externalId)throw Error("ShipOS: externalId is required for signIn");return this.ctx.log(`Signing in customer: ${G.externalId}`),this.customer={externalId:G.externalId,metadata:G.metadata},this.ctx.setCustomerId(G.externalId),await this.ctx.request("/v1/customers/identify",{method:"POST",body:{externalId:G.externalId,metadata:G.metadata??{}}}),this.ctx.log(`Customer signed in: ${G.externalId}`),this.customer}signOut(){this.ctx.log("Signing out customer"),this.customer=null,this.ctx.setCustomerId(null)}get(){return this.customer}}var C="https://api.shipos.app",k=60000,x="0.1.0";class w{apiKey;baseUrl;environment;cache;debug;customerId=null;featureFlags;configs;customers;constructor(G){if(!G.apiKey)throw Error("ShipOS: apiKey is required");this.apiKey=G.apiKey,this.baseUrl=G.baseUrl||C,this.environment=G.environment||"production",this.cache=new P(G.cacheTTL||k),this.debug=G.debug||!1;let q={request:this.request.bind(this),cache:this.cache,getEnvironment:this.getEnvironment.bind(this),log:this.log.bind(this),setCustomerId:(z)=>{this.customerId=z}};this.featureFlags=new _(q),this.configs=new I(q),this.customers=new j(q)}log(...G){if(this.debug)console.log("[ShipOS]",...G)}async request(G,q={}){let z=`${this.baseUrl}${G}`,J=q.method||"GET";this.log(`${J} ${z}`);let Y={"x-shipos-key":this.apiKey,"x-shipos-env":this.environment,"x-shipos-sdk-version":x,"Content-Type":"application/json"};if(this.customerId)Y["x-shipos-customer-id"]=this.customerId;let Q={method:J,headers:Y};if(q.body&&J!=="GET")Q.body=JSON.stringify(q.body);let Z=await fetch(z,Q);if(!Z.ok){let B=await Z.json().catch(()=>({error:`HTTP ${Z.status}`,code:"HTTP_ERROR"}));throw Error(B.error||`Request failed: ${Z.status}`)}return Z.json()}clearCache(){this.cache.clear(),this.log("Cache cleared")}setEnvironment(G){this.environment=G,this.cache.clear(),this.log(`Environment changed to: ${G}`)}getEnvironment(){return this.environment}}function F(G){return new w(G)}import{createContext as m,useContext as p,useState as H,useEffect as h,useCallback as U}from"react";import{jsxDEV as d}from"react/jsx-dev-runtime";var T=m(null);function f({config:G,children:q,initialFlags:z={}}){let[J]=H(()=>new w(G)),[Y,Q]=H(z),[Z,B]=H(Object.keys(z).length===0),[M,N]=H(null),[W,O]=H(null),D=U(async()=>{try{B(!0),N(null);let X=await J.featureFlags.getAll();Q(X)}catch(X){N(X instanceof Error?X:Error("Failed to fetch flags"))}finally{B(!1)}},[J]),L=U(async()=>{try{N(null);let X=await J.featureFlags.refresh();Q(X)}catch(X){N(X instanceof Error?X:Error("Failed to refresh flags"))}},[J]),E=U(async(X)=>{let V=await J.customers.signIn(X);return O(V),V},[J]),y=U(()=>{J.customers.signOut(),O(null)},[J]);h(()=>{if(Object.keys(z).length===0)D()},[D,z]);let S={client:J,flags:Y,isLoading:Z,error:M,refreshFlags:L,customer:W,signIn:E,signOut:y};return d(T.Provider,{value:S,children:q},void 0,!1,void 0,this)}function $(){let G=p(T);if(!G)throw Error("useShipOS must be used within a ShipOSProvider");return G}import{useState as v,useEffect as u,useCallback as b}from"react";function g(){let{flags:G,isLoading:q,error:z,refreshFlags:J}=$();return{flags:G,isLoading:q,error:z,refreshFlags:J}}function R(G,q=!1){let{flags:z,isLoading:J,error:Y}=$();return{enabled:z[G]??q,isLoading:J,error:Y}}function c(G){let{client:q}=$(),[z,J]=v(null),[Y,Q]=v(!0),[Z,B]=v(null),M=b(async()=>{try{Q(!0),B(null);let W=await q.configs.get(G);J(W)}catch(W){B(W instanceof Error?W:Error(`Failed to fetch config: ${G}`))}finally{Q(!1)}},[q,G]),N=b(async()=>{try{B(null);let W=await q.configs.refresh(G);J(W)}catch(W){B(W instanceof Error?W:Error(`Failed to refresh config: ${G}`))}},[q,G]);return u(()=>{M()},[M]),{config:z,isLoading:Y,error:Z,refresh:N}}function a(){let{customer:G,signIn:q,signOut:z}=$();return{customer:G,signIn:q,signOut:z}}import{jsxDEV as K,Fragment as A}from"react/jsx-dev-runtime";function l({flag:G,children:q,fallback:z=null,loading:J=null}){let{enabled:Y,isLoading:Q}=R(G);if(Q&&J)return K(A,{children:J},void 0,!1,void 0,this);return Y?K(A,{children:q},void 0,!1,void 0,this):K(A,{children:z},void 0,!1,void 0,this)}function r({flag:G,children:q}){let{enabled:z,isLoading:J}=R(G);if(J||!z)return null;return K(A,{children:q},void 0,!1,void 0,this)}function i({flag:G,children:q}){let{enabled:z,isLoading:J}=R(G);if(J||z)return null;return K(A,{children:q},void 0,!1,void 0,this)}export{$ as useShipOS,g as useFlags,R as useFlag,a as useCustomer,c as useConfig,f as ShipOSProvider,r as FeatureEnabled,i as FeatureDisabled,l as Feature};
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { type ReactNode } from "react";
|
|
2
|
+
import { ShipOS, type ShipOSConfig, type FlagsResponse, type CustomerInfo, type SignInOptions } from "../index";
|
|
3
|
+
/**
|
|
4
|
+
* ShipOS Context Value
|
|
5
|
+
*/
|
|
6
|
+
interface ShipOSContextValue {
|
|
7
|
+
/** The ShipOS client instance */
|
|
8
|
+
client: ShipOS;
|
|
9
|
+
/** All feature flags (cached) */
|
|
10
|
+
flags: FlagsResponse;
|
|
11
|
+
/** Whether flags are currently loading */
|
|
12
|
+
isLoading: boolean;
|
|
13
|
+
/** Error if flags failed to load */
|
|
14
|
+
error: Error | null;
|
|
15
|
+
/** Refresh flags from the API */
|
|
16
|
+
refreshFlags: () => Promise<void>;
|
|
17
|
+
/** Current signed-in customer */
|
|
18
|
+
customer: CustomerInfo | null;
|
|
19
|
+
/** Sign in a customer */
|
|
20
|
+
signIn: (options: SignInOptions) => Promise<CustomerInfo>;
|
|
21
|
+
/** Sign out the current customer */
|
|
22
|
+
signOut: () => void;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* ShipOS Provider Props
|
|
26
|
+
*/
|
|
27
|
+
interface ShipOSProviderProps {
|
|
28
|
+
/** ShipOS configuration */
|
|
29
|
+
config: ShipOSConfig;
|
|
30
|
+
/** Child components */
|
|
31
|
+
children: ReactNode;
|
|
32
|
+
/** Initial flags (for SSR) */
|
|
33
|
+
initialFlags?: FlagsResponse;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* ShipOS Provider
|
|
37
|
+
*
|
|
38
|
+
* Provides the ShipOS client, flags, and customer context to all child components.
|
|
39
|
+
*
|
|
40
|
+
* @example
|
|
41
|
+
* ```tsx
|
|
42
|
+
* import { ShipOSProvider } from '@shipos/sdk/react';
|
|
43
|
+
*
|
|
44
|
+
* function App() {
|
|
45
|
+
* return (
|
|
46
|
+
* <ShipOSProvider config={{ apiKey: 'your-api-key' }}>
|
|
47
|
+
* <YourApp />
|
|
48
|
+
* </ShipOSProvider>
|
|
49
|
+
* );
|
|
50
|
+
* }
|
|
51
|
+
* ```
|
|
52
|
+
*/
|
|
53
|
+
export declare function ShipOSProvider({ config, children, initialFlags, }: ShipOSProviderProps): import("react/jsx-runtime").JSX.Element;
|
|
54
|
+
/**
|
|
55
|
+
* Hook to access the ShipOS context
|
|
56
|
+
*
|
|
57
|
+
* @throws Error if used outside of ShipOSProvider
|
|
58
|
+
*/
|
|
59
|
+
export declare function useShipOS(): ShipOSContextValue;
|
|
60
|
+
export {};
|
|
61
|
+
//# sourceMappingURL=provider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../../src/react/provider.tsx"],"names":[],"mappings":"AAEA,OAAO,EAML,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AACf,OAAO,EACL,MAAM,EACN,KAAK,YAAY,EACjB,KAAK,aAAa,EAClB,KAAK,YAAY,EACjB,KAAK,aAAa,EACnB,MAAM,UAAU,CAAC;AAElB;;GAEG;AACH,UAAU,kBAAkB;IAC1B,iCAAiC;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,iCAAiC;IACjC,KAAK,EAAE,aAAa,CAAC;IACrB,0CAA0C;IAC1C,SAAS,EAAE,OAAO,CAAC;IACnB,oCAAoC;IACpC,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IACpB,iCAAiC;IACjC,YAAY,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAClC,iCAAiC;IACjC,QAAQ,EAAE,YAAY,GAAG,IAAI,CAAC;IAC9B,yBAAyB;IACzB,MAAM,EAAE,CAAC,OAAO,EAAE,aAAa,KAAK,OAAO,CAAC,YAAY,CAAC,CAAC;IAC1D,oCAAoC;IACpC,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAID;;GAEG;AACH,UAAU,mBAAmB;IAC3B,2BAA2B;IAC3B,MAAM,EAAE,YAAY,CAAC;IACrB,uBAAuB;IACvB,QAAQ,EAAE,SAAS,CAAC;IACpB,8BAA8B;IAC9B,YAAY,CAAC,EAAE,aAAa,CAAC;CAC9B;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,cAAc,CAAC,EAC7B,MAAM,EACN,QAAQ,EACR,YAAiB,GAClB,EAAE,mBAAmB,2CAqErB;AAED;;;;GAIG;AACH,wBAAgB,SAAS,IAAI,kBAAkB,CAM9C"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ShipOS SDK Types
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Configuration options for the ShipOS client
|
|
6
|
+
*/
|
|
7
|
+
export interface ShipOSConfig {
|
|
8
|
+
/** Your ShipOS API key */
|
|
9
|
+
apiKey: string;
|
|
10
|
+
/** Base URL for the ShipOS API (defaults to production) */
|
|
11
|
+
baseUrl?: string;
|
|
12
|
+
/** Environment to fetch flags/configs for (defaults to 'production') */
|
|
13
|
+
environment?: string;
|
|
14
|
+
/** Cache TTL in milliseconds (defaults to 60000 - 1 minute) */
|
|
15
|
+
cacheTTL?: number;
|
|
16
|
+
/** Enable debug logging */
|
|
17
|
+
debug?: boolean;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Feature flags response type
|
|
21
|
+
*/
|
|
22
|
+
export type FlagsResponse = Record<string, boolean>;
|
|
23
|
+
/**
|
|
24
|
+
* Config response type (generic for typed configs)
|
|
25
|
+
*/
|
|
26
|
+
export type ConfigResponse<T = Record<string, unknown>> = T;
|
|
27
|
+
/**
|
|
28
|
+
* API error response
|
|
29
|
+
*/
|
|
30
|
+
export interface ApiError {
|
|
31
|
+
error: string;
|
|
32
|
+
code?: string;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Cache entry with timestamp
|
|
36
|
+
*/
|
|
37
|
+
export interface CacheEntry<T> {
|
|
38
|
+
data: T;
|
|
39
|
+
timestamp: number;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Result type for async operations
|
|
43
|
+
*/
|
|
44
|
+
export type Result<T, E = Error> = {
|
|
45
|
+
success: true;
|
|
46
|
+
data: T;
|
|
47
|
+
} | {
|
|
48
|
+
success: false;
|
|
49
|
+
error: E;
|
|
50
|
+
};
|
|
51
|
+
/**
|
|
52
|
+
* Customer information returned after sign-in
|
|
53
|
+
*/
|
|
54
|
+
export interface CustomerInfo {
|
|
55
|
+
/** External ID used to identify the customer */
|
|
56
|
+
externalId: string;
|
|
57
|
+
/** Optional metadata associated with the customer */
|
|
58
|
+
metadata?: Record<string, unknown>;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Options for signing in a customer
|
|
62
|
+
*/
|
|
63
|
+
export interface SignInOptions {
|
|
64
|
+
/** External ID used to identify the customer in your system */
|
|
65
|
+
externalId: string;
|
|
66
|
+
/** Optional JSON metadata to associate with the customer */
|
|
67
|
+
metadata?: Record<string, unknown>;
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,0BAA0B;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,2DAA2D;IAC3D,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,wEAAwE;IACxE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,+DAA+D;IAC/D,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,2BAA2B;IAC3B,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,MAAM,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAEpD;;GAEG;AACH,MAAM,MAAM,cAAc,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;AAE5D;;GAEG;AACH,MAAM,WAAW,QAAQ;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;GAEG;AACH,MAAM,WAAW,UAAU,CAAC,CAAC;IAC3B,IAAI,EAAE,CAAC,CAAC;IACR,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,MAAM,MAAM,CAAC,CAAC,EAAE,CAAC,GAAG,KAAK,IAC3B;IAAE,OAAO,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,CAAC,CAAA;CAAE,GAC1B;IAAE,OAAO,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,CAAC,CAAA;CAAE,CAAC;AAEjC;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,gDAAgD;IAChD,UAAU,EAAE,MAAM,CAAC;IACnB,qDAAqD;IACrD,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,+DAA+D;IAC/D,UAAU,EAAE,MAAM,CAAC;IACnB,4DAA4D;IAC5D,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "shipos",
|
|
3
|
+
"version": "0.0.0",
|
|
4
|
+
"description": "ShipOS SDK for feature flags and global configs",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"module": "./dist/index.js",
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"import": "./dist/index.js",
|
|
12
|
+
"types": "./dist/index.d.ts"
|
|
13
|
+
},
|
|
14
|
+
"./react": {
|
|
15
|
+
"import": "./dist/react/index.js",
|
|
16
|
+
"types": "./dist/react/index.d.ts"
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
"files": [
|
|
20
|
+
"dist",
|
|
21
|
+
"README.md"
|
|
22
|
+
],
|
|
23
|
+
"scripts": {
|
|
24
|
+
"build:bundle": "bun build ./src/index.ts ./src/react/index.ts --outdir ./dist --target browser --format esm --external react",
|
|
25
|
+
"build": "bun run build:bundle -- --minify && bun run build:types",
|
|
26
|
+
"build:types": "tsc --emitDeclarationOnly --declaration --outDir ./dist",
|
|
27
|
+
"dev": "bun run build:bundle -- --watch",
|
|
28
|
+
"clean": "rm -rf dist",
|
|
29
|
+
"prepublishOnly": "bun run build"
|
|
30
|
+
},
|
|
31
|
+
"keywords": [
|
|
32
|
+
"shipos",
|
|
33
|
+
"feature-flags",
|
|
34
|
+
"config",
|
|
35
|
+
"sdk",
|
|
36
|
+
"react"
|
|
37
|
+
],
|
|
38
|
+
"author": "",
|
|
39
|
+
"license": "UNLICENSED",
|
|
40
|
+
"devDependencies": {
|
|
41
|
+
"@types/bun": "latest",
|
|
42
|
+
"@types/react": "^19.0.0"
|
|
43
|
+
},
|
|
44
|
+
"peerDependencies": {
|
|
45
|
+
"react": "^18 || ^19",
|
|
46
|
+
"typescript": "^5"
|
|
47
|
+
},
|
|
48
|
+
"peerDependenciesMeta": {
|
|
49
|
+
"react": {
|
|
50
|
+
"optional": true
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|