Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@interval/sdk

Package Overview
Dependencies
Maintainers
3
Versions
54
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@interval/sdk - npm Package Compare versions

Comparing version 0.33.0 to 0.34.0

dist/classes/DataChannelConnection.d.ts

2

dist/classes/Action.d.ts

@@ -0,1 +1,2 @@

import { AccessControlDefinition } from '../internalRpcSchema';
import { ExplicitIntervalActionDefinition, IntervalActionDefinition, IntervalActionHandler } from '../types';

@@ -8,3 +9,4 @@ export default class Action implements ExplicitIntervalActionDefinition {

description?: string;
access?: AccessControlDefinition;
constructor(def: ExplicitIntervalActionDefinition | IntervalActionDefinition);
}

7

dist/classes/IntervalClient.d.ts
/// <reference types="node" />
import { AsyncLocalStorage } from 'async_hooks';
import { ActionEnvironment } from '../internalRpcSchema';
import type { IntervalActionStore, IntervalPageStore } from '../types';
import { Interval, InternalConfig } from '..';
import type { AsyncLocalStorage } from 'async_hooks';
declare let actionLocalStorage: AsyncLocalStorage<IntervalActionStore> | undefined;
declare let pageLocalStorage: AsyncLocalStorage<IntervalPageStore> | undefined;
export { actionLocalStorage, pageLocalStorage };
export declare const DEFAULT_WEBSOCKET_ENDPOINT = "wss://interval.com/websocket";
export declare function getHttpEndpoint(wsEndpoint: string): string;
export declare const sleep: (ms: number) => Promise<unknown>;
export declare const actionLocalStorage: AsyncLocalStorage<IntervalActionStore>;
export declare const pageLocalStorage: AsyncLocalStorage<IntervalPageStore>;
export default class IntervalClient {

@@ -12,0 +13,0 @@ #private;

@@ -39,5 +39,5 @@ "use strict";

};
var _IntervalClient_instances, _IntervalClient_interval, _IntervalClient_ghostOrgId, _IntervalClient_apiKey, _IntervalClient_endpoint, _IntervalClient_httpEndpoint, _IntervalClient_logger, _IntervalClient_retryIntervalMs, _IntervalClient_pingIntervalMs, _IntervalClient_closeUnresponsiveConnectionTimeoutMs, _IntervalClient_reinitializeBatchTimeoutMs, _IntervalClient_pingIntervalHandle, _IntervalClient_intentionallyClosed, _IntervalClient_config, _IntervalClient_actionDefinitions, _IntervalClient_pageDefinitions, _IntervalClient_actionHandlers, _IntervalClient_pageHandlers, _IntervalClient_walkRoutes, _IntervalClient_log_get, _IntervalClient_pageIOClients, _IntervalClient_ioResponseHandlers, _IntervalClient_pendingIOCalls, _IntervalClient_transactionLoadingStates, _IntervalClient_transactionCompleteCallbacks, _IntervalClient_ws, _IntervalClient_serverRpc, _IntervalClient_isConnected, _IntervalClient_isInitialized, _IntervalClient_reinitializeTimeout, _IntervalClient_resendPendingIOCalls, _IntervalClient_resendTransactionLoadingStates, _IntervalClient_findOrCreateGhostModeAccount, _IntervalClient_createSocketConnection, _IntervalClient_createRPCClient, _IntervalClient_initializeHost, _IntervalClient_send, _IntervalClient_sendLog, _IntervalClient_sendRedirect;
var _IntervalClient_instances, _IntervalClient_interval, _IntervalClient_apiKey, _IntervalClient_endpoint, _IntervalClient_httpEndpoint, _IntervalClient_logger, _IntervalClient_retryIntervalMs, _IntervalClient_pingIntervalMs, _IntervalClient_closeUnresponsiveConnectionTimeoutMs, _IntervalClient_reinitializeBatchTimeoutMs, _IntervalClient_pingIntervalHandle, _IntervalClient_intentionallyClosed, _IntervalClient_config, _IntervalClient_actionDefinitions, _IntervalClient_pageDefinitions, _IntervalClient_actionHandlers, _IntervalClient_pageHandlers, _IntervalClient_walkRoutes, _IntervalClient_log_get, _IntervalClient_pageIOClients, _IntervalClient_ioResponseHandlers, _IntervalClient_pendingIOCalls, _IntervalClient_transactionLoadingStates, _IntervalClient_transactionCompleteCallbacks, _IntervalClient_ws, _IntervalClient_serverRpc, _IntervalClient_isConnected, _IntervalClient_isInitialized, _IntervalClient_reinitializeTimeout, _IntervalClient_resendPendingIOCalls, _IntervalClient_resendTransactionLoadingStates, _IntervalClient_createSocketConnection, _IntervalClient_createRPCHandlers, _IntervalClient_createRPCClient, _IntervalClient_initializeHost, _IntervalClient_send, _IntervalClient_sendLog, _IntervalClient_sendRedirect;
Object.defineProperty(exports, "__esModule", { value: true });
exports.pageLocalStorage = exports.actionLocalStorage = exports.sleep = exports.getHttpEndpoint = exports.DEFAULT_WEBSOCKET_ENDPOINT = void 0;
exports.sleep = exports.getHttpEndpoint = exports.DEFAULT_WEBSOCKET_ENDPOINT = exports.pageLocalStorage = exports.actionLocalStorage = void 0;
const zod_1 = require("zod");

@@ -47,3 +47,2 @@ const uuid_1 = require("uuid");

const node_fetch_1 = __importDefault(require("node-fetch"));
const async_hooks_1 = require("async_hooks");
const superjson = __importStar(require("superjson"));

@@ -60,7 +59,22 @@ const ISocket_1 = __importStar(require("./ISocket"));

const TransactionLoadingState_1 = __importDefault(require("../classes/TransactionLoadingState"));
const localConfig_1 = __importDefault(require("../localConfig"));
const __1 = require("..");
const Page_1 = __importDefault(require("./Page"));
const Layout_1 = require("./Layout");
const fileActionLoader_1 = __importDefault(require("../utils/fileActionLoader"));
let actionLocalStorage;
exports.actionLocalStorage = actionLocalStorage;
let pageLocalStorage;
exports.pageLocalStorage = pageLocalStorage;
async function initAsyncLocalStorage() {
try {
if (typeof window === 'undefined') {
const { default: { AsyncLocalStorage }, } = await Promise.resolve().then(() => __importStar(require('async_hooks')));
exports.actionLocalStorage = actionLocalStorage = new AsyncLocalStorage();
exports.pageLocalStorage = pageLocalStorage = new AsyncLocalStorage();
}
}
catch (err) {
console.error('Failed initializing AsyncLocalStorage stores');
}
}
initAsyncLocalStorage();
exports.DEFAULT_WEBSOCKET_ENDPOINT = 'wss://interval.com/websocket';

