@vimine/sdk 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,57 @@
1
+ // GENERATED by scripts/gen-types.mjs from openapi/v1.json — do not edit. Regenerate: npm run spec:types
2
+ // Spec version 2026-09-19 · 45 paths · 35 schemas
3
+ /** Every operation of the document: id → [method, path]. */
4
+ export const operations = {
5
+ getOpenApi: ['GET', '/v1/openapi.json'],
6
+ getCardKeys: ['GET', '/v1/card-keys'],
7
+ getApsPublicConfig: ['GET', '/v1/aps/{slug}'],
8
+ verifyCard: ['GET', '/v1/verify/{card_token}'],
9
+ validateFiscalCode: ['POST', '/v1/validate/fiscal-code'],
10
+ oauthToken: ['POST', '/v1/oauth/token'],
11
+ oauthRevoke: ['POST', '/v1/oauth/revoke'],
12
+ oauthClientInfo: ['GET', '/v1/oauth/client-info'],
13
+ getMe: ['GET', '/v1/me'],
14
+ closeMe: ['DELETE', '/v1/me'],
15
+ updateMe: ['PATCH', '/v1/me'],
16
+ exportMe: ['GET', '/v1/me/export'],
17
+ getMyMembership: ['GET', '/v1/me/membership'],
18
+ requestMyMembership: ['POST', '/v1/me/membership'],
19
+ renewMyMembership: ['POST', '/v1/me/membership/renew'],
20
+ setNetworkOptIn: ['PATCH', '/v1/me/membership/network-opt-in'],
21
+ getMyCardImage: ['GET', '/v1/me/membership/card.svg'],
22
+ emailMyCard: ['POST', '/v1/me/membership/card/email'],
23
+ getGoogleWalletLink: ['GET', '/v1/me/membership/wallet/google'],
24
+ getMyMembershipEvents: ['GET', '/v1/me/membership/events'],
25
+ getMyStatuto: ['GET', '/v1/me/membership/statuto'],
26
+ acceptMyStatuto: ['POST', '/v1/me/membership/statuto/accept'],
27
+ getMyAcceptances: ['GET', '/v1/me/acceptances'],
28
+ recordMyAcceptance: ['POST', '/v1/me/acceptances'],
29
+ getMyCard: ['GET', '/v1/me/membership/card'],
30
+ getMyConnections: ['GET', '/v1/me/connections'],
31
+ revokeMyConnection: ['DELETE', '/v1/me/connections/{client_id}'],
32
+ listMemberships: ['GET', '/v1/memberships'],
33
+ getMembershipStatus: ['GET', '/v1/memberships/{id}/status'],
34
+ getSandbox: ['GET', '/v1/sandbox'],
35
+ resetSandbox: ['POST', '/v1/sandbox/reset'],
36
+ signup: ['POST', '/v1/signup'],
37
+ enroll: ['POST', '/v1/enroll'],
38
+ confirmEnrollment: ['POST', '/v1/enroll/confirm'],
39
+ createCheckin: ['POST', '/v1/checkins'],
40
+ listPublicEvents: ['GET', '/v1/aps/{slug}/events'],
41
+ getPublicEvent: ['GET', '/v1/aps/{slug}/events/{event}'],
42
+ listEvents: ['GET', '/v1/events'],
43
+ getEvent: ['GET', '/v1/events/{slug}'],
44
+ getEventEligibility: ['GET', '/v1/events/{slug}/eligibility'],
45
+ createRegistration: ['POST', '/v1/events/{slug}/registrations'],
46
+ listEventRegistrations: ['GET', '/v1/events/{slug}/registrations'],
47
+ listMyRegistrations: ['GET', '/v1/me/registrations'],
48
+ getMyRegistration: ['GET', '/v1/me/registrations/{id}'],
49
+ cancelMyRegistration: ['DELETE', '/v1/me/registrations/{id}'],
50
+ createGuestRegistration: ['POST', '/v1/events/{slug}/registrations/guest'],
51
+ confirmGuestRegistration: ['POST', '/v1/registrations/confirm'],
52
+ listLegalDocuments: ['GET', '/v1/legal'],
53
+ getSubProcessors: ['GET', '/v1/legal/sub-processors'],
54
+ getLegalDocument: ['GET', '/v1/legal/{kind}'],
55
+ getApsPrivacyNotice: ['GET', '/v1/aps/{slug}/privacy-notice'],
56
+ };
57
+ //# sourceMappingURL=generated.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generated.js","sourceRoot":"","sources":["../src/generated.ts"],"names":[],"mappings":"AAAA,wGAAwG;AACxG,kDAAkD;AA2hBlD,4DAA4D;AAC5D,MAAM,CAAC,MAAM,UAAU,GAAG;IACtB,UAAU,EAAE,CAAC,KAAK,EAAE,kBAAkB,CAAC;IACvC,WAAW,EAAE,CAAC,KAAK,EAAE,eAAe,CAAC;IACrC,kBAAkB,EAAE,CAAC,KAAK,EAAE,gBAAgB,CAAC;IAC7C,UAAU,EAAE,CAAC,KAAK,EAAE,yBAAyB,CAAC;IAC9C,kBAAkB,EAAE,CAAC,MAAM,EAAE,0BAA0B,CAAC;IACxD,UAAU,EAAE,CAAC,MAAM,EAAE,iBAAiB,CAAC;IACvC,WAAW,EAAE,CAAC,MAAM,EAAE,kBAAkB,CAAC;IACzC,eAAe,EAAE,CAAC,KAAK,EAAE,uBAAuB,CAAC;IACjD,KAAK,EAAE,CAAC,KAAK,EAAE,QAAQ,CAAC;IACxB,OAAO,EAAE,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAC7B,QAAQ,EAAE,CAAC,OAAO,EAAE,QAAQ,CAAC;IAC7B,QAAQ,EAAE,CAAC,KAAK,EAAE,eAAe,CAAC;IAClC,eAAe,EAAE,CAAC,KAAK,EAAE,mBAAmB,CAAC;IAC7C,mBAAmB,EAAE,CAAC,MAAM,EAAE,mBAAmB,CAAC;IAClD,iBAAiB,EAAE,CAAC,MAAM,EAAE,yBAAyB,CAAC;IACtD,eAAe,EAAE,CAAC,OAAO,EAAE,kCAAkC,CAAC;IAC9D,cAAc,EAAE,CAAC,KAAK,EAAE,4BAA4B,CAAC;IACrD,WAAW,EAAE,CAAC,MAAM,EAAE,8BAA8B,CAAC;IACrD,mBAAmB,EAAE,CAAC,KAAK,EAAE,iCAAiC,CAAC;IAC/D,qBAAqB,EAAE,CAAC,KAAK,EAAE,0BAA0B,CAAC;IAC1D,YAAY,EAAE,CAAC,KAAK,EAAE,2BAA2B,CAAC;IAClD,eAAe,EAAE,CAAC,MAAM,EAAE,kCAAkC,CAAC;IAC7D,gBAAgB,EAAE,CAAC,KAAK,EAAE,oBAAoB,CAAC;IAC/C,kBAAkB,EAAE,CAAC,MAAM,EAAE,oBAAoB,CAAC;IAClD,SAAS,EAAE,CAAC,KAAK,EAAE,wBAAwB,CAAC;IAC5C,gBAAgB,EAAE,CAAC,KAAK,EAAE,oBAAoB,CAAC;IAC/C,kBAAkB,EAAE,CAAC,QAAQ,EAAE,gCAAgC,CAAC;IAChE,eAAe,EAAE,CAAC,KAAK,EAAE,iBAAiB,CAAC;IAC3C,mBAAmB,EAAE,CAAC,KAAK,EAAE,6BAA6B,CAAC;IAC3D,UAAU,EAAE,CAAC,KAAK,EAAE,aAAa,CAAC;IAClC,YAAY,EAAE,CAAC,MAAM,EAAE,mBAAmB,CAAC;IAC3C,MAAM,EAAE,CAAC,MAAM,EAAE,YAAY,CAAC;IAC9B,MAAM,EAAE,CAAC,MAAM,EAAE,YAAY,CAAC;IAC9B,iBAAiB,EAAE,CAAC,MAAM,EAAE,oBAAoB,CAAC;IACjD,aAAa,EAAE,CAAC,MAAM,EAAE,cAAc,CAAC;IACvC,gBAAgB,EAAE,CAAC,KAAK,EAAE,uBAAuB,CAAC;IAClD,cAAc,EAAE,CAAC,KAAK,EAAE,+BAA+B,CAAC;IACxD,UAAU,EAAE,CAAC,KAAK,EAAE,YAAY,CAAC;IACjC,QAAQ,EAAE,CAAC,KAAK,EAAE,mBAAmB,CAAC;IACtC,mBAAmB,EAAE,CAAC,KAAK,EAAE,+BAA+B,CAAC;IAC7D,kBAAkB,EAAE,CAAC,MAAM,EAAE,iCAAiC,CAAC;IAC/D,sBAAsB,EAAE,CAAC,KAAK,EAAE,iCAAiC,CAAC;IAClE,mBAAmB,EAAE,CAAC,KAAK,EAAE,sBAAsB,CAAC;IACpD,iBAAiB,EAAE,CAAC,KAAK,EAAE,2BAA2B,CAAC;IACvD,oBAAoB,EAAE,CAAC,QAAQ,EAAE,2BAA2B,CAAC;IAC7D,uBAAuB,EAAE,CAAC,MAAM,EAAE,uCAAuC,CAAC;IAC1E,wBAAwB,EAAE,CAAC,MAAM,EAAE,2BAA2B,CAAC;IAC/D,kBAAkB,EAAE,CAAC,KAAK,EAAE,WAAW,CAAC;IACxC,gBAAgB,EAAE,CAAC,KAAK,EAAE,0BAA0B,CAAC;IACrD,gBAAgB,EAAE,CAAC,KAAK,EAAE,kBAAkB,CAAC;IAC7C,mBAAmB,EAAE,CAAC,KAAK,EAAE,+BAA+B,CAAC;CACvD,CAAC","sourcesContent":["// GENERATED by scripts/gen-types.mjs from openapi/v1.json — do not edit. Regenerate: npm run spec:types\n// Spec version 2026-09-19 · 45 paths · 35 schemas\n\nexport interface Problem {\n type: string;\n title: string;\n status: number;\n detail?: string;\n code: string;\n request_id?: string;\n errors?: Array<{\n field?: string;\n code?: string;\n message?: string;\n }>;\n}\n\nexport interface Verification {\n status: \"active\" | \"inactive\";\n valid_until?: string;\n /** With `reason: not_yet_valid`: the card is genuine and active, and becomes usable at this moment */\n valid_from?: string;\n reason?: \"expired\" | \"invalid\" | \"not_yet_valid\";\n /** Present for registration tokens */\n kind?: \"card\" | \"registration\";\n event?: {\n slug?: string;\n starts_at?: string;\n } | null;\n}\n\nexport interface MembershipType {\n uid?: string;\n cod?: string;\n name?: string;\n description?: string | null;\n quota_amount?: number | null;\n currency?: string;\n expiry_model?: \"solar_year\" | \"rolling_12\" | \"rolling_24\" | \"prorated_solar\" | \"custom\";\n network_eligible?: boolean;\n}\n\nexport interface Statuto {\n uid?: string;\n version?: number;\n approvaldate?: string | null;\n sha256?: string | null;\n content?: string | null;\n document_url?: string | null;\n}\n\nexport interface ApsPublicConfig {\n /** The language this answer is written in */\n locale?: string;\n /** The languages the association offers: its own, plus those it enabled */\n locales?: Array<string>;\n aps: {\n slug?: string;\n name?: string;\n brandcolor?: string | null;\n picture_url?: string | null;\n citta?: string | null;\n provincia?: string | null;\n enroll_enabled?: boolean;\n /** How the association admits its members, so that an applicant can be told up front what to expect. `model`: `board` — the request waits for a decision of the association’s board, and any fee is paid after it; `provisional` — admitted at once, ratified by the board later; `automatic` — active as soon as the conditions are met. `delay_hours`: the hours between admission and a USABLE card (0 = at once): the membership is active from admission, the card counts at the door only afterwards (see `valid_from`). */\n admission?: {\n model?: \"board\" | \"provisional\" | \"automatic\";\n delay_hours?: number;\n };\n /** Kept for compatibility: true when `admission.model` is `board`. Read `admission` instead. */\n approval_required?: boolean;\n /** Whether the association collects its members’ address — of every member or of nobody. `none`: do not ask (an `address` sent anyway is not stored); `optional`; `required`: enrolment answers 422 without one. */\n member_address?: \"none\" | \"optional\" | \"required\";\n /** How to pay the fee, as the association words it */\n payment_instructions?: string | null;\n /** The activities of general interest the association carries out (Italian Third Sector Code, art. 5): `cod` is the letter of the article, `description` its Italian wording; one is marked as prevalent. */\n activity_sectors?: Array<{\n cod?: string;\n description?: string;\n prevalent?: boolean;\n }>;\n /** Present when the association is registered in the RUNTS (the Italian national register of Third Sector entities), as checked by the platform against the official public lists; null otherwise. Never typed by the association. */\n registry?: {\n /** Section of the register */\n section?: \"APS\" | \"ODV\" | \"EF\" | \"IS\" | \"RA\" | \"SOMS\" | \"ALTRI\" | null | null;\n /** Repertory number */\n number?: string | null;\n registered_on?: string | null;\n /** Date of the official list the check ran against */\n checked_on?: string | null;\n } | null;\n };\n membership_types: Array<MembershipType>;\n statuto: Statuto | unknown;\n /** The association's in-force privacy notice to members (full text: GET /v1/aps/{slug}/privacy-notice) */\n privacy_notice?: PrivacyNoticeRef | unknown;\n}\n\nexport interface FiscalCodeCheck {\n /** Codice fiscale (16 characters) */\n code: string;\n first_name?: string;\n last_name?: string;\n gender?: \"M\" | \"F\";\n /** Date of birth */\n date?: string;\n /** Birthplace: the comune, for a person born in Italy */\n place?: string;\n /** Birth country, ISO 3166-1 alpha-2. A code encodes the comune for people born in Italy and only the STATE for everybody else: anything but IT is compared with that state and `place` is ignored */\n country?: string;\n}\n\nexport interface FiscalCodeResult {\n valid?: boolean;\n error?: \"invalid\" | \"mismatch\" | null;\n /** What disagrees with the code, when `error` is `mismatch` */\n mismatches?: Array<\"lastName\" | \"firstName\" | \"gender\" | \"date\" | \"place\">;\n /** `names_swapped`: the code matches once surname and given name are exchanged */\n hints?: Array<\"names_swapped\">;\n /** The date of birth the code itself encodes */\n birth_date?: string | null;\n /** The birth country the code itself encodes, ISO 3166-1 alpha-2 (IT for a comune) */\n birth_country?: string | null;\n}\n\nexport interface CardKeys {\n keys?: Array<{\n kty?: string;\n crv?: string;\n x?: string;\n kid?: string;\n use?: string;\n alg?: string;\n }>;\n}\n\nexport interface SignupRequest {\n email: string;\n first_name: string;\n last_name: string;\n phone?: string | null;\n dob?: string | null;\n /** Demographic only: it is not cross-checked */\n gender?: \"M\" | \"F\" | null;\n /** Comune (born in Italy) or city, free text (born abroad) */\n birthplace?: string | null;\n /** ISO 3166-1 alpha-2 */\n birth_country?: string | null;\n /** Validated and cross-checked against the other fields when present */\n codicefiscale?: string | null;\n /** The person confirms a code that disagrees with their particulars (422 `codicefiscale_mismatch` with `confirmable: true`) */\n codicefiscale_confirmed?: boolean;\n /** The language of the page the person filled in (`it`, `en`; a regional tag such as `en-GB` is reduced to its language). It decides the language of the mails that follow and becomes the preference of a NEW account; an existing account keeps its own. Unsupported values are ignored */\n locale?: string | null;\n /** The account terms (platform_terms) the person accepted on your site — optional, but when given it must name the in-force version */\n accept_terms?: LegalRef;\n /** The platform privacy notice (platform_privacy) the person read on your site — optional, same rule */\n acknowledge_privacy?: LegalRef;\n}\n\nexport interface EnrollRequest {\n email: string;\n first_name: string;\n last_name: string;\n /** Optional. A person is identified by a fiscal code OR by `dob` + `birthplace` + `birth_country` — never neither (422 `required` on each missing particular). When present it is validated and cross-checked against the names, the date and the place (the state, for people born abroad) */\n codicefiscale?: string | null;\n /** The person confirms a code that disagrees with their particulars (422 `codicefiscale_mismatch` with `confirmable: true`) */\n codicefiscale_confirmed?: boolean;\n /** Residence or, where different, domicile. Asked of every member or of nobody: the public profile says what the association declared (`member_address`: none — ignored, not stored · optional · required — 422 `required` on `address` without it) */\n address?: MemberAddress;\n phone?: string | null;\n dob?: string | null;\n /** Demographic only: it is not cross-checked */\n gender?: \"M\" | \"F\" | null;\n /** Comune (born in Italy) or city, free text (born abroad) */\n birthplace?: string | null;\n /** ISO 3166-1 alpha-2 */\n birth_country?: string | null;\n /** One of the association’s membership types (omit when it has exactly one) */\n membership_type?: string;\n /** The language of the page the person filled in (`it`, `en`; a regional tag such as `en-GB` is reduced to its language). It decides the language of the mails that follow and becomes the preference of a NEW account; an existing account keeps its own. Unsupported values are ignored */\n locale?: string | null;\n /** The in-force statuto the person accepted on your site (from GET /v1/aps/{slug}) */\n accept_statuto: {\n version: number;\n sha256?: string;\n };\n /** The association's privacy notice the person read on your site (GET /v1/aps/{slug} → privacy_notice). REQUIRED when the association publishes one; 422 `privacy_notice_outdated` when it is not the in-force version */\n privacy_notice?: PrivacyNoticeAck;\n /** The account terms (platform_terms) the person accepted on your site — optional, must name the in-force version */\n accept_terms?: LegalRef;\n /** The platform privacy notice (platform_privacy) the person read — optional, same rule */\n acknowledge_privacy?: LegalRef;\n}\n\nexport interface Accepted {\n status: \"accepted\";\n}\n\nexport interface Me {\n /** The subject identifier of this person, as in the ID token */\n sub: string;\n email: string;\n email_verified: boolean;\n first_name?: string | null;\n last_name?: string | null;\n phone?: string | null;\n dob?: string | null;\n /** Demographic only */\n gender?: \"M\" | \"F\" | null;\n birthplace?: string | null;\n /** ISO 3166-1 alpha-2 */\n birth_country?: string | null;\n /** Optional: a person may have none */\n codicefiscale?: string | null;\n /** How the person is identified. `matched`: a fiscal code that agrees with their particulars; `mismatch_confirmed`: a code that disagrees, confirmed by the person; `absent`: no code — date, place and country of birth identify them; null: not identified yet (they cannot request a membership) */\n codicefiscale_check?: \"matched\" | \"mismatch_confirmed\" | \"absent\" | null;\n /** The language the person chose for the platform and its mails; null: never chosen — the language of the request, then of the association, applies */\n locale?: \"it\" | \"en\" | null;\n updated_at?: string | null;\n}\n\nexport interface MemberAddress {\n kind?: \"residence\" | \"domicile\";\n /** Street and number */\n line: string;\n postal_code?: string | null;\n city: string;\n /** Italian addresses only (two letters); dropped abroad */\n province?: string | null;\n /** ISO 3166-1 alpha-2 */\n country?: string;\n}\n\nexport interface EnrollConfirmRequest {\n token: string;\n /** Only after a 409 `identification_required`: what the account still lacks — a fiscal code, or date, place and country of birth. Completes the EMPTY fields of the profile, never over what is there */\n identification?: {\n dob?: string;\n birthplace?: string;\n birth_country?: string;\n codicefiscale?: string;\n codicefiscale_confirmed?: boolean;\n };\n}\n\nexport interface Event {\n id?: string;\n slug?: string;\n /** The language the `title` was served in. When it is not the one you asked for, the association has no translation: you got its Italian text, not a machine translation */\n locale?: string;\n /** The languages in which this event has a title — the association’s own always, plus those it enabled and wrote */\n locales?: Array<string>;\n title?: string;\n summary?: string | null;\n /** Markdown; render it yourself */\n description_md?: string | null;\n starts_at?: string;\n ends_at?: string | null;\n timezone?: string;\n status?: \"published\" | \"completed\" | \"cancelled\";\n visibility?: \"members_only\" | \"public\";\n location?: {\n name?: string | null;\n address?: string | null;\n lat?: number | null;\n lng?: number | null;\n } | null;\n cover_url?: string | null;\n gallery?: Array<{\n url?: string;\n alt?: string | null;\n order?: number;\n }>;\n links?: Array<{\n label?: string;\n url?: string;\n }>;\n registration?: {\n opens_at?: string | null;\n closes_at?: string | null;\n capacity?: number | null;\n remaining?: number | null;\n cancellation_hours?: number;\n };\n registration_types?: Array<{\n uid?: string;\n cod?: string;\n name?: string;\n description?: string | null;\n /** 0 = free */\n amount?: number;\n currency?: string;\n quantity?: number | null;\n /** Places left (never who holds them) */\n remaining?: number | null;\n max_per_user?: number;\n requires_active_membership?: boolean;\n open?: boolean;\n reason?: \"sold_out\" | \"registration_not_open\" | \"registration_closed\" | null | null;\n opens_at?: string | null;\n closes_at?: string | null;\n }>;\n published_at?: string | null;\n cancelled_at?: string | null;\n cancel_reason?: string | null;\n}\n\nexport interface Registration {\n id?: string;\n status?: \"reserved\" | \"confirmed\" | \"cancelled\" | \"refunded\";\n event?: {\n id?: string;\n slug?: string;\n title?: string;\n starts_at?: string;\n ends_at?: string | null;\n timezone?: string;\n status?: string;\n location?: string | null;\n };\n registration_type?: {\n uid?: string;\n cod?: string;\n name?: string;\n amount?: number;\n currency?: string;\n };\n quantity?: number;\n reserved_until?: string | null;\n checked_in_at?: string | null;\n cancelled_at?: string | null;\n cancel_reason?: string | null;\n can_cancel?: boolean;\n payment?: {\n status?: string;\n amount?: number;\n currency?: string;\n method?: string;\n paid_at?: string;\n } | null;\n /** How to pay the contribution while reserved */\n payment_instructions?: string | null;\n /** Free text the person wrote. Withheld (null) from third-party clients when the association declared it processes special categories of data */\n note?: string | null;\n created_at?: string;\n /** The registration QR payload (vmt_…), confirmed registrations only */\n token?: string | null;\n}\n\nexport interface Eligibility {\n can_register?: boolean;\n membership_verdict?: string | null;\n types?: Array<{\n uid?: string;\n cod?: string;\n can_register?: boolean;\n reasons?: Array<string>;\n pending_membership?: boolean;\n }>;\n}\n\nexport interface RegistrationRequest {\n registration_type: string;\n note?: string | null;\n quantity?: number;\n /** The language the registration was made in (`it`, `en`): the language of the mails to a guest, and the fallback for a member who never chose one. Defaults to Accept-Language */\n locale?: string | null;\n}\n\nexport interface GuestRegistrationRequest {\n email: string;\n first_name: string;\n last_name: string;\n registration_type: string;\n note?: string | null;\n /** The language the registration was made in (`it`, `en`): the language of the mails to a guest, and the fallback for a member who never chose one. Defaults to Accept-Language */\n locale?: string | null;\n}\n\nexport interface RegistrationListItem {\n id?: string;\n status?: string;\n registration_type?: string | null;\n membership_id?: string | null;\n quantity?: number;\n checked_in_at?: string | null;\n created_at?: string;\n}\n\nexport interface LegalDocumentSummary {\n uid?: string;\n /** Document kind (platform_terms, platform_privacy, platform_cookie, aps_terms, aps_dpa, aps_dpa_annex1_processing … developer_terms) */\n kind: string;\n locale: \"it\" | \"en\";\n /** Version label (1.0, 1.1, …) */\n version: string;\n title: string;\n /** What changed in this version */\n summary?: string | null;\n effective_from?: string | null;\n retired_at?: string | null;\n /** SHA-256 of the canonical template body */\n sha256?: string | null;\n /** This is the in-force version of the kind in its locale */\n current: boolean;\n requires_reacceptance?: boolean;\n}\n\nexport interface LegalDocumentList {\n documents: Array<LegalDocumentSummary>;\n /** Previous versions (with ?all=1) */\n archive?: Array<LegalDocumentSummary>;\n}\n\nexport type LegalDocument = unknown;\n\nexport interface SubProcessor {\n cod: string;\n name: string;\n entity?: string | null;\n service: string;\n data_categories?: string | null;\n location?: string | null;\n transfer_basis?: string | null;\n role: \"processor\" | \"controller\" | \"none\";\n status: \"active\" | \"planned\" | \"retired\";\n since?: string | null;\n until?: string | null;\n website?: string | null;\n}\n\nexport interface SubProcessorRegistry {\n /** The in-force Annex 3 version the registry is bound to */\n version?: string | null;\n effective_from?: string | null;\n notice_days?: number;\n at?: string;\n active: Array<SubProcessor>;\n planned: Array<SubProcessor>;\n /** Vendors that process no tenant data (transparency) */\n other: Array<SubProcessor>;\n}\n\nexport interface PrivacyNoticeRef {\n uid: string;\n version: number;\n locale: string;\n title?: string;\n sha256?: string | null;\n effective_from?: string | null;\n}\n\nexport type PrivacyNotice = unknown;\n\nexport interface LegalRef {\n /** The in-force version label shown (GET /v1/legal/{kind}) */\n version: string;\n /** Its template hash, when published */\n sha256?: string;\n}\n\nexport interface PrivacyNoticeAck {\n /** The in-force notice version shown (GET /v1/aps/{slug} → privacy_notice) */\n version: number;\n sha256?: string;\n /** The language of the notice you showed (`privacy_notice.locale` of the answer you read it from). Each language is its own document, with its own version: name it when you read the profile with `?locale=`. Default: the request’s `locale`, then the association’s language */\n locale?: string;\n}\n\nexport interface AcceptanceRecord {\n at: string;\n action: \"accepted\" | \"acknowledged\" | \"consented\" | \"withdrawn\" | \"declared\";\n channel?: \"ui\" | \"public\" | \"api\" | \"job\" | \"paper\";\n kind: string;\n title?: string;\n version: string;\n sha256?: string | null;\n /** Hash of the text actually shown */\n rendered_sha256?: string | null;\n locale?: string | null;\n /** The association the act concerns, when any */\n association?: string | null;\n}\n\nexport interface PendingDocument {\n kind: string;\n title?: string;\n locale?: string;\n version: string | number;\n sha256?: string | null;\n effective_from?: string | null;\n /** What the person is asked to do */\n action: \"accepted\" | \"acknowledged\" | \"consented\";\n /** Never acted on any version of this kind (false: a new version requires it again) */\n first?: boolean;\n}\n\nexport interface MyAcceptances {\n items: Array<AcceptanceRecord>;\n pending: {\n /** Account-layer documents still to accept / acknowledge */\n platform?: Array<PendingDocument>;\n /** This association's notice to members, when not yet acknowledged */\n privacy_notice?: PendingDocument | unknown;\n };\n}\n\nexport interface AcceptanceRequest {\n /** platform_terms | platform_privacy | network_consent | privacy_notice */\n kind: string;\n /** The in-force version shown */\n version: string | number;\n sha256?: string;\n}\n\nexport interface AcceptanceResult {\n recorded: boolean;\n kind: string;\n action: string;\n version: string;\n at: string;\n}\n\nexport interface EnrollConfirmResult {\n status: \"pending\" | \"active\" | \"suspended\" | \"revoked\" | \"rejected\";\n /** The person already had a membership request or membership here */\n already: boolean;\n /** Why the membership is still pending, in order: the association’s approval first (when it admits by decision of its board), then the fee. Empty when active */\n pending_reasons?: Array<\"approval\" | \"payment\">;\n /** May the fee be paid yet? False while the approval is pending: approval opens payment */\n payment_open?: boolean;\n /** When the card becomes usable, for an active membership inside the association’s usability delay; null otherwise */\n valid_from?: string | null;\n association: {\n name?: string;\n slug?: string;\n };\n}\n\n/** Every operation of the document: id → [method, path]. */\nexport const operations = {\n getOpenApi: ['GET', '/v1/openapi.json'],\n getCardKeys: ['GET', '/v1/card-keys'],\n getApsPublicConfig: ['GET', '/v1/aps/{slug}'],\n verifyCard: ['GET', '/v1/verify/{card_token}'],\n validateFiscalCode: ['POST', '/v1/validate/fiscal-code'],\n oauthToken: ['POST', '/v1/oauth/token'],\n oauthRevoke: ['POST', '/v1/oauth/revoke'],\n oauthClientInfo: ['GET', '/v1/oauth/client-info'],\n getMe: ['GET', '/v1/me'],\n closeMe: ['DELETE', '/v1/me'],\n updateMe: ['PATCH', '/v1/me'],\n exportMe: ['GET', '/v1/me/export'],\n getMyMembership: ['GET', '/v1/me/membership'],\n requestMyMembership: ['POST', '/v1/me/membership'],\n renewMyMembership: ['POST', '/v1/me/membership/renew'],\n setNetworkOptIn: ['PATCH', '/v1/me/membership/network-opt-in'],\n getMyCardImage: ['GET', '/v1/me/membership/card.svg'],\n emailMyCard: ['POST', '/v1/me/membership/card/email'],\n getGoogleWalletLink: ['GET', '/v1/me/membership/wallet/google'],\n getMyMembershipEvents: ['GET', '/v1/me/membership/events'],\n getMyStatuto: ['GET', '/v1/me/membership/statuto'],\n acceptMyStatuto: ['POST', '/v1/me/membership/statuto/accept'],\n getMyAcceptances: ['GET', '/v1/me/acceptances'],\n recordMyAcceptance: ['POST', '/v1/me/acceptances'],\n getMyCard: ['GET', '/v1/me/membership/card'],\n getMyConnections: ['GET', '/v1/me/connections'],\n revokeMyConnection: ['DELETE', '/v1/me/connections/{client_id}'],\n listMemberships: ['GET', '/v1/memberships'],\n getMembershipStatus: ['GET', '/v1/memberships/{id}/status'],\n getSandbox: ['GET', '/v1/sandbox'],\n resetSandbox: ['POST', '/v1/sandbox/reset'],\n signup: ['POST', '/v1/signup'],\n enroll: ['POST', '/v1/enroll'],\n confirmEnrollment: ['POST', '/v1/enroll/confirm'],\n createCheckin: ['POST', '/v1/checkins'],\n listPublicEvents: ['GET', '/v1/aps/{slug}/events'],\n getPublicEvent: ['GET', '/v1/aps/{slug}/events/{event}'],\n listEvents: ['GET', '/v1/events'],\n getEvent: ['GET', '/v1/events/{slug}'],\n getEventEligibility: ['GET', '/v1/events/{slug}/eligibility'],\n createRegistration: ['POST', '/v1/events/{slug}/registrations'],\n listEventRegistrations: ['GET', '/v1/events/{slug}/registrations'],\n listMyRegistrations: ['GET', '/v1/me/registrations'],\n getMyRegistration: ['GET', '/v1/me/registrations/{id}'],\n cancelMyRegistration: ['DELETE', '/v1/me/registrations/{id}'],\n createGuestRegistration: ['POST', '/v1/events/{slug}/registrations/guest'],\n confirmGuestRegistration: ['POST', '/v1/registrations/confirm'],\n listLegalDocuments: ['GET', '/v1/legal'],\n getSubProcessors: ['GET', '/v1/legal/sub-processors'],\n getLegalDocument: ['GET', '/v1/legal/{kind}'],\n getApsPrivacyNotice: ['GET', '/v1/aps/{slug}/privacy-notice'],\n} as const;\nexport type OperationId = keyof typeof operations;\n"]}
@@ -0,0 +1,205 @@
1
+ import { type PublicApi } from './public.js';
2
+ import { type StorageKind, type TokenStorage } from './storage.js';
3
+ import type { AcceptanceInput, AcceptanceResult, Accepted, Card, Connection, Eligibility, Event, EventList, EventListParams, LocaleParam, Me, Membership, MembershipEvents, MembershipRequest, MembershipRequestResult, MeUpdate, MyAcceptances, NetworkOptIn, Registration, RegistrationList, RegistrationRequest, RenewResult, Scope, StatutoAccept, StatutoInfo } from './types.js';
4
+ export { VimineError } from './errors.js';
5
+ export type { FieldError, ProblemDetails } from './errors.js';
6
+ export { createPkce, createState, createVerifier, createChallenge, base64url } from './pkce.js';
7
+ export { MemoryStorage, type StorageKind, type TokenStorage } from './storage.js';
8
+ /** The OpenAPI document's own vocabulary (generated from openapi/v1.json — `npm run spec:types`). */
9
+ export type * as Spec from './generated.js';
10
+ export { publicApi, DEFAULT_API_URL, eventQuery, type PublicApi, type PublicOptions } from './public.js';
11
+ export type * from './types.js';
12
+ export declare const DEFAULT_APP_URL = "https://app.vimine.network";
13
+ export interface VimineOptions {
14
+ /** Your client id (`vmc_…`), from the association's developer console. */
15
+ clientId: string;
16
+ /** One of the redirect URIs registered for the client — the page that calls `handleRedirect()`. */
17
+ redirectUri: string;
18
+ /** Default permissions to ask for; `signIn()` may override. */
19
+ scopes?: Scope[];
20
+ /** The API origin (default production). */
21
+ apiUrl?: string;
22
+ /** The app origin that hosts sign-in and consent (default production). */
23
+ appUrl?: string;
24
+ /** Where tokens live: `session` (default, per tab), `local` (shared across tabs), `memory`, or your own adapter. */
25
+ storage?: StorageKind | TokenStorage;
26
+ /** Storage key prefix (default derived from the client id). */
27
+ storageKey?: string;
28
+ /** UI language of the hosted pages. */
29
+ locale?: 'it' | 'en';
30
+ /** Custom fetch (tests, polyfills). */
31
+ fetch?: typeof fetch;
32
+ /** How to leave the page (default: the top window's `location.assign`). */
33
+ navigate?: (url: string) => void;
34
+ }
35
+ export interface SignInOptions {
36
+ scopes?: Scope[];
37
+ /** `login` forces the credential form even with a live session; `consent` forces the consent screen. */
38
+ prompt?: 'login' | 'consent';
39
+ /** Your own state to get back after the redirect (kept in storage, not sent). */
40
+ returnTo?: string;
41
+ }
42
+ export interface Session {
43
+ accessToken: string;
44
+ refreshToken: string | null;
45
+ /** Absolute time (ms) the access token expires. */
46
+ expiresAt: number;
47
+ scope: Scope[];
48
+ /** The member's pairwise subject for this association. */
49
+ sub: string | null;
50
+ /** `test` for sessions minted through a sandbox client. */
51
+ mode?: 'live' | 'test';
52
+ }
53
+ export interface RedirectResult {
54
+ session: Session;
55
+ /** The `returnTo` given to `signIn()`, if any. */
56
+ returnTo: string | null;
57
+ }
58
+ export interface SignOutOptions {
59
+ /** Also end the member's Vimine session (single sign-out): leaves the page for the app's logout route. */
60
+ everywhere?: boolean;
61
+ /** Where the app sends the member afterwards (must be on a registered origin); default: `redirectUri`. */
62
+ postLogoutRedirectUri?: string;
63
+ state?: string;
64
+ }
65
+ export declare class Vimine {
66
+ readonly options: Required<Pick<VimineOptions, 'clientId' | 'redirectUri' | 'apiUrl' | 'appUrl' | 'locale'>> & VimineOptions;
67
+ /** The public, credential-less endpoints (verify a card, an association's profile, fiscal code, card keys). */
68
+ readonly public: PublicApi;
69
+ private readonly storage;
70
+ private readonly fetchImpl;
71
+ private readonly keys;
72
+ private refreshing;
73
+ private readonly listeners;
74
+ constructor(options: VimineOptions);
75
+ /** Build the authorization URL and remember the pending flow. Use `signIn()` unless you render the link yourself. */
76
+ createSignInUrl(opts?: SignInOptions): Promise<string>;
77
+ /**
78
+ * Start the sign-in: navigates the TOP window to the hosted sign-in + consent page. Call it from a user
79
+ * gesture (a click). From inside a cross-origin or sandboxed frame the navigation is refused (`framed`):
80
+ * the hosted page is never shown in a frame.
81
+ */
82
+ signIn(opts?: SignInOptions): Promise<void>;
83
+ /** Does this URL carry the parameters of a sign-in redirect (`code`+`state` or `error`)? */
84
+ hasRedirectParams(url?: string): boolean;
85
+ /**
86
+ * On the redirect page: exchange the authorization code for tokens and store the session. Returns null when
87
+ * the URL carries no sign-in parameters. Throws `state_mismatch` / `no_flow` for a redirect this client did
88
+ * not start, and the OAuth error (`access_denied`, …) when the member did not authorize.
89
+ */
90
+ handleRedirect(opts?: {
91
+ url?: string;
92
+ cleanUrl?: boolean;
93
+ }): Promise<RedirectResult | null>;
94
+ getSession(): Session | null;
95
+ isSignedIn(): boolean;
96
+ /** A valid access token, refreshed when about to expire. Throws `not_signed_in` when there is no session. */
97
+ getAccessToken(): Promise<string>;
98
+ /** Rotate the session (single-flight). An unusable refresh token ends the session. */
99
+ refresh(): Promise<Session>;
100
+ /** Revoke the session (RFC 7009) and forget it; with `everywhere`, also end the member's Vimine session. */
101
+ signOut(opts?: SignOutOptions): Promise<void>;
102
+ /** Subscribe to session changes (sign-in, refresh, sign-out; other tabs when storage is `local`). */
103
+ onChange(listener: (session: Session | null) => void): () => void;
104
+ /** An authenticated call to the API; JSON in and out, problem details as `VimineError`, one retry after a refresh on 401. */
105
+ request<T>(path: string, init?: RequestInit & {
106
+ idempotencyKey?: string;
107
+ }): Promise<T>;
108
+ /** The member's profile (`profile:read` / `profile:write`). */
109
+ readonly me: {
110
+ get: () => Promise<Me>;
111
+ /**
112
+ * A fiscal code that disagrees with the particulars answers 422 with a `codicefiscale_mismatch` entry in
113
+ * `errors[]`; when that entry says `confirmable: true` the person may confirm it: send `codicefiscale_confirmed: true`.
114
+ */
115
+ update: (patch: MeUpdate) => Promise<Me>;
116
+ };
117
+ /** The member's membership in this association (`membership:read`, `membership:request`, `statuto:accept`). */
118
+ readonly membership: {
119
+ get: () => Promise<Membership>;
120
+ /**
121
+ * Ask for a membership. 422 `identification_required` when the profile is not identified yet — a fiscal code, or
122
+ * date, place and country of birth: `errors[]` names what is missing; complete it with `me.update()` and ask again.
123
+ */
124
+ request: (body: MembershipRequest, opts?: {
125
+ idempotencyKey?: string;
126
+ }) => Promise<MembershipRequestResult>;
127
+ events: (params?: {
128
+ limit?: number;
129
+ cursor?: string;
130
+ }) => Promise<MembershipEvents>;
131
+ statuto: () => Promise<StatutoInfo>;
132
+ acceptStatuto: (body: StatutoAccept) => Promise<{
133
+ accepted: true;
134
+ version: number;
135
+ }>;
136
+ /** The signed card token and its window. 409 `not_active` unless the membership is active: only an active membership has a card. */
137
+ card: () => Promise<Card>;
138
+ /** Self-service renewal (`membership:request`): renewed at once for a free type with no approval gate, else a request. */
139
+ renew: (body: StatutoAccept, opts?: {
140
+ idempotencyKey?: string;
141
+ }) => Promise<RenewResult>;
142
+ /** Network consent (`network:manage`); 409 `not_eligible` when the membership type is not in the network. */
143
+ setNetworkOptIn: (optIn: boolean) => Promise<NetworkOptIn>;
144
+ /** A Save-to-Google-Wallet link for the card (`membership:read`); 409 `not_active` when there is no card yet, 503 when the deployment has no wallet issuer. */
145
+ googleWalletUrl: () => Promise<{
146
+ url: string;
147
+ }>;
148
+ /** The card as SVG markup (with the current QR) — inline it, or hand it to `<vimine-card>`. 409 `not_active` unless the membership is active. */
149
+ cardSvg: () => Promise<string>;
150
+ /** Ask the API to e-mail the member their card (SVG + QR attached). 409 `not_active` unless the membership is active. */
151
+ emailCard: () => Promise<Accepted>;
152
+ };
153
+ /**
154
+ * The member's legal acceptances (`legal:read`, `legal:accept`): what they accepted or acknowledged, what is still
155
+ * pending — the account terms, the platform privacy notice, this association's notice to members — and the call
156
+ * that records one at the in-force version your app showed (422 `<kind>_outdated` otherwise).
157
+ */
158
+ readonly legal: {
159
+ acceptances: (params?: {
160
+ locale?: "it" | "en";
161
+ }) => Promise<MyAcceptances>;
162
+ record: (body: AcceptanceInput, opts?: {
163
+ idempotencyKey?: string;
164
+ }) => Promise<AcceptanceResult>;
165
+ };
166
+ /** Events of the association (`events:read`): published ones, members-only included — the public ones need no sign-in: `publicApi().events`. */
167
+ readonly events: {
168
+ /** `filter`: upcoming (default) | past | cancelled | all; `from` / `to` bound `starts_at`. */
169
+ list: (params?: EventListParams) => Promise<EventList>;
170
+ get: (slug: string, params?: LocaleParam) => Promise<Event>;
171
+ /** May the member register, per registration type, with reasons. */
172
+ eligibility: (slug: string) => Promise<Eligibility>;
173
+ };
174
+ /** The member's event registrations (`registrations:read` / `registrations:write`). */
175
+ readonly registrations: {
176
+ /**
177
+ * Register for an event: a free type answers `confirmed` with the QR `token`; a paid one answers `reserved`
178
+ * with `payment_instructions` until the association records the contribution. `422 not_eligible` carries
179
+ * the reasons. Retries are safe: an `Idempotency-Key` is generated unless you pass one.
180
+ */
181
+ create: (slug: string, body: RegistrationRequest, opts?: {
182
+ idempotencyKey?: string;
183
+ }) => Promise<Registration>;
184
+ /** The member's registrations, newest event first (`filter: 'upcoming'` for the ones still to come). */
185
+ list: (params?: {
186
+ filter?: "upcoming" | "all";
187
+ }) => Promise<RegistrationList>;
188
+ get: (id: string) => Promise<Registration>;
189
+ /** Cancel inside the event's cancellation window — `409 window_closed` otherwise. */
190
+ cancel: (id: string) => Promise<Registration>;
191
+ /** The QR payload of a confirmed registration (what the door scans), or null. */
192
+ tokenPayload: (id: string) => Promise<string | null>;
193
+ };
194
+ /** The apps the member authorized in this association. */
195
+ readonly connections: {
196
+ list: () => Promise<{
197
+ items: Connection[];
198
+ }>;
199
+ revoke: (clientId: string) => Promise<void>;
200
+ };
201
+ private tokenRequest;
202
+ private storeTokens;
203
+ private clearSession;
204
+ private emit;
205
+ }