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

librus-sdk

v0.7.1

Published

TypeScript SDK and CLI for Librus family portal and Gateway API 2.0 flows.

Readme

librus-sdk

CI CodeQL Snyk Security OpenSSF Scorecard

Fresh TypeScript SDK and CLI for the Librus family portal and Gateway API 2.0 JSON flows.

For Portal accounts, this project logs into portal.librus.pl, loads linked child accounts from portal/api/v3/SynergiaAccounts, and uses the selected child account's bearer token against https://api.librus.pl/3.0.

For school-issued accounts, it can also log in with the Gateway API 2.0 login and password, keep the resulting Synergia cookies, and read https://synergia.librus.pl/gateway/api/2.0. That backend is already scoped to one account and does not support Portal-only child discovery.

It intentionally does not reuse the legacy synergia.librus.pl HTML-scraping approach.

Acknowledgements

This implementation was inspired by Mati365/librus-api.

Security

Report vulnerabilities privately as described in SECURITY.md.

Never commit, log, or print real credentials, bearer tokens, cookies, or other secrets in source files, fixtures, examples, or documentation.

The repository also publishes a weekly OpenSSF Scorecard report from GitHub Actions so maintainers can track workflow hardening and other supply-chain signals over time.

Install

This package requires Node.js 22 or newer.

Install the package from npm:

npm install librus-sdk

Use the CLI without installing it globally:

npm exec --package librus-sdk -- librus-sdk --version
npm exec --package librus-sdk -- librus-sdk children list
npm exec --package librus-sdk -- librus-sdk grades list --child <id-or-login>

The canonical CLI binary is librus-sdk. A deprecated librus alias remains temporarily for compatibility and prints a warning before delegating.

The package also ships a generated openapi.json for the SDK-supported child-scoped https://api.librus.pl/3.0 surface, so non-TypeScript consumers can generate clients in other languages. It is also exported as librus-sdk/openapi.json.

Public Interface

This README is the canonical public-interface reference for the npm package and CLI published from this repository.

Environment

LibrusSession.fromEnv() and the CLI read credentials and timeout settings from these variables:

| Variable | Required | Purpose | | ------------------------- | ---------------- | ------------------------------------------------------------------ | | LIBRUS_API_BACKEND | No | Optional api_v3 or gateway_api_20 selector. | | LIBRUS_PORTAL_EMAIL | api_v3 | Portal login email used for portal.librus.pl. | | LIBRUS_PORTAL_PASSWORD | api_v3 | Portal login password used for portal.librus.pl. | | LIBRUS_GATEWAY_LOGIN | gateway_api_20 | School-issued Gateway API 2.0 login. This is not an email address. | | LIBRUS_GATEWAY_PASSWORD | gateway_api_20 | Password for the Gateway API 2.0 login. | | LIBRUS_CHILD | No | Optional default child id or login for api_v3 CLI commands. | | LIBRUS_TIMEOUT_MS | No | Positive integer request timeout in milliseconds. |

If no timeout is configured, portal and child-scoped SDK requests default to 30000 milliseconds. Invalid timeout values fail fast with CONFIGURATION_ERROR.

When no LIBRUS_API_BACKEND is set, complete Portal credentials select api_v3. If Portal credentials are absent and complete Gateway credentials are present, gateway_api_20 is selected. If neither set is complete, the default is api_v3 so missing-credential errors stay Portal-oriented. When both credential sets are complete, api_v3 wins unless LIBRUS_API_BACKEND=gateway_api_20 is set explicitly.

Empty credential variables are treated as invalid. If a portal-prefixed credential variable is set but empty, the deprecated compatibility alias for that credential is ignored. LIBRUS_CHILD is used only by api_v3; CLI --child wins over LIBRUS_CHILD, and explicit --child is rejected for gateway_api_20 because that backend is already scoped to one account.

Top-Level SDK Entry Points

Import from the package root:

import {
  BffApiClient,
  GatewayApi20AuthClient,
  LibrusSession,
  PortalClient,
  SynergiaApiClient,
  generateOpenApiDocument,
  LibrusSdkError,
  type LibrusApiBackend,
} from "librus-sdk";

| Export | Purpose | | ------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | | LibrusSession | Recommended high-level entry point. Handles login, linked-child discovery, child selection, and creation of child-scoped API clients. | | BffApiClient | Experimental child-scoped client for selected https://testbff.librus.pl/v1 mobile backend reads. | | GatewayApi20AuthClient | Lower-level Gateway API 2.0 login/password auth client for synergia.librus.pl/gateway/api/2.0 cookie-backed requests. | | PortalClient | Lower-level portal session client for portal.librus.pl login, /Me, and /SynergiaAccounts. | | SynergiaApiClient | Child-scoped GET client for the supported https://api.librus.pl/3.0 surface when you already have a bearer token. | | generateOpenApiDocument | Generates the shipped OpenAPI document for the supported child-scoped GET subset. |

Recommended session flow:

import { LibrusSession } from "librus-sdk";

const session = LibrusSession.fromEnv();
const children = await session.listChildren();
const client = await session.forChild(children[0]);
const grades = await client.getGrades();
console.log(grades);

Gateway API 2.0 flow:

LIBRUS_API_BACKEND=gateway_api_20
LIBRUS_GATEWAY_LOGIN=1234567
LIBRUS_GATEWAY_PASSWORD=your-password
npm exec --package librus-sdk -- librus-sdk grades list
import { LibrusSession } from "librus-sdk";

const session = LibrusSession.fromGatewayCredentials({
  login: "1234567",
  password: "your-password",
});
const client = await session.forChild();
const grades = await client.getGrades();
console.log(grades);

Gateway API 2.0 is already child-scoped. getPortalMe(), getSynergiaAccounts(), listChildren(), resolveChild(...), forChildBff(...), and forChildWiadomosci(...) require Portal auth and fail with UNSUPPORTED_BACKEND in gateway_api_20.

Current high-level methods on LibrusSession:

  • LibrusSession.fromEnv(env?)
  • LibrusSession.fromGatewayCredentials(credentials, options?)
  • new LibrusSession({ apiBackend?, credentials, portalClient?, portalClientOptions?, gatewayApi20AuthClient?, gatewayApi20AuthClientOptions?, bffClientOptions?, synergiaClientOptions?, wiadomosciClientOptions?, requestTimeoutMs? })
  • login()
  • getApiBackend()
  • getPortalMe()
  • getSynergiaAccounts()
  • listChildren()
  • resolveChild(selector)
  • forChild(selectorOrChild)
  • forChildWiadomosci(selectorOrChild)
  • forChildBff(selectorOrChild)

Current methods on PortalClient:

  • new PortalClient(options?)
  • login(credentials)
  • getMe()
  • getSynergiaAccounts()
  • isLoggedIn()

SynergiaApiClient exposes explicit child-scoped read methods grouped by endpoint family rather than raw route strings:

| Domain | Methods exposed today | | -------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | Profile | getMe() | | Grades | getGrades(), getGradeAverages(subjectId?), getGradeCategories(), getGradeComments(), getBehaviourGrades(), getBehaviourGradeTypes(), getBehaviourGradePoints(), getBehaviourPointCategories(), getBehaviourPointComments(), getBehaviourSystemProposal(), getDescriptiveGrades(), getDescriptiveGradeComments(), getDescriptiveGradeSkills(), getDescriptiveGradeText(subjectId), getDescriptiveGradeTextCategories(), getDescriptiveTextGrades(), getDescriptiveTextGradeSkills(), getPointGrades(subjectId?), getPointGradeAverages(subjectId?), getPointGradeCategories(), getPointGradeComments(), getTextGrades() | | Attendance | getAttendances(), getAttendanceTypes() | | Timetable | getTimetableWeek(weekStart), getTimetableDay(day), getTimetableEntry(id), getCalendars(), getClassFreeDays(), getClassFreeDayTypes(), getSchoolFreeDays(), getTeacherFreeDays(), getSubstitution(id), getVirtualClasses() | | Lessons | listLessons(), getLesson(id), listPlannedLessons(), getPlannedLesson(id), getPlannedLessonAttachment(id), listRealizations(), getRealization(id) | | Homework | getHomeWorks(), getHomeworkAssignments(), getHomeworkAssignmentAttachment(id), getHomeworkCategories() | | Messages | listMessages(options?), getMessage(id), getUnreadMessages(), listMessagesForUser(userId), listMessageReceiverGroups(), getMessageReceiverGroup(id), getMessageAttachment(id). listMessages supports afterId, page, limit, alternativeBody, changeNewLine, and getAllTypes query options. | | Announcements and notes | listSchoolNotices(), getSchoolNotice(id), listNotes(), getNote(id), listNoteCategories() | | School metadata | getSchool(), getSchoolById(id), getClass(), getClassroom(id), listSubjects(), getSubject(id), listUsers(), getUser(id) | | Notifications and justifications | getLuckyNumber(forDay?), getNotificationCenter(), getPushConfigurations(), listJustifications(options?), getJustification(id), listParentTeacherConferences(), getSystemData() | | Auth reads | listAuthPhotos(), getAuthPhoto(id), getAuthUserInfo(id), getAuthTokenInfo(), getAuthClassroom(id) |

Attachment-style methods such as getHomeworkAssignmentAttachment(id), getMessageAttachment(id), and getPlannedLessonAttachment(id) return SynergiaBinaryResult with { data, contentType, contentDisposition }.

When a SynergiaApiClient is created through api_v3 LibrusSession.forChild(child), reads use bearer-token requests against https://api.librus.pl/3.0 by default. When it is created through gateway_api_20 with LibrusSession.forChild() and no child selector, reads use cookie-backed requests against https://synergia.librus.pl/gateway/api/2.0 instead; API 3.0 bearer requests are not expected to work for that backend.

Use LibrusSession.forChildWiadomosci() to opt in to the portal-authenticated https://wiadomosci.librus.pl/api inbox backend for listMessages(), getMessage(id), and getUnreadMessages(). Other child-scoped reads, message receiver groups, and message attachment downloads continue to use the session's default Synergia transport. Direct new SynergiaApiClient(token) construction keeps using API 3.0 for all methods unless lower-level transport options or a custom message backend are supplied.

BffApiClient currently exposes the research-oriented listMessages() method for GET https://testbff.librus.pl/v1/Messages. It uses the selected child's Synergia access token as x-zse-authorization and returns the raw { inboxMessages } BFF response shape.

getAuthPhoto(id) mirrors the live API and returns JSON with the photo payload under data.photo, including base64 content in data.photo.content. The CLI auth photo --output <path> command decodes that content before writing the file.

HomeWork.LessonNo mirrors the live Librus payload and may be string, number, or null. HomeWork.Subject may be omitted entirely or returned as null.

Constructor And Helper Option Shapes

These tables describe the option objects currently accepted by the exported constructors and helpers. The interface names are the current source names used in the generated .d.ts, but the package documents the accepted property shapes here rather than promising every helper type as a named top-level export.

LibrusSession constructor options (LibrusSessionOptions):

| Property | Required | Meaning | | ------------------------------- | -------- | ------------------------------------------------------------------------------------ | | credentials | Yes | Portal { email, password } or Gateway { login, password } credentials. | | apiBackend | No | api_v3 by default, or gateway_api_20 for Gateway API 2.0 credentials. | | portalClient | No | Reuse an existing PortalClient instance instead of constructing one internally. | | portalClientOptions | No | Passed to the internally created PortalClient when portalClient is not supplied. | | gatewayApi20AuthClient | No | Reuse an existing Gateway API 2.0 auth client in gateway_api_20. | | gatewayApi20AuthClientOptions | No | Passed to the internally created Gateway API 2.0 auth client. | | bffClientOptions | No | Passed to BFF clients created by forChildBff(...). | | synergiaClientOptions | No | Passed to SynergiaApiClient instances created by forChild(...). | | wiadomosciClientOptions | No | Passed to wiadomosci-backed clients created by forChildWiadomosci(...). | | requestTimeoutMs | No | Session-wide default timeout for internally created portal and child clients. |

PortalClient constructor options (PortalClientOptions):

| Property | Required | Meaning | | ------------------ | -------- | ----------------------------------------------------------------------------------- | | fetch | No | Custom fetch implementation. The client wraps it in cookie-backed session handling. | | portalBaseUrl | No | Portal origin. Defaults to https://portal.librus.pl. | | portalApiBaseUrl | No | Portal API base URL. Defaults to ${portalBaseUrl}/api/v3. | | loginPath | No | Login page path. Defaults to /konto-librus/login. | | loginActionPath | No | Login form submission path. Defaults to /konto-librus/login/action. | | requestTimeoutMs | No | Positive integer timeout in milliseconds. Defaults to 30000. |