@@ -77,4 +91,2 @@ function getHttpEndpoint(wsEndpoint) {

exports.sleep = sleep;
exports.actionLocalStorage = new async_hooks_1.AsyncLocalStorage();
exports.pageLocalStorage = new async_hooks_1.AsyncLocalStorage();
class IntervalClient {

@@ -84,3 +96,2 @@ constructor(interval, config) {

_IntervalClient_interval.set(this, void 0);
_IntervalClient_ghostOrgId.set(this, void 0);
_IntervalClient_apiKey.set(this, void 0);

@@ -133,2 +144,5 @@ _IntervalClient_endpoint.set(this, exports.DEFAULT_WEBSOCKET_ENDPOINT);

__classPrivateFieldSet(this, _IntervalClient_httpEndpoint, getHttpEndpoint(__classPrivateFieldGet(this, _IntervalClient_endpoint, "f")), "f");
if (config.setHostHandlers) {
config.setHostHandlers(__classPrivateFieldGet(this, _IntervalClient_instances, "m", _IntervalClient_createRPCHandlers).call(this));
}
}

@@ -150,4 +164,20 @@ get isConnected() {

async listen() {
await this.initializeConnection();
await __classPrivateFieldGet(this, _IntervalClient_instances, "m", _IntervalClient_initializeHost).call(this);
if (__classPrivateFieldGet(this, _IntervalClient_config, "f").setHostHandlers && __classPrivateFieldGet(this, _IntervalClient_config, "f").getClientHandlers) {
// in browser demo mode, we don't need to initialize the connection
this.organization = {
name: 'Demo Organization',
slug: 'demo',
};
this.environment = 'development';
await __classPrivateFieldGet(this, _IntervalClient_instances, "m", _IntervalClient_walkRoutes).call(this);
const isInitialInitialization = !__classPrivateFieldGet(this, _IntervalClient_isInitialized, "f");
__classPrivateFieldSet(this, _IntervalClient_isInitialized, true, "f");
if (isInitialInitialization) {
__classPrivateFieldGet(this, _IntervalClient_instances, "a", _IntervalClient_log_get).prod(`🔗 Connected! Access your actions within the demo dashboard nearby.`);
}
}
else {
await this.initializeConnection();
await __classPrivateFieldGet(this, _IntervalClient_instances, "m", _IntervalClient_initializeHost).call(this);
}
}

@@ -216,2 +246,7 @@ async initializeConnection() {

}
if (response.warnings.length) {
for (const warning of response.warnings) {
__classPrivateFieldGet(this, _IntervalClient_instances, "a", _IntervalClient_log_get).warn(warning);
}
}
if (response.invalidSlugs.length > 0) {

@@ -239,3 +274,3 @@ __classPrivateFieldGet(this, _IntervalClient_instances, "a", _IntervalClient_log_get).warn('[Interval]', '⚠ Invalid slugs detected:\n');

exports.default = IntervalClient;
_IntervalClient_interval = new WeakMap(), _IntervalClient_ghostOrgId = new WeakMap(), _IntervalClient_apiKey = new WeakMap(), _IntervalClient_endpoint = new WeakMap(), _IntervalClient_httpEndpoint = new WeakMap(), _IntervalClient_logger = new WeakMap(), _IntervalClient_retryIntervalMs = new WeakMap(), _IntervalClient_pingIntervalMs = new WeakMap(), _IntervalClient_closeUnresponsiveConnectionTimeoutMs = new WeakMap(), _IntervalClient_reinitializeBatchTimeoutMs = new WeakMap(), _IntervalClient_pingIntervalHandle = new WeakMap(), _IntervalClient_intentionallyClosed = new WeakMap(), _IntervalClient_config = new WeakMap(), _IntervalClient_actionDefinitions = new WeakMap(), _IntervalClient_pageDefinitions = new WeakMap(), _IntervalClient_actionHandlers = new WeakMap(), _IntervalClient_pageHandlers = new WeakMap(), _IntervalClient_pageIOClients = new WeakMap(), _IntervalClient_ioResponseHandlers = new WeakMap(), _IntervalClient_pendingIOCalls = new WeakMap(), _IntervalClient_transactionLoadingStates = new WeakMap(), _IntervalClient_transactionCompleteCallbacks = new WeakMap(), _IntervalClient_ws = new WeakMap(), _IntervalClient_serverRpc = new WeakMap(), _IntervalClient_isConnected = new WeakMap(), _IntervalClient_isInitialized = new WeakMap(), _IntervalClient_reinitializeTimeout = new WeakMap(), _IntervalClient_instances = new WeakSet(), _IntervalClient_walkRoutes = async function _IntervalClient_walkRoutes() {
_IntervalClient_interval = new WeakMap(), _IntervalClient_apiKey = new WeakMap(), _IntervalClient_endpoint = new WeakMap(), _IntervalClient_httpEndpoint = new WeakMap(), _IntervalClient_logger = new WeakMap(), _IntervalClient_retryIntervalMs = new WeakMap(), _IntervalClient_pingIntervalMs = new WeakMap(), _IntervalClient_closeUnresponsiveConnectionTimeoutMs = new WeakMap(), _IntervalClient_reinitializeBatchTimeoutMs = new WeakMap(), _IntervalClient_pingIntervalHandle = new WeakMap(), _IntervalClient_intentionallyClosed = new WeakMap(), _IntervalClient_config = new WeakMap(), _IntervalClient_actionDefinitions = new WeakMap(), _IntervalClient_pageDefinitions = new WeakMap(), _IntervalClient_actionHandlers = new WeakMap(), _IntervalClient_pageHandlers = new WeakMap(), _IntervalClient_pageIOClients = new WeakMap(), _IntervalClient_ioResponseHandlers = new WeakMap(), _IntervalClient_pendingIOCalls = new WeakMap(), _IntervalClient_transactionLoadingStates = new WeakMap(), _IntervalClient_transactionCompleteCallbacks = new WeakMap(), _IntervalClient_ws = new WeakMap(), _IntervalClient_serverRpc = new WeakMap(), _IntervalClient_isConnected = new WeakMap(), _IntervalClient_isInitialized = new WeakMap(), _IntervalClient_reinitializeTimeout = new WeakMap(), _IntervalClient_instances = new WeakSet(), _IntervalClient_walkRoutes = async function _IntervalClient_walkRoutes() {
const pageDefinitions = [];

@@ -252,2 +287,3 @@ const actionDefinitions = [];

unlisted: router.unlisted,
access: router.access,
});

@@ -273,5 +309,6 @@ if (router.handler) {

let fileSystemRoutes;
if (__classPrivateFieldGet(this, _IntervalClient_config, "f").routesDirectory) {
if (typeof window === 'undefined' && __classPrivateFieldGet(this, _IntervalClient_config, "f").routesDirectory) {
try {
fileSystemRoutes = await (0, fileActionLoader_1.default)(__classPrivateFieldGet(this, _IntervalClient_config, "f").routesDirectory, __classPrivateFieldGet(this, _IntervalClient_logger, "f"));
const { default: loadRoutesFromFileSystem } = await Promise.resolve().then(() => __importStar(require('../utils/fileActionLoader')));
fileSystemRoutes = await loadRoutesFromFileSystem(__classPrivateFieldGet(this, _IntervalClient_config, "f").routesDirectory, __classPrivateFieldGet(this, _IntervalClient_logger, "f"));
}

@@ -384,24 +421,2 @@ catch (err) {

}
}, _IntervalClient_findOrCreateGhostModeAccount = async function _IntervalClient_findOrCreateGhostModeAccount() {
let config = await localConfig_1.default.get();
let ghostOrgId = config === null || config === void 0 ? void 0 : config.ghostOrgId;
if (!ghostOrgId) {
const response = await (0, node_fetch_1.default)(__classPrivateFieldGet(this, _IntervalClient_httpEndpoint, "f") + '/api/auth/ghost/create', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
})
.then(r => r.json())
.then(r => internalRpcSchema_1.CREATE_GHOST_MODE_ACCOUNT.returns.parseAsync(r))
.catch(err => {
__classPrivateFieldGet(this, _IntervalClient_instances, "a", _IntervalClient_log_get).debug(err);
throw new __1.IntervalError('Received invalid API response.');
});
await localConfig_1.default.write({
ghostOrgId: response.ghostOrgId,
});
ghostOrgId = response.ghostOrgId;
}
return ghostOrgId;
}, _IntervalClient_createSocketConnection =

@@ -418,12 +433,2 @@ /**

}
else if (!__classPrivateFieldGet(this, _IntervalClient_apiKey, "f")) {
try {
__classPrivateFieldSet(this, _IntervalClient_ghostOrgId, await __classPrivateFieldGet(this, _IntervalClient_instances, "m", _IntervalClient_findOrCreateGhostModeAccount).call(this), "f");
headers['x-ghost-org-id'] = __classPrivateFieldGet(this, _IntervalClient_ghostOrgId, "f");
}
catch (err) {
__classPrivateFieldGet(this, _IntervalClient_instances, "a", _IntervalClient_log_get).debug('Failed creating ghost mode account:', err);
// User-facing error will be shown when trying to connect below
}
}
const ws = new ISocket_1.default(new ws_1.WebSocket(__classPrivateFieldGet(this, _IntervalClient_endpoint, "f"), {

@@ -502,78 +507,285 @@ headers,

await __classPrivateFieldGet(this, _IntervalClient_instances, "m", _IntervalClient_initializeHost).call(this);
}, _IntervalClient_createRPCClient = function _IntervalClient_createRPCClient(requestId) {
if (!__classPrivateFieldGet(this, _IntervalClient_ws, "f")) {
throw new Error('ISocket not initialized');
}
const serverRpc = new DuplexRPCClient_1.DuplexRPCClient({
communicator: __classPrivateFieldGet(this, _IntervalClient_ws, "f"),
canCall: internalRpcSchema_1.wsServerSchema,
canRespondTo: internalRpcSchema_1.hostSchema,
handlers: {
OPEN_PAGE: async (inputs) => {
if (!this.organization) {
__classPrivateFieldGet(this, _IntervalClient_instances, "a", _IntervalClient_log_get).error('No organization defined');
return { type: 'ERROR' };
}, _IntervalClient_createRPCHandlers = function _IntervalClient_createRPCHandlers(requestId) {
const intervalClient = this;
return {
START_TRANSACTION: async (inputs) => {
if (!intervalClient.organization) {
__classPrivateFieldGet(intervalClient, _IntervalClient_instances, "a", _IntervalClient_log_get).error('No organization defined');
return;
}
const { action, transactionId } = inputs;
const actionHandler = __classPrivateFieldGet(intervalClient, _IntervalClient_actionHandlers, "f").get(action.slug);
__classPrivateFieldGet(intervalClient, _IntervalClient_instances, "a", _IntervalClient_log_get).debug(actionHandler);
if (!actionHandler) {
__classPrivateFieldGet(intervalClient, _IntervalClient_instances, "a", _IntervalClient_log_get).debug('No actionHandler called', action.slug);
return;
}
const client = new IOClient_1.IOClient({
logger: __classPrivateFieldGet(intervalClient, _IntervalClient_logger, "f"),
send: async (ioRenderInstruction) => {
var _a;
const ioCall = JSON.stringify(ioRenderInstruction);
__classPrivateFieldGet(intervalClient, _IntervalClient_pendingIOCalls, "f").set(transactionId, ioCall);
if (__classPrivateFieldGet(this, _IntervalClient_config, "f").getClientHandlers) {
await ((_a = __classPrivateFieldGet(this, _IntervalClient_config, "f").getClientHandlers()) === null || _a === void 0 ? void 0 : _a.RENDER({
transactionId,
toRender: ioCall,
}));
}
else {
await __classPrivateFieldGet(intervalClient, _IntervalClient_instances, "m", _IntervalClient_send).call(intervalClient, 'SEND_IO_CALL', {
transactionId,
ioCall,
});
}
__classPrivateFieldGet(intervalClient, _IntervalClient_transactionLoadingStates, "f").delete(transactionId);
},
isDemo: !!__classPrivateFieldGet(this, _IntervalClient_config, "f").getClientHandlers,
// onAddInlineAction: handler => {
// const key = v4()
// intervalClient.#actionHandlers.set(key, handler)
// return key
// },
});
__classPrivateFieldGet(intervalClient, _IntervalClient_ioResponseHandlers, "f").set(transactionId, client.onResponse.bind(client));
// To maintain consistent ordering for logs despite network race conditions
let logIndex = 0;
let { params, paramsMeta } = inputs;
if (params && paramsMeta) {
params = superjson.deserialize({
json: params,
meta: paramsMeta,
});
}
const ctx = {
user: inputs.user,
// TODO: Remove intervalClient when all active SDKs support superjson
params: (0, deserialize_1.deserializeDates)(params),
environment: inputs.environment,
organization: intervalClient.organization,
action,
log: (...args) => __classPrivateFieldGet(intervalClient, _IntervalClient_instances, "m", _IntervalClient_sendLog).call(intervalClient, transactionId, logIndex++, ...args),
notify: async (config) => {
await __classPrivateFieldGet(intervalClient, _IntervalClient_interval, "f").notify({
...config,
transactionId: inputs.transactionId,
});
},
loading: new TransactionLoadingState_1.default({
logger: __classPrivateFieldGet(intervalClient, _IntervalClient_logger, "f"),
send: async (loadingState) => {
var _a;
__classPrivateFieldGet(intervalClient, _IntervalClient_transactionLoadingStates, "f").set(transactionId, loadingState);
if (__classPrivateFieldGet(this, _IntervalClient_config, "f").getClientHandlers) {
await ((_a = __classPrivateFieldGet(this, _IntervalClient_config, "f").getClientHandlers()) === null || _a === void 0 ? void 0 : _a.LOADING_STATE({
transactionId,
...loadingState,
}));
}
else {
await __classPrivateFieldGet(intervalClient, _IntervalClient_instances, "m", _IntervalClient_send).call(intervalClient, 'SEND_LOADING_CALL', {
transactionId,
...loadingState,
});
}
},
}),
redirect: (props) => __classPrivateFieldGet(intervalClient, _IntervalClient_instances, "m", _IntervalClient_sendRedirect).call(intervalClient, transactionId, props),
};
const { io } = client;
const handleAction = () => {
actionHandler(client.io, ctx)
.then(res => {
// Allow actions to return data even after being canceled
var _a;
const { json, meta } = superjson.serialize(res);
const result = {
schemaVersion: internalRpcSchema_1.TRANSACTION_RESULT_SCHEMA_VERSION,
status: 'SUCCESS',
data: (_a = json) !== null && _a !== void 0 ? _a : null,
meta,
};
return result;
})
.catch(err => {
// Action did not catch the cancellation error
if (err instanceof IOError_1.default && err.kind === 'CANCELED')
throw err;
__classPrivateFieldGet(intervalClient, _IntervalClient_logger, "f").error(err);
const result = {
schemaVersion: internalRpcSchema_1.TRANSACTION_RESULT_SCHEMA_VERSION,
status: 'FAILURE',
data: err.message
? { error: err.name, message: err.message }
: null,
};
return result;
})
.then(async (res) => {
var _a;
if (__classPrivateFieldGet(this, _IntervalClient_config, "f").getClientHandlers) {
(_a = __classPrivateFieldGet(this, _IntervalClient_config, "f").getClientHandlers()) === null || _a === void 0 ? void 0 : _a.TRANSACTION_COMPLETED({
transactionId,
resultStatus: res.status,
result: JSON.stringify(res),
});
}
else {
await __classPrivateFieldGet(intervalClient, _IntervalClient_instances, "m", _IntervalClient_send).call(intervalClient, 'MARK_TRANSACTION_COMPLETE', {
transactionId,
result: JSON.stringify(res),
});
}
if (requestId) {
const callbacks = __classPrivateFieldGet(intervalClient, _IntervalClient_transactionCompleteCallbacks, "f").get(requestId);
if (callbacks) {
const [resolve] = callbacks;
resolve();
}
else {
__classPrivateFieldGet(intervalClient, _IntervalClient_instances, "a", _IntervalClient_log_get).debug('No transaction complete callbacks found for requestId', requestId);
}
}
})
.catch(err => {
if (err instanceof IOError_1.default) {
switch (err.kind) {
case 'CANCELED':
__classPrivateFieldGet(intervalClient, _IntervalClient_instances, "a", _IntervalClient_log_get).prod('Transaction canceled for action', action.slug);
break;
case 'TRANSACTION_CLOSED':
__classPrivateFieldGet(intervalClient, _IntervalClient_instances, "a", _IntervalClient_log_get).prod('Attempted to make IO call after transaction already closed in action', action.slug);
break;
}
}
else {
__classPrivateFieldGet(intervalClient, _IntervalClient_instances, "a", _IntervalClient_log_get).error('Error sending action response', err);
}
if (requestId) {
const callbacks = __classPrivateFieldGet(intervalClient, _IntervalClient_transactionCompleteCallbacks, "f").get(requestId);
if (callbacks) {
const [_, reject] = callbacks;
reject(err);
}
else {
__classPrivateFieldGet(intervalClient, _IntervalClient_instances, "a", _IntervalClient_log_get).debug('No transaction complete callbacks found for requestId', requestId);
}
}
})
.finally(() => {
__classPrivateFieldGet(intervalClient, _IntervalClient_pendingIOCalls, "f").delete(transactionId);
__classPrivateFieldGet(intervalClient, _IntervalClient_transactionLoadingStates, "f").delete(transactionId);
__classPrivateFieldGet(intervalClient, _IntervalClient_ioResponseHandlers, "f").delete(transactionId);
for (const key of client.inlineActionKeys.values()) {
__classPrivateFieldGet(intervalClient, _IntervalClient_actionHandlers, "f").delete(key);
}
});
};
if (actionLocalStorage) {
actionLocalStorage.run({ io, ctx }, () => {
handleAction();
});
}
else {
handleAction();
}
return;
},
IO_RESPONSE: async (inputs) => {
__classPrivateFieldGet(this, _IntervalClient_instances, "a", _IntervalClient_log_get).debug('got io response', inputs);
try {
const ioResp = ioSchema_1.IO_RESPONSE.parse(JSON.parse(inputs.value));
const replyHandler = __classPrivateFieldGet(this, _IntervalClient_ioResponseHandlers, "f").get(ioResp.transactionId);
if (!replyHandler) {
__classPrivateFieldGet(this, _IntervalClient_instances, "a", _IntervalClient_log_get).debug('Missing reply handler for', inputs.transactionId);
return;
}
const { pageKey } = inputs;
const pageHandler = __classPrivateFieldGet(this, _IntervalClient_pageHandlers, "f").get(inputs.page.slug);
if (!pageHandler) {
__classPrivateFieldGet(this, _IntervalClient_instances, "a", _IntervalClient_log_get).debug('No app handler called', inputs.page.slug);
return { type: 'ERROR' };
replyHandler(ioResp);
}
catch (err) {
if (err instanceof zod_1.ZodError) {
__classPrivateFieldGet(this, _IntervalClient_instances, "a", _IntervalClient_log_get).error('Received invalid IO response:', inputs);
__classPrivateFieldGet(this, _IntervalClient_instances, "a", _IntervalClient_log_get).debug(err);
}
let { params, paramsMeta } = inputs;
if (params && paramsMeta) {
params = superjson.deserialize({
json: params,
meta: paramsMeta,
});
else {
__classPrivateFieldGet(this, _IntervalClient_instances, "a", _IntervalClient_log_get).error('Failed handling IO response:', err);
}
const ctx = {
user: inputs.user,
params: (0, deserialize_1.deserializeDates)(params),
environment: inputs.environment,
organization: this.organization,
page: inputs.page,
};
let page;
let menuItems = undefined;
let renderInstruction = undefined;
let errors = [];
const MAX_PAGE_RETRIES = 5;
const sendPage = async () => {
if (page instanceof Layout_1.Basic) {
const pageLayout = {
kind: 'BASIC',
title: page.title === undefined
? undefined
: typeof page.title === 'string'
? page.title
: null,
description: page.description === undefined
? undefined
: typeof page.description === 'string'
? page.description
: null,
menuItems,
children: renderInstruction,
errors,
};
if (page.metadata) {
const items = [];
for (const pageItem of page.metadata) {
let { label, value, error, ...rest } = pageItem;
if (typeof value === 'function' || value instanceof Promise) {
items.push({ ...rest, label });
}
else {
items.push({ ...rest, label, value, error });
}
}
},
OPEN_PAGE: async (inputs) => {
if (!this.organization) {
__classPrivateFieldGet(this, _IntervalClient_instances, "a", _IntervalClient_log_get).error('No organization defined');
return { type: 'ERROR' };
}
const { pageKey } = inputs;
const pageHandler = __classPrivateFieldGet(this, _IntervalClient_pageHandlers, "f").get(inputs.page.slug);
if (!pageHandler) {
__classPrivateFieldGet(this, _IntervalClient_instances, "a", _IntervalClient_log_get).debug('No app handler called', inputs.page.slug);
return { type: 'ERROR' };
}
let { params, paramsMeta } = inputs;
if (params && paramsMeta) {
params = superjson.deserialize({
json: params,
meta: paramsMeta,
});
}
const ctx = {
user: inputs.user,
params: (0, deserialize_1.deserializeDates)(params),
environment: inputs.environment,
organization: this.organization,
page: inputs.page,
};
let page;
let menuItems = undefined;
let renderInstruction = undefined;
let errors = [];
const MAX_PAGE_RETRIES = 5;
const sendPage = async () => {
var _a;
if (page instanceof Layout_1.Basic) {
const pageLayout = {
kind: 'BASIC',
title: page.title === undefined
? undefined
: typeof page.title === 'string'
? page.title
: null,
description: page.description === undefined
? undefined
: typeof page.description === 'string'
? page.description
: null,
menuItems,
children: renderInstruction,
errors,
};
if (page.metadata) {
const items = [];
for (const pageItem of page.metadata) {
let { label, value, error } = pageItem;
if (typeof value === 'function' || value instanceof Promise) {
items.push({ label });
}
const { json, meta } = superjson.serialize(items);
if (json) {
pageLayout.metadata = {
json: json,
meta,
};
else {
items.push({ label, value, error });
}
}
const { json, meta } = superjson.serialize(items);
if (json) {
pageLayout.metadata = {
json: json,
meta,
};
}
}
if (__classPrivateFieldGet(this, _IntervalClient_config, "f").getClientHandlers) {
await ((_a = __classPrivateFieldGet(this, _IntervalClient_config, "f").getClientHandlers()) === null || _a === void 0 ? void 0 : _a.RENDER_PAGE({
pageKey,
page: JSON.stringify(pageLayout),
hostInstanceId: 'demo',
}));
}
else {
for (let i = 0; i < MAX_PAGE_RETRIES; i++) {

@@ -595,83 +807,107 @@ try {

}
};
// What follows is a pretty convoluted way to coalesce
// `scheduleSendPage` calls into non-clobbering/overlapping
// `sendPage `calls. This can probably be simplified but I
// can't think of a better way at the moment.
// Tracks whether a send is currently in progress
let sendPagePromise = null;
// Keeps track of a brief timeout to coalesce rapid send calls
let pageSendTimeout = null;
// Tracks whether a new send needs to happen after the current one
let newPageScheduled = false;
const processSendPage = () => {
newPageScheduled = false;
pageSendTimeout = null;
sendPagePromise = sendPage()
.catch(err => {
__classPrivateFieldGet(this, _IntervalClient_logger, "f").error(`Failed sending page with key ${pageKey}`, err);
})
.finally(() => {
sendPagePromise = null;
if (newPageScheduled) {
scheduleSendPage();
}
});
};
const scheduleSendPage = () => {
newPageScheduled = true;
if (sendPagePromise)
return;
if (pageSendTimeout)
return;
pageSendTimeout = setTimeout(processSendPage, 0);
};
const client = new IOClient_1.IOClient({
logger: __classPrivateFieldGet(this, _IntervalClient_logger, "f"),
send: async (instruction) => {
renderInstruction = instruction;
}
};
// What follows is a pretty convoluted way to coalesce
// `scheduleSendPage` calls into non-clobbering/overlapping
// `sendPage `calls. This can probably be simplified but I
// can't think of a better way at the moment.
// Tracks whether a send is currently in progress
let sendPagePromise = null;
// Keeps track of a brief timeout to coalesce rapid send calls
let pageSendTimeout = null;
// Tracks whether a new send needs to happen after the current one
let newPageScheduled = false;
const processSendPage = () => {
newPageScheduled = false;
pageSendTimeout = null;
sendPagePromise = sendPage()
.catch(err => {
__classPrivateFieldGet(this, _IntervalClient_logger, "f").error(`Failed sending page with key ${pageKey}`, err);
})
.finally(() => {
sendPagePromise = null;
if (newPageScheduled) {
scheduleSendPage();
},
// onAddInlineAction: () => {
// const key = v4()
// this.#actionHandlers.set(key, handler)
// return key
// },
}
});
const { io: { group, display }, } = client;
__classPrivateFieldGet(this, _IntervalClient_pageIOClients, "f").set(pageKey, client);
__classPrivateFieldGet(this, _IntervalClient_ioResponseHandlers, "f").set(pageKey, client.onResponse.bind(client));
const pageError = (error, layoutKey) => {
if (error instanceof Error) {
return {
layoutKey,
error: error.name,
message: error.message,
};
};
const scheduleSendPage = () => {
newPageScheduled = true;
if (sendPagePromise)
return;
if (pageSendTimeout)
return;
pageSendTimeout = setTimeout(processSendPage, 0);
};
const client = new IOClient_1.IOClient({
logger: __classPrivateFieldGet(this, _IntervalClient_logger, "f"),
send: async (instruction) => {
renderInstruction = instruction;
scheduleSendPage();
},
isDemo: !!__classPrivateFieldGet(this, _IntervalClient_config, "f").getClientHandlers,
// onAddInlineAction: () => {
// const key = v4()
// this.#actionHandlers.set(key, handler)
// return key
// },
});
const { io: { group, display }, } = client;
__classPrivateFieldGet(this, _IntervalClient_pageIOClients, "f").set(pageKey, client);
__classPrivateFieldGet(this, _IntervalClient_ioResponseHandlers, "f").set(pageKey, client.onResponse.bind(client));
const pageError = (error, layoutKey) => {
if (error instanceof Error) {
return {
layoutKey,
error: error.name,
message: error.message,
};
}
else {
return {
layoutKey,
error: 'Unknown error',
message: String(error),
};
}
};
const handlePage = () => {
pageHandler(display, ctx)
.then(res => {
page = res;
if (typeof page.title === 'function') {
try {
page.title = page.title();
}
catch (err) {
__classPrivateFieldGet(this, _IntervalClient_logger, "f").error(err);
errors.push(pageError(err, 'title'));
}
}
else {
return {
layoutKey,
error: 'Unknown error',
message: String(error),
};
if (page.title instanceof Promise) {
page.title
.then(title => {
page.title = title;
scheduleSendPage();
})
.catch(err => {
__classPrivateFieldGet(this, _IntervalClient_logger, "f").error(err);
errors.push(pageError(err, 'title'));
scheduleSendPage();
});
}
};
exports.pageLocalStorage.run({ display, ctx }, () => {
pageHandler(display, ctx)
.then(res => {
page = res;
if (typeof page.title === 'function') {
if (page.description) {
if (typeof page.description === 'function') {
try {
page.title = page.title();
page.description = page.description();
}
catch (err) {
__classPrivateFieldGet(this, _IntervalClient_logger, "f").error(err);
errors.push(pageError(err, 'title'));
errors.push(pageError(err, 'description'));
}
}
if (page.title instanceof Promise) {
page.title
.then(title => {
page.title = title;
if (page.description instanceof Promise) {
page.description
.then(description => {
page.description = description;
scheduleSendPage();

@@ -681,286 +917,114 @@ })

__classPrivateFieldGet(this, _IntervalClient_logger, "f").error(err);
errors.push(pageError(err, 'title'));
errors.push(pageError(err, 'description'));
scheduleSendPage();
});
}
if (page.description) {
if (typeof page.description === 'function') {
try {
page.description = page.description();
}
catch (err) {
__classPrivateFieldGet(this, _IntervalClient_logger, "f").error(err);
errors.push(pageError(err, 'description'));
}
}
if (page.description instanceof Promise) {
page.description
.then(description => {
page.description = description;
scheduleSendPage();
})
.catch(err => {
__classPrivateFieldGet(this, _IntervalClient_logger, "f").error(err);
errors.push(pageError(err, 'description'));
scheduleSendPage();
});
}
}
if (page.menuItems) {
menuItems = page.menuItems.map(menuItem => {
// if (
// 'action' in menuItem &&
// typeof menuItem['action'] === 'function'
// ) {
// const inlineAction = client.addInlineAction(menuItem.action)
// return {
// ...menuItem,
// inlineAction,
// }
// }
return menuItem;
});
}
if (page instanceof Layout_1.Basic) {
const { metadata } = page;
if (metadata) {
for (let i = 0; i < metadata.length; i++) {
let { value } = metadata[i];
if (typeof value === 'function') {
try {
value = value();
metadata[i].value = value;
}
catch (err) {
__classPrivateFieldGet(this, _IntervalClient_logger, "f").error(err);
const error = pageError(err, 'metadata');
errors.push(error);
metadata[i].value = null;
metadata[i].error = error.message;
}
}
if (page.menuItems) {
menuItems = page.menuItems.map(menuItem => {
// if (
// 'action' in menuItem &&
// typeof menuItem['action'] === 'function'
// ) {
// const inlineAction = client.addInlineAction(menuItem.action)
// return {
// ...menuItem,
// inlineAction,
// }
// }
return menuItem;
});
}
if (page instanceof Layout_1.Basic) {
const { metadata } = page;
if (metadata) {
for (let i = 0; i < metadata.length; i++) {
let { value } = metadata[i];
if (typeof value === 'function') {
try {
value = value();
metadata[i].value = value;
}
if (value instanceof Promise) {
value
.then(resolved => {
metadata[i].value = resolved;
scheduleSendPage();
})
.catch(err => {
__classPrivateFieldGet(this, _IntervalClient_logger, "f").error(err);
const error = pageError(err, 'metadata');
errors.push(error);
metadata[i].value = null;
metadata[i].error = error.message;
scheduleSendPage();
});
catch (err) {
__classPrivateFieldGet(this, _IntervalClient_logger, "f").error(err);
const error = pageError(err, 'metadata');
errors.push(error);
metadata[i].value = null;
metadata[i].error = error.message;
}
}
if (value instanceof Promise) {
value
.then(resolved => {
metadata[i].value = resolved;
scheduleSendPage();
})
.catch(err => {
__classPrivateFieldGet(this, _IntervalClient_logger, "f").error(err);
const error = pageError(err, 'metadata');
errors.push(error);
metadata[i].value = null;
metadata[i].error = error.message;
scheduleSendPage();
});
}
}
}
if (page.children) {
group(page.children).then(() => {
__classPrivateFieldGet(this, _IntervalClient_logger, "f").debug('Initial children render complete for pageKey', pageKey);
});
}
else {
scheduleSendPage();
}
})
.catch(async (err) => {
__classPrivateFieldGet(this, _IntervalClient_logger, "f").error(err);
errors.push(pageError(err));
const pageLayout = {
kind: 'BASIC',
errors,
};
await __classPrivateFieldGet(this, _IntervalClient_instances, "m", _IntervalClient_send).call(this, 'SEND_PAGE', {
pageKey,
page: JSON.stringify(pageLayout),
});
});
});
return {
type: 'SUCCESS',
pageKey,
};
},
CLOSE_PAGE: async (inputs) => {
const client = __classPrivateFieldGet(this, _IntervalClient_pageIOClients, "f").get(inputs.pageKey);
if (client) {
for (const key of client.inlineActionKeys.values()) {
__classPrivateFieldGet(this, _IntervalClient_actionHandlers, "f").delete(key);
}
client.inlineActionKeys.clear();
__classPrivateFieldGet(this, _IntervalClient_pageIOClients, "f").delete(inputs.pageKey);
}
__classPrivateFieldGet(this, _IntervalClient_ioResponseHandlers, "f").delete(inputs.pageKey);
},
START_TRANSACTION: async (inputs) => {
if (!this.organization) {
__classPrivateFieldGet(this, _IntervalClient_instances, "a", _IntervalClient_log_get).error('No organization defined');
return;
}
const { action, transactionId } = inputs;
const actionHandler = __classPrivateFieldGet(this, _IntervalClient_actionHandlers, "f").get(action.slug);
__classPrivateFieldGet(this, _IntervalClient_instances, "a", _IntervalClient_log_get).debug(actionHandler);
if (!actionHandler) {
__classPrivateFieldGet(this, _IntervalClient_instances, "a", _IntervalClient_log_get).debug('No actionHandler called', action.slug);
return;
}
const client = new IOClient_1.IOClient({
logger: __classPrivateFieldGet(this, _IntervalClient_logger, "f"),
send: async (ioRenderInstruction) => {
const ioCall = JSON.stringify(ioRenderInstruction);
__classPrivateFieldGet(this, _IntervalClient_pendingIOCalls, "f").set(transactionId, ioCall);
await __classPrivateFieldGet(this, _IntervalClient_instances, "m", _IntervalClient_send).call(this, 'SEND_IO_CALL', {
transactionId,
ioCall,
if (page.children) {
group(page.children).then(() => {
__classPrivateFieldGet(this, _IntervalClient_logger, "f").debug('Initial children render complete for pageKey', pageKey);
});
__classPrivateFieldGet(this, _IntervalClient_transactionLoadingStates, "f").delete(transactionId);
},
// onAddInlineAction: handler => {
// const key = v4()
// this.#actionHandlers.set(key, handler)
// return key
// },
});
__classPrivateFieldGet(this, _IntervalClient_ioResponseHandlers, "f").set(transactionId, client.onResponse.bind(client));
// To maintain consistent ordering for logs despite network race conditions
let logIndex = 0;
let { params, paramsMeta } = inputs;
if (params && paramsMeta) {
params = superjson.deserialize({
json: params,
meta: paramsMeta,
});
}
const ctx = {
user: inputs.user,
// TODO: Remove this when all active SDKs support superjson
params: (0, deserialize_1.deserializeDates)(params),
environment: inputs.environment,
organization: this.organization,
action,
log: (...args) => __classPrivateFieldGet(this, _IntervalClient_instances, "m", _IntervalClient_sendLog).call(this, transactionId, logIndex++, ...args),
notify: async (config) => {
await __classPrivateFieldGet(this, _IntervalClient_interval, "f").notify({
...config,
transactionId: inputs.transactionId,
});
},
loading: new TransactionLoadingState_1.default({
logger: __classPrivateFieldGet(this, _IntervalClient_logger, "f"),
send: async (loadingState) => {
__classPrivateFieldGet(this, _IntervalClient_transactionLoadingStates, "f").set(transactionId, loadingState);
await __classPrivateFieldGet(this, _IntervalClient_instances, "m", _IntervalClient_send).call(this, 'SEND_LOADING_CALL', {
transactionId,
...loadingState,
});
},
}),
redirect: (props) => __classPrivateFieldGet(this, _IntervalClient_instances, "m", _IntervalClient_sendRedirect).call(this, transactionId, props),
};
const { io } = client;
exports.actionLocalStorage.run({ io, ctx }, () => {
actionHandler(client.io, ctx)
.then(res => {
// Allow actions to return data even after being canceled
var _a;
const { json, meta } = superjson.serialize(res);
const result = {
schemaVersion: internalRpcSchema_1.TRANSACTION_RESULT_SCHEMA_VERSION,
status: 'SUCCESS',
data: (_a = json) !== null && _a !== void 0 ? _a : null,
meta,
};
return result;
})
.catch(err => {
// Action did not catch the cancellation error
if (err instanceof IOError_1.default && err.kind === 'CANCELED')
throw err;
__classPrivateFieldGet(this, _IntervalClient_logger, "f").error(err);
const result = {
schemaVersion: internalRpcSchema_1.TRANSACTION_RESULT_SCHEMA_VERSION,
status: 'FAILURE',
data: err.message
? { error: err.name, message: err.message }
: null,
};
return result;
})
.then(async (res) => {
await __classPrivateFieldGet(this, _IntervalClient_instances, "m", _IntervalClient_send).call(this, 'MARK_TRANSACTION_COMPLETE', {
transactionId,
result: JSON.stringify(res),
});
if (requestId) {
const callbacks = __classPrivateFieldGet(this, _IntervalClient_transactionCompleteCallbacks, "f").get(requestId);
if (callbacks) {
const [resolve] = callbacks;
resolve();
}
else {
__classPrivateFieldGet(this, _IntervalClient_instances, "a", _IntervalClient_log_get).debug('No transaction complete callbacks found for requestId', requestId);
}
}
})
.catch(err => {
if (err instanceof IOError_1.default) {
switch (err.kind) {
case 'CANCELED':
__classPrivateFieldGet(this, _IntervalClient_instances, "a", _IntervalClient_log_get).prod('Transaction canceled for action', action.slug);
break;
case 'TRANSACTION_CLOSED':
__classPrivateFieldGet(this, _IntervalClient_instances, "a", _IntervalClient_log_get).prod('Attempted to make IO call after transaction already closed in action', action.slug);
break;
}
}
else {
__classPrivateFieldGet(this, _IntervalClient_instances, "a", _IntervalClient_log_get).error('Error sending action response', err);
}
if (requestId) {
const callbacks = __classPrivateFieldGet(this, _IntervalClient_transactionCompleteCallbacks, "f").get(requestId);
if (callbacks) {
const [_, reject] = callbacks;
reject(err);
}
else {
__classPrivateFieldGet(this, _IntervalClient_instances, "a", _IntervalClient_log_get).debug('No transaction complete callbacks found for requestId', requestId);
}
}
})
.finally(() => {
__classPrivateFieldGet(this, _IntervalClient_pendingIOCalls, "f").delete(transactionId);
__classPrivateFieldGet(this, _IntervalClient_transactionLoadingStates, "f").delete(transactionId);
__classPrivateFieldGet(this, _IntervalClient_ioResponseHandlers, "f").delete(transactionId);
for (const key of client.inlineActionKeys.values()) {
__classPrivateFieldGet(this, _IntervalClient_actionHandlers, "f").delete(key);
}
});
});
return;
},
IO_RESPONSE: async (inputs) => {
__classPrivateFieldGet(this, _IntervalClient_instances, "a", _IntervalClient_log_get).debug('got io response', inputs);
try {
const ioResp = ioSchema_1.IO_RESPONSE.parse(JSON.parse(inputs.value));
const replyHandler = __classPrivateFieldGet(this, _IntervalClient_ioResponseHandlers, "f").get(ioResp.transactionId);
if (!replyHandler) {
__classPrivateFieldGet(this, _IntervalClient_instances, "a", _IntervalClient_log_get).debug('Missing reply handler for', inputs.transactionId);
return;
}
replyHandler(ioResp);
}
catch (err) {
if (err instanceof zod_1.ZodError) {
__classPrivateFieldGet(this, _IntervalClient_instances, "a", _IntervalClient_log_get).error('Received invalid IO response:', inputs);
__classPrivateFieldGet(this, _IntervalClient_instances, "a", _IntervalClient_log_get).debug(err);
}
else {
__classPrivateFieldGet(this, _IntervalClient_instances, "a", _IntervalClient_log_get).error('Failed handling IO response:', err);
scheduleSendPage();
}
})
.catch(async (err) => {
__classPrivateFieldGet(this, _IntervalClient_logger, "f").error(err);
errors.push(pageError(err));
const pageLayout = {
kind: 'BASIC',
errors,
};
await __classPrivateFieldGet(this, _IntervalClient_instances, "m", _IntervalClient_send).call(this, 'SEND_PAGE', {
pageKey,
page: JSON.stringify(pageLayout),
});
});
};
if (pageLocalStorage) {
pageLocalStorage.run({ display, ctx }, () => {
handlePage();
});
}
else {
handlePage();
}
return {
type: 'SUCCESS',
pageKey,
};
},
CLOSE_PAGE: async (inputs) => {
const client = __classPrivateFieldGet(this, _IntervalClient_pageIOClients, "f").get(inputs.pageKey);
if (client) {
for (const key of client.inlineActionKeys.values()) {
__classPrivateFieldGet(this, _IntervalClient_actionHandlers, "f").delete(key);
}
},
client.inlineActionKeys.clear();
__classPrivateFieldGet(this, _IntervalClient_pageIOClients, "f").delete(inputs.pageKey);
}
__classPrivateFieldGet(this, _IntervalClient_ioResponseHandlers, "f").delete(inputs.pageKey);
},
};
}, _IntervalClient_createRPCClient = function _IntervalClient_createRPCClient(requestId) {
if (!__classPrivateFieldGet(this, _IntervalClient_ws, "f")) {
throw new Error('ISocket not initialized');
}
const serverRpc = new DuplexRPCClient_1.DuplexRPCClient({
communicator: __classPrivateFieldGet(this, _IntervalClient_ws, "f"),
canCall: internalRpcSchema_1.wsServerSchema,
canRespondTo: internalRpcSchema_1.hostSchema,
handlers: __classPrivateFieldGet(this, _IntervalClient_instances, "m", _IntervalClient_createRPCHandlers).call(this, requestId),
});

@@ -1008,2 +1072,7 @@ __classPrivateFieldSet(this, _IntervalClient_serverRpc, serverRpc, "f");

}
if (response.warnings.length) {
for (const warning of response.warnings) {
__classPrivateFieldGet(this, _IntervalClient_instances, "a", _IntervalClient_log_get).warn(warning);
}
}
this.organization = response.organization;

@@ -1036,2 +1105,3 @@ this.environment = response.environment;

}, _IntervalClient_sendLog = async function _IntervalClient_sendLog(transactionId, index, ...args) {
var _a;
if (!args.length)

@@ -1054,11 +1124,24 @@ return;

}
await __classPrivateFieldGet(this, _IntervalClient_instances, "m", _IntervalClient_send).call(this, 'SEND_LOG', {
transactionId,
data,
index,
timestamp: new Date().valueOf(),
}).catch(err => {
__classPrivateFieldGet(this, _IntervalClient_logger, "f").error('Failed sending log to Interval', err);
});
if (__classPrivateFieldGet(this, _IntervalClient_config, "f").getClientHandlers) {
await ((_a = __classPrivateFieldGet(this, _IntervalClient_config, "f").getClientHandlers()) === null || _a === void 0 ? void 0 : _a.LOG({
transactionId,
data,
timestamp: new Date().valueOf(),
index,
}));
}
else {
await __classPrivateFieldGet(this, _IntervalClient_instances, "m", _IntervalClient_send).call(this, 'SEND_LOG', {
transactionId,
data,
index,
timestamp: new Date().valueOf(),
}).catch(err => {
__classPrivateFieldGet(this, _IntervalClient_logger, "f").error('Failed sending log to Interval', err);
});
}
}, _IntervalClient_sendRedirect = async function _IntervalClient_sendRedirect(transactionId, props) {
if (__classPrivateFieldGet(this, _IntervalClient_config, "f").getClientHandlers) {
throw new __1.IntervalError(`The ctx.redirect method isn't supported in demo mode`);
}
const response = await __classPrivateFieldGet(this, _IntervalClient_instances, "m", _IntervalClient_send).call(this, 'SEND_REDIRECT', {

@@ -1065,0 +1148,0 @@ transactionId,

@@ -11,2 +11,3 @@ /// <reference types="node" />

send: IORenderSender;
isDemo?: boolean;
}

@@ -27,2 +28,3 @@ export declare type IOClientRenderReturnValues<Components extends [AnyIOComponent, ...AnyIOComponent[]]> = {

send: IORenderSender;
isDemo: boolean;
onResponseHandler: ResponseHandlerFn | undefined;

@@ -72,4 +74,5 @@ inlineActionKeys: Set<string>;

}): RequiredPropsInputIOComponentFunction<MethodName, Props, Output>;
createExclusiveIOMethod<MethodName extends T_IO_INPUT_METHOD_NAMES, Props extends object = T_IO_PROPS<MethodName>, Output = T_IO_RETURNS<MethodName>>(methodName: MethodName, { componentDef, }?: {
createExclusiveIOMethod<MethodName extends T_IO_INPUT_METHOD_NAMES, Props extends object = T_IO_PROPS<MethodName>, Output = T_IO_RETURNS<MethodName>>(methodName: MethodName, { componentDef, demoUnsupported, }?: {
componentDef?: IOComponentDefinition<MethodName, Props, Output>;
demoUnsupported?: boolean;
}): ExclusiveIOComponentFunction<MethodName, Props, Output>;

@@ -76,0 +79,0 @@ /**

@@ -61,2 +61,3 @@ "use strict";

this.send = config.send;
this.isDemo = !!config.isDemo;
// this.onAddInlineAction = config.onAddInlineAction

@@ -247,4 +248,7 @@ }

}
createExclusiveIOMethod(methodName, { componentDef, } = {}) {
createExclusiveIOMethod(methodName, { componentDef, demoUnsupported = false, } = {}) {
return (label, props) => {
if (demoUnsupported && this.isDemo) {
throw new __1.IntervalError(`The ${methodName} method isn't supported in demo mode`);
}
const promiseProps = this.getPromiseProps(methodName, props, componentDef);

@@ -266,3 +270,5 @@ return new IOPromise_1.ExclusiveIOPromise({

confirm: this.createExclusiveIOMethod('CONFIRM'),
confirmIdentity: this.createExclusiveIOMethod('CONFIRM_IDENTITY'),
confirmIdentity: this.createExclusiveIOMethod('CONFIRM_IDENTITY', {
demoUnsupported: true,
}),
search: this.createIOMethod('SEARCH', {

@@ -269,0 +275,0 @@ propsRequired: true,

@@ -46,7 +46,7 @@ "use strict";

// Immediately resolve any methods defined as immediate in schema
setImmediate(() => {
setTimeout(() => {
if ((0, ioSchema_1.resolvesImmediately)(methodName) && this.resolver) {
this.resolver(null);
}
});
}, 0);
}

@@ -53,0 +53,0 @@ async handleValidation(returnValue) {

import { Evt } from 'evt';
import { AccessControlDefinition } from '../internalRpcSchema';
import { IntervalActionDefinition, IntervalPageHandler, IntervalRouteDefinitions } from '../types';

@@ -11,2 +12,3 @@ export interface PageConfig {

handler?: IntervalPageHandler;
access?: AccessControlDefinition;
}

@@ -20,2 +22,3 @@ export default class Page {

handler?: IntervalPageHandler;
access?: AccessControlDefinition;
onChange: Evt<void>;

@@ -22,0 +25,0 @@ constructor(config: PageConfig);

@@ -21,2 +21,3 @@ "use strict";

};
this.access = config.access;
this.handler = config.handler;

@@ -23,0 +24,0 @@ this.onChange = new evt_1.Evt();

@@ -41,3 +41,3 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
const node_fetch_1 = __importDefault(require("node-fetch"));
const cross_fetch_1 = __importDefault(require("cross-fetch"));
const superjson = __importStar(require("superjson"));

@@ -77,3 +77,3 @@ const __1 = require("..");

}
const response = await (0, node_fetch_1.default)(__classPrivateFieldGet(this, _Routes_instances, "m", _Routes_getAddress).call(this, 'enqueue'), {
const response = await (0, cross_fetch_1.default)(__classPrivateFieldGet(this, _Routes_instances, "m", _Routes_getAddress).call(this, 'enqueue'), {
method: 'POST',

@@ -112,3 +112,3 @@ headers: {

}
const response = await (0, node_fetch_1.default)(__classPrivateFieldGet(this, _Routes_instances, "m", _Routes_getAddress).call(this, 'dequeue'), {
const response = await (0, cross_fetch_1.default)(__classPrivateFieldGet(this, _Routes_instances, "m", _Routes_getAddress).call(this, 'dequeue'), {
method: 'POST',

@@ -115,0 +115,0 @@ headers: {

@@ -8,3 +8,3 @@ "use strict";

const path_1 = __importDefault(require("path"));
const node_fetch_1 = __importDefault(require("node-fetch"));
const cross_fetch_1 = __importDefault(require("cross-fetch"));
const __1 = require("..");

@@ -15,3 +15,3 @@ const MAX_RETRIES = 3;

try {
const r = await (0, node_fetch_1.default)(url);
const r = await (0, cross_fetch_1.default)(url);
return r;

@@ -18,0 +18,0 @@ }

@@ -43,3 +43,3 @@ "use strict";

const evt_1 = require("evt");
const node_fetch_1 = __importDefault(require("node-fetch"));
const cross_fetch_1 = __importDefault(require("cross-fetch"));
const _1 = __importStar(require("."));

@@ -220,3 +220,3 @@ Object.defineProperty(exports, "io", { enumerable: true, get: function () { return _1.io; } });

};
const response = await (0, node_fetch_1.default)(`${this.httpEndpoint}/api/hosts/declare`, {
const response = await (0, cross_fetch_1.default)(`${this.httpEndpoint}/api/hosts/declare`, {
method: 'POST',

@@ -223,0 +223,0 @@ headers: {

@@ -5,2 +5,4 @@ import Routes from './classes/Routes';

import Page from './classes/Page';
import { ClientSchema, HostSchema } from './internalRpcSchema';
import { DuplexRPCHandlers } from './classes/DuplexRPCClient';
import { SerializableRecord } from './ioSchema';

@@ -24,2 +26,4 @@ import type { ActionCtx, ActionLogFn, IO, IntervalActionHandler, IntervalActionStore, NotifyConfig, IntervalRouteDefinitions, IntervalPageStore, PageCtx, IntervalActionDefinition } from './types';

reinitializeBatchTimeoutMs?: number;
getClientHandlers?: () => DuplexRPCHandlers<ClientSchema> | undefined;
setHostHandlers?: (handlers: DuplexRPCHandlers<HostSchema>) => void;
}

@@ -26,0 +30,0 @@ export interface QueuedAction {

@@ -42,3 +42,3 @@ "use strict";

exports.Action = exports.IntervalError = exports.IOError = exports.Interval = exports.ctx = exports.io = exports.getSomeStore = exports.getPageStore = exports.getActionStore = void 0;
const node_fetch_1 = __importDefault(require("node-fetch"));
const cross_fetch_1 = __importDefault(require("cross-fetch"));
const Routes_1 = __importDefault(require("./classes/Routes"));

@@ -55,5 +55,8 @@ const IOError_1 = __importDefault(require("./classes/IOError"));

function getActionStore() {
if (!IntervalClient_1.actionLocalStorage) {
throw new IntervalError_1.default('Global io and ctx objects are only available in a Node.js context');
}
const store = IntervalClient_1.actionLocalStorage.getStore();
if (!store) {
throw new IntervalError_1.default('Global io and ctx objects can only be used inside an IntervalActionHandler');
throw new IntervalError_1.default('Global io and ctx objects can only be used inside an Action');
}

@@ -64,5 +67,8 @@ return store;

function getPageStore() {
if (!IntervalClient_1.pageLocalStorage) {
throw new IntervalError_1.default('Global io and ctx objects are only available in a Node.js context');
}
const store = IntervalClient_1.pageLocalStorage.getStore();
if (!store) {
throw new IntervalError_1.default('Global io and ctx objects can only be used inside an App');
throw new IntervalError_1.default('Global io and ctx objects can only be used inside a Page');
}

@@ -157,3 +163,22 @@ return store;

async notify(config) {
var _a, _b, _c;
var _a, _b, _c, _d, _e, _f;
if (!config.transactionId &&
(((_a = __classPrivateFieldGet(this, _Interval_client, "f")) === null || _a === void 0 ? void 0 : _a.environment) === 'development' ||
(!((_b = __classPrivateFieldGet(this, _Interval_client, "f")) === null || _b === void 0 ? void 0 : _b.environment) && !((_c = __classPrivateFieldGet(this, _Interval_apiKey, "f")) === null || _c === void 0 ? void 0 : _c.startsWith('live_'))))) {
__classPrivateFieldGet(this, _Interval_instances, "a", _Interval_log_get).warn('Calls to notify() outside of a transaction currently have no effect when Interval is instantiated with a development API key. Please use a live key to send notifications.');
}
const clientHandlers = (_e = (_d = this.config).getClientHandlers) === null || _e === void 0 ? void 0 : _e.call(_d);
if (clientHandlers) {
clientHandlers.NOTIFY({
...config,
transactionId: (_f = config.transactionId) !== null && _f !== void 0 ? _f : 'demo',
deliveries: config.delivery || [
{
method: 'EMAIL',
to: 'demo@interval.com',
},
],
});
return;
}
let body;

@@ -171,8 +196,3 @@ try {

}
if (!config.transactionId &&
(((_a = __classPrivateFieldGet(this, _Interval_client, "f")) === null || _a === void 0 ? void 0 : _a.environment) === 'development' ||
(!((_b = __classPrivateFieldGet(this, _Interval_client, "f")) === null || _b === void 0 ? void 0 : _b.environment) && !((_c = __classPrivateFieldGet(this, _Interval_apiKey, "f")) === null || _c === void 0 ? void 0 : _c.startsWith('live_'))))) {
__classPrivateFieldGet(this, _Interval_instances, "a", _Interval_log_get).warn('Calls to notify() outside of a transaction currently have no effect when Interval is instantiated with a development API key. Please use a live key to send notifications.');
}
const response = await (0, node_fetch_1.default)(`${__classPrivateFieldGet(this, _Interval_httpEndpoint, "f")}/api/notify`, {
const response = await (0, cross_fetch_1.default)(`${__classPrivateFieldGet(this, _Interval_httpEndpoint, "f")}/api/notify`, {
method: 'POST',

@@ -179,0 +199,0 @@ headers: {

@@ -67,2 +67,10 @@ import { z } from 'zod';

export declare type LoadingState = z.input<typeof LOADING_STATE>;
export declare const ACCESS_CONTROL_DEFINITION: z.ZodUnion<[z.ZodLiteral<"entire-organization">, z.ZodObject<{
teams: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
}, "strip", z.ZodTypeAny, {
teams?: string[] | undefined;
}, {
teams?: string[] | undefined;
}>]>;
export declare type AccessControlDefinition = z.infer<typeof ACCESS_CONTROL_DEFINITION>;
export declare const ACTION_DEFINITION: z.ZodObject<{

@@ -75,2 +83,9 @@ groupSlug: z.ZodOptional<z.ZodString>;

unlisted: z.ZodOptional<z.ZodBoolean>;
access: z.ZodOptional<z.ZodUnion<[z.ZodLiteral<"entire-organization">, z.ZodObject<{
teams: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
}, "strip", z.ZodTypeAny, {
teams?: string[] | undefined;
}, {
teams?: string[] | undefined;
}>]>>;
}, "strip", z.ZodTypeAny, {

@@ -82,2 +97,5 @@ description?: string | undefined;

unlisted?: boolean | undefined;
access?: "entire-organization" | {
teams?: string[] | undefined;
} | undefined;
slug: string;

@@ -90,2 +108,5 @@ }, {

unlisted?: boolean | undefined;
access?: "entire-organization" | {
teams?: string[] | undefined;
} | undefined;
slug: string;

@@ -101,5 +122,15 @@ }>;

unlisted: z.ZodOptional<z.ZodBoolean>;
access: z.ZodOptional<z.ZodUnion<[z.ZodLiteral<"entire-organization">, z.ZodObject<{
teams: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
}, "strip", z.ZodTypeAny, {
teams?: string[] | undefined;
}, {
teams?: string[] | undefined;
}>]>>;
}, "strip", z.ZodTypeAny, {
description?: string | undefined;
unlisted?: boolean | undefined;
access?: "entire-organization" | {
teams?: string[] | undefined;
} | undefined;
hasHandler?: boolean | undefined;

@@ -112,2 +143,5 @@ hasIndex?: boolean | undefined;

unlisted?: boolean | undefined;
access?: "entire-organization" | {
teams?: string[] | undefined;
} | undefined;
hasHandler?: boolean | undefined;

@@ -268,2 +302,9 @@ hasIndex?: boolean | undefined;

unlisted: z.ZodOptional<z.ZodBoolean>;
access: z.ZodOptional<z.ZodUnion<[z.ZodLiteral<"entire-organization">, z.ZodObject<{
teams: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
}, "strip", z.ZodTypeAny, {
teams?: string[] | undefined;
}, {
teams?: string[] | undefined;
}>]>>;
}, "strip", z.ZodTypeAny, {

@@ -275,2 +316,5 @@ description?: string | undefined;

unlisted?: boolean | undefined;
access?: "entire-organization" | {
teams?: string[] | undefined;
} | undefined;
slug: string;

@@ -283,2 +327,5 @@ }, {

unlisted?: boolean | undefined;
access?: "entire-organization" | {
teams?: string[] | undefined;
} | undefined;
slug: string;

@@ -293,5 +340,15 @@ }>, "many">;

unlisted: z.ZodOptional<z.ZodBoolean>;
access: z.ZodOptional<z.ZodUnion<[z.ZodLiteral<"entire-organization">, z.ZodObject<{
teams: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
}, "strip", z.ZodTypeAny, {
teams?: string[] | undefined;
}, {
teams?: string[] | undefined;
}>]>>;
}, "strip", z.ZodTypeAny, {
description?: string | undefined;
unlisted?: boolean | undefined;
access?: "entire-organization" | {
teams?: string[] | undefined;
} | undefined;
hasHandler?: boolean | undefined;

@@ -304,2 +361,5 @@ hasIndex?: boolean | undefined;

unlisted?: boolean | undefined;
access?: "entire-organization" | {
teams?: string[] | undefined;
} | undefined;
hasHandler?: boolean | undefined;

@@ -316,2 +376,5 @@ hasIndex?: boolean | undefined;

unlisted?: boolean | undefined;
access?: "entire-organization" | {
teams?: string[] | undefined;
} | undefined;
hasHandler?: boolean | undefined;

@@ -329,2 +392,5 @@ hasIndex?: boolean | undefined;

unlisted?: boolean | undefined;
access?: "entire-organization" | {
teams?: string[] | undefined;
} | undefined;
slug: string;

@@ -338,2 +404,5 @@ }[];

unlisted?: boolean | undefined;
access?: "entire-organization" | {
teams?: string[] | undefined;
} | undefined;
hasHandler?: boolean | undefined;

@@ -351,2 +420,5 @@ hasIndex?: boolean | undefined;

unlisted?: boolean | undefined;
access?: "entire-organization" | {
teams?: string[] | undefined;
} | undefined;
slug: string;

@@ -373,2 +445,3 @@ }[];

}>>>;
warnings: z.ZodArray<z.ZodString, "many">;
}, "strip", z.ZodTypeAny, {

@@ -382,2 +455,3 @@ sdkAlert?: {

invalidSlugs: string[];
warnings: string[];
}, {

@@ -391,2 +465,3 @@ sdkAlert?: {

invalidSlugs: string[];
warnings: string[];
}> | z.ZodObject<{

@@ -700,2 +775,9 @@ type: z.ZodLiteral<"error">;

unlisted: z.ZodOptional<z.ZodBoolean>;
access: z.ZodOptional<z.ZodUnion<[z.ZodLiteral<"entire-organization">, z.ZodObject<{
teams: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
}, "strip", z.ZodTypeAny, {
teams?: string[] | undefined;
}, {
teams?: string[] | undefined;
}>]>>;
}, "strip", z.ZodTypeAny, {

@@ -707,2 +789,5 @@ description?: string | undefined;

unlisted?: boolean | undefined;
access?: "entire-organization" | {
teams?: string[] | undefined;
} | undefined;
slug: string;

@@ -715,2 +800,5 @@ }, {

unlisted?: boolean | undefined;
access?: "entire-organization" | {
teams?: string[] | undefined;
} | undefined;
slug: string;

@@ -725,5 +813,15 @@ }>, "many">;

unlisted: z.ZodOptional<z.ZodBoolean>;
access: z.ZodOptional<z.ZodUnion<[z.ZodLiteral<"entire-organization">, z.ZodObject<{
teams: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
}, "strip", z.ZodTypeAny, {
teams?: string[] | undefined;
}, {
teams?: string[] | undefined;
}>]>>;
}, "strip", z.ZodTypeAny, {
description?: string | undefined;
unlisted?: boolean | undefined;
access?: "entire-organization" | {
teams?: string[] | undefined;
} | undefined;
hasHandler?: boolean | undefined;

@@ -736,2 +834,5 @@ hasIndex?: boolean | undefined;

unlisted?: boolean | undefined;
access?: "entire-organization" | {
teams?: string[] | undefined;
} | undefined;
hasHandler?: boolean | undefined;

@@ -746,2 +847,5 @@ hasIndex?: boolean | undefined;

unlisted?: boolean | undefined;
access?: "entire-organization" | {
teams?: string[] | undefined;
} | undefined;
hasHandler?: boolean | undefined;

@@ -758,2 +862,5 @@ hasIndex?: boolean | undefined;

unlisted?: boolean | undefined;
access?: "entire-organization" | {
teams?: string[] | undefined;
} | undefined;
slug: string;

@@ -765,2 +872,5 @@ }[];

unlisted?: boolean | undefined;
access?: "entire-organization" | {
teams?: string[] | undefined;
} | undefined;
hasHandler?: boolean | undefined;

@@ -777,2 +887,5 @@ hasIndex?: boolean | undefined;

unlisted?: boolean | undefined;
access?: "entire-organization" | {
teams?: string[] | undefined;
} | undefined;
slug: string;

@@ -809,2 +922,3 @@ }[];

}>>>;
warnings: z.ZodArray<z.ZodString, "many">;
}, "strip", z.ZodTypeAny, {

@@ -818,2 +932,3 @@ sdkAlert?: {

invalidSlugs: string[];
warnings: string[];
environment: "live" | "development";

@@ -833,2 +948,3 @@ organization: {

invalidSlugs: string[];
warnings: string[];
environment: "live" | "development";

@@ -891,6 +1007,9 @@ organization: {

resultStatus: z.ZodEnum<["SUCCESS", "FAILURE", "CANCELED", "REDIRECTED"]>;
result: z.ZodOptional<z.ZodString>;
}, "strip", z.ZodTypeAny, {
result?: string | undefined;
transactionId: string;
resultStatus: "CANCELED" | "SUCCESS" | "FAILURE" | "REDIRECTED";
}, {
result?: string | undefined;
transactionId: string;

@@ -897,0 +1016,0 @@ resultStatus: "CANCELED" | "SUCCESS" | "FAILURE" | "REDIRECTED";

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.hostSchema = exports.clientSchema = exports.wsServerSchema = exports.DECLARE_HOST = exports.NOTIFY = exports.DEQUEUE_ACTION = exports.CREATE_GHOST_MODE_ACCOUNT = exports.ENQUEUE_ACTION = exports.PAGE_DEFINITION = exports.ACTION_DEFINITION = exports.LOADING_OPTIONS = exports.actionEnvironment = exports.TRANSACTION_RESULT_SCHEMA_VERSION = exports.DUPLEX_MESSAGE_SCHEMA = void 0;
exports.hostSchema = exports.clientSchema = exports.wsServerSchema = exports.DECLARE_HOST = exports.NOTIFY = exports.DEQUEUE_ACTION = exports.CREATE_GHOST_MODE_ACCOUNT = exports.ENQUEUE_ACTION = exports.PAGE_DEFINITION = exports.ACTION_DEFINITION = exports.ACCESS_CONTROL_DEFINITION = exports.LOADING_OPTIONS = exports.actionEnvironment = exports.TRANSACTION_RESULT_SCHEMA_VERSION = exports.DUPLEX_MESSAGE_SCHEMA = void 0;
const zod_1 = require("zod");

@@ -30,2 +30,8 @@ const ioSchema_1 = require("./ioSchema");

});
exports.ACCESS_CONTROL_DEFINITION = zod_1.z.union([
zod_1.z.literal('entire-organization'),
zod_1.z.object({
teams: zod_1.z.array(zod_1.z.string()).optional(),
}),
]);
exports.ACTION_DEFINITION = zod_1.z.object({

@@ -38,2 +44,3 @@ groupSlug: zod_1.z.string().optional(),

unlisted: zod_1.z.boolean().optional(),
access: exports.ACCESS_CONTROL_DEFINITION.optional(),
});

@@ -48,2 +55,3 @@ exports.PAGE_DEFINITION = zod_1.z.object({

unlisted: zod_1.z.boolean().optional(),
access: exports.ACCESS_CONTROL_DEFINITION.optional(),
});

@@ -127,2 +135,3 @@ exports.ENQUEUE_ACTION = {

sdkAlert: SDK_ALERT.nullish(),
warnings: zod_1.z.array(zod_1.z.string()),
}),

@@ -270,2 +279,3 @@ zod_1.z.object({

sdkAlert: SDK_ALERT.nullish(),
warnings: zod_1.z.array(zod_1.z.string()),
}),

@@ -292,2 +302,3 @@ zod_1.z.object({

resultStatus: zod_1.z.enum(['SUCCESS', 'FAILURE', 'CANCELED', 'REDIRECTED']),
result: zod_1.z.string().optional(),
}),

@@ -294,0 +305,0 @@ returns: zod_1.z.void().nullable(),

/// <reference types="node" />
import type { z } from 'zod';
import type { T_IO_RENDER_INPUT, T_IO_RESPONSE, T_IO_PROPS, T_IO_RETURNS, T_IO_STATE, T_IO_Schema, T_IO_METHOD_NAMES, IOFunctionReturnType, T_IO_DISPLAY_METHOD_NAMES, T_IO_INPUT_METHOD_NAMES, menuItem, buttonItem, ButtonTheme, serializableRecord, ImageSize, SerializableRecord, LegacyLinkProps } from './ioSchema';
import type { HostSchema } from './internalRpcSchema';
import type { AccessControlDefinition, HostSchema } from './internalRpcSchema';
import type { IOClient, IOClientRenderValidator } from './classes/IOClient';

@@ -50,2 +50,3 @@ import type IOComponent from './classes/IOComponent';

description?: string;
access?: AccessControlDefinition;
}

@@ -52,0 +53,0 @@ export declare type IntervalActionDefinition = IntervalActionHandler | ExplicitIntervalActionDefinition | Action;

@@ -33,3 +33,3 @@ "use strict";

const path_1 = __importDefault(require("path"));
const promises_1 = __importStar(require("fs/promises"));
const promises_1 = __importDefault(require("fs/promises"));
const Action_1 = __importDefault(require("../classes/Action"));

@@ -51,3 +51,3 @@ const Page_1 = __importDefault(require("../classes/Page"));

const slug = path_1.default.basename(file, ext || undefined);
if ((await (0, promises_1.stat)(fullPath)).isDirectory()) {
if ((await promises_1.default.stat(fullPath)).isDirectory()) {
const group = await loadFolder(path_1.default.join(currentDirectory, slug), logger);

@@ -54,0 +54,0 @@ router.routes[slug] = group;

{
"name": "@interval/sdk",
"version": "0.33.0",
"version": "0.34.0",
"homepage": "https://interval.com",

@@ -25,4 +25,4 @@ "repository": {

"dependencies": {
"cross-fetch": "^3.1.5",
"evt": "^2.4.10",
"node-fetch": "^2.0.0",
"superjson": "^1.9.1",

@@ -29,0 +29,0 @@ "uuid": "^9.0.0",

<a href="https://interval.com">
<img alt="Interval" width="100" height="100" style="border-radius: 6px;" src="interval-avatar.png">
<img alt="Interval" width="100" height="100" style="border-radius: 6px;" src="https://interval.com/img/readme-assets/interval-avatar.png">
</a>

@@ -53,3 +53,3 @@

<img alt="An image containing a code sample alongside a screenshot of the Interval app it generates." src="screenshot.png">
<img alt="An image containing a code sample alongside a screenshot of the Interval app it generates." src="https://interval.com/img/readme-assets/screenshot.png">

@@ -56,0 +56,0 @@ ## More about Interval

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc