UNPKG

@softlock/sdk

Version:

Official Softlock SDK for access key validation and management

1,197 lines (1,176 loc) 48.8 kB
"use client"; 'use strict'; var crossFetch = require('cross-fetch'); var require$$0 = require('react'); // Error types class SoftlockError extends Error { constructor(message, code, statusCode) { super(message); this.code = code; this.statusCode = statusCode; this.name = 'SoftlockError'; } } class ValidationError extends SoftlockError { constructor(message, code) { super(message, code, 400); this.name = 'ValidationError'; } } class NetworkError extends SoftlockError { constructor(message, statusCode) { super(message, 'NETWORK_ERROR', statusCode); this.name = 'NetworkError'; } } class ConfigurationError extends SoftlockError { constructor(message) { super(message, 'CONFIG_ERROR', 500); this.name = 'ConfigurationError'; } } /** * Core Softlock client for access key validation */ class SoftlockClient { constructor(config) { this.cache = new Map(); this.config = { baseUrl: 'https://api.softlock.dev', cacheTtl: 5 * 60 * 1000, // 5 minutes debug: false, ...config, }; if (!this.config.tenantId) { throw new ConfigurationError('tenantId is required'); } } /** * Validate an access key */ async validateKey(keyValue) { if (!keyValue) { throw new ValidationError('Key value is required'); } // Check cache first const cacheKey = `validate:${keyValue}`; const cached = this.cache.get(cacheKey); if (cached && Date.now() - cached.timestamp < cached.ttl) { if (this.config.debug) { console.log('[SoftlockClient] Returning cached result for key:', keyValue); } return { ...cached.result, cached: true }; } try { const url = `${this.config.baseUrl}/api/validate-key`; const headers = { 'Content-Type': 'application/json', }; if (this.config.apiKey) { headers['Authorization'] = `Bearer ${this.config.apiKey}`; } const body = JSON.stringify({ key: keyValue, tenantId: this.config.tenantId, }); if (this.config.debug) { console.log('[SoftlockClient] Validating key:', { url, keyValue, tenantId: this.config.tenantId }); } const response = await crossFetch.fetch(url, { method: 'POST', headers, body, }); if (!response.ok) { const errorText = await response.text(); let errorMessage = `HTTP ${response.status}`; try { const errorJson = JSON.parse(errorText); errorMessage = errorJson.error || errorJson.message || errorMessage; } catch (_a) { errorMessage = errorText || errorMessage; } throw new NetworkError(errorMessage, response.status); } const result = await response.json(); if (this.config.debug) { console.log('[SoftlockClient] Validation result:', result); } // Cache the result this.cache.set(cacheKey, { result, timestamp: Date.now(), ttl: this.config.cacheTtl, }); return result; } catch (error) { if (this.config.debug) { console.error('[SoftlockClient] Validation error:', error); } if (error instanceof Error) { throw error; } throw new NetworkError('Network request failed'); } } /** * Clear validation cache */ clearCache() { this.cache.clear(); } /** * Update configuration */ updateConfig(newConfig) { this.config = { ...this.config, ...newConfig }; } /** * Get current configuration (without sensitive data) */ getConfig() { const { apiKey, ...publicConfig } = this.config; return publicConfig; } } // Default client instance let defaultClient = null; /** * Initialize the default Softlock client */ function initSoftlock(config) { defaultClient = new SoftlockClient(config); return defaultClient; } /** * Get the default client instance */ function getSoftlockClient() { if (!defaultClient) { throw new ConfigurationError('Softlock client not initialized. Call initSoftlock() first.'); } return defaultClient; } /** * Validate a key using the default client */ async function validateKey(keyValue) { return getSoftlockClient().validateKey(keyValue); } /** * React hook for access key validation */ function useAccessKey(initialKey, options = {}) { const { autoValidate = false, refetchInterval, disableCache = false, } = options; const [result, setResult] = require$$0.useState(null); const [loading, setLoading] = require$$0.useState(false); const [error, setError] = require$$0.useState(null); const [currentKey, setCurrentKey] = require$$0.useState(initialKey); const intervalRef = require$$0.useRef(null); const mountedRef = require$$0.useRef(true); require$$0.useRef(true); const validate = require$$0.useCallback(async (key) => { if (!key) { const errorResult = { valid: false, error: 'No key provided', }; setResult(errorResult); setError('No key provided'); return errorResult; } setLoading(true); setError(null); try { const client = getSoftlockClient(); // Temporarily disable cache if requested if (disableCache) { client.clearCache(); } const validationResult = await client.validateKey(key); // Always set state in development mode to handle React Strict Mode if (process.env.NODE_ENV === 'development' || mountedRef.current) { setResult(validationResult); setCurrentKey(key); if (!validationResult.valid && validationResult.error) { setError(validationResult.error); } } return validationResult; } catch (err) { console.error('[useAccessKey] Validation error:', err); const errorMessage = err instanceof Error ? err.message : 'Validation failed'; const errorResult = { valid: false, error: errorMessage, }; if (mountedRef.current || process.env.NODE_ENV === 'development') { setResult(errorResult); setError(errorMessage); } return errorResult; } finally { if (mountedRef.current || process.env.NODE_ENV === 'development') { setLoading(false); } } }, [disableCache]); const clear = require$$0.useCallback(() => { setResult(null); setError(null); setCurrentKey(undefined); if (intervalRef.current) { clearInterval(intervalRef.current); intervalRef.current = null; } }, []); const retry = require$$0.useCallback(() => { if (currentKey) { validate(currentKey); } }, [currentKey, validate]); // Auto-validate on mount if key is provided require$$0.useEffect(() => { if (autoValidate && initialKey) { validate(initialKey); } }, [autoValidate, initialKey, validate]); // Set up refetch interval require$$0.useEffect(() => { if (refetchInterval && currentKey) { intervalRef.current = setInterval(() => { validate(currentKey); }, refetchInterval); return () => { if (intervalRef.current) { clearInterval(intervalRef.current); } }; } }, [refetchInterval, currentKey, validate]); // Cleanup on unmount require$$0.useEffect(() => { mountedRef.current = true; // Ensure it's set to true on mount return () => { mountedRef.current = false; if (intervalRef.current) { clearInterval(intervalRef.current); } }; }, []); return { result, loading, error, validate, clear, retry, }; } /** * Hook for managing user access state */ function useUserAccess(userId) { const [hasAccess, setHasAccess] = require$$0.useState(null); const [userKey, setUserKey] = require$$0.useState(); const { result, loading, error, validate } = useAccessKey(userKey, { autoValidate: true, }); require$$0.useEffect(() => { if (result) { setHasAccess(result.valid); } }, [result]); const checkAccess = require$$0.useCallback((key) => { setUserKey(key); return validate(key); }, [validate]); const revokeAccess = require$$0.useCallback(() => { setHasAccess(false); setUserKey(undefined); }, []); return { hasAccess, loading, error, checkAccess, revokeAccess, userKey, validationResult: result, }; } /** * Hook for protecting components based on access key validation */ function useAccessGuard(keyValue, options = {}) { const { result, loading, error, validate } = useAccessKey(keyValue, { autoValidate: !!keyValue, }); const [isAuthorized, setIsAuthorized] = require$$0.useState(null); require$$0.useEffect(() => { if (result) { const authorized = result.valid; setIsAuthorized(authorized); if (!authorized && options.onUnauthorized) { options.onUnauthorized(); } if (!authorized && options.redirectUrl) { window.location.href = options.redirectUrl; } } }, [result, options]); const checkKey = require$$0.useCallback((key) => { return validate(key); }, [validate]); return { isAuthorized, loading, error, checkKey, validationResult: result, }; } var jsxRuntime = {exports: {}}; var reactJsxRuntime_production = {}; /** * @license React * react-jsx-runtime.production.js * * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ var hasRequiredReactJsxRuntime_production; function requireReactJsxRuntime_production () { if (hasRequiredReactJsxRuntime_production) return reactJsxRuntime_production; hasRequiredReactJsxRuntime_production = 1; var REACT_ELEMENT_TYPE = Symbol.for("react.transitional.element"), REACT_FRAGMENT_TYPE = Symbol.for("react.fragment"); function jsxProd(type, config, maybeKey) { var key = null; void 0 !== maybeKey && (key = "" + maybeKey); void 0 !== config.key && (key = "" + config.key); if ("key" in config) { maybeKey = {}; for (var propName in config) "key" !== propName && (maybeKey[propName] = config[propName]); } else maybeKey = config; config = maybeKey.ref; return { $$typeof: REACT_ELEMENT_TYPE, type: type, key: key, ref: void 0 !== config ? config : null, props: maybeKey }; } reactJsxRuntime_production.Fragment = REACT_FRAGMENT_TYPE; reactJsxRuntime_production.jsx = jsxProd; reactJsxRuntime_production.jsxs = jsxProd; return reactJsxRuntime_production; } var reactJsxRuntime_development = {}; /** * @license React * react-jsx-runtime.development.js * * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ var hasRequiredReactJsxRuntime_development; function requireReactJsxRuntime_development () { if (hasRequiredReactJsxRuntime_development) return reactJsxRuntime_development; hasRequiredReactJsxRuntime_development = 1; "production" !== process.env.NODE_ENV && (function () { function getComponentNameFromType(type) { if (null == type) return null; if ("function" === typeof type) return type.$$typeof === REACT_CLIENT_REFERENCE$2 ? null : type.displayName || type.name || null; if ("string" === typeof type) return type; switch (type) { case REACT_FRAGMENT_TYPE: return "Fragment"; case REACT_PORTAL_TYPE: return "Portal"; case REACT_PROFILER_TYPE: return "Profiler"; case REACT_STRICT_MODE_TYPE: return "StrictMode"; case REACT_SUSPENSE_TYPE: return "Suspense"; case REACT_SUSPENSE_LIST_TYPE: return "SuspenseList"; } if ("object" === typeof type) switch ( ("number" === typeof type.tag && console.error( "Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue." ), type.$$typeof) ) { case REACT_CONTEXT_TYPE: return (type.displayName || "Context") + ".Provider"; case REACT_CONSUMER_TYPE: return (type._context.displayName || "Context") + ".Consumer"; case REACT_FORWARD_REF_TYPE: var innerType = type.render; type = type.displayName; type || ((type = innerType.displayName || innerType.name || ""), (type = "" !== type ? "ForwardRef(" + type + ")" : "ForwardRef")); return type; case REACT_MEMO_TYPE: return ( (innerType = type.displayName || null), null !== innerType ? innerType : getComponentNameFromType(type.type) || "Memo" ); case REACT_LAZY_TYPE: innerType = type._payload; type = type._init; try { return getComponentNameFromType(type(innerType)); } catch (x) {} } return null; } function testStringCoercion(value) { return "" + value; } function checkKeyStringCoercion(value) { try { testStringCoercion(value); var JSCompiler_inline_result = !1; } catch (e) { JSCompiler_inline_result = true; } if (JSCompiler_inline_result) { JSCompiler_inline_result = console; var JSCompiler_temp_const = JSCompiler_inline_result.error; var JSCompiler_inline_result$jscomp$0 = ("function" === typeof Symbol && Symbol.toStringTag && value[Symbol.toStringTag]) || value.constructor.name || "Object"; JSCompiler_temp_const.call( JSCompiler_inline_result, "The provided key is an unsupported type %s. This value must be coerced to a string before using it here.", JSCompiler_inline_result$jscomp$0 ); return testStringCoercion(value); } } function disabledLog() {} function disableLogs() { if (0 === disabledDepth) { prevLog = console.log; prevInfo = console.info; prevWarn = console.warn; prevError = console.error; prevGroup = console.group; prevGroupCollapsed = console.groupCollapsed; prevGroupEnd = console.groupEnd; var props = { configurable: true, enumerable: true, value: disabledLog, writable: true }; Object.defineProperties(console, { info: props, log: props, warn: props, error: props, group: props, groupCollapsed: props, groupEnd: props }); } disabledDepth++; } function reenableLogs() { disabledDepth--; if (0 === disabledDepth) { var props = { configurable: true, enumerable: true, writable: true }; Object.defineProperties(console, { log: assign({}, props, { value: prevLog }), info: assign({}, props, { value: prevInfo }), warn: assign({}, props, { value: prevWarn }), error: assign({}, props, { value: prevError }), group: assign({}, props, { value: prevGroup }), groupCollapsed: assign({}, props, { value: prevGroupCollapsed }), groupEnd: assign({}, props, { value: prevGroupEnd }) }); } 0 > disabledDepth && console.error( "disabledDepth fell below zero. This is a bug in React. Please file an issue." ); } function describeBuiltInComponentFrame(name) { if (void 0 === prefix) try { throw Error(); } catch (x) { var match = x.stack.trim().match(/\n( *(at )?)/); prefix = (match && match[1]) || ""; suffix = -1 < x.stack.indexOf("\n at") ? " (<anonymous>)" : -1 < x.stack.indexOf("@") ? "@unknown:0:0" : ""; } return "\n" + prefix + name + suffix; } function describeNativeComponentFrame(fn, construct) { if (!fn || reentry) return ""; var frame = componentFrameCache.get(fn); if (void 0 !== frame) return frame; reentry = true; frame = Error.prepareStackTrace; Error.prepareStackTrace = void 0; var previousDispatcher = null; previousDispatcher = ReactSharedInternals.H; ReactSharedInternals.H = null; disableLogs(); try { var RunInRootFrame = { DetermineComponentFrameRoot: function () { try { if (construct) { var Fake = function () { throw Error(); }; Object.defineProperty(Fake.prototype, "props", { set: function () { throw Error(); } }); if ("object" === typeof Reflect && Reflect.construct) { try { Reflect.construct(Fake, []); } catch (x) { var control = x; } Reflect.construct(fn, [], Fake); } else { try { Fake.call(); } catch (x$0) { control = x$0; } fn.call(Fake.prototype); } } else { try { throw Error(); } catch (x$1) { control = x$1; } (Fake = fn()) && "function" === typeof Fake.catch && Fake.catch(function () {}); } } catch (sample) { if (sample && control && "string" === typeof sample.stack) return [sample.stack, control.stack]; } return [null, null]; } }; RunInRootFrame.DetermineComponentFrameRoot.displayName = "DetermineComponentFrameRoot"; var namePropDescriptor = Object.getOwnPropertyDescriptor( RunInRootFrame.DetermineComponentFrameRoot, "name" ); namePropDescriptor && namePropDescriptor.configurable && Object.defineProperty( RunInRootFrame.DetermineComponentFrameRoot, "name", { value: "DetermineComponentFrameRoot" } ); var _RunInRootFrame$Deter = RunInRootFrame.DetermineComponentFrameRoot(), sampleStack = _RunInRootFrame$Deter[0], controlStack = _RunInRootFrame$Deter[1]; if (sampleStack && controlStack) { var sampleLines = sampleStack.split("\n"), controlLines = controlStack.split("\n"); for ( _RunInRootFrame$Deter = namePropDescriptor = 0; namePropDescriptor < sampleLines.length && !sampleLines[namePropDescriptor].includes( "DetermineComponentFrameRoot" ); ) namePropDescriptor++; for ( ; _RunInRootFrame$Deter < controlLines.length && !controlLines[_RunInRootFrame$Deter].includes( "DetermineComponentFrameRoot" ); ) _RunInRootFrame$Deter++; if ( namePropDescriptor === sampleLines.length || _RunInRootFrame$Deter === controlLines.length ) for ( namePropDescriptor = sampleLines.length - 1, _RunInRootFrame$Deter = controlLines.length - 1; 1 <= namePropDescriptor && 0 <= _RunInRootFrame$Deter && sampleLines[namePropDescriptor] !== controlLines[_RunInRootFrame$Deter]; ) _RunInRootFrame$Deter--; for ( ; 1 <= namePropDescriptor && 0 <= _RunInRootFrame$Deter; namePropDescriptor--, _RunInRootFrame$Deter-- ) if ( sampleLines[namePropDescriptor] !== controlLines[_RunInRootFrame$Deter] ) { if (1 !== namePropDescriptor || 1 !== _RunInRootFrame$Deter) { do if ( (namePropDescriptor--, _RunInRootFrame$Deter--, 0 > _RunInRootFrame$Deter || sampleLines[namePropDescriptor] !== controlLines[_RunInRootFrame$Deter]) ) { var _frame = "\n" + sampleLines[namePropDescriptor].replace( " at new ", " at " ); fn.displayName && _frame.includes("<anonymous>") && (_frame = _frame.replace("<anonymous>", fn.displayName)); "function" === typeof fn && componentFrameCache.set(fn, _frame); return _frame; } while (1 <= namePropDescriptor && 0 <= _RunInRootFrame$Deter); } break; } } } finally { (reentry = false), (ReactSharedInternals.H = previousDispatcher), reenableLogs(), (Error.prepareStackTrace = frame); } sampleLines = (sampleLines = fn ? fn.displayName || fn.name : "") ? describeBuiltInComponentFrame(sampleLines) : ""; "function" === typeof fn && componentFrameCache.set(fn, sampleLines); return sampleLines; } function describeUnknownElementTypeFrameInDEV(type) { if (null == type) return ""; if ("function" === typeof type) { var prototype = type.prototype; return describeNativeComponentFrame( type, !(!prototype || !prototype.isReactComponent) ); } if ("string" === typeof type) return describeBuiltInComponentFrame(type); switch (type) { case REACT_SUSPENSE_TYPE: return describeBuiltInComponentFrame("Suspense"); case REACT_SUSPENSE_LIST_TYPE: return describeBuiltInComponentFrame("SuspenseList"); } if ("object" === typeof type) switch (type.$$typeof) { case REACT_FORWARD_REF_TYPE: return (type = describeNativeComponentFrame(type.render, false)), type; case REACT_MEMO_TYPE: return describeUnknownElementTypeFrameInDEV(type.type); case REACT_LAZY_TYPE: prototype = type._payload; type = type._init; try { return describeUnknownElementTypeFrameInDEV(type(prototype)); } catch (x) {} } return ""; } function getOwner() { var dispatcher = ReactSharedInternals.A; return null === dispatcher ? null : dispatcher.getOwner(); } function hasValidKey(config) { if (hasOwnProperty.call(config, "key")) { var getter = Object.getOwnPropertyDescriptor(config, "key").get; if (getter && getter.isReactWarning) return false; } return void 0 !== config.key; } function defineKeyPropWarningGetter(props, displayName) { function warnAboutAccessingKey() { specialPropKeyWarningShown || ((specialPropKeyWarningShown = true), console.error( "%s: `key` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://react.dev/link/special-props)", displayName )); } warnAboutAccessingKey.isReactWarning = true; Object.defineProperty(props, "key", { get: warnAboutAccessingKey, configurable: true }); } function elementRefGetterWithDeprecationWarning() { var componentName = getComponentNameFromType(this.type); didWarnAboutElementRef[componentName] || ((didWarnAboutElementRef[componentName] = true), console.error( "Accessing element.ref was removed in React 19. ref is now a regular prop. It will be removed from the JSX Element type in a future release." )); componentName = this.props.ref; return void 0 !== componentName ? componentName : null; } function ReactElement(type, key, self, source, owner, props) { self = props.ref; type = { $$typeof: REACT_ELEMENT_TYPE, type: type, key: key, props: props, _owner: owner }; null !== (void 0 !== self ? self : null) ? Object.defineProperty(type, "ref", { enumerable: false, get: elementRefGetterWithDeprecationWarning }) : Object.defineProperty(type, "ref", { enumerable: false, value: null }); type._store = {}; Object.defineProperty(type._store, "validated", { configurable: false, enumerable: false, writable: true, value: 0 }); Object.defineProperty(type, "_debugInfo", { configurable: false, enumerable: false, writable: true, value: null }); Object.freeze && (Object.freeze(type.props), Object.freeze(type)); return type; } function jsxDEVImpl( type, config, maybeKey, isStaticChildren, source, self ) { if ( "string" === typeof type || "function" === typeof type || type === REACT_FRAGMENT_TYPE || type === REACT_PROFILER_TYPE || type === REACT_STRICT_MODE_TYPE || type === REACT_SUSPENSE_TYPE || type === REACT_SUSPENSE_LIST_TYPE || type === REACT_OFFSCREEN_TYPE || ("object" === typeof type && null !== type && (type.$$typeof === REACT_LAZY_TYPE || type.$$typeof === REACT_MEMO_TYPE || type.$$typeof === REACT_CONTEXT_TYPE || type.$$typeof === REACT_CONSUMER_TYPE || type.$$typeof === REACT_FORWARD_REF_TYPE || type.$$typeof === REACT_CLIENT_REFERENCE$1 || void 0 !== type.getModuleId)) ) { var children = config.children; if (void 0 !== children) if (isStaticChildren) if (isArrayImpl(children)) { for ( isStaticChildren = 0; isStaticChildren < children.length; isStaticChildren++ ) validateChildKeys(children[isStaticChildren], type); Object.freeze && Object.freeze(children); } else console.error( "React.jsx: Static children should always be an array. You are likely explicitly calling React.jsxs or React.jsxDEV. Use the Babel transform instead." ); else validateChildKeys(children, type); } else { children = ""; if ( void 0 === type || ("object" === typeof type && null !== type && 0 === Object.keys(type).length) ) children += " You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports."; null === type ? (isStaticChildren = "null") : isArrayImpl(type) ? (isStaticChildren = "array") : void 0 !== type && type.$$typeof === REACT_ELEMENT_TYPE ? ((isStaticChildren = "<" + (getComponentNameFromType(type.type) || "Unknown") + " />"), (children = " Did you accidentally export a JSX literal instead of a component?")) : (isStaticChildren = typeof type); console.error( "React.jsx: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: %s.%s", isStaticChildren, children ); } if (hasOwnProperty.call(config, "key")) { children = getComponentNameFromType(type); var keys = Object.keys(config).filter(function (k) { return "key" !== k; }); isStaticChildren = 0 < keys.length ? "{key: someKey, " + keys.join(": ..., ") + ": ...}" : "{key: someKey}"; didWarnAboutKeySpread[children + isStaticChildren] || ((keys = 0 < keys.length ? "{" + keys.join(": ..., ") + ": ...}" : "{}"), console.error( 'A props object containing a "key" prop is being spread into JSX:\n let props = %s;\n <%s {...props} />\nReact keys must be passed directly to JSX without using spread:\n let props = %s;\n <%s key={someKey} {...props} />', isStaticChildren, children, keys, children ), (didWarnAboutKeySpread[children + isStaticChildren] = true)); } children = null; void 0 !== maybeKey && (checkKeyStringCoercion(maybeKey), (children = "" + maybeKey)); hasValidKey(config) && (checkKeyStringCoercion(config.key), (children = "" + config.key)); if ("key" in config) { maybeKey = {}; for (var propName in config) "key" !== propName && (maybeKey[propName] = config[propName]); } else maybeKey = config; children && defineKeyPropWarningGetter( maybeKey, "function" === typeof type ? type.displayName || type.name || "Unknown" : type ); return ReactElement(type, children, self, source, getOwner(), maybeKey); } function validateChildKeys(node, parentType) { if ( "object" === typeof node && node && node.$$typeof !== REACT_CLIENT_REFERENCE ) if (isArrayImpl(node)) for (var i = 0; i < node.length; i++) { var child = node[i]; isValidElement(child) && validateExplicitKey(child, parentType); } else if (isValidElement(node)) node._store && (node._store.validated = 1); else if ( (null === node || "object" !== typeof node ? (i = null) : ((i = (MAYBE_ITERATOR_SYMBOL && node[MAYBE_ITERATOR_SYMBOL]) || node["@@iterator"]), (i = "function" === typeof i ? i : null)), "function" === typeof i && i !== node.entries && ((i = i.call(node)), i !== node)) ) for (; !(node = i.next()).done; ) isValidElement(node.value) && validateExplicitKey(node.value, parentType); } function isValidElement(object) { return ( "object" === typeof object && null !== object && object.$$typeof === REACT_ELEMENT_TYPE ); } function validateExplicitKey(element, parentType) { if ( element._store && !element._store.validated && null == element.key && ((element._store.validated = 1), (parentType = getCurrentComponentErrorInfo(parentType)), !ownerHasKeyUseWarning[parentType]) ) { ownerHasKeyUseWarning[parentType] = true; var childOwner = ""; element && null != element._owner && element._owner !== getOwner() && ((childOwner = null), "number" === typeof element._owner.tag ? (childOwner = getComponentNameFromType(element._owner.type)) : "string" === typeof element._owner.name && (childOwner = element._owner.name), (childOwner = " It was passed a child from " + childOwner + ".")); var prevGetCurrentStack = ReactSharedInternals.getCurrentStack; ReactSharedInternals.getCurrentStack = function () { var stack = describeUnknownElementTypeFrameInDEV(element.type); prevGetCurrentStack && (stack += prevGetCurrentStack() || ""); return stack; }; console.error( 'Each child in a list should have a unique "key" prop.%s%s See https://react.dev/link/warning-keys for more information.', parentType, childOwner ); ReactSharedInternals.getCurrentStack = prevGetCurrentStack; } } function getCurrentComponentErrorInfo(parentType) { var info = "", owner = getOwner(); owner && (owner = getComponentNameFromType(owner.type)) && (info = "\n\nCheck the render method of `" + owner + "`."); info || ((parentType = getComponentNameFromType(parentType)) && (info = "\n\nCheck the top-level render call using <" + parentType + ">.")); return info; } var React = require$$0, REACT_ELEMENT_TYPE = Symbol.for("react.transitional.element"), REACT_PORTAL_TYPE = Symbol.for("react.portal"), REACT_FRAGMENT_TYPE = Symbol.for("react.fragment"), REACT_STRICT_MODE_TYPE = Symbol.for("react.strict_mode"), REACT_PROFILER_TYPE = Symbol.for("react.profiler"); var REACT_CONSUMER_TYPE = Symbol.for("react.consumer"), REACT_CONTEXT_TYPE = Symbol.for("react.context"), REACT_FORWARD_REF_TYPE = Symbol.for("react.forward_ref"), REACT_SUSPENSE_TYPE = Symbol.for("react.suspense"), REACT_SUSPENSE_LIST_TYPE = Symbol.for("react.suspense_list"), REACT_MEMO_TYPE = Symbol.for("react.memo"), REACT_LAZY_TYPE = Symbol.for("react.lazy"), REACT_OFFSCREEN_TYPE = Symbol.for("react.offscreen"), MAYBE_ITERATOR_SYMBOL = Symbol.iterator, REACT_CLIENT_REFERENCE$2 = Symbol.for("react.client.reference"), ReactSharedInternals = React.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE, hasOwnProperty = Object.prototype.hasOwnProperty, assign = Object.assign, REACT_CLIENT_REFERENCE$1 = Symbol.for("react.client.reference"), isArrayImpl = Array.isArray, disabledDepth = 0, prevLog, prevInfo, prevWarn, prevError, prevGroup, prevGroupCollapsed, prevGroupEnd; disabledLog.__reactDisabledLog = true; var prefix, suffix, reentry = false; var componentFrameCache = new ( "function" === typeof WeakMap ? WeakMap : Map )(); var REACT_CLIENT_REFERENCE = Symbol.for("react.client.reference"), specialPropKeyWarningShown; var didWarnAboutElementRef = {}; var didWarnAboutKeySpread = {}, ownerHasKeyUseWarning = {}; reactJsxRuntime_development.Fragment = REACT_FRAGMENT_TYPE; reactJsxRuntime_development.jsx = function (type, config, maybeKey, source, self) { return jsxDEVImpl(type, config, maybeKey, false, source, self); }; reactJsxRuntime_development.jsxs = function (type, config, maybeKey, source, self) { return jsxDEVImpl(type, config, maybeKey, true, source, self); }; })(); return reactJsxRuntime_development; } if (process.env.NODE_ENV === 'production') { jsxRuntime.exports = requireReactJsxRuntime_production(); } else { jsxRuntime.exports = requireReactJsxRuntime_development(); } var jsxRuntimeExports = jsxRuntime.exports; /** * Component for validating access keys with built-in UI */ function AccessKeyValidator({ initialKey = '', placeholder = 'Enter your access key...', validateButtonText = 'Validate', clearButtonText = 'Clear', showClearButton = true, autoValidate = false, debounceDelay = 500, className = '', onValidation, onKeyChange, disabled = false, }) { const [keyValue, setKeyValue] = require$$0.useState(initialKey); const [debounceTimer, setDebounceTimer] = require$$0.useState(null); const { result, loading, error, validate, clear } = useAccessKey(undefined, { autoValidate: false, }); const handleKeyChange = (value) => { setKeyValue(value); onKeyChange === null || onKeyChange === void 0 ? void 0 : onKeyChange(value); if (autoValidate && value.trim()) { // Clear existing timer if (debounceTimer) { clearTimeout(debounceTimer); } // Set new timer const timer = setTimeout(() => { handleValidate(value); }, debounceDelay); setDebounceTimer(timer); } }; const handleValidate = async (key) => { const keyToValidate = key || keyValue; if (!keyToValidate.trim()) return; const result = await validate(keyToValidate); onValidation === null || onValidation === void 0 ? void 0 : onValidation(result); }; const handleClear = () => { setKeyValue(''); clear(); onKeyChange === null || onKeyChange === void 0 ? void 0 : onKeyChange(''); if (debounceTimer) { clearTimeout(debounceTimer); setDebounceTimer(null); } }; const getResultStyle = () => { if (!result) return ''; return result.valid ? 'border-green-500 bg-green-50' : 'border-red-500 bg-red-50'; }; const getResultText = () => { if (loading) return 'Validating...'; if (!result) return ''; if (result.valid) { return result.cached ? '✅ Valid (cached)' : '✅ Valid access key'; } return `❌ ${result.error || 'Invalid access key'}`; }; const getResultTextColor = () => { if (loading) return 'text-blue-600'; if (!result) return ''; return result.valid ? 'text-green-700' : 'text-red-700'; }; return (jsxRuntimeExports.jsx("div", { className: `softlock-validator ${className}`, children: jsxRuntimeExports.jsxs("div", { className: "flex flex-col space-y-3", children: [jsxRuntimeExports.jsxs("div", { className: "flex space-x-2", children: [jsxRuntimeExports.jsx("input", { type: "text", value: keyValue, onChange: (e) => handleKeyChange(e.target.value), placeholder: placeholder, disabled: disabled || loading, className: `flex-1 px-3 py-2 border rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 ${getResultStyle()}`, onKeyDown: (e) => { if (e.key === 'Enter' && !autoValidate) { handleValidate(); } } }), !autoValidate && (jsxRuntimeExports.jsx("button", { onClick: () => handleValidate(), disabled: disabled || loading || !keyValue.trim(), className: "px-4 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700 disabled:opacity-50 disabled:cursor-not-allowed", children: loading ? 'Validating...' : validateButtonText })), showClearButton && (keyValue || result) && (jsxRuntimeExports.jsx("button", { onClick: handleClear, disabled: disabled, className: "px-4 py-2 bg-gray-500 text-white rounded-md hover:bg-gray-600 disabled:opacity-50", children: clearButtonText }))] }), (result || loading) && (jsxRuntimeExports.jsx("div", { className: `text-sm font-medium ${getResultTextColor()}`, children: getResultText() })), error && !result && (jsxRuntimeExports.jsxs("div", { className: "text-sm text-red-600", children: ["Error: ", error] }))] }) })); } /** * Component that conditionally renders children based on access key validation */ function AccessGuard({ keyValue, children, fallback, loadingComponent, redirectUrl, onUnauthorized, className, }) { const { isAuthorized, loading } = useAccessGuard(keyValue, { redirectUrl, onUnauthorized, }); if (loading) { if (loadingComponent) { return jsxRuntimeExports.jsx("div", { className: className, children: loadingComponent }); } return (jsxRuntimeExports.jsxs("div", { className: `flex items-center justify-center p-4 ${className || ''}`, children: [jsxRuntimeExports.jsx("div", { className: "animate-spin rounded-full h-6 w-6 border-b-2 border-blue-500" }), jsxRuntimeExports.jsx("span", { className: "ml-2 text-gray-600", children: "Verifying access..." })] })); } if (isAuthorized === false) { if (fallback) { return jsxRuntimeExports.jsx("div", { className: className, children: fallback }); } return (jsxRuntimeExports.jsxs("div", { className: `p-4 text-center bg-gray-50 border border-gray-200 rounded-md ${className || ''}`, children: [jsxRuntimeExports.jsx("div", { className: "text-red-500 text-lg mb-2", children: "\uD83D\uDD12" }), jsxRuntimeExports.jsx("h3", { className: "text-lg font-semibold text-gray-700 mb-2", children: "Access Denied" }), jsxRuntimeExports.jsx("p", { className: "text-gray-500", children: "You don't have permission to view this content." })] })); } if (isAuthorized === true) { return jsxRuntimeExports.jsx("div", { className: className, children: children }); } // isAuthorized is null (no key provided or unknown state) return (jsxRuntimeExports.jsxs("div", { className: `p-4 text-center bg-gray-50 border border-gray-200 rounded-md ${className || ''}`, children: [jsxRuntimeExports.jsx("div", { className: "text-gray-400 text-lg mb-2", children: "\uD83D\uDD11" }), jsxRuntimeExports.jsx("h3", { className: "text-lg font-semibold text-gray-700 mb-2", children: "Access Key Required" }), jsxRuntimeExports.jsx("p", { className: "text-gray-500", children: "Please provide a valid access key to view this content." })] })); } /** * Props for AccessStatus component */ /** * Component that displays the current access status */ function AccessStatus({ keyValue, showDetails = false, refreshInterval, className, }) { const { result, loading, error, retry } = useAccessKey(keyValue, { autoValidate: !!keyValue, refetchInterval: refreshInterval, }); if (!keyValue) { return (jsxRuntimeExports.jsxs("div", { className: `p-4 text-center bg-gray-50 border border-gray-200 rounded-md ${className || ''}`, children: [jsxRuntimeExports.jsx("div", { className: "text-gray-400 text-lg mb-2", children: "\uD83D\uDD11" }), jsxRuntimeExports.jsx("p", { className: "text-gray-500", children: "No access key provided" })] })); } if (loading) { return (jsxRuntimeExports.jsxs("div", { className: `flex items-center justify-center p-4 ${className || ''}`, children: [jsxRuntimeExports.jsx("div", { className: "animate-spin rounded-full h-5 w-5 border-b-2 border-blue-500" }), jsxRuntimeExports.jsx("span", { className: "ml-2 text-gray-600", children: "Checking access..." })] })); } if (error) { return (jsxRuntimeExports.jsx("div", { className: `p-4 bg-red-50 border border-red-200 rounded-md ${className || ''}`, children: jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between", children: [jsxRuntimeExports.jsxs("div", { children: [jsxRuntimeExports.jsx("div", { className: "text-red-500 text-lg mb-1", children: "\u274C" }), jsxRuntimeExports.jsx("h3", { className: "text-sm font-semibold text-red-800", children: "Validation Error" }), jsxRuntimeExports.jsx("p", { className: "text-red-600 text-sm", children: error })] }), jsxRuntimeExports.jsx("button", { onClick: retry, className: "px-3 py-1 text-sm bg-red-100 text-red-700 rounded hover:bg-red-200", children: "Retry" })] }) })); } if (!result) { return (jsxRuntimeExports.jsxs("div", { className: `p-4 text-center bg-gray-50 border border-gray-200 rounded-md ${className || ''}`, children: [jsxRuntimeExports.jsx("div", { className: "text-gray-400 text-lg mb-2", children: "\u2753" }), jsxRuntimeExports.jsx("p", { className: "text-gray-500", children: "No validation result" })] })); } if (!result.valid) { return (jsxRuntimeExports.jsxs("div", { className: `p-4 bg-red-50 border border-red-200 rounded-md ${className || ''}`, children: [jsxRuntimeExports.jsx("div", { className: "text-red-500 text-lg mb-2", children: "\u274C" }), jsxRuntimeExports.jsx("h3", { className: "text-sm font-semibold text-red-800 mb-1", children: "Access Denied" }), jsxRuntimeExports.jsx("p", { className: "text-red-600 text-sm", children: result.error || 'Invalid access key' })] })); } // Valid access key return (jsxRuntimeExports.jsxs("div", { className: `p-4 bg-green-50 border border-green-200 rounded-md ${className || ''}`, children: [jsxRuntimeExports.jsx("div", { className: "text-green-500 text-lg mb-2", children: "\u2705" }), jsxRuntimeExports.jsx("h3", { className: "text-sm font-semibold text-green-800 mb-2", children: "Access Granted" }), showDetails && result.key && (jsxRuntimeExports.jsxs("div", { className: "space-y-2 text-sm", children: [jsxRuntimeExports.jsxs("div", { className: "grid grid-cols-2 gap-2", children: [jsxRuntimeExports.jsxs("div", { children: [jsxRuntimeExports.jsx("span", { className: "font-medium text-green-700", children: "Status:" }), jsxRuntimeExports.jsx("span", { className: "ml-2 text-green-600", children: result.key.status })] }), result.key.discord_tag && (jsxRuntimeExports.jsxs("div", { children: [jsxRuntimeExports.jsx("span", { className: "font-medium text-green-700", children: "User:" }), jsxRuntimeExports.jsx("span", { className: "ml-2 text-green-600", children: result.key.discord_tag })] })), jsxRuntimeExports.jsxs("div", { children: [jsxRuntimeExports.jsx("span", { className: "font-medium text-green-700", children: "Created:" }), jsxRuntimeExports.jsx("span", { className: "ml-2 text-green-600", children: new Date(result.key.created_at).toLocaleDateString() })] }), result.key.expires_at && (jsxRuntimeExports.jsxs("div", { children: [jsxRuntimeExports.jsx("span", { className: "font-medium text-green-700", children: "Expires:" }), jsxRuntimeExports.jsx("span", { className: "ml-2 text-green-600", children: new Date(result.key.expires_at).toLocaleDateString() })] }))] }), result.cached && (jsxRuntimeExports.jsx("div", { className: "text-xs text-green-600 mt-2", children: "\u2139\uFE0F Cached result" }))] }))] })); } exports.AccessGuard = AccessGuard; exports.AccessKeyValidator = AccessKeyValidator; exports.AccessStatus = AccessStatus; exports.SoftlockClient = SoftlockClient; exports.getSoftlockClient = getSoftlockClient; exports.initSoftlock = initSoftlock; exports.useAccessGuard = useAccessGuard; exports.useAccessKey = useAccessKey; exports.useUserAccess = useUserAccess; exports.validateKey = validateKey; //# sourceMappingURL=client.js.map