SynergiaApiClient constructor options (SynergiaApiClientOptions):

| Property | Required | Meaning | | ------------------ | -------- | --------------------------------------------------------------- | | fetch | No | Custom fetch implementation for child-scoped API requests. | | apiBaseUrl | No | Synergia API base URL. Defaults to https://api.librus.pl/3.0. | | authMode | No | bearer by default, or cookie for Gateway-created sessions. | | requestTimeoutMs | No | Positive integer timeout in milliseconds. Defaults to 30000. |

generateOpenApiDocument() options (GenerateOpenApiDocumentOptions):

| Property | Required | Meaning | | ----------- | -------- | ---------------------------------------------------------------------------------------------------------------- | | title | No | Overrides the generated OpenAPI info.title. | | version | No | Overrides the generated OpenAPI info.version. Pass the package version when generating a publishable document. | | serverUrl | No | Overrides the default server URL https://api.librus.pl/3.0. |

Public Types And Errors

In addition to the top-level classes above, the package root re-exports the model and error modules under src/sdk/models/.

| Category | Public surface | | ------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Portal and child-account types | PortalCredentials, PortalMe, ChildAccount, SynergiaAccountsResponse | | Shared response helpers | ApiRef, SynergiaBinaryResult, other common helper interfaces used by SDK responses | | Synergia response models | Response and entity interfaces for the supported child-scoped API surface under the synergia model barrels | | Error classes | LibrusSdkError, LibrusApiError, LibrusAuthenticationError, LibrusConfigurationError, LibrusNetworkTimeoutError, LibrusPortalPageError, LibrusResponseValidationError |

CLI Surface

Root CLI commands:

  • librus-sdk --help
  • librus-sdk --version

Every leaf command supports --format <text|json>. In api_v3, child-scoped commands require a child selector: pass --child <id-or-login> or set LIBRUS_CHILD. --child wins when both are present. In gateway_api_20, the account is already child-scoped, so the same commands run without --child and explicit --child fails with UNSUPPORTED_BACKEND. Portal-only commands such as children list, messages bff-list, and messages wiadomosci-list are not available in gateway_api_20.

| Family | Subcommands | Extra selectors and flags | | ---------------- | ----------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | children | list | Portal-only; no child selector. | | me | root command | api_v3 requires a child selector; gateway_api_20 does not. | | grades | list | api_v3 requires a child selector; gateway_api_20 does not. | | attendance | list | api_v3 requires a child selector; gateway_api_20 does not. | | homework | list | api_v3 requires a child selector; gateway_api_20 does not. | | messages | list, bff-list, get, unread, wiadomosci-list, wiadomosci-get, wiadomosci-unread | list, get, and unread support --backend <api3\|wiadomosci> and default to api3; get and wiadomosci-get require --id <id>; bff-* and wiadomosci-* are Portal-only. | | timetable | week, day, entry | week requires --week-start <YYYY-MM-DD>; day requires --day <YYYY-MM-DD>; entry requires --id <id>; api_v3 requires a child selector; gateway_api_20 does not. | | announcements | list, get | get requires --id <id>; api_v3 requires a child selector; gateway_api_20 does not. | | notes | list, get | get requires --id <id>; api_v3 requires a child selector; gateway_api_20 does not. | | lessons | list, get, planned-list, planned-get, planned-attachment, realizations-list, realizations-get | get, planned-get, and realizations-get require --id <id>; planned-attachment requires --id <id> and --output <path>; api_v3 requires a child selector; gateway_api_20 does not. | | lucky-number | get | Optional --for-day <YYYY-MM-DD>; api_v3 requires a child selector; gateway_api_20 does not. | | notifications | center, push-configurations | api_v3 requires a child selector; gateway_api_20 does not. | | justifications | list, get, conferences, system-data | list supports --date-from <YYYY-MM-DD>; get requires --id <id>; api_v3 requires a child selector; gateway_api_20 does not. | | auth | photos, photo, user-info, token-info, classroom | photo requires --id <id> and --output <path>; user-info and classroom require --id <id>; api_v3 requires a child selector for child-scoped auth commands; gateway_api_20 does not. |

