@flagdeck/vue
Version:
Vue integration for Flagdeck feature flags
358 lines (357 loc) • 8.95 kB
JavaScript
import { inject as R, getCurrentInstance as O, ref as i, onMounted as N, onUnmounted as p, watch as I, defineComponent as F } from "vue";
import { Flagdeck as C } from "@flagdeck/js";
const m = Symbol("Flagdeck");
function _() {
const r = R(m);
if (!r) {
const t = O();
if (t != null && t.appContext.config.globalProperties.$flagdeck)
return {
client: t.appContext.config.globalProperties.$flagdeck,
isReady: !0,
// Changed from userContext
context: t.appContext.config.globalProperties.$flagdeckContext || {},
// Changed from $flagdeckUserContext
setContext: (e) => {
t.appContext.config.globalProperties.$flagdeckContext = // Changed from $flagdeckUserContext
e;
}
};
throw new Error(
"useFlagdeck must be used within a component that has FlagdeckPlugin installed"
);
}
return r;
}
function b(r, t = !1) {
const { client: e, context: s } = _(), o = i(t), u = i(!0), l = i(void 0), c = i(null), E = (a) => {
switch (a) {
case "FLAG_NOT_FOUND":
return "notfound";
case "FLAG_INACTIVE":
return "inactive";
case "INVALID_API_KEY":
case "API_KEY_EXPIRED":
case "ENVIRONMENT_MISMATCH":
case "ENVIRONMENT_DISABLED":
case "INVALID_ENVIRONMENT":
return "configuration";
default:
return "other";
}
}, d = async () => {
if (!e) {
u.value = !1;
return;
}
try {
if (e.evaluateFlag) {
const a = await e.evaluateFlag(r, s);
if (o.value = !!a.value, a.error) {
const n = E(a.error.code);
l.value = {
code: a.error.code,
message: a.error.message,
type: n
};
} else
l.value = void 0;
} else
o.value = await e.isEnabled(
r,
s,
// Changed from userContext
t
);
} catch (a) {
console.error(`Error evaluating flag ${r}:`, a), o.value = t;
const n = a;
l.value = {
code: n.code || "UNKNOWN_ERROR",
message: n.message || "Unknown error occurred",
type: "other"
};
} finally {
u.value = !1;
}
};
return N(() => {
var a;
d(), e != null && e.onFlagChange && ((a = e.areRealTimeUpdatesEnabled) != null && a.call(e)) && (c.value = e.onFlagChange(r, (n) => {
o.value = !!n, l.value && (l.value = void 0);
}));
}), p(() => {
c.value && (c.value(), c.value = null);
}), I(
() => s,
// Changed from userContext
() => {
d();
},
{ deep: !0 }
), {
isEnabled: o,
isLoading: u,
error: l
};
}
function T(r, t) {
const { client: e, context: s } = _(), o = i(t), u = i(!0), l = i(void 0), c = i(null), E = (a) => {
switch (a) {
case "FLAG_NOT_FOUND":
return "notfound";
case "FLAG_INACTIVE":
return "inactive";
case "INVALID_API_KEY":
case "API_KEY_EXPIRED":
case "ENVIRONMENT_MISMATCH":
case "ENVIRONMENT_DISABLED":
case "INVALID_ENVIRONMENT":
return "configuration";
default:
return "other";
}
}, d = async () => {
if (!e) {
u.value = !1;
return;
}
try {
if (e.evaluateFlag) {
const a = await e.evaluateFlag(r, s);
if (o.value = a.value, a.error) {
const n = E(a.error.code);
l.value = {
code: a.error.code,
message: a.error.message,
type: n
};
} else
l.value = void 0;
} else
o.value = await e.getValue(
r,
s,
// Changed from userContext
t
);
} catch (a) {
console.error(`Error evaluating flag ${r}:`, a), o.value = t;
const n = a;
l.value = {
code: n.code || "UNKNOWN_ERROR",
message: n.message || "Unknown error occurred",
type: "other"
};
} finally {
u.value = !1;
}
};
return N(() => {
var a;
d(), e != null && e.onFlagChange && ((a = e.areRealTimeUpdatesEnabled) != null && a.call(e)) && (c.value = e.onFlagChange(r, (n) => {
o.value = n, l.value && (l.value = void 0);
}));
}), p(() => {
c.value && (c.value(), c.value = null);
}), I(
() => s,
// Changed from userContext
() => {
d();
},
{ deep: !0 }
), {
value: o,
isLoading: u,
error: l
};
}
function w(r, t) {
const { client: e, context: s } = _(), o = i(
Object.fromEntries(r.map((a) => [a, t]))
), u = i(!0), l = i({}), c = i(/* @__PURE__ */ new Map()), E = (a) => {
switch (a) {
case "FLAG_NOT_FOUND":
return "notfound";
case "FLAG_INACTIVE":
return "inactive";
case "INVALID_API_KEY":
case "API_KEY_EXPIRED":
case "ENVIRONMENT_MISMATCH":
case "ENVIRONMENT_DISABLED":
case "INVALID_ENVIRONMENT":
return "configuration";
default:
return "other";
}
}, d = async () => {
if (!e || r.length === 0) {
u.value = !1;
return;
}
try {
if (e.evaluateBulk) {
const a = await e.evaluateBulk(r, s), n = {}, v = {};
Object.entries(a.results).forEach(([g, f]) => {
if (n[g] = f.value, f.error) {
const A = E(f.error.code);
v[g] = {
code: f.error.code,
message: f.error.message,
type: A
};
}
}), o.value = n, l.value = v;
} else
o.value = await e.getValues(
r,
s,
// Changed from userContext
t
);
} catch (a) {
console.error("Error evaluating flags:", a), o.value = Object.fromEntries(
r.map((g) => [g, t])
);
const n = a, v = {
code: n.code || "UNKNOWN_ERROR",
message: n.message || "Unknown error occurred",
type: "other"
};
l.value = Object.fromEntries(
r.map((g) => [g, v])
);
} finally {
u.value = !1;
}
};
return N(() => {
var a;
d(), e != null && e.onFlagChange && ((a = e.areRealTimeUpdatesEnabled) != null && a.call(e)) && r.forEach((n) => {
const v = e.onFlagChange(n, (g) => {
if (o.value = {
...o.value,
[n]: g
}, l.value[n]) {
const f = { ...l.value };
delete f[n], l.value = f;
}
});
c.value.set(n, v);
});
}), p(() => {
c.value.forEach((a) => {
typeof a == "function" && a();
}), c.value.clear();
}), I(
() => s,
// Changed from userContext
() => {
d();
},
{ deep: !0 }
), {
values: o,
isLoading: u,
errors: l
};
}
const P = F({
name: "FeatureFlag",
props: {
flagKey: {
type: String,
required: !0
},
defaultEnabled: {
type: Boolean,
default: !1
},
renderNull: {
type: Boolean,
default: !1
}
},
emits: ["error", "not-found", "inactive"],
setup(r, { slots: t, emit: e }) {
const { isEnabled: s, isLoading: o, error: u } = b(
r.flagKey,
r.defaultEnabled
);
return u.value && (e("error", u.value), u.value.type === "notfound" ? e("not-found") : u.value.type === "inactive" && e("inactive")), () => o.value && t.loading ? t.loading() : s.value ? t.default ? t.default() : null : r.renderNull ? null : t.fallback ? t.fallback() : null;
}
}), V = F({
name: "FlagValue",
props: {
flagKey: {
type: String,
required: !0
},
defaultValue: {
type: null,
required: !0
}
},
setup(r, { slots: t }) {
const e = T(r.flagKey, r.defaultValue);
return () => t.default ? t.default({
value: e.value.value,
isLoading: e.isLoading.value,
error: e.error.value
}) : null;
}
}), x = F({
name: "WithFeature",
props: {
flagKey: {
type: String,
required: !0
},
defaultEnabled: {
type: Boolean,
default: !1
}
},
setup(r, { slots: t }) {
const e = b(r.flagKey, r.defaultEnabled);
return () => t.default ? t.default({
isEnabled: e.isEnabled.value,
isLoading: e.isLoading.value,
error: e.error.value
}) : null;
}
}), h = (r, t) => {
const e = new C(
t.clientOptions
);
r.provide(m, {
client: e,
isReady: !0,
context: t.context || {},
// Changed from userContext
setContext: (s) => {
r.config.globalProperties.$flagdeckContext = s;
}
}), r.config.globalProperties.$flagdeck = e, r.config.globalProperties.$flagdeckContext = t.context || {};
}, D = {
install: h
};
function k(r) {
return {
install: (t) => {
h(t, r);
}
};
}
export {
P as FeatureFlag,
V as FlagValue,
D as FlagdeckPlugin,
x as WithFeature,
k as createFlagdeckPlugin,
b as useFlag,
T as useFlagValue,
_ as useFlagdeck,
w as useFlags
};