@softlock/sdk
Version:
Official Softlock SDK for access key validation and management
1,197 lines (1,176 loc) • 48.8 kB
JavaScript
"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