CLI Output Contract

  • Human-readable text is the default stdout format for successful commands.
  • --format json is the stable machine-readable interface for automation.
  • Errors are written to stderr and follow the selected output format.
  • Non-successful commands return a non-zero exit code.
  • children list JSON output is { lastModification, children }.
  • Child-scoped read commands emit { child, data } in JSON output for api_v3 and { data } for gateway_api_20, where the session is already child-scoped.
  • Download commands such as lessons planned-attachment and auth photo write the requested file first, then report saved-file metadata instead of raw bytes. JSON output keeps the same { child, data } envelope, where data contains { path, bytes, contentType, contentDisposition }.
  • Text output is meant for terminal readability. It is not a stable parsing contract.
  • Current text rendering normalizes epoch-style *Date fields to local YYYY-MM-DD HH:mm:ss values and turns escaped message bodies and <br> tags into readable terminal text.

Error-Code Contract

Consumers should branch on error.code, not on the free-form message text.

JSON stderr shape is stable:

{
  "error": {
    "code": "CONFIGURATION_ERROR",
    "message": "Missing portal credentials. Email: LIBRUS_PORTAL_EMAIL is unset; fallback LIBRUS_EMAIL is unset. Password: LIBRUS_PORTAL_PASSWORD is unset; fallback LIBRUS_PASSWORD is unset.",
    "details": {}
  }
}

Contract:

  • error.code is the stable discriminator for machine handling.
  • error.message is human-facing and may be refined without changing the error category.
  • error.details is optional and extensible. Callers should ignore unknown keys.
  • Existing documented codes stay stable.
  • Future SDK features may add new codes without changing the overall JSON error envelope.

Current codes emitted by the SDK and CLI:

| Code | Meaning | | ---------------------------- | -------------------------------------------------------------------------- | | CONFIGURATION_ERROR | Required credentials or other local configuration are missing or invalid. | | AUTHENTICATION_FAILED | Portal or Gateway API 2.0 authentication failed. | | PORTAL_LOGIN_PAGE_INVALID | The portal login page no longer matches the expected CSRF-token structure. | | NETWORK_TIMEOUT | A portal or Synergia request exceeded the configured timeout. | | API_REQUEST_FAILED | A portal or Synergia request failed with a non-maintenance HTTP error. | | SERVICE_MAINTENANCE | The Synergia API reported maintenance mode. | | RESPONSE_VALIDATION_FAILED | The live payload no longer matches the validated SDK schema. | | CHILD_NOT_FOUND | No linked child account matched the provided selector. | | AMBIGUOUS_CHILD | More than one linked child account matched the provided selector. | | CHILD_REQUIRED | api_v3 needs --child, LIBRUS_CHILD, or an SDK child selector. | | UNSUPPORTED_BACKEND | The selected API backend cannot support the requested operation. | | CLI_USAGE_ERROR | The CLI arguments were invalid, incomplete, or used unsupported values. | | INTERNAL_ERROR | Unexpected non-SDK error wrapper used by the CLI fallback path. |

Troubleshooting

Direct API 3.0 messages reads can fail with HTTP 403 even when other child-scoped endpoints such as grades list still work. CLI messages list, messages get, and messages unread use API 3.0 by default. Pass --backend wiadomosci or use messages wiadomosci-list, messages wiadomosci-get, and messages wiadomosci-unread to read through the portal-authenticated wiadomosci.librus.pl inbox backend.

When a /Messages request returns API_REQUEST_FAILED with status: 403, the SDK and CLI now add diagnostics under error.details:

  • feature: "messages"
  • requiredScope: "messages"
  • scopePresent when Auth/TokenInfo exposes scopes for the same child token
  • tokenScopes when those scopes are readable
  • hint pointing to librus-sdk auth token-info --child <id-or-login>

Use the auth helper directly when you need to compare child tokens:

npm exec --package librus-sdk -- librus-sdk auth token-info --child <id-or-login>

For timeout handling, the SDK throws LibrusNetworkTimeoutError, and the CLI writes the same NETWORK_TIMEOUT failure to stderr. With --format json, stderr includes secret-safe details shaped like { endpoint, timeoutMs }. With --format text, stderr still includes the same stable code and the human-facing timeout message. The endpoint is the request URL only; credentials, bearer tokens, and cookie values are not included.

OpenAPI

