@shieldlabs-ai/vue 1.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.
@@ -0,0 +1,166 @@
1
+ import { ShieldLabsError, IdentifyOptions, IdentifyResult, ShieldLabsAgent, LoadOptions } from '@shieldlabs-ai/js';
2
+ export { IdentifyOptions, IdentifyResult, InteractionIdentifier, LoadOptions, ShieldLabsAgent, ShieldLabsError, ShieldLabsErrorCode } from '@shieldlabs-ai/js';
3
+ import { Ref, App, MaybeRefOrGetter, InjectionKey } from 'vue';
4
+
5
+ /**
6
+ * State of the agent for this app:
7
+ *
8
+ * - `loading`: not ready yet. Always the value during server-side rendering and in the first render
9
+ * of every component, so that hydration matches the server HTML. With `autoLoad: false` it stays
10
+ * `loading` until `load()` is called.
11
+ * - `ready`: the agent is loaded; identifications start right away.
12
+ * - `error`: the last load failed. `error` says why; the next `identify()`, `check()`, `getAgent()`
13
+ * or `load()` tries again.
14
+ */
15
+ type ShieldLabsStatus = 'loading' | 'ready' | 'error';
16
+ /**
17
+ * `checkOnLoad` plugin option. `true` runs one anonymous `check()` when the agent is ready,
18
+ * `{ userId }` runs it for a User HID. Default `false`.
19
+ */
20
+ type CheckOnLoadOption = boolean | {
21
+ userId?: string | null;
22
+ };
23
+ /** Options of `createShieldLabs()`: the `@shieldlabs-ai/js` load options plus the plugin options. */
24
+ interface ShieldLabsOptions extends LoadOptions {
25
+ /**
26
+ * Runs `check()` once when the agent becomes ready, for passive monitoring of the visit. The agent
27
+ * limits it to one per visit every five minutes. Skipped when an `identify()` or `check()` for the
28
+ * same User HID is already in flight at that moment: that call identifies the visit, and the agent
29
+ * runs one identification at a time for a User HID. Default `false`.
30
+ */
31
+ checkOnLoad?: CheckOnLoadOption;
32
+ /**
33
+ * Loads the agent right after the app is mounted (default `true`). With `false` nothing loads until
34
+ * `load()` from `useShieldLabs()` is called, for example once the visitor has given consent. Until
35
+ * then `status` stays `loading` and `getAgent()` waits, while `identify()` and `check()` fail fast
36
+ * instead of waiting: `identify()` rejects with `not_initialized`, `check()` resolves `null`, and
37
+ * the `identify()` of `useIdentify()` resolves `null` with a `not_initialized` error.
38
+ */
39
+ autoLoad?: boolean;
40
+ }
41
+ /** The Vue plugin returned by {@link createShieldLabs}. Pass it to `app.use()`. */
42
+ interface ShieldLabsPlugin {
43
+ install: (app: App) => void;
44
+ }
45
+ /** What `useShieldLabs()` returns, and what the plugin provides under `shieldLabsKey`. */
46
+ interface ShieldLabsContext {
47
+ /** `loading`, `ready` or `error`. */
48
+ readonly status: Readonly<Ref<ShieldLabsStatus>>;
49
+ /** Why the last load failed, otherwise `null`. */
50
+ readonly error: Readonly<Ref<ShieldLabsError | null>>;
51
+ /**
52
+ * Fresh identification with a new request ID. Waits for the agent; `timeout` covers the wait and
53
+ * the agent's answer together. Rejects with a `ShieldLabsError` when there is no identification,
54
+ * and with `not_initialized` right away while `autoLoad: false` waits for `load()`.
55
+ */
56
+ identify: (options?: IdentifyOptions) => Promise<IdentifyResult>;
57
+ /**
58
+ * Background check, limited by the agent to one per visit every five minutes. Resolves `null`
59
+ * when the agent skipped it, and right away while `autoLoad: false` waits for `load()`. Waits for
60
+ * the agent like `identify()`.
61
+ */
62
+ check: (options?: IdentifyOptions) => Promise<IdentifyResult | null>;
63
+ /**
64
+ * Starts loading the agent now, unless it is loaded or loading. With `autoLoad: false` nothing
65
+ * loads before this call. After a failed load it loads again. The outcome shows in `status` and
66
+ * `error`. Does nothing during server-side rendering.
67
+ */
68
+ load: () => void;
69
+ /**
70
+ * The agent of `@shieldlabs-ai/js` once it has loaded, for example to identify on the first
71
+ * interaction with a form: `getAgent().then((agent) => agent.identifyOnInteraction(form))`.
72
+ * Loads the agent when needed; with `autoLoad: false` it waits until `load()` is called, with no
73
+ * timeout of its own. Rejects with the `ShieldLabsError` of a failed load, and with
74
+ * `unsupported_environment` during server-side rendering.
75
+ */
76
+ getAgent: () => Promise<ShieldLabsAgent>;
77
+ }
78
+ /** Return value of `useShieldLabs()`. */
79
+ type UseShieldLabsReturn = ShieldLabsContext;
80
+ /** Options of `useIdentify()`. */
81
+ interface UseIdentifyOptions {
82
+ /**
83
+ * User HID computed on your server, read when `identify()` runs. A string, a ref or a getter;
84
+ * `undefined` or `null` for anonymous identifications.
85
+ */
86
+ userId?: MaybeRefOrGetter<string | null | undefined>;
87
+ /**
88
+ * Calls `identify()` once when the component is mounted (after the agent is ready). Each call is
89
+ * a billable identification: use it sparingly. With `autoLoad: false` that identification ends
90
+ * right away with a `not_initialized` error unless `load()` was called before the component
91
+ * mounted, and a later `load()` does not start it again. Default `false`.
92
+ */
93
+ runOnMount?: boolean;
94
+ }
95
+ /** Return value of `useIdentify()`. */
96
+ interface UseIdentifyReturn {
97
+ /**
98
+ * Runs a fresh identification. Resolves with the result, or `null` when there is no
99
+ * identification (the reason is in `error`); it never rejects. Options override the composable's
100
+ * `userId` for this call, and `timeout` covers the wait for the agent and its answer together.
101
+ * While a call of this helper with the same `userId` and `timeout` is in flight (a double submit),
102
+ * it returns that call instead of starting another identification. A call without `timeout`
103
+ * counts as one with the plugin's `timeout` (10 seconds by default).
104
+ */
105
+ identify: (options?: IdentifyOptions) => Promise<IdentifyResult | null>;
106
+ /** The result of the latest `identify()`, `null` before it resolves or when it failed. */
107
+ readonly result: Readonly<Ref<IdentifyResult | null>>;
108
+ /** `true` while the latest `identify()` runs. */
109
+ readonly isLoading: Readonly<Ref<boolean>>;
110
+ /** Why the latest `identify()` returned `null`, otherwise `null`. */
111
+ readonly error: Readonly<Ref<ShieldLabsError | null>>;
112
+ /**
113
+ * Clears `result`, `error` and `isLoading`. A call still in flight no longer updates them, unless
114
+ * `identify()` is called again with the same `userId` and `timeout` while it runs: that call
115
+ * returns it.
116
+ */
117
+ reset: () => void;
118
+ }
119
+
120
+ /**
121
+ * Creates the ShieldLabs plugin for `app.use()`. The plugin loads the agent once per app, after the
122
+ * app is mounted in the browser (with `autoLoad: false`, when `load()` from `useShieldLabs()` is
123
+ * called): never during server-side rendering and never before hydration.
124
+ * The load options (`publicKey`, `environment`, `scriptUrl`, `timeout`) are checked by
125
+ * `@shieldlabs-ai/js` when the agent loads; a problem shows up in `status` and `error`.
126
+ *
127
+ * @example
128
+ * createApp(App)
129
+ * .use(createShieldLabs({ publicKey: import.meta.env.VITE_SHIELDLABS_PUBLIC_KEY }))
130
+ * .mount('#app');
131
+ */
132
+ declare function createShieldLabs(options: ShieldLabsOptions): ShieldLabsPlugin;
133
+
134
+ /**
135
+ * The agent state of the app (`status`, `error`), its `identify()` and `check()`, `load()` to start
136
+ * loading (with `autoLoad: false`, for example after consent) and `getAgent()` for the agent itself.
137
+ *
138
+ * Inside a component, `status` is `loading` and `error` is `null` until the component is mounted,
139
+ * as during server-side rendering, so hydration always matches the server HTML. Nothing loads or
140
+ * identifies during server-side rendering.
141
+ */
142
+ declare function useShieldLabs(): UseShieldLabsReturn;
143
+ /**
144
+ * An identify helper with `result`, `isLoading` and `error` refs. `identify()` never rejects: it
145
+ * resolves `null` when there is no identification, so the protected action can go ahead as
146
+ * unverified. `userId` is read when `identify()` runs; changing it never starts an identification.
147
+ *
148
+ * @example
149
+ * const { identify, isLoading } = useIdentify({ userId: () => user.value?.hid });
150
+ * async function onSubmit() {
151
+ * const result = await identify();
152
+ * await fetch('/api/signup', { method: 'POST', body: JSON.stringify({ requestId: result?.requestId ?? null }) });
153
+ * }
154
+ */
155
+ declare function useIdentify(options?: UseIdentifyOptions): UseIdentifyReturn;
156
+
157
+ /**
158
+ * Injection key under which the plugin provides the {@link ShieldLabsContext} of an app. Use it
159
+ * with `provide()` to give components a stand-in context in tests.
160
+ */
161
+ declare const shieldLabsKey: InjectionKey<ShieldLabsContext>;
162
+
163
+ /** Version of `@shieldlabs-ai/vue`. A test keeps it equal to `package.json`. */
164
+ declare const VERSION = "1.0.0";
165
+
166
+ export { type CheckOnLoadOption, type ShieldLabsContext, type ShieldLabsOptions, type ShieldLabsPlugin, type ShieldLabsStatus, type UseIdentifyOptions, type UseIdentifyReturn, type UseShieldLabsReturn, VERSION, createShieldLabs, shieldLabsKey, useIdentify, useShieldLabs };
package/dist/index.js ADDED
@@ -0,0 +1,361 @@
1
+ import { ShieldLabsError, load } from '@shieldlabs-ai/js';
2
+ export { ShieldLabsError } from '@shieldlabs-ai/js';
3
+ import { getCurrentInstance, shallowRef, onMounted, computed, shallowReadonly, toValue, hasInjectionContext, inject } from 'vue';
4
+
5
+ // src/plugin.ts
6
+ var shieldLabsKey = /* @__PURE__ */ Symbol("shieldlabs");
7
+ var DEFAULT_TIMEOUT = 1e4;
8
+ var MAX_TIMEOUT = 2147483647;
9
+ var internals = /* @__PURE__ */ new WeakMap();
10
+ var serverContext;
11
+ function isBrowser() {
12
+ return typeof window !== "undefined" && typeof document !== "undefined";
13
+ }
14
+ function toShieldLabsError(reason, code, message) {
15
+ return reason instanceof ShieldLabsError ? reason : new ShieldLabsError(code, message, reason);
16
+ }
17
+ function isObject(value) {
18
+ return typeof value === "object" && value !== null;
19
+ }
20
+ function isTimeout(value) {
21
+ return typeof value === "number" && value > 0 && value <= MAX_TIMEOUT;
22
+ }
23
+ function ignore() {
24
+ }
25
+ function userOf(options) {
26
+ return isObject(options) && typeof options.userId === "string" ? options.userId : void 0;
27
+ }
28
+ function withTimeLeft(options, left, total) {
29
+ const raw = options;
30
+ if (left >= total) return options;
31
+ if (raw === void 0 || raw === null) return { timeout: left };
32
+ if (!isObject(raw) || raw.timeout !== void 0 && !isTimeout(raw.timeout)) return options;
33
+ return { ...options, timeout: left };
34
+ }
35
+ function createContext(loadOptions, checkOnLoad, autoLoad) {
36
+ const status = shallowRef("loading");
37
+ const error = shallowRef(null);
38
+ let loading;
39
+ let agent;
40
+ let loadAllowed = autoLoad;
41
+ let started = false;
42
+ let checked = false;
43
+ const inFlight = [];
44
+ let allow = ignore;
45
+ const allowed = new Promise((resolve) => {
46
+ allow = resolve;
47
+ });
48
+ allowed.catch(ignore);
49
+ const defaultTimeout = isTimeout(loadOptions.timeout) ? loadOptions.timeout : DEFAULT_TIMEOUT;
50
+ const runCheckOnLoad = (ready) => {
51
+ var _a;
52
+ if (checkOnLoad === false || checked) return;
53
+ checked = true;
54
+ const userId = checkOnLoad === true ? void 0 : (_a = checkOnLoad.userId) != null ? _a : void 0;
55
+ if (inFlight.includes(userId)) return;
56
+ const options = userId === void 0 ? void 0 : { userId };
57
+ new Promise((resolve) => {
58
+ resolve(ready.check(options));
59
+ }).catch((reason) => {
60
+ if (reason instanceof ShieldLabsError && reason.code === "invalid_options") {
61
+ console.warn("[ShieldLabs] checkOnLoad: " + reason.message);
62
+ }
63
+ });
64
+ };
65
+ const startLoad = () => {
66
+ if (loading) return loading;
67
+ started = true;
68
+ const next = new Promise((resolve) => {
69
+ resolve(load(loadOptions));
70
+ }).catch((reason) => {
71
+ throw toShieldLabsError(reason, "load_failed", "Could not load the ShieldLabs agent.");
72
+ });
73
+ loading = next;
74
+ status.value = "loading";
75
+ error.value = null;
76
+ next.then(
77
+ (ready) => {
78
+ agent = ready;
79
+ status.value = "ready";
80
+ runCheckOnLoad(ready);
81
+ },
82
+ (reason) => {
83
+ loading = void 0;
84
+ const failure = toShieldLabsError(reason, "load_failed", "Could not load the ShieldLabs agent.");
85
+ if (failure.code === "invalid_options") console.warn("[ShieldLabs] " + failure.message);
86
+ error.value = failure;
87
+ status.value = "error";
88
+ }
89
+ );
90
+ return next;
91
+ };
92
+ const getAgent = () => {
93
+ if (!isBrowser()) return load(loadOptions);
94
+ return loadAllowed ? startLoad() : allowed;
95
+ };
96
+ const loadNow = () => {
97
+ if (!isBrowser()) return;
98
+ const first = !loadAllowed;
99
+ loadAllowed = true;
100
+ const next = startLoad();
101
+ if (first) allow(next);
102
+ };
103
+ const beforeLoad = () => !loadAllowed && isBrowser();
104
+ const notLoaded = () => new ShieldLabsError("not_initialized", "The ShieldLabs agent is not loaded. With autoLoad: false it loads once load() is called.");
105
+ const timedOut = (total) => new ShieldLabsError("timeout", "The ShieldLabs agent did not load within " + String(total) + " ms.");
106
+ const withAgent = (options, call) => {
107
+ const user = userOf(options);
108
+ inFlight.push(user);
109
+ const outcome = new Promise((resolve, reject) => {
110
+ if (agent) {
111
+ resolve(call(agent, options));
112
+ return;
113
+ }
114
+ const raw = options;
115
+ const own = isObject(raw) ? raw.timeout : void 0;
116
+ const total = isTimeout(own) ? own : defaultTimeout;
117
+ const startedAt = Date.now();
118
+ let settled = false;
119
+ const timer = setTimeout(() => {
120
+ settled = true;
121
+ reject(timedOut(total));
122
+ }, total);
123
+ getAgent().then(
124
+ (ready) => {
125
+ if (settled) return;
126
+ settled = true;
127
+ clearTimeout(timer);
128
+ const left = total - (Date.now() - startedAt);
129
+ if (left < 1) reject(timedOut(total));
130
+ else resolve(call(ready, withTimeLeft(options, left, total)));
131
+ },
132
+ (reason) => {
133
+ if (settled) return;
134
+ settled = true;
135
+ clearTimeout(timer);
136
+ reject(toShieldLabsError(reason, "load_failed", "Could not load the ShieldLabs agent."));
137
+ }
138
+ );
139
+ });
140
+ const finish = () => {
141
+ inFlight.splice(inFlight.indexOf(user), 1);
142
+ };
143
+ outcome.then(finish, finish);
144
+ return outcome;
145
+ };
146
+ const context = {
147
+ status: shallowReadonly(status),
148
+ error: shallowReadonly(error),
149
+ // Like the agent: identify() rejects with not_initialized, check() resolves null.
150
+ identify: (options) => beforeLoad() ? Promise.reject(notLoaded()) : withAgent(options, (ready, agentOptions) => ready.identify(agentOptions)),
151
+ check: (options) => beforeLoad() ? Promise.resolve(null) : withAgent(options, (ready, agentOptions) => ready.check(agentOptions)),
152
+ load: loadNow,
153
+ getAgent
154
+ };
155
+ internals.set(context, {
156
+ // With autoLoad the plugin starts loading once the app is mounted, unless a load has already
157
+ // started. After a failed load only identify(), check(), getAgent() and load() load again.
158
+ start: () => {
159
+ if (started || !autoLoad || !isBrowser()) return;
160
+ void startLoad();
161
+ },
162
+ defaultTimeout
163
+ });
164
+ return context;
165
+ }
166
+ function startContext(context) {
167
+ var _a;
168
+ (_a = internals.get(context)) == null ? void 0 : _a.start();
169
+ }
170
+ function defaultTimeoutOf(context) {
171
+ var _a, _b;
172
+ return (_b = (_a = internals.get(context)) == null ? void 0 : _a.defaultTimeout) != null ? _b : DEFAULT_TIMEOUT;
173
+ }
174
+ function createServerContext() {
175
+ const unsupported = () => Promise.reject(
176
+ new ShieldLabsError("unsupported_environment", "ShieldLabs identifies in the browser, not during server-side rendering.")
177
+ );
178
+ return {
179
+ status: shallowReadonly(shallowRef("loading")),
180
+ error: shallowReadonly(shallowRef(null)),
181
+ identify: unsupported,
182
+ check: unsupported,
183
+ load: ignore,
184
+ getAgent: unsupported
185
+ };
186
+ }
187
+ function injectContext(caller) {
188
+ const inContext = hasInjectionContext();
189
+ const context = inContext ? inject(shieldLabsKey, null) : null;
190
+ if (context) return context;
191
+ if (!isBrowser()) return serverContext != null ? serverContext : serverContext = createServerContext();
192
+ if (!inContext) {
193
+ throw new Error("[ShieldLabs] " + caller + "() must be called inside setup() of a component or in app.runWithContext().");
194
+ }
195
+ throw new Error(
196
+ "[ShieldLabs] " + caller + "() found no ShieldLabs plugin. Install it before mounting the app: app.use(createShieldLabs({ publicKey })). In Nuxt, add the client plugin plugins/shieldlabs.client.ts."
197
+ );
198
+ }
199
+
200
+ // src/plugin.ts
201
+ var installedApps = /* @__PURE__ */ new WeakSet();
202
+ function invalidOptions(message) {
203
+ return new ShieldLabsError("invalid_options", message);
204
+ }
205
+ function checkCheckOnLoad(value) {
206
+ if (value === void 0 || value === false) return false;
207
+ if (value === true) return true;
208
+ if (typeof value === "object" && value !== null) {
209
+ const userId = value.userId;
210
+ if (userId === void 0 || userId === null) return {};
211
+ if (typeof userId === "string") return { userId };
212
+ }
213
+ throw invalidOptions("checkOnLoad must be true, false or { userId }.");
214
+ }
215
+ function createShieldLabs(options) {
216
+ var _a;
217
+ const candidate = options;
218
+ if (typeof candidate !== "object" || candidate === null) {
219
+ throw invalidOptions("createShieldLabs() needs an options object with the Public Key of your domain: createShieldLabs({ publicKey }).");
220
+ }
221
+ const checkOnLoad = checkCheckOnLoad(options.checkOnLoad);
222
+ const autoLoad = (_a = options.autoLoad) != null ? _a : true;
223
+ if (typeof autoLoad !== "boolean") throw invalidOptions("autoLoad must be true or false.");
224
+ const loadOptions = { publicKey: options.publicKey };
225
+ if (options.environment !== void 0) loadOptions.environment = options.environment;
226
+ if (options.scriptUrl !== void 0) loadOptions.scriptUrl = options.scriptUrl;
227
+ if (options.timeout !== void 0) loadOptions.timeout = options.timeout;
228
+ return {
229
+ install(app) {
230
+ if (installedApps.has(app)) {
231
+ console.warn("[ShieldLabs] This app already has a ShieldLabs plugin; the second one is ignored.");
232
+ return;
233
+ }
234
+ installedApps.add(app);
235
+ const context = createContext(loadOptions, checkOnLoad, autoLoad);
236
+ app.provide(shieldLabsKey, context);
237
+ const mount = app.mount.bind(app);
238
+ app.mount = (...args) => {
239
+ const root = mount(...args);
240
+ startContext(context);
241
+ return root;
242
+ };
243
+ }
244
+ };
245
+ }
246
+ function useShieldLabs() {
247
+ const context = injectContext("useShieldLabs");
248
+ if (!getCurrentInstance()) return context;
249
+ const mounted = shallowRef(false);
250
+ onMounted(() => {
251
+ mounted.value = true;
252
+ startContext(context);
253
+ });
254
+ return {
255
+ status: computed(() => mounted.value ? context.status.value : "loading"),
256
+ error: computed(() => mounted.value ? context.error.value : null),
257
+ identify: context.identify,
258
+ check: context.check,
259
+ load: context.load,
260
+ getAgent: context.getAgent
261
+ };
262
+ }
263
+ function orUndefined(value) {
264
+ return value != null ? value : void 0;
265
+ }
266
+ function boundOf(timeout, fallback) {
267
+ return timeout === void 0 ? fallback : timeout;
268
+ }
269
+ function useIdentify(options = {}) {
270
+ const context = injectContext("useIdentify");
271
+ const defaultTimeout = defaultTimeoutOf(context);
272
+ const result = shallowRef(null);
273
+ const isLoading = shallowRef(false);
274
+ const error = shallowRef(null);
275
+ const running = /* @__PURE__ */ new Set();
276
+ let lastId = 0;
277
+ let owner = 0;
278
+ const own = (id) => {
279
+ owner = id;
280
+ result.value = null;
281
+ error.value = null;
282
+ isLoading.value = true;
283
+ };
284
+ const identify = (overrides) => {
285
+ const given = overrides != null ? overrides : {};
286
+ let callOptions = given;
287
+ let key;
288
+ if (typeof given === "object" && given !== null) {
289
+ const picked = given;
290
+ const userId = "userId" in picked ? orUndefined(picked.userId) : orUndefined(toValue(options.userId));
291
+ const timeout = picked.timeout;
292
+ const bound = boundOf(timeout, defaultTimeout);
293
+ for (const call of running) {
294
+ if (call.userId === userId && Object.is(call.timeout, bound)) {
295
+ if (owner !== call.id) own(call.id);
296
+ return call.promise;
297
+ }
298
+ }
299
+ key = { userId, timeout: bound };
300
+ const built = {};
301
+ if (userId !== void 0) built.userId = userId;
302
+ if (timeout !== void 0) built.timeout = timeout;
303
+ callOptions = built;
304
+ }
305
+ const id = ++lastId;
306
+ own(id);
307
+ const promise = new Promise((resolve) => {
308
+ resolve(context.identify(callOptions));
309
+ }).then(
310
+ (value) => {
311
+ if (owner === id) {
312
+ result.value = value;
313
+ isLoading.value = false;
314
+ }
315
+ return value;
316
+ },
317
+ (reason) => {
318
+ const failure = toShieldLabsError(reason, "not_initialized", "The identification did not start.");
319
+ if (owner === id) {
320
+ error.value = failure;
321
+ isLoading.value = false;
322
+ }
323
+ return null;
324
+ }
325
+ );
326
+ if (key !== void 0) {
327
+ const entry = { id, ...key, promise };
328
+ running.add(entry);
329
+ void promise.then(() => {
330
+ running.delete(entry);
331
+ });
332
+ }
333
+ return promise;
334
+ };
335
+ const reset = () => {
336
+ owner = 0;
337
+ result.value = null;
338
+ error.value = null;
339
+ isLoading.value = false;
340
+ };
341
+ if (getCurrentInstance()) {
342
+ onMounted(() => {
343
+ startContext(context);
344
+ if (options.runOnMount === true) void identify();
345
+ });
346
+ } else if (options.runOnMount === true && isBrowser()) {
347
+ void identify();
348
+ }
349
+ return {
350
+ identify,
351
+ result: shallowReadonly(result),
352
+ isLoading: shallowReadonly(isLoading),
353
+ error: shallowReadonly(error),
354
+ reset
355
+ };
356
+ }
357
+
358
+ // src/version.ts
359
+ var VERSION = "1.0.0";
360
+
361
+ export { VERSION, createShieldLabs, shieldLabsKey, useIdentify, useShieldLabs };
package/package.json ADDED
@@ -0,0 +1,79 @@
1
+ {
2
+ "name": "@shieldlabs-ai/vue",
3
+ "version": "1.0.0",
4
+ "description": "Vue 3 and Nuxt bindings for ShieldLabs device intelligence: a plugin that loads the agent once and composables that return a request ID with loading and error state.",
5
+ "keywords": [
6
+ "shieldlabs",
7
+ "vue",
8
+ "nuxt",
9
+ "device-intelligence",
10
+ "fraud-detection",
11
+ "risk-score",
12
+ "identification"
13
+ ],
14
+ "homepage": "https://docs.shieldlabs.ai",
15
+ "bugs": {
16
+ "url": "https://github.com/ShieldLabs-ai/shieldlabs-vue/issues",
17
+ "email": "contact@shieldlabs.ai"
18
+ },
19
+ "repository": {
20
+ "type": "git",
21
+ "url": "git+https://github.com/ShieldLabs-ai/shieldlabs-vue.git"
22
+ },
23
+ "license": "MIT",
24
+ "author": "ShieldLabs Inc. <contact@shieldlabs.ai>",
25
+ "type": "module",
26
+ "sideEffects": false,
27
+ "main": "./dist/index.cjs",
28
+ "module": "./dist/index.js",
29
+ "types": "./dist/index.d.ts",
30
+ "exports": {
31
+ ".": {
32
+ "import": {
33
+ "types": "./dist/index.d.ts",
34
+ "default": "./dist/index.js"
35
+ },
36
+ "require": {
37
+ "types": "./dist/index.d.cts",
38
+ "default": "./dist/index.cjs"
39
+ }
40
+ },
41
+ "./package.json": "./package.json"
42
+ },
43
+ "files": [
44
+ "dist",
45
+ "CHANGELOG.md"
46
+ ],
47
+ "engines": {
48
+ "node": ">=18"
49
+ },
50
+ "publishConfig": {
51
+ "access": "public"
52
+ },
53
+ "scripts": {
54
+ "build": "tsup",
55
+ "typecheck": "tsc --noEmit && tsc --noEmit -p tsconfig.build.json",
56
+ "lint": "eslint .",
57
+ "pretest": "npm run build",
58
+ "test": "vitest run",
59
+ "prepublishOnly": "npm run build"
60
+ },
61
+ "peerDependencies": {
62
+ "@shieldlabs-ai/js": "^1.0.0",
63
+ "vue": "^3.3.0"
64
+ },
65
+ "devDependencies": {
66
+ "@eslint/js": "~9.39.5",
67
+ "@types/node": "^22.0.0",
68
+ "@vitest/coverage-v8": "~3.2.7",
69
+ "@vue/test-utils": "^2.4.6",
70
+ "eslint": "~9.39.5",
71
+ "happy-dom": "^20.14.5",
72
+ "tsup": "^8.5.1",
73
+ "typescript": "~5.9.3",
74
+ "typescript-eslint": "^8.71.0",
75
+ "vite": "~6.4.3",
76
+ "vitest": "~3.2.7",
77
+ "vue": "~3.5.22"
78
+ }
79
+ }