@buildrflags/vue 0.1.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 +190 -0
- package/dist/composables.d.ts +89 -0
- package/dist/composables.d.ts.map +1 -0
- package/dist/composables.js +128 -0
- package/dist/composables.js.map +1 -0
- package/dist/index.d.ts +43 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +45 -0
- package/dist/index.js.map +1 -0
- package/dist/plugin.d.ts +31 -0
- package/dist/plugin.d.ts.map +1 -0
- package/dist/plugin.js +101 -0
- package/dist/plugin.js.map +1 -0
- package/dist/types.d.ts +69 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +5 -0
- package/dist/types.js.map +1 -0
- package/package.json +63 -0
package/README.md
ADDED
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
# @buildrflags/vue
|
|
2
|
+
|
|
3
|
+
Official Vue 3 SDK for [BuildrFlags](https://flags.buildrlab.com) — feature flags made simple.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @buildrflags/vue
|
|
9
|
+
# or
|
|
10
|
+
pnpm add @buildrflags/vue
|
|
11
|
+
# or
|
|
12
|
+
yarn add @buildrflags/vue
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Quick Start
|
|
16
|
+
|
|
17
|
+
### 1. Install the Plugin
|
|
18
|
+
|
|
19
|
+
```ts
|
|
20
|
+
// main.ts
|
|
21
|
+
import { createApp } from 'vue';
|
|
22
|
+
import { BuildrFlagsPlugin } from '@buildrflags/vue';
|
|
23
|
+
import App from './App.vue';
|
|
24
|
+
|
|
25
|
+
const app = createApp(App);
|
|
26
|
+
|
|
27
|
+
app.use(BuildrFlagsPlugin, {
|
|
28
|
+
apiKey: 'bf_production_xxx', // Your BuildrFlags API key
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
app.mount('#app');
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
### 2. Use Feature Flags in Components
|
|
35
|
+
|
|
36
|
+
```vue
|
|
37
|
+
<script setup lang="ts">
|
|
38
|
+
import { useFlag } from '@buildrflags/vue';
|
|
39
|
+
|
|
40
|
+
const { enabled, isLoading } = useFlag('new-checkout-flow');
|
|
41
|
+
</script>
|
|
42
|
+
|
|
43
|
+
<template>
|
|
44
|
+
<LoadingSpinner v-if="isLoading" />
|
|
45
|
+
<NewCheckout v-else-if="enabled" />
|
|
46
|
+
<OldCheckout v-else />
|
|
47
|
+
</template>
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## Composables
|
|
51
|
+
|
|
52
|
+
### `useFlag(flagKey)`
|
|
53
|
+
|
|
54
|
+
Get the evaluation result for a single flag.
|
|
55
|
+
|
|
56
|
+
```vue
|
|
57
|
+
<script setup lang="ts">
|
|
58
|
+
import { useFlag } from '@buildrflags/vue';
|
|
59
|
+
|
|
60
|
+
const { enabled, isLoading } = useFlag('dark-mode');
|
|
61
|
+
</script>
|
|
62
|
+
|
|
63
|
+
<template>
|
|
64
|
+
<DarkTheme v-if="enabled" />
|
|
65
|
+
<LightTheme v-else />
|
|
66
|
+
</template>
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### `useFlagValue(flagKey, defaultValue?)`
|
|
70
|
+
|
|
71
|
+
Simple boolean access with optional default value.
|
|
72
|
+
|
|
73
|
+
```vue
|
|
74
|
+
<script setup lang="ts">
|
|
75
|
+
import { useFlagValue } from '@buildrflags/vue';
|
|
76
|
+
|
|
77
|
+
// Returns false while loading, true once flag is fetched (if enabled)
|
|
78
|
+
const showBanner = useFlagValue('promo-banner', false);
|
|
79
|
+
</script>
|
|
80
|
+
|
|
81
|
+
<template>
|
|
82
|
+
<PromoBanner v-if="showBanner" />
|
|
83
|
+
</template>
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### `useFlags()`
|
|
87
|
+
|
|
88
|
+
Get all flags with loading/error state and manual refresh.
|
|
89
|
+
|
|
90
|
+
```vue
|
|
91
|
+
<script setup lang="ts">
|
|
92
|
+
import { useFlags } from '@buildrflags/vue';
|
|
93
|
+
|
|
94
|
+
const { flags, isLoading, error, refresh } = useFlags();
|
|
95
|
+
</script>
|
|
96
|
+
|
|
97
|
+
<template>
|
|
98
|
+
<div v-if="error" class="error">{{ error }}</div>
|
|
99
|
+
<button @click="refresh">Refresh Flags</button>
|
|
100
|
+
<pre>{{ flags }}</pre>
|
|
101
|
+
</template>
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### `useFlagsEnabled(flagKeys, mode?)`
|
|
105
|
+
|
|
106
|
+
Check multiple flags at once. Mode can be `'all'` (default) or `'any'`.
|
|
107
|
+
|
|
108
|
+
```vue
|
|
109
|
+
<script setup lang="ts">
|
|
110
|
+
import { useFlagsEnabled } from '@buildrflags/vue';
|
|
111
|
+
|
|
112
|
+
// All flags must be enabled
|
|
113
|
+
const canAccessPremium = useFlagsEnabled(['premium-tier', 'new-dashboard'], 'all');
|
|
114
|
+
|
|
115
|
+
// At least one flag must be enabled
|
|
116
|
+
const showAnyPromo = useFlagsEnabled(['black-friday', 'cyber-monday'], 'any');
|
|
117
|
+
</script>
|
|
118
|
+
|
|
119
|
+
<template>
|
|
120
|
+
<PremiumDashboard v-if="canAccessPremium" />
|
|
121
|
+
<PromoSection v-if="showAnyPromo" />
|
|
122
|
+
</template>
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
## Plugin Options
|
|
126
|
+
|
|
127
|
+
```ts
|
|
128
|
+
interface BuildrFlagsPluginOptions {
|
|
129
|
+
// Required: Your BuildrFlags API key
|
|
130
|
+
apiKey: string;
|
|
131
|
+
|
|
132
|
+
// Optional: Custom API base URL
|
|
133
|
+
// Default: 'https://api.flags.buildrlab.com'
|
|
134
|
+
baseUrl?: string;
|
|
135
|
+
|
|
136
|
+
// Optional: Auto-refresh interval in milliseconds
|
|
137
|
+
// Set to 0 to disable auto-refresh
|
|
138
|
+
// Default: 60000 (1 minute)
|
|
139
|
+
refreshInterval?: number;
|
|
140
|
+
|
|
141
|
+
// Optional: Pre-loaded flags for SSR/SSG
|
|
142
|
+
initialFlags?: Record<string, boolean>;
|
|
143
|
+
}
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
## Server-Side Rendering (SSR)
|
|
147
|
+
|
|
148
|
+
For SSR with Nuxt or similar, you can pre-load flags server-side:
|
|
149
|
+
|
|
150
|
+
```ts
|
|
151
|
+
// Server-side: fetch flags during SSR
|
|
152
|
+
const response = await fetch('https://api.flags.buildrlab.com/api/evaluate/all', {
|
|
153
|
+
headers: { 'X-API-Key': 'bf_production_xxx' },
|
|
154
|
+
});
|
|
155
|
+
const { flags } = await response.json();
|
|
156
|
+
|
|
157
|
+
// Convert to a simple map
|
|
158
|
+
const initialFlags: Record<string, boolean> = {};
|
|
159
|
+
for (const flag of flags) {
|
|
160
|
+
initialFlags[flag.flagKey] = flag.enabled;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
// Pass to plugin
|
|
164
|
+
app.use(BuildrFlagsPlugin, {
|
|
165
|
+
apiKey: 'bf_production_xxx',
|
|
166
|
+
initialFlags,
|
|
167
|
+
});
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
## TypeScript Support
|
|
171
|
+
|
|
172
|
+
This package is written in TypeScript and includes full type definitions.
|
|
173
|
+
|
|
174
|
+
```ts
|
|
175
|
+
import type {
|
|
176
|
+
BuildrFlagsPluginOptions,
|
|
177
|
+
BuildrFlagsState,
|
|
178
|
+
UseFlagResult,
|
|
179
|
+
UseFlagsResult,
|
|
180
|
+
} from '@buildrflags/vue';
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
## Requirements
|
|
184
|
+
|
|
185
|
+
- Vue 3.3+
|
|
186
|
+
- TypeScript 5.0+ (optional, but recommended)
|
|
187
|
+
|
|
188
|
+
## License
|
|
189
|
+
|
|
190
|
+
MIT © [BuildrLab](https://buildrlab.com)
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { type ComputedRef } from 'vue';
|
|
2
|
+
import type { UseFlagResult, UseFlagsResult } from './types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Composable to get the evaluation result for a single flag.
|
|
5
|
+
*
|
|
6
|
+
* @param flagKey - The key of the flag to evaluate
|
|
7
|
+
* @returns Object with reactive `enabled` and `isLoading` refs
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```vue
|
|
11
|
+
* <script setup lang="ts">
|
|
12
|
+
* import { useFlag } from '@buildrflags/vue';
|
|
13
|
+
*
|
|
14
|
+
* const { enabled, isLoading } = useFlag('features.darkMode');
|
|
15
|
+
* </script>
|
|
16
|
+
*
|
|
17
|
+
* <template>
|
|
18
|
+
* <Spinner v-if="isLoading" />
|
|
19
|
+
* <DarkTheme v-else-if="enabled" />
|
|
20
|
+
* <LightTheme v-else />
|
|
21
|
+
* </template>
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
24
|
+
export declare function useFlag(flagKey: string): UseFlagResult;
|
|
25
|
+
/**
|
|
26
|
+
* Composable to get all flags and loading/error state.
|
|
27
|
+
*
|
|
28
|
+
* @returns Object with reactive `flags`, `isLoading`, `error`, and `refresh` function
|
|
29
|
+
*
|
|
30
|
+
* @example
|
|
31
|
+
* ```vue
|
|
32
|
+
* <script setup lang="ts">
|
|
33
|
+
* import { useFlags } from '@buildrflags/vue';
|
|
34
|
+
*
|
|
35
|
+
* const { flags, isLoading, error, refresh } = useFlags();
|
|
36
|
+
* </script>
|
|
37
|
+
*
|
|
38
|
+
* <template>
|
|
39
|
+
* <div v-if="error">Error: {{ error }}</div>
|
|
40
|
+
* <button @click="refresh">Refresh</button>
|
|
41
|
+
* </template>
|
|
42
|
+
* ```
|
|
43
|
+
*/
|
|
44
|
+
export declare function useFlags(): UseFlagsResult;
|
|
45
|
+
/**
|
|
46
|
+
* Composable that returns just the boolean value for a flag as a computed ref.
|
|
47
|
+
* Returns the `defaultValue` (or `false`) while loading or if the flag is not found.
|
|
48
|
+
*
|
|
49
|
+
* @param flagKey - The key of the flag to evaluate
|
|
50
|
+
* @param defaultValue - Value to return while loading or when flag is missing (default: false)
|
|
51
|
+
* @returns Computed boolean ref
|
|
52
|
+
*
|
|
53
|
+
* @example
|
|
54
|
+
* ```vue
|
|
55
|
+
* <script setup lang="ts">
|
|
56
|
+
* import { useFlagValue } from '@buildrflags/vue';
|
|
57
|
+
*
|
|
58
|
+
* const showBanner = useFlagValue('ui.showBanner', true);
|
|
59
|
+
* </script>
|
|
60
|
+
*
|
|
61
|
+
* <template>
|
|
62
|
+
* <Banner v-if="showBanner" />
|
|
63
|
+
* </template>
|
|
64
|
+
* ```
|
|
65
|
+
*/
|
|
66
|
+
export declare function useFlagValue(flagKey: string, defaultValue?: boolean): ComputedRef<boolean>;
|
|
67
|
+
/**
|
|
68
|
+
* Composable to check if multiple flags are enabled.
|
|
69
|
+
* Useful for checking feature combinations.
|
|
70
|
+
*
|
|
71
|
+
* @param flagKeys - Array of flag keys to check
|
|
72
|
+
* @param mode - 'all' (default) requires all flags enabled, 'any' requires at least one
|
|
73
|
+
* @returns Computed boolean ref
|
|
74
|
+
*
|
|
75
|
+
* @example
|
|
76
|
+
* ```vue
|
|
77
|
+
* <script setup lang="ts">
|
|
78
|
+
* import { useFlagsEnabled } from '@buildrflags/vue';
|
|
79
|
+
*
|
|
80
|
+
* // All flags must be enabled
|
|
81
|
+
* const allEnabled = useFlagsEnabled(['feature.a', 'feature.b'], 'all');
|
|
82
|
+
*
|
|
83
|
+
* // At least one flag must be enabled
|
|
84
|
+
* const anyEnabled = useFlagsEnabled(['feature.a', 'feature.b'], 'any');
|
|
85
|
+
* </script>
|
|
86
|
+
* ```
|
|
87
|
+
*/
|
|
88
|
+
export declare function useFlagsEnabled(flagKeys: string[], mode?: 'all' | 'any'): ComputedRef<boolean>;
|
|
89
|
+
//# sourceMappingURL=composables.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"composables.d.ts","sourceRoot":"","sources":["../src/composables.ts"],"names":[],"mappings":"AAAA,OAAO,EAAoB,KAAK,WAAW,EAAY,MAAM,KAAK,CAAC;AACnE,OAAO,KAAK,EAAE,aAAa,EAAE,cAAc,EAAoB,MAAM,YAAY,CAAC;AAqBlF;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,aAAa,CAUtD;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,QAAQ,IAAI,cAAc,CAIzC;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,YAAY,UAAQ,GAAG,WAAW,CAAC,OAAO,CAAC,CAOxF;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,MAAM,EAAE,EAClB,IAAI,GAAE,KAAK,GAAG,KAAa,GAC1B,WAAW,CAAC,OAAO,CAAC,CAStB"}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import { inject, computed } from 'vue';
|
|
2
|
+
import { BUILDR_FLAGS_KEY } from './types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Injects the BuildrFlags state from the plugin.
|
|
5
|
+
*
|
|
6
|
+
* @throws Error if used outside of a component with BuildrFlagsPlugin installed
|
|
7
|
+
* @internal
|
|
8
|
+
*/
|
|
9
|
+
function useBuildrFlagsContext() {
|
|
10
|
+
const state = inject(BUILDR_FLAGS_KEY);
|
|
11
|
+
if (!state) {
|
|
12
|
+
throw new Error('BuildrFlags: useFlag/useFlags must be used within a component tree that has BuildrFlagsPlugin installed.');
|
|
13
|
+
}
|
|
14
|
+
return state;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Composable to get the evaluation result for a single flag.
|
|
18
|
+
*
|
|
19
|
+
* @param flagKey - The key of the flag to evaluate
|
|
20
|
+
* @returns Object with reactive `enabled` and `isLoading` refs
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* ```vue
|
|
24
|
+
* <script setup lang="ts">
|
|
25
|
+
* import { useFlag } from '@buildrflags/vue';
|
|
26
|
+
*
|
|
27
|
+
* const { enabled, isLoading } = useFlag('features.darkMode');
|
|
28
|
+
* </script>
|
|
29
|
+
*
|
|
30
|
+
* <template>
|
|
31
|
+
* <Spinner v-if="isLoading" />
|
|
32
|
+
* <DarkTheme v-else-if="enabled" />
|
|
33
|
+
* <LightTheme v-else />
|
|
34
|
+
* </template>
|
|
35
|
+
* ```
|
|
36
|
+
*/
|
|
37
|
+
export function useFlag(flagKey) {
|
|
38
|
+
const { flags, isLoading } = useBuildrFlagsContext();
|
|
39
|
+
// Create a computed ref that tracks the specific flag
|
|
40
|
+
const enabled = computed(() => flags.value[flagKey] ?? false);
|
|
41
|
+
return {
|
|
42
|
+
enabled: enabled,
|
|
43
|
+
isLoading,
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Composable to get all flags and loading/error state.
|
|
48
|
+
*
|
|
49
|
+
* @returns Object with reactive `flags`, `isLoading`, `error`, and `refresh` function
|
|
50
|
+
*
|
|
51
|
+
* @example
|
|
52
|
+
* ```vue
|
|
53
|
+
* <script setup lang="ts">
|
|
54
|
+
* import { useFlags } from '@buildrflags/vue';
|
|
55
|
+
*
|
|
56
|
+
* const { flags, isLoading, error, refresh } = useFlags();
|
|
57
|
+
* </script>
|
|
58
|
+
*
|
|
59
|
+
* <template>
|
|
60
|
+
* <div v-if="error">Error: {{ error }}</div>
|
|
61
|
+
* <button @click="refresh">Refresh</button>
|
|
62
|
+
* </template>
|
|
63
|
+
* ```
|
|
64
|
+
*/
|
|
65
|
+
export function useFlags() {
|
|
66
|
+
const { flags, isLoading, error, refresh } = useBuildrFlagsContext();
|
|
67
|
+
return { flags, isLoading, error, refresh };
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Composable that returns just the boolean value for a flag as a computed ref.
|
|
71
|
+
* Returns the `defaultValue` (or `false`) while loading or if the flag is not found.
|
|
72
|
+
*
|
|
73
|
+
* @param flagKey - The key of the flag to evaluate
|
|
74
|
+
* @param defaultValue - Value to return while loading or when flag is missing (default: false)
|
|
75
|
+
* @returns Computed boolean ref
|
|
76
|
+
*
|
|
77
|
+
* @example
|
|
78
|
+
* ```vue
|
|
79
|
+
* <script setup lang="ts">
|
|
80
|
+
* import { useFlagValue } from '@buildrflags/vue';
|
|
81
|
+
*
|
|
82
|
+
* const showBanner = useFlagValue('ui.showBanner', true);
|
|
83
|
+
* </script>
|
|
84
|
+
*
|
|
85
|
+
* <template>
|
|
86
|
+
* <Banner v-if="showBanner" />
|
|
87
|
+
* </template>
|
|
88
|
+
* ```
|
|
89
|
+
*/
|
|
90
|
+
export function useFlagValue(flagKey, defaultValue = false) {
|
|
91
|
+
const { flags, isLoading } = useBuildrFlagsContext();
|
|
92
|
+
return computed(() => {
|
|
93
|
+
if (isLoading.value)
|
|
94
|
+
return defaultValue;
|
|
95
|
+
return flags.value[flagKey] ?? defaultValue;
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Composable to check if multiple flags are enabled.
|
|
100
|
+
* Useful for checking feature combinations.
|
|
101
|
+
*
|
|
102
|
+
* @param flagKeys - Array of flag keys to check
|
|
103
|
+
* @param mode - 'all' (default) requires all flags enabled, 'any' requires at least one
|
|
104
|
+
* @returns Computed boolean ref
|
|
105
|
+
*
|
|
106
|
+
* @example
|
|
107
|
+
* ```vue
|
|
108
|
+
* <script setup lang="ts">
|
|
109
|
+
* import { useFlagsEnabled } from '@buildrflags/vue';
|
|
110
|
+
*
|
|
111
|
+
* // All flags must be enabled
|
|
112
|
+
* const allEnabled = useFlagsEnabled(['feature.a', 'feature.b'], 'all');
|
|
113
|
+
*
|
|
114
|
+
* // At least one flag must be enabled
|
|
115
|
+
* const anyEnabled = useFlagsEnabled(['feature.a', 'feature.b'], 'any');
|
|
116
|
+
* </script>
|
|
117
|
+
* ```
|
|
118
|
+
*/
|
|
119
|
+
export function useFlagsEnabled(flagKeys, mode = 'all') {
|
|
120
|
+
const { flags, isLoading } = useBuildrFlagsContext();
|
|
121
|
+
return computed(() => {
|
|
122
|
+
if (isLoading.value)
|
|
123
|
+
return false;
|
|
124
|
+
const checkFn = mode === 'all' ? 'every' : 'some';
|
|
125
|
+
return flagKeys[checkFn]((key) => flags.value[key] === true);
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
//# sourceMappingURL=composables.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"composables.js","sourceRoot":"","sources":["../src/composables.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,QAAQ,EAA8B,MAAM,KAAK,CAAC;AAEnE,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAE9C;;;;;GAKG;AACH,SAAS,qBAAqB;IAC5B,MAAM,KAAK,GAAG,MAAM,CAAC,gBAAgB,CAAC,CAAC;IAEvC,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,IAAI,KAAK,CACb,0GAA0G,CAC3G,CAAC;IACJ,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,UAAU,OAAO,CAAC,OAAe;IACrC,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,qBAAqB,EAAE,CAAC;IAErD,sDAAsD;IACtD,MAAM,OAAO,GAAG,QAAQ,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,KAAK,CAAC,CAAC;IAE9D,OAAO;QACL,OAAO,EAAE,OAAkC;QAC3C,SAAS;KACV,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,UAAU,QAAQ;IACtB,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,qBAAqB,EAAE,CAAC;IAErE,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC;AAC9C,CAAC;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,UAAU,YAAY,CAAC,OAAe,EAAE,YAAY,GAAG,KAAK;IAChE,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,qBAAqB,EAAE,CAAC;IAErD,OAAO,QAAQ,CAAC,GAAG,EAAE;QACnB,IAAI,SAAS,CAAC,KAAK;YAAE,OAAO,YAAY,CAAC;QACzC,OAAO,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,YAAY,CAAC;IAC9C,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,UAAU,eAAe,CAC7B,QAAkB,EAClB,OAAsB,KAAK;IAE3B,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,qBAAqB,EAAE,CAAC;IAErD,OAAO,QAAQ,CAAC,GAAG,EAAE;QACnB,IAAI,SAAS,CAAC,KAAK;YAAE,OAAO,KAAK,CAAC;QAElC,MAAM,OAAO,GAAG,IAAI,KAAK,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC;QAClD,OAAO,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,IAAI,CAAC,CAAC;IAC/D,CAAC,CAAC,CAAC;AACL,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BuildrFlags Vue SDK
|
|
3
|
+
*
|
|
4
|
+
* Vue composables and plugin for feature flag evaluation.
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* ```ts
|
|
8
|
+
* // main.ts
|
|
9
|
+
* import { createApp } from 'vue';
|
|
10
|
+
* import { BuildrFlagsPlugin } from '@buildrflags/vue';
|
|
11
|
+
* import App from './App.vue';
|
|
12
|
+
*
|
|
13
|
+
* const app = createApp(App);
|
|
14
|
+
*
|
|
15
|
+
* app.use(BuildrFlagsPlugin, {
|
|
16
|
+
* apiKey: 'bf_production_xxx',
|
|
17
|
+
* });
|
|
18
|
+
*
|
|
19
|
+
* app.mount('#app');
|
|
20
|
+
* ```
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* ```vue
|
|
24
|
+
* <!-- MyComponent.vue -->
|
|
25
|
+
* <script setup lang="ts">
|
|
26
|
+
* import { useFlag } from '@buildrflags/vue';
|
|
27
|
+
*
|
|
28
|
+
* const { enabled } = useFlag('my-feature');
|
|
29
|
+
* </script>
|
|
30
|
+
*
|
|
31
|
+
* <template>
|
|
32
|
+
* <NewFeature v-if="enabled" />
|
|
33
|
+
* <OldFeature v-else />
|
|
34
|
+
* </template>
|
|
35
|
+
* ```
|
|
36
|
+
*
|
|
37
|
+
* @packageDocumentation
|
|
38
|
+
*/
|
|
39
|
+
export { BuildrFlagsPlugin, createBuildrFlagsState } from './plugin.js';
|
|
40
|
+
export { useFlag, useFlags, useFlagValue, useFlagsEnabled } from './composables.js';
|
|
41
|
+
export type { BuildrFlagsPluginOptions, BuildrFlagsState, UseFlagResult, UseFlagsResult, FlagResult, BulkEvaluateResponse, } from './types.js';
|
|
42
|
+
export { BUILDR_FLAGS_KEY } from './types.js';
|
|
43
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AAGH,OAAO,EAAE,iBAAiB,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AAGxE,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAGpF,YAAY,EACV,wBAAwB,EACxB,gBAAgB,EAChB,aAAa,EACb,cAAc,EACd,UAAU,EACV,oBAAoB,GACrB,MAAM,YAAY,CAAC;AAGpB,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BuildrFlags Vue SDK
|
|
3
|
+
*
|
|
4
|
+
* Vue composables and plugin for feature flag evaluation.
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* ```ts
|
|
8
|
+
* // main.ts
|
|
9
|
+
* import { createApp } from 'vue';
|
|
10
|
+
* import { BuildrFlagsPlugin } from '@buildrflags/vue';
|
|
11
|
+
* import App from './App.vue';
|
|
12
|
+
*
|
|
13
|
+
* const app = createApp(App);
|
|
14
|
+
*
|
|
15
|
+
* app.use(BuildrFlagsPlugin, {
|
|
16
|
+
* apiKey: 'bf_production_xxx',
|
|
17
|
+
* });
|
|
18
|
+
*
|
|
19
|
+
* app.mount('#app');
|
|
20
|
+
* ```
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* ```vue
|
|
24
|
+
* <!-- MyComponent.vue -->
|
|
25
|
+
* <script setup lang="ts">
|
|
26
|
+
* import { useFlag } from '@buildrflags/vue';
|
|
27
|
+
*
|
|
28
|
+
* const { enabled } = useFlag('my-feature');
|
|
29
|
+
* </script>
|
|
30
|
+
*
|
|
31
|
+
* <template>
|
|
32
|
+
* <NewFeature v-if="enabled" />
|
|
33
|
+
* <OldFeature v-else />
|
|
34
|
+
* </template>
|
|
35
|
+
* ```
|
|
36
|
+
*
|
|
37
|
+
* @packageDocumentation
|
|
38
|
+
*/
|
|
39
|
+
// Plugin
|
|
40
|
+
export { BuildrFlagsPlugin, createBuildrFlagsState } from './plugin.js';
|
|
41
|
+
// Composables
|
|
42
|
+
export { useFlag, useFlags, useFlagValue, useFlagsEnabled } from './composables.js';
|
|
43
|
+
// Injection key (for advanced usage)
|
|
44
|
+
export { BUILDR_FLAGS_KEY } from './types.js';
|
|
45
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AAEH,SAAS;AACT,OAAO,EAAE,iBAAiB,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AAExE,cAAc;AACd,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAYpF,qCAAqC;AACrC,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC"}
|
package/dist/plugin.d.ts
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { type Plugin } from 'vue';
|
|
2
|
+
import type { BuildrFlagsPluginOptions, BuildrFlagsState } from './types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Creates the BuildrFlags state with automatic fetching and refresh.
|
|
5
|
+
*
|
|
6
|
+
* @internal
|
|
7
|
+
*/
|
|
8
|
+
export declare function createBuildrFlagsState(options: BuildrFlagsPluginOptions): BuildrFlagsState;
|
|
9
|
+
/**
|
|
10
|
+
* Vue plugin for BuildrFlags.
|
|
11
|
+
*
|
|
12
|
+
* Install this plugin in your Vue app to provide feature flag state
|
|
13
|
+
* to all components via composables.
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```ts
|
|
17
|
+
* import { createApp } from 'vue';
|
|
18
|
+
* import { BuildrFlagsPlugin } from '@buildrflags/vue';
|
|
19
|
+
* import App from './App.vue';
|
|
20
|
+
*
|
|
21
|
+
* const app = createApp(App);
|
|
22
|
+
*
|
|
23
|
+
* app.use(BuildrFlagsPlugin, {
|
|
24
|
+
* apiKey: 'bf_production_xxx',
|
|
25
|
+
* });
|
|
26
|
+
*
|
|
27
|
+
* app.mount('#app');
|
|
28
|
+
* ```
|
|
29
|
+
*/
|
|
30
|
+
export declare const BuildrFlagsPlugin: Plugin<[BuildrFlagsPluginOptions]>;
|
|
31
|
+
//# sourceMappingURL=plugin.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiB,KAAK,MAAM,EAAE,MAAM,KAAK,CAAC;AACjD,OAAO,KAAK,EACV,wBAAwB,EACxB,gBAAgB,EAEjB,MAAM,YAAY,CAAC;AAMpB;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,wBAAwB,GAAG,gBAAgB,CA2E1F;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,eAAO,MAAM,iBAAiB,EAAE,MAAM,CAAC,CAAC,wBAAwB,CAAC,CAKhE,CAAC"}
|
package/dist/plugin.js
ADDED
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { ref } from 'vue';
|
|
2
|
+
import { BUILDR_FLAGS_KEY } from './types.js';
|
|
3
|
+
const DEFAULT_BASE_URL = 'https://api.flags.buildrlab.com';
|
|
4
|
+
const DEFAULT_REFRESH_INTERVAL = 60_000; // 1 minute
|
|
5
|
+
/**
|
|
6
|
+
* Creates the BuildrFlags state with automatic fetching and refresh.
|
|
7
|
+
*
|
|
8
|
+
* @internal
|
|
9
|
+
*/
|
|
10
|
+
export function createBuildrFlagsState(options) {
|
|
11
|
+
const { apiKey, baseUrl, refreshInterval, initialFlags } = options;
|
|
12
|
+
const resolvedBaseUrl = (baseUrl ?? DEFAULT_BASE_URL).replace(/\/$/, '');
|
|
13
|
+
const resolvedRefreshInterval = refreshInterval ?? DEFAULT_REFRESH_INTERVAL;
|
|
14
|
+
const flags = ref(initialFlags ?? {});
|
|
15
|
+
const isLoading = ref(initialFlags === undefined);
|
|
16
|
+
const error = ref(null);
|
|
17
|
+
let intervalId;
|
|
18
|
+
let mounted = true;
|
|
19
|
+
const fetchFlags = async () => {
|
|
20
|
+
try {
|
|
21
|
+
const response = await fetch(`${resolvedBaseUrl}/api/evaluate/all`, {
|
|
22
|
+
method: 'GET',
|
|
23
|
+
headers: {
|
|
24
|
+
'X-API-Key': apiKey,
|
|
25
|
+
},
|
|
26
|
+
});
|
|
27
|
+
if (!response.ok) {
|
|
28
|
+
const text = await response.text().catch(() => 'Unknown error');
|
|
29
|
+
throw new Error(`API request failed: ${response.status} ${text}`);
|
|
30
|
+
}
|
|
31
|
+
const data = (await response.json());
|
|
32
|
+
if (!mounted)
|
|
33
|
+
return;
|
|
34
|
+
const flagMap = {};
|
|
35
|
+
for (const flag of data.flags) {
|
|
36
|
+
flagMap[flag.flagKey] = flag.enabled;
|
|
37
|
+
}
|
|
38
|
+
flags.value = flagMap;
|
|
39
|
+
error.value = null;
|
|
40
|
+
isLoading.value = false;
|
|
41
|
+
}
|
|
42
|
+
catch (err) {
|
|
43
|
+
if (!mounted)
|
|
44
|
+
return;
|
|
45
|
+
const message = err instanceof Error ? err.message : 'Failed to fetch flags';
|
|
46
|
+
error.value = message;
|
|
47
|
+
isLoading.value = false;
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
// Initial fetch
|
|
51
|
+
void fetchFlags();
|
|
52
|
+
// Set up auto-refresh
|
|
53
|
+
if (resolvedRefreshInterval > 0) {
|
|
54
|
+
intervalId = setInterval(() => {
|
|
55
|
+
void fetchFlags();
|
|
56
|
+
}, resolvedRefreshInterval);
|
|
57
|
+
}
|
|
58
|
+
// Cleanup function (called when plugin is uninstalled)
|
|
59
|
+
const cleanup = () => {
|
|
60
|
+
mounted = false;
|
|
61
|
+
if (intervalId !== undefined) {
|
|
62
|
+
clearInterval(intervalId);
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
// Store cleanup on the state for potential future use
|
|
66
|
+
flags.__cleanup = cleanup;
|
|
67
|
+
return {
|
|
68
|
+
flags,
|
|
69
|
+
isLoading,
|
|
70
|
+
error,
|
|
71
|
+
refresh: fetchFlags,
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Vue plugin for BuildrFlags.
|
|
76
|
+
*
|
|
77
|
+
* Install this plugin in your Vue app to provide feature flag state
|
|
78
|
+
* to all components via composables.
|
|
79
|
+
*
|
|
80
|
+
* @example
|
|
81
|
+
* ```ts
|
|
82
|
+
* import { createApp } from 'vue';
|
|
83
|
+
* import { BuildrFlagsPlugin } from '@buildrflags/vue';
|
|
84
|
+
* import App from './App.vue';
|
|
85
|
+
*
|
|
86
|
+
* const app = createApp(App);
|
|
87
|
+
*
|
|
88
|
+
* app.use(BuildrFlagsPlugin, {
|
|
89
|
+
* apiKey: 'bf_production_xxx',
|
|
90
|
+
* });
|
|
91
|
+
*
|
|
92
|
+
* app.mount('#app');
|
|
93
|
+
* ```
|
|
94
|
+
*/
|
|
95
|
+
export const BuildrFlagsPlugin = {
|
|
96
|
+
install(app, options) {
|
|
97
|
+
const state = createBuildrFlagsState(options);
|
|
98
|
+
app.provide(BUILDR_FLAGS_KEY, state);
|
|
99
|
+
},
|
|
100
|
+
};
|
|
101
|
+
//# sourceMappingURL=plugin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin.js","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import type { InjectionKey, Ref } from 'vue';
|
|
2
|
+
/**
|
|
3
|
+
* A single flag result from the bulk evaluation API.
|
|
4
|
+
*/
|
|
5
|
+
export interface FlagResult {
|
|
6
|
+
flagKey: string;
|
|
7
|
+
enabled: boolean;
|
|
8
|
+
reason: string;
|
|
9
|
+
fetchedAt: string;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Response shape from GET /api/evaluate/all.
|
|
13
|
+
*/
|
|
14
|
+
export interface BulkEvaluateResponse {
|
|
15
|
+
flags: FlagResult[];
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* State held in the BuildrFlags Vue context.
|
|
19
|
+
*/
|
|
20
|
+
export interface BuildrFlagsState {
|
|
21
|
+
/** Map of flagKey → enabled boolean. */
|
|
22
|
+
flags: Ref<Record<string, boolean>>;
|
|
23
|
+
/** True until the first successful fetch completes. */
|
|
24
|
+
isLoading: Ref<boolean>;
|
|
25
|
+
/** Error message from the most recent fetch, or null. */
|
|
26
|
+
error: Ref<string | null>;
|
|
27
|
+
/** Manually refresh flags from the API. */
|
|
28
|
+
refresh: () => Promise<void>;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Options for the BuildrFlags plugin.
|
|
32
|
+
*/
|
|
33
|
+
export interface BuildrFlagsPluginOptions {
|
|
34
|
+
/** Your BuildrFlags API key (starts with "bf_"). */
|
|
35
|
+
apiKey: string;
|
|
36
|
+
/** Base URL for the BuildrFlags API. @default "https://api.flags.buildrlab.com" */
|
|
37
|
+
baseUrl?: string;
|
|
38
|
+
/** Auto-refresh interval in milliseconds. Set to 0 to disable. @default 60000 */
|
|
39
|
+
refreshInterval?: number;
|
|
40
|
+
/** Pre-loaded flags for SSG/SSR (skips initial fetch when provided). */
|
|
41
|
+
initialFlags?: Record<string, boolean>;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Return type for the useFlag composable.
|
|
45
|
+
*/
|
|
46
|
+
export interface UseFlagResult {
|
|
47
|
+
/** Whether the flag is enabled (reactive). */
|
|
48
|
+
enabled: Ref<boolean>;
|
|
49
|
+
/** True until the first fetch completes (reactive). */
|
|
50
|
+
isLoading: Ref<boolean>;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Return type for the useFlags composable.
|
|
54
|
+
*/
|
|
55
|
+
export interface UseFlagsResult {
|
|
56
|
+
/** All flags as a key → boolean map (reactive). */
|
|
57
|
+
flags: Ref<Record<string, boolean>>;
|
|
58
|
+
/** True until the first fetch completes (reactive). */
|
|
59
|
+
isLoading: Ref<boolean>;
|
|
60
|
+
/** Error message from the most recent fetch, or null (reactive). */
|
|
61
|
+
error: Ref<string | null>;
|
|
62
|
+
/** Manually refresh flags from the API. */
|
|
63
|
+
refresh: () => Promise<void>;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Injection key for the BuildrFlags context.
|
|
67
|
+
*/
|
|
68
|
+
export declare const BUILDR_FLAGS_KEY: InjectionKey<BuildrFlagsState>;
|
|
69
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAE7C;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,UAAU,EAAE,CAAC;CACrB;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,wCAAwC;IACxC,KAAK,EAAE,GAAG,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IACpC,uDAAuD;IACvD,SAAS,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;IACxB,yDAAyD;IACzD,KAAK,EAAE,GAAG,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAC1B,2CAA2C;IAC3C,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9B;AAED;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACvC,oDAAoD;IACpD,MAAM,EAAE,MAAM,CAAC;IACf,mFAAmF;IACnF,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,iFAAiF;IACjF,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,wEAAwE;IACxE,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACxC;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,8CAA8C;IAC9C,OAAO,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;IACtB,uDAAuD;IACvD,SAAS,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;CACzB;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,mDAAmD;IACnD,KAAK,EAAE,GAAG,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IACpC,uDAAuD;IACvD,SAAS,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;IACxB,oEAAoE;IACpE,KAAK,EAAE,GAAG,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAC1B,2CAA2C;IAC3C,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9B;AAED;;GAEG;AACH,eAAO,MAAM,gBAAgB,EAAE,YAAY,CAAC,gBAAgB,CAA0B,CAAC"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAuEA;;GAEG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAmC,MAAM,CAAC,cAAc,CAAC,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@buildrflags/vue",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Vue composables and plugin for BuildrFlags feature flag evaluation",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"module": "./dist/index.js",
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"import": "./dist/index.js"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"files": [
|
|
16
|
+
"dist",
|
|
17
|
+
"README.md"
|
|
18
|
+
],
|
|
19
|
+
"scripts": {
|
|
20
|
+
"build": "tsc",
|
|
21
|
+
"dev": "tsc --watch",
|
|
22
|
+
"lint": "eslint src --ext .ts",
|
|
23
|
+
"lint:fix": "eslint src --ext .ts --fix",
|
|
24
|
+
"typecheck": "tsc --noEmit",
|
|
25
|
+
"test": "vitest run",
|
|
26
|
+
"test:watch": "vitest",
|
|
27
|
+
"test:coverage": "vitest run --coverage",
|
|
28
|
+
"clean": "rm -rf dist node_modules"
|
|
29
|
+
},
|
|
30
|
+
"keywords": [
|
|
31
|
+
"feature-flags",
|
|
32
|
+
"buildrflags",
|
|
33
|
+
"vue",
|
|
34
|
+
"vue3",
|
|
35
|
+
"composables",
|
|
36
|
+
"feature-toggles"
|
|
37
|
+
],
|
|
38
|
+
"author": "BuildrLab <hello@buildrlab.com>",
|
|
39
|
+
"license": "MIT",
|
|
40
|
+
"repository": {
|
|
41
|
+
"type": "git",
|
|
42
|
+
"url": "https://github.com/buildrlab/buildrflags.git",
|
|
43
|
+
"directory": "sdks/vue"
|
|
44
|
+
},
|
|
45
|
+
"homepage": "https://flags.buildrlab.com",
|
|
46
|
+
"bugs": {
|
|
47
|
+
"url": "https://github.com/buildrlab/buildrflags/issues"
|
|
48
|
+
},
|
|
49
|
+
"peerDependencies": {
|
|
50
|
+
"vue": "^3.3.0"
|
|
51
|
+
},
|
|
52
|
+
"devDependencies": {
|
|
53
|
+
"@types/node": "^25.2.3",
|
|
54
|
+
"@vitejs/plugin-vue": "^6.0.4",
|
|
55
|
+
"@vue/test-utils": "^2.4.0",
|
|
56
|
+
"eslint": "^10.0.0",
|
|
57
|
+
"happy-dom": "^20.6.1",
|
|
58
|
+
"typescript": "^5.6.0",
|
|
59
|
+
"vite": "^7.3.1",
|
|
60
|
+
"vitest": "^4.0.18",
|
|
61
|
+
"vue": "^3.5.0"
|
|
62
|
+
}
|
|
63
|
+
}
|