openapi.json is generated from the SDK's supported Synergia GET endpoints and the shared valibot response schemas. The document is best-effort and intentionally covers only the child-scoped api.librus.pl/3.0 requests, not the portal.librus.pl login flow.

Regenerate or verify the file locally with:

npm run openapi:generate
npm run openapi:check

You can also generate the document programmatically:

import { generateOpenApiDocument } from "librus-sdk";

const openApi = generateOpenApiDocument({ version: "0.4.0" });

Release And Versioning Policy

Repository release policy, SemVer rules, tag naming, changelog-backed release notes, and badge-homepage guidance are documented in docs/releasing.md.

Local Development

npm install
npm run validate
npm run openapi:generate
npm run cli -- children list
npm run cli -- grades list --child <id-or-login>

More examples:

npm run cli -- me --child <id-or-login>
npm run cli -- attendance list --child <id-or-login>
npm run cli -- homework list --child <id-or-login>
npm run cli -- lessons list --child <id-or-login>
npm run cli -- lucky-number get --child <id-or-login>
npm run cli -- messages list --child <id-or-login>
npm run cli -- timetable week --child <id-or-login> --week-start 2026-03-30
npm run cli -- announcements list --child <id-or-login>
npm run cli -- notes list --child <id-or-login>
npm run cli -- justifications conferences --child <id-or-login>
npm run cli -- auth photo --child <id-or-login> --id <photo-id> --output ./photo.jpg

Testing And Dynamic Analysis

The required pre-merge verification command for this repository is:

npm run validate

npm run validate runs the same canonical checks used by the CI validation gate:

  • npm run lint
  • npm run format:check
  • npm run build
  • npm run test:coverage
  • npm run pack:check

Behavior changes should add or update focused Vitest coverage in the closest relevant suite under test/.

This repository's dynamic-analysis evidence is the automated Vitest test suite plus coverage checks. That evidence comes from npm run test:coverage locally and the Validation gate CI job in ./.github/workflows/ci.yml.

For Best Practices and repository-policy purposes, this project does not rely on fuzzing or browser scanning as its dynamic-analysis evidence.

Current CI jobs:

  • Validation gate: runs the required npm run validate path before merge.
  • Dependency vulnerability gate: fails on high or critical npm advisories.
  • Snyk Security: fails on high or critical dependency vulnerabilities using the configured SNYK_TOKEN GitHub Actions secret.
  • Trivy scan (informational): publishes vulnerability and secret-scan results for review.

Live Integration Tests

This repo also includes optional live integration tests for the built SDK and CLI artifacts in dist.

They are intended for local manual verification only:

  • they require real Librus credentials
  • they are manual-only and not required for ordinary merges
  • they are not part of npm test
  • they are not part of npm run validate
  • they are not run in CI or release automation

Create a dedicated Portal env file at .env.integration.local:

[email protected]
LIBRUS_PORTAL_PASSWORD=your-password

Then run:

npm run test:integration
npm run test:integration:sdk
npm run test:integration:cli

npm run report:integration
npm run report:integration:sdk
npm run report:integration:cli

For Gateway API 2.0 verification, create .env.integration.gateway-api-20.local with the school-issued login. The login is printed or issued by the school; it is not an email address.

LIBRUS_GATEWAY_LOGIN=1234567
LIBRUS_GATEWAY_PASSWORD=your-password

Then run:

npm run test:integration:gateway-api-20
npm run test:integration:gateway-api-20:sdk
npm run test:integration:gateway-api-20:cli

npm run report:integration:gateway-api-20
npm run report:integration:gateway-api-20:sdk
npm run report:integration:gateway-api-20:cli

The Gateway API 2.0 integration scripts force LIBRUS_API_BACKEND=gateway_api_20, so a developer shell with Portal variables set will not accidentally run the Portal matrix. The Gateway matrix is already child-scoped: SDK checks use session.forChild() without a selector, and CLI checks run commands such as librus-sdk grades list without --child. Portal-only checks are skipped in the Gateway report because gateway_api_20 cannot list Portal-linked children or create Portal-backed BFF/wiadomosci clients.

To limit the Portal live run to specific children, set LIBRUS_TEST_CHILDREN as a comma-separated list of child ids or logins:

LIBRUS_TEST_CHILDREN=7147345 npm run test:integration
LIBRUS_TEST_CHILDREN=7147345,child-login npm run report:integration