npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@supertokens-plugins/squadup-nodejs

v0.3.2

Published

SquadUp ticketing plugin for SuperTokens

Readme

SuperTokens SquadUp Plugin

Adds an authenticated endpoint for listing SquadUp tickets for the current SuperTokens user.

import SquadUpPlugin from "@supertokens-plugins/squadup-nodejs";

SuperTokens.init({
  experimental: {
    plugins: [
      SquadUpPlugin.init({
        apiKey: process.env.SQUADUP_API_KEY!,
      }),
    ],
  },
});

Endpoint

GET /auth/plugin/squadup/tickets

The endpoint requires a SuperTokens session. It uses a passwordless email login method, or a verified third-party email login method, as the SquadUp lookup email. The method's tenantIds must include the verified session tenant. Linked-user login methods from other tenants are excluded; no eligible method returns HTTP 400 without calling SquadUp.

Tenant credentials

Configure exactly one of apiKey: string or resolveApiKey: ({ tenantId, userContext }) => Promise<string | undefined>. Static credentials remain supported. The resolver runs on every valid request; credentials are never cached or written into shared plugin configuration. tenantId comes exclusively from the verified session's getTenantId(), never from query parameters. userContext is the SDK request context.

SquadUpPlugin.init({
  resolveApiKey: async ({ tenantId, userContext }) => {
    return tenantCredentials.getSquadUpApiKey(tenantId, userContext);
  },
});

Return undefined when the tenant has no integration configured: the endpoint returns HTTP 503. Resolver exceptions or invalid resolved keys return a sanitized HTTP 500. Neither case calls SquadUp or looks up the user. Keys must be non-empty strings. The plugin's own logs omit exception details, upstream URLs and tokens.

SquadUp requests carry the API key in the URL's access_token query parameter. HTTP tracing and other request instrumentation can record that URL independently of plugin logging. Consumers must omit these credential-bearing requests from tracing or redact their credentials before recording/exporting them.

Pagination and email cache

?pageSize=25 controls the upstream page_size. defaultPageSize and maxPageSize both default to 100 and must be positive integers, with defaultPageSize <= maxPageSize. Invalid or oversized queries return HTTP 400 before credential resolution, user lookup or SquadUp calls.

Each plugin instance has a bounded, least-recently-used email cache keyed by [tenantId, userId]. Defaults: emailCache: { ttlMs: 30_000, maxEntries: 1000 }. Set emailCache: false, ttlMs: 0, or maxEntries: 0 to disable it. Concurrent misses for a resident entry share one user lookup; thrown failures are not cached. TTL starts when the lookup completes. Eviction can remove pending lookups too, so a subsequent request may start a new lookup under capacity pressure.

Email, verification, and login-method tenant membership changes can remain stale for up to the cache TTL (30 seconds by default). Unsupported/missing emails are cached for the same interval. Disable caching when every request must recheck current user state. Tickets and tenant credentials are never cached.

Per-ticket QR/PDF visibility

ticketAvailabilityWindowMs defaults to the numeric value 7_200_000 (two hours). It accepts either a finite, non-negative number or a synchronous callback:

SquadUpPlugin.init({
  apiKey: process.env.SQUADUP_API_KEY!,
  ticketAvailabilityWindowMs: ({ event, ticket, tenantId, userContext }) => {
    return ticket.type === "VIP" ? 24 * 60 * 60 * 1000 : 2 * 60 * 60 * 1000;
  },
});

The callback receives the upstream event and ticket as SDK JSONObject values, plus the verified tenant and request context. It runs once per ticket and must return a finite, non-negative number; exceptions and invalid results produce a sanitized HTTP 500.

Visibility affects only each ticket's qrcode_str and pdf_url. Events, tickets and their other metadata remain in the response, including mixed events with both available and unavailable tickets. QR/PDF are visible when eventStart - now <= window, including the exact boundary and past events. The ticket's event.start_at takes precedence; if absent/null, the enclosing event's start_at is used. Unknown or invalid dates hide QR/PDF (null); an explicitly invalid ticket date does not fall back to the enclosing event. Supported timestamps use YYYY-MM-DDTHH:mm:ss[.fraction]Z or an explicit ±HH:mm offset, with valid calendar and clock components. Timezone-free dates, normalized impossible dates, and the unknown offset -00:00 are rejected. Fractional seconds are supported beyond millisecond precision; visibility rounds up to the next millisecond when necessary so truncation cannot reveal tickets early.

Debugging failures

Packing/publishing runs prepack to rebuild the package and smoke-test both compiled entrypoints, including the embedded version, numeric IDs, missing metadata, and upstream 404 handling. Run npm run build && npm run test:package to verify artifacts locally.

For a local test with a real token from SSM, build the plugin and run from this package:

npm run build
node scripts/diagnose.cjs --tenant <tenantId> --email <email> --profile st-admin

Pass --token '<token>' to supply a token directly and skip AWS entirely. This does not update SSM. A literal token can appear in shell history and process arguments.

The runner reads /managed-backend-api/production/tenants/<tenantId>/squadup-token from SSM in us-east-2 (override with --environment and --region). It needs the AWS CLI and an authenticated profile with SSM/KMS read access. It uses a local session/email fixture and makes a real SquadUp request through the built plugin; it does not test SuperTokens authentication or the ECS task role. Normal output includes HTTP status, event count, and safe plugin failure diagnostics. The local runner prints raw setup errors and their causes for troubleshooting; redact sensitive values before sharing those errors. Successful response bodies and supplied tokens are not printed.

Set enableDebugLogs: true to write failure diagnostics to stderr. Each failure includes tenantId, stage, and durationMs, plus upstreamStatus when a response was received. Validation failures include the first failing schema field, expectedType, and actualType; network failures include an allowlisted transportCode when available. Stages distinguish credential resolution, email lookup, upstream transport/HTTP, JSON parsing, response validation, and visibility-policy failures. No request/response bodies, email addresses, URLs, QR codes, raw exception messages, or user context are logged. HTTP 404 remains a successful empty list and is not logged as a failure.

Example: {"stage":"response_validation","tenantId":"tenant-a","durationMs":150,"upstreamStatus":200,"field":"attendees[0].attendee_guests","expectedType":"array","actualType":"object"}.

These are stderr debug logs, not OpenTelemetry spans. Consumers must collect stderr to see them; the existing public API error responses remain sanitized.

Responses

Event and ticket metadata passes through as returned by SquadUp: no required IDs, names, types, images, or locations, and no field-type enforcement or ID conversion. Unknown fields and null values are preserved. The plugin only checks the objects and arrays it traverses: attendees, each attendee's event and attendee_guests, and each guest's ticket. It assembles event tickets arrays and applies the configured QR/PDF visibility policy; unknown dates hide QR/PDF without rejecting metadata.

| HTTP | Meaning | | ---- | ------------------------------------------------------------------------------- | | 200 | { status: "OK", events: [...] } (an empty attendees list yields events: []) | | 400 | Invalid page size or no supported verified email (BAD_INPUT_ERROR) | | 401 | Missing session | | 500 | Credential resolver, user lookup, or visibility-policy failure | | 502 | SquadUp transport, non-2xx except 404, invalid JSON, or invalid response fields | | 503 | Tenant integration not configured |

SquadUp HTTP 404 means no tickets exist for the email and returns HTTP 200 with { status: "OK", events: [] }, regardless of the upstream response body.

Error responses contain status and a sanitized message. Successful upstream responses must contain an attendees array with event and guest/ticket objects. Fields used for traversal are checked before mapping; metadata fields are not validated.