@vimine/sdk 0.3.2 → 0.3.3

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.
@@ -1,6 +1,173 @@
1
1
  import { Vimine, type VimineOptions } from "./index.js";
2
+ declare const STRINGS: {
3
+ it: {
4
+ signIn: string;
5
+ signOut: string;
6
+ loading: string;
7
+ notSignedIn: string;
8
+ noMembership: string;
9
+ notActive: string;
10
+ error: string;
11
+ noEvents: string;
12
+ free: string;
13
+ places: string;
14
+ register: string;
15
+ signInToRegister: string;
16
+ joinAndBook: string;
17
+ alreadyMember: string;
18
+ registered: string;
19
+ reserved: string;
20
+ details: string;
21
+ reason: Record<string, string>;
22
+ };
23
+ en: {
24
+ signIn: string;
25
+ signOut: string;
26
+ loading: string;
27
+ notSignedIn: string;
28
+ noMembership: string;
29
+ notActive: string;
30
+ error: string;
31
+ noEvents: string;
32
+ free: string;
33
+ places: string;
34
+ register: string;
35
+ signInToRegister: string;
36
+ joinAndBook: string;
37
+ alreadyMember: string;
38
+ registered: string;
39
+ reserved: string;
40
+ details: string;
41
+ reason: Record<string, string>;
42
+ };
43
+ "zh-Hans": {
44
+ signIn: string;
45
+ signOut: string;
46
+ loading: string;
47
+ notSignedIn: string;
48
+ noMembership: string;
49
+ notActive: string;
50
+ error: string;
51
+ noEvents: string;
52
+ free: string;
53
+ places: string;
54
+ register: string;
55
+ signInToRegister: string;
56
+ joinAndBook: string;
57
+ alreadyMember: string;
58
+ registered: string;
59
+ reserved: string;
60
+ details: string;
61
+ reason: Record<string, string>;
62
+ };
63
+ "zh-Hant": {
64
+ signIn: string;
65
+ signOut: string;
66
+ loading: string;
67
+ notSignedIn: string;
68
+ noMembership: string;
69
+ notActive: string;
70
+ error: string;
71
+ noEvents: string;
72
+ free: string;
73
+ places: string;
74
+ register: string;
75
+ signInToRegister: string;
76
+ joinAndBook: string;
77
+ alreadyMember: string;
78
+ registered: string;
79
+ reserved: string;
80
+ details: string;
81
+ reason: Record<string, string>;
82
+ };
83
+ fr: {
84
+ signIn: string;
85
+ signOut: string;
86
+ loading: string;
87
+ notSignedIn: string;
88
+ noMembership: string;
89
+ notActive: string;
90
+ error: string;
91
+ noEvents: string;
92
+ free: string;
93
+ places: string;
94
+ register: string;
95
+ signInToRegister: string;
96
+ joinAndBook: string;
97
+ alreadyMember: string;
98
+ registered: string;
99
+ reserved: string;
100
+ details: string;
101
+ reason: Record<string, string>;
102
+ };
103
+ es: {
104
+ signIn: string;
105
+ signOut: string;
106
+ loading: string;
107
+ notSignedIn: string;
108
+ noMembership: string;
109
+ notActive: string;
110
+ error: string;
111
+ noEvents: string;
112
+ free: string;
113
+ places: string;
114
+ register: string;
115
+ signInToRegister: string;
116
+ joinAndBook: string;
117
+ alreadyMember: string;
118
+ registered: string;
119
+ reserved: string;
120
+ details: string;
121
+ reason: Record<string, string>;
122
+ };
123
+ de: {
124
+ signIn: string;
125
+ signOut: string;
126
+ loading: string;
127
+ notSignedIn: string;
128
+ noMembership: string;
129
+ notActive: string;
130
+ error: string;
131
+ noEvents: string;
132
+ free: string;
133
+ places: string;
134
+ register: string;
135
+ signInToRegister: string;
136
+ joinAndBook: string;
137
+ alreadyMember: string;
138
+ registered: string;
139
+ reserved: string;
140
+ details: string;
141
+ reason: Record<string, string>;
142
+ };
143
+ "pt-BR": {
144
+ signIn: string;
145
+ signOut: string;
146
+ loading: string;
147
+ notSignedIn: string;
148
+ noMembership: string;
149
+ notActive: string;
150
+ error: string;
151
+ noEvents: string;
152
+ free: string;
153
+ places: string;
154
+ register: string;
155
+ signInToRegister: string;
156
+ joinAndBook: string;
157
+ alreadyMember: string;
158
+ registered: string;
159
+ reserved: string;
160
+ details: string;
161
+ reason: Record<string, string>;
162
+ };
163
+ };
164
+ type Lang = keyof typeof STRINGS;
165
+ /** The elements' language for a page's tag, or null when they do not speak it (`preview`: drafts included). */
166
+ export declare const matchLang: (tag: string, preview?: boolean) => Lang | null;
2
167
  /** The client the elements use. Call once; pass your own instance to share it with the rest of the page. */
3
- export declare function defineVimineElements(options: VimineOptions | Vimine): Vimine;
168
+ export declare function defineVimineElements(options: VimineOptions | Vimine, elements?: {
169
+ previewLanguages?: boolean;
170
+ }): Vimine;
4
171
  /** `<vimine-sign-in scope="…" return-to="/area" label="…" handle-redirect>` — a sign-in / sign-out button. */
5
172
  export declare class VimineSignIn extends HTMLElement {
6
173
  private unsubscribe;
@@ -79,3 +246,4 @@ export declare class VimineEvents extends HTMLElement {
79
246
  private card;
80
247
  private typeRow;
81
248
  }
249
+ export {};
package/dist/elements.js CHANGED
@@ -90,15 +90,255 @@ const STRINGS = {
90
90
  invalid_type: "invalid type",
91
91
  },
92
92
  },
93
+ "zh-Hans": {
94
+ signIn: "使用 Vimine 登录",
95
+ signOut: "退出",
96
+ loading: "加载中…",
97
+ notSignedIn: "请登录以查看您的会员卡。",
98
+ noMembership: "您在这个协会没有会员卡。",
99
+ notActive: "会员卡尚未生效:生效后会显示二维码。",
100
+ error: "出现错误。",
101
+ noEvents: "暂无安排的活动。",
102
+ free: "免费",
103
+ places: "个名额",
104
+ register: "报名",
105
+ signInToRegister: "登录后报名",
106
+ joinAndBook: "加入协会并预约",
107
+ alreadyMember: "已是会员?请登录",
108
+ registered: "报名已确认",
109
+ reserved: "名额已保留:等待缴纳参与费",
110
+ details: "详情",
111
+ reason: {
112
+ sold_out: "名额已满",
113
+ event_full: "已满员",
114
+ registration_not_open: "报名尚未开始",
115
+ registration_closed: "报名已截止",
116
+ membership_required: "仅限会员",
117
+ membership_not_active: "会员卡无效",
118
+ membership_not_yet_valid: "在该日期您的会员卡尚不可用",
119
+ membership_type_not_allowed: "该会员卡类型不在允许范围内",
120
+ max_per_user: "已报名",
121
+ event_past: "活动已结束",
122
+ event_cancelled: "活动已取消",
123
+ event_not_published: "未发布",
124
+ plan_limit: "不可用",
125
+ invalid_type: "类型无效",
126
+ },
127
+ },
128
+ "zh-Hant": {
129
+ signIn: "使用 Vimine 登入",
130
+ signOut: "退出",
131
+ loading: "載入中…",
132
+ notSignedIn: "請登入以檢視您的會員卡。",
133
+ noMembership: "您在這個協會沒有會員卡。",
134
+ notActive: "會員卡尚未生效:生效後會顯示二維碼。",
135
+ error: "出現錯誤。",
136
+ noEvents: "暫無安排的活動。",
137
+ free: "免費",
138
+ places: "個名額",
139
+ register: "報名",
140
+ signInToRegister: "登入後報名",
141
+ joinAndBook: "加入協會並預約",
142
+ alreadyMember: "已是會員?請登入",
143
+ registered: "報名已確認",
144
+ reserved: "名額已保留:等待繳納參與費",
145
+ details: "詳情",
146
+ reason: {
147
+ sold_out: "名額已滿",
148
+ event_full: "已滿員",
149
+ registration_not_open: "報名尚未開始",
150
+ registration_closed: "報名已截止",
151
+ membership_required: "僅限會員",
152
+ membership_not_active: "會員卡無效",
153
+ membership_not_yet_valid: "在該日期您的會員卡尚不可用",
154
+ membership_type_not_allowed: "該會員卡類型不在允許範圍內",
155
+ max_per_user: "已報名",
156
+ event_past: "活動已結束",
157
+ event_cancelled: "活動已取消",
158
+ event_not_published: "未釋出",
159
+ plan_limit: "不可用",
160
+ invalid_type: "類型無效",
161
+ },
162
+ },
163
+ "fr": {
164
+ signIn: "Se connecter avec Vimine",
165
+ signOut: "Se déconnecter",
166
+ loading: "Chargement…",
167
+ notSignedIn: "Connectez-vous pour voir votre carte.",
168
+ noMembership: "Aucune carte dans cette association.",
169
+ notActive: "La carte n'est pas encore active : le code apparaîtra lorsqu'elle le sera.",
170
+ error: "Une erreur s'est produite.",
171
+ noEvents: "Aucun événement prévu.",
172
+ free: "gratuite",
173
+ places: "places",
174
+ register: "S'inscrire",
175
+ signInToRegister: "Se connecter pour s'inscrire",
176
+ joinAndBook: "Adhérer à l'association et réserver",
177
+ alreadyMember: "Déjà membre : se connecter",
178
+ registered: "Inscription confirmée",
179
+ reserved: "Place réservée : en attente de la contribution",
180
+ details: "Détails",
181
+ reason: {
182
+ sold_out: "plus de places",
183
+ event_full: "complet",
184
+ registration_not_open: "inscriptions pas encore ouvertes",
185
+ registration_closed: "inscriptions closes",
186
+ membership_required: "réservé aux membres",
187
+ membership_not_active: "adhésion non valable",
188
+ membership_not_yet_valid: "la carte n'est pas encore utilisable à cette date",
189
+ membership_type_not_allowed: "type d'adhésion non admis",
190
+ max_per_user: "déjà inscrit",
191
+ event_past: "événement terminé",
192
+ event_cancelled: "événement annulé",
193
+ event_not_published: "non publié",
194
+ plan_limit: "non disponible",
195
+ invalid_type: "type non valide",
196
+ },
197
+ },
198
+ "es": {
199
+ signIn: "Iniciar sesión con Vimine",
200
+ signOut: "Cerrar sesión",
201
+ loading: "Cargando…",
202
+ notSignedIn: "Inicia sesión para ver tu carné.",
203
+ noMembership: "No tienes carné en esta asociación.",
204
+ notActive: "El carné aún no está activo: el código aparece cuando lo esté.",
205
+ error: "Se ha producido un error.",
206
+ noEvents: "No hay eventos programados.",
207
+ free: "gratuita",
208
+ places: "plazas",
209
+ register: "Inscríbete",
210
+ signInToRegister: "Inicia sesión para inscribirte",
211
+ joinAndBook: "Hazte socio y reserva",
212
+ alreadyMember: "¿Ya eres socio? Inicia sesión",
213
+ registered: "Inscripción confirmada",
214
+ reserved: "Plaza reservada: pendiente de la contribución",
215
+ details: "Detalles",
216
+ reason: {
217
+ sold_out: "agotado",
218
+ event_full: "completo",
219
+ registration_not_open: "inscripciones aún no abiertas",
220
+ registration_closed: "inscripciones cerradas",
221
+ membership_required: "solo para socios",
222
+ membership_not_active: "carné no válido",
223
+ membership_not_yet_valid: "el carné aún no se puede usar en esa fecha",
224
+ membership_type_not_allowed: "tipo de carné no admitido",
225
+ max_per_user: "ya inscrito",
226
+ event_past: "evento finalizado",
227
+ event_cancelled: "evento cancelado",
228
+ event_not_published: "no publicado",
229
+ plan_limit: "no disponible",
230
+ invalid_type: "tipo no válido",
231
+ },
232
+ },
233
+ "de": {
234
+ signIn: "Mit Vimine anmelden",
235
+ signOut: "Abmelden",
236
+ loading: "Wird geladen…",
237
+ notSignedIn: "Melden Sie sich an, um Ihren Ausweis zu sehen.",
238
+ noMembership: "Keine Mitgliedschaft in diesem Verein.",
239
+ notActive: "Der Ausweis ist noch nicht aktiv: Der Code erscheint, sobald er es ist.",
240
+ error: "Ein Fehler ist aufgetreten.",
241
+ noEvents: "Keine Veranstaltungen geplant.",
242
+ free: "kostenlos",
243
+ places: "Plätze",
244
+ register: "Teilnehmen",
245
+ signInToRegister: "Zum Teilnehmen anmelden",
246
+ joinAndBook: "Dem Verein beitreten und Platz reservieren",
247
+ alreadyMember: "Schon Mitglied? Anmelden",
248
+ registered: "Anmeldung bestätigt",
249
+ reserved: "Platz reserviert: Beitrag ausstehend",
250
+ details: "Details",
251
+ reason: {
252
+ sold_out: "ausgebucht",
253
+ event_full: "voll",
254
+ registration_not_open: "Anmeldung noch nicht offen",
255
+ registration_closed: "Anmeldung geschlossen",
256
+ membership_required: "nur für Mitglieder",
257
+ membership_not_active: "Mitgliedschaft nicht gültig",
258
+ membership_not_yet_valid: "Ihr Ausweis ist an diesem Datum noch nicht nutzbar",
259
+ membership_type_not_allowed: "Mitgliedsart nicht zugelassen",
260
+ max_per_user: "bereits angemeldet",
261
+ event_past: "Veranstaltung vorbei",
262
+ event_cancelled: "Veranstaltung abgesagt",
263
+ event_not_published: "nicht veröffentlicht",
264
+ plan_limit: "nicht verfügbar",
265
+ invalid_type: "ungültige Art",
266
+ },
267
+ },
268
+ "pt-BR": {
269
+ signIn: "Entrar com Vimine",
270
+ signOut: "Sair",
271
+ loading: "Carregando…",
272
+ notSignedIn: "Entre para ver sua carteirinha.",
273
+ noMembership: "Nenhuma carteirinha nesta associação.",
274
+ notActive: "A carteirinha ainda não está ativa: o código aparece quando ela for ativada.",
275
+ error: "Ocorreu um erro.",
276
+ noEvents: "Nenhum evento programado.",
277
+ free: "gratuita",
278
+ places: "vagas",
279
+ register: "Inscrever-se",
280
+ signInToRegister: "Entre para se inscrever",
281
+ joinAndBook: "Associe-se e reserve",
282
+ alreadyMember: "Já sou associado: entrar",
283
+ registered: "Inscrição confirmada",
284
+ reserved: "Vaga reservada: aguardando a contribuição",
285
+ details: "Detalhes",
286
+ reason: {
287
+ sold_out: "esgotado",
288
+ event_full: "lotado",
289
+ registration_not_open: "inscrições ainda não abertas",
290
+ registration_closed: "inscrições encerradas",
291
+ membership_required: "exclusivo para associados",
292
+ membership_not_active: "carteirinha inválida",
293
+ membership_not_yet_valid: "a carteirinha ainda não pode ser usada nessa data",
294
+ membership_type_not_allowed: "tipo de carteirinha não admitido",
295
+ max_per_user: "já inscrito",
296
+ event_past: "evento encerrado",
297
+ event_cancelled: "evento cancelado",
298
+ event_not_published: "não publicado",
299
+ plan_limit: "indisponível",
300
+ invalid_type: "tipo inválido",
301
+ },
302
+ },
303
+ };
304
+ // Languages drafted and not yet read by a native speaker — as on the platform, which serves a draft only where its preview
305
+ // switch names it. Their strings ship, but an element speaks one only on a page that opted in
306
+ // (`defineVimineElements(options, { previewLanguages: true })`); elsewhere it speaks Italian, as the platform would.
307
+ // A language leaves this list with the platform, in an SDK release. Empty since 2026-10-20: the platform enabled its six
308
+ // drafted languages ahead of their review (the owner's decision), and the elements speak them with it.
309
+ const DRAFT_LANGS = [];
310
+ let previewLanguages = false;
311
+ // The page's language → the elements' own: the tag itself, Chinese by script (zh-TW, zh-HK → Traditional; zh, zh-CN →
312
+ // Simplified), any other variant to the language's (en-GB → en, pt-PT → pt-BR); Italian otherwise. The platform's rule.
313
+ const LANGS = Object.keys(STRINGS);
314
+ /** The elements' language for a page's tag, or null when they do not speak it (`preview`: drafts included). */
315
+ export const matchLang = (tag, preview = previewLanguages) => {
316
+ const served = LANGS.filter((l) => preview || !DRAFT_LANGS.includes(l));
317
+ const lower = tag.trim().replace(/_/g, "-").toLowerCase();
318
+ const exact = served.find((l) => l.toLowerCase() === lower);
319
+ if (exact)
320
+ return exact;
321
+ const [lang, ...rest] = lower.split("-");
322
+ if (lang === "zh") {
323
+ const script = rest.some((p) => ["hant", "tw", "hk", "mo"].includes(p)) ? "zh-Hant" : "zh-Hans";
324
+ return served.includes(script) ? script : null;
325
+ }
326
+ return served.find((l) => l.toLowerCase().split("-")[0] === lang) || null;
93
327
  };
94
- const langOf = (el) => {
95
- const l = (el.getAttribute("lang") ||
96
- el.closest("[lang]")?.getAttribute("lang") ||
97
- document.documentElement.lang ||
98
- "it")
99
- .slice(0, 2)
100
- .toLowerCase();
101
- return l === "en" ? "en" : "it";
328
+ const langOf = (el) => matchLang(el.getAttribute("lang") ||
329
+ el.closest("[lang]")?.getAttribute("lang") ||
330
+ document.documentElement.lang ||
331
+ "it") || "it";
332
+ // Dates and amounts in the reader's conventions: English with day-month order, Chinese naming its script.
333
+ const INTL = {
334
+ it: "it-IT",
335
+ en: "en-GB",
336
+ "zh-Hans": "zh-Hans-CN",
337
+ "zh-Hant": "zh-Hant-TW",
338
+ fr: "fr-FR",
339
+ es: "es-ES",
340
+ de: "de-DE",
341
+ "pt-BR": "pt-BR",
102
342
  };
103
343
  const BASE_CSS = /* CSS */ `
104
344
  :host { display: inline-block; font-family: var(--vimine-font, system-ui, sans-serif); color: var(--vimine-color, #111); }
@@ -114,8 +354,9 @@ const shadow = (el, css) => {
114
354
  return root;
115
355
  };
116
356
  /** The client the elements use. Call once; pass your own instance to share it with the rest of the page. */
117
- export function defineVimineElements(options) {
357
+ export function defineVimineElements(options, elements = {}) {
118
358
  shared = options instanceof Vimine ? options : new Vimine(options);
359
+ previewLanguages = !!elements.previewLanguages;
119
360
  if (typeof customElements !== "undefined") {
120
361
  if (!customElements.get("vimine-sign-in"))
121
362
  customElements.define("vimine-sign-in", VimineSignIn);
@@ -366,7 +607,7 @@ export class VimineEnroll extends HTMLElement {
366
607
  }
367
608
  const money = (amount, currency, lang) => {
368
609
  try {
369
- return new Intl.NumberFormat(lang === "en" ? "en-GB" : "it-IT", {
610
+ return new Intl.NumberFormat(INTL[lang], {
370
611
  style: "currency",
371
612
  currency: currency || "EUR",
372
613
  }).format(amount);
@@ -377,7 +618,7 @@ const money = (amount, currency, lang) => {
377
618
  };
378
619
  const when = (iso, tz, lang) => {
379
620
  try {
380
- return new Date(iso).toLocaleString(lang === "en" ? "en-GB" : "it-IT", {
621
+ return new Date(iso).toLocaleString(INTL[lang], {
381
622
  timeZone: tz,
382
623
  dateStyle: "full",
383
624
  timeStyle: "short",
@@ -1 +1 @@
1
- {"version":3,"file":"elements.js","sourceRoot":"","sources":["../src/elements.ts"],"names":[],"mappings":"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","sourcesContent":["// @vimine/sdk/elements — the low-code tier: three custom elements over the browser client, Shadow DOM,\n// styled through `--vimine-*` CSS custom properties, Italian by default (`lang=\"en\"` on the element or the page\n// switches the strings). Register them once, then use the tags anywhere (CMS pages, static sites):\n//\n// import { defineVimineElements } from '@vimine/sdk/elements';\n// defineVimineElements({ clientId: 'vmc_…', redirectUri: 'https://www.example.org/callback' });\n//\n// <vimine-sign-in scope=\"membership:read\"></vimine-sign-in> a \"Sign in with Vimine\" button\n// <vimine-card></vimine-card> the signed-in member's card (SVG + QR)\n// <vimine-enroll slug=\"your-slug\"></vimine-enroll> the hosted enrolment form (iframe, Embed v0), in the\n// element's language; someone who already has a\n// Vimine account is offered a hand-off to the hosted\n// page, where they join in one step\n// <vimine-events slug=\"your-slug\"></vimine-events> the association's events (public ones for\n// visitors, every one for a signed-in member) with\n// a register button per type\n//\n// The callback page still calls `client.handleRedirect()` (or `<vimine-sign-in>` does it for you when\n// `handle-redirect` is set on the element and the page is the redirect URI).\nimport { Vimine, type VimineOptions } from \"./index.js\";\nimport type { Event, Registration, RegistrationType, Scope } from \"./types.js\";\n\nlet shared: Vimine | null = null;\n\nconst STRINGS = {\n it: {\n signIn: \"Accedi con Vimine\",\n signOut: \"Esci\",\n loading: \"Caricamento…\",\n notSignedIn: \"Accedi per vedere la tua tessera.\",\n noMembership: \"Nessuna tessera in questa associazione.\",\n notActive:\n \"La tessera non è ancora attiva: il codice compare quando lo diventa.\",\n error: \"Si è verificato un errore.\",\n noEvents: \"Nessun evento in programma.\",\n free: \"gratuita\",\n places: \"posti\",\n register: \"Iscriviti\",\n signInToRegister: \"Accedi per iscriverti\",\n joinAndBook: \"Iscriviti all’associazione e prenota\",\n alreadyMember: \"Sono già socio: accedi\",\n registered: \"Iscrizione confermata\",\n reserved: \"Posto riservato: in attesa del contributo\",\n details: \"Dettagli\",\n reason: {\n sold_out: \"esaurito\",\n event_full: \"al completo\",\n registration_not_open: \"iscrizioni non ancora aperte\",\n registration_closed: \"iscrizioni chiuse\",\n membership_required: \"riservato ai soci\",\n membership_not_active: \"tessera non valida\",\n membership_not_yet_valid:\n \"la tessera non è ancora utilizzabile a quella data\",\n membership_type_not_allowed: \"tipo di tessera non ammesso\",\n max_per_user: \"già iscritto\",\n event_past: \"evento concluso\",\n event_cancelled: \"evento annullato\",\n event_not_published: \"non pubblicato\",\n plan_limit: \"non disponibile\",\n invalid_type: \"tipo non valido\",\n } as Record<string, string>,\n },\n en: {\n signIn: \"Sign in with Vimine\",\n signOut: \"Sign out\",\n loading: \"Loading…\",\n notSignedIn: \"Sign in to see your card.\",\n noMembership: \"No membership in this association.\",\n notActive: \"The card is not active yet: its code appears once it is.\",\n error: \"Something went wrong.\",\n noEvents: \"No upcoming events.\",\n free: \"free\",\n places: \"places\",\n register: \"Register\",\n signInToRegister: \"Sign in to register\",\n joinAndBook: \"Join the association and book\",\n alreadyMember: \"Already a member? Sign in\",\n registered: \"Registration confirmed\",\n reserved: \"Place reserved: awaiting the contribution\",\n details: \"Details\",\n reason: {\n sold_out: \"sold out\",\n event_full: \"full\",\n registration_not_open: \"registrations not open yet\",\n registration_closed: \"registrations closed\",\n membership_required: \"members only\",\n membership_not_active: \"membership not valid\",\n membership_not_yet_valid: \"your card is not usable yet on that date\",\n membership_type_not_allowed: \"membership type not admitted\",\n max_per_user: \"already registered\",\n event_past: \"event over\",\n event_cancelled: \"event cancelled\",\n event_not_published: \"not published\",\n plan_limit: \"not available\",\n invalid_type: \"invalid type\",\n } as Record<string, string>,\n },\n};\ntype Lang = keyof typeof STRINGS;\nconst langOf = (el: HTMLElement): Lang => {\n const l = (\n el.getAttribute(\"lang\") ||\n el.closest(\"[lang]\")?.getAttribute(\"lang\") ||\n document.documentElement.lang ||\n \"it\"\n )\n .slice(0, 2)\n .toLowerCase();\n return l === \"en\" ? \"en\" : \"it\";\n};\n\nconst BASE_CSS = /* CSS */ `\n:host { display: inline-block; font-family: var(--vimine-font, system-ui, sans-serif); color: var(--vimine-color, #111); }\nbutton { cursor: pointer; border: 0; border-radius: var(--vimine-radius, 999px); padding: var(--vimine-padding, 0.65rem 1.1rem);\n background: var(--vimine-accent, #0a0e1a); color: var(--vimine-accent-contrast, #fff); font: inherit; font-weight: 600; }\nbutton:disabled { opacity: .6; cursor: default; }\n.muted { color: var(--vimine-muted, #666); font-size: .9em; }\n.error { color: var(--vimine-error, #a33); font-size: .9em; }\n`;\n\nconst shadow = (el: HTMLElement, css: string): ShadowRoot => {\n const root = el.shadowRoot || el.attachShadow({ mode: \"open\" });\n root.innerHTML = `<style>${BASE_CSS}${css}</style>`;\n return root;\n};\n\n/** The client the elements use. Call once; pass your own instance to share it with the rest of the page. */\nexport function defineVimineElements(options: VimineOptions | Vimine): Vimine {\n shared = options instanceof Vimine ? options : new Vimine(options);\n if (typeof customElements !== \"undefined\") {\n if (!customElements.get(\"vimine-sign-in\"))\n customElements.define(\"vimine-sign-in\", VimineSignIn);\n if (!customElements.get(\"vimine-card\"))\n customElements.define(\"vimine-card\", VimineCard);\n if (!customElements.get(\"vimine-enroll\"))\n customElements.define(\"vimine-enroll\", VimineEnroll);\n if (!customElements.get(\"vimine-events\"))\n customElements.define(\"vimine-events\", VimineEvents);\n }\n return shared;\n}\n\nconst client = (): Vimine => {\n if (!shared)\n throw new Error(\n \"Vimine elements: call defineVimineElements({ clientId, redirectUri }) first\",\n );\n return shared;\n};\n\n/** `<vimine-sign-in scope=\"…\" return-to=\"/area\" label=\"…\" handle-redirect>` — a sign-in / sign-out button. */\nexport class VimineSignIn extends HTMLElement {\n private unsubscribe: (() => void) | null = null;\n connectedCallback(): void {\n void this.boot();\n }\n disconnectedCallback(): void {\n this.unsubscribe?.();\n this.unsubscribe = null;\n }\n private async boot(): Promise<void> {\n const mp = client();\n if (this.hasAttribute(\"handle-redirect\")) {\n try {\n await mp.handleRedirect();\n } catch (err) {\n this.render(err instanceof Error ? err.message : String(err));\n return;\n }\n }\n this.render();\n this.unsubscribe = mp.onChange(() => this.render());\n }\n private render(error?: string): void {\n const mp = client();\n const t = STRINGS[langOf(this)];\n const root = shadow(this, \"\");\n const btn = document.createElement(\"button\");\n btn.type = \"button\";\n if (mp.isSignedIn()) {\n btn.textContent = this.getAttribute(\"label-signed-in\") || t.signOut;\n btn.addEventListener(\n \"click\",\n () => void mp.signOut({ everywhere: this.hasAttribute(\"everywhere\") }),\n );\n } else {\n btn.textContent = this.getAttribute(\"label\") || t.signIn;\n btn.addEventListener(\"click\", () => {\n const scopes = (this.getAttribute(\"scope\") || \"\")\n .split(/[\\s,]+/)\n .filter(Boolean) as Scope[];\n void mp.signIn({\n ...(scopes.length ? { scopes } : {}),\n ...(this.getAttribute(\"return-to\")\n ? { returnTo: this.getAttribute(\"return-to\")! }\n : {}),\n });\n });\n }\n root.appendChild(btn);\n if (error) {\n const e = document.createElement(\"div\");\n e.className = \"error\";\n e.textContent = error;\n root.appendChild(e);\n }\n this.dispatchEvent(\n new CustomEvent(\"vimine-change\", {\n detail: { signedIn: mp.isSignedIn() },\n bubbles: true,\n }),\n );\n }\n}\n\n/** `<vimine-card>` — the signed-in member's card as SVG (with the live QR); refreshes when the session changes. */\nexport class VimineCard extends HTMLElement {\n private unsubscribe: (() => void) | null = null;\n connectedCallback(): void {\n void this.render();\n this.unsubscribe = client().onChange(() => void this.render());\n }\n disconnectedCallback(): void {\n this.unsubscribe?.();\n this.unsubscribe = null;\n }\n private async render(): Promise<void> {\n const mp = client();\n const t = STRINGS[langOf(this)];\n const root = shadow(\n this,\n \":host { display: block; max-width: var(--vimine-card-width, 600px); } svg { width: 100%; height: auto; display: block; border-radius: 24px; box-shadow: var(--vimine-card-shadow, 0 8px 30px rgba(0,0,0,.12)); }\",\n );\n const note = (cls: string, text: string) => {\n const d = document.createElement(\"div\");\n d.className = cls;\n d.textContent = text;\n root.appendChild(d);\n };\n if (!mp.isSignedIn()) return note(\"muted\", t.notSignedIn);\n note(\"muted\", t.loading);\n try {\n const svg = await mp.membership.cardSvg();\n root.innerHTML = `<style>${BASE_CSS}:host { display: block; max-width: var(--vimine-card-width, 600px); } svg { width: 100%; height: auto; display: block; border-radius: 24px; box-shadow: var(--vimine-card-shadow, 0 8px 30px rgba(0,0,0,.12)); }</style>${svg}`;\n this.dispatchEvent(\n new CustomEvent(\"vimine-card\", {\n detail: { loaded: true },\n bubbles: true,\n }),\n );\n } catch (err) {\n root.innerHTML = `<style>${BASE_CSS}</style>`;\n const code = (err as { code?: string })?.code;\n // `not_active`: the membership exists but has no card (pending, suspended, revoked) — a state, not a failure.\n const quiet = code === \"not_found\" || code === \"not_active\";\n note(\n quiet ? \"muted\" : \"error\",\n code === \"not_found\"\n ? t.noMembership\n : code === \"not_active\"\n ? t.notActive\n : t.error,\n );\n }\n }\n}\n\n/** The hosted enrolment page of an association, in a language: the frame's address, and where a hand-off lands. */\n/**\n * How the hosted enrolment page looks inside the host site: its scheme, the accent of its buttons, links and the\n * association's name, and the ground behind its cards (`transparent`: the host page shows through). The page reads them\n * from its address — a framed page cannot see the host's CSS — and ignores anything that is not a colour or a keyword.\n */\nexport type EnrollAppearance = { scheme?: \"light\" | \"dark\"; accent?: string; background?: string; font?: Typeface };\n\n/** The faces the hosted page offers — served by Vimine itself — or `system`, the device's own. They set everything. */\nexport const TYPEFACES = [\n \"system\",\n \"inter\",\n \"roboto\",\n \"open-sans\",\n \"montserrat\",\n \"nunito\",\n \"lora\",\n \"merriweather\",\n \"roboto-slab\",\n] as const;\nexport type Typeface = (typeof TYPEFACES)[number];\n\nconst HEX = /^#?([0-9a-f]{3}|[0-9a-f]{6})$/i;\nconst appearanceQuery = (a?: EnrollAppearance): string => {\n if (!a) return \"\";\n const out: string[] = [];\n if (a.scheme === \"light\" || a.scheme === \"dark\") out.push(`scheme=${a.scheme}`);\n if (a.accent && HEX.test(a.accent)) out.push(`accent=${encodeURIComponent(a.accent.replace(/^#/, \"\"))}`);\n if (a.background === \"transparent\") out.push(\"background=transparent\");\n else if (a.background && HEX.test(a.background))\n out.push(`background=${encodeURIComponent(a.background.replace(/^#/, \"\"))}`);\n if (a.font && (TYPEFACES as readonly string[]).includes(a.font)) out.push(`font=${a.font}`);\n return out.length ? `&${out.join(\"&\")}` : \"\";\n};\n\nexport const enrollUrl = (appUrl: string, slug: string, lang: string, appearance?: EnrollAppearance): string =>\n `${appUrl.replace(/\\/+$/, \"\")}/enroll/${encodeURIComponent(slug)}?locale=${encodeURIComponent(lang)}${appearanceQuery(appearance)}`;\n\n/**\n * The same page, opened FROM an event: the person joins the association and asks for a place at the event in one go.\n * The request carries the event; the place is confirmed, or held until the membership is active.\n */\nexport const eventEnrollUrl = (\n appUrl: string,\n slug: string,\n event: string,\n lang: string,\n): string =>\n `${enrollUrl(appUrl, slug, lang)}&event=${encodeURIComponent(event)}`;\n\n/** Any CSS colour (a name, `rgb()`, `hsl()`, a hex) as `#rrggbb`, resolved by the browser; null when it is none. */\nconst hexColour = (root: ShadowRoot, value: string): string | null => {\n const v = value.trim();\n if (!v) return null;\n const probe = document.createElement(\"span\");\n probe.style.color = v;\n if (!probe.style.color) return null;\n root.appendChild(probe);\n const m = /rgba?\\(([^)]+)\\)/.exec(getComputedStyle(probe).color);\n probe.remove();\n const parts = (m?.[1] ?? \"\").split(/[\\s,/]+/).filter(Boolean).map(Number);\n if (parts.length < 3) return null;\n const [r = 0, g = 0, b = 0, alpha] = parts;\n if (alpha === 0) return null;\n return `#${[r, g, b].map((n) => Math.round(n).toString(16).padStart(2, \"0\")).join(\"\")}`;\n};\n\n/**\n * The page's look from the host's CSS: `--vimine-scheme` (light | dark), `--vimine-accent` and `--vimine-background` (a\n * colour, or `transparent`), `--vimine-typeface` (one of TYPEFACES) — custom properties inherit, so one rule on `:root`\n * styles every Vimine element at once.\n */\nconst appearanceOf = (el: HTMLElement, root: ShadowRoot): EnrollAppearance => {\n const css = getComputedStyle(el);\n const read = (name: string) => css.getPropertyValue(name).trim();\n const out: EnrollAppearance = {};\n const scheme = read(\"--vimine-scheme\");\n if (scheme === \"light\" || scheme === \"dark\") out.scheme = scheme;\n const accent = hexColour(root, read(\"--vimine-accent\"));\n if (accent) out.accent = accent;\n const background = read(\"--vimine-background\");\n if (background === \"transparent\") out.background = \"transparent\";\n else {\n const bg = hexColour(root, background);\n if (bg) out.background = bg;\n }\n const typeface = read(\"--vimine-typeface\");\n if ((TYPEFACES as readonly string[]).includes(typeface)) out.font = typeface as Typeface;\n return out;\n};\n\n/**\n * `<vimine-enroll slug=\"…\" app-url=\"https://app.vimine.network\" height=\"900\" lang=\"en\">` — the hosted enrolment form.\n *\n * Styled like the other elements, through CSS custom properties on the element or any ancestor:\n *\n * vimine-enroll { --vimine-scheme: light; --vimine-accent: #1e3a5f; --vimine-background: transparent; }\n *\n * `--vimine-scheme` the page's scheme; `--vimine-accent` its buttons, links and the association's name (moved towards\n * the page's ink when it would not read on its cards); `--vimine-background` the ground behind the cards;\n * `--vimine-typeface` the face of the whole page, fields included — one of TYPEFACES, served by Vimine (a framed page\n * cannot use the host's fonts). The frame is styled once, when the element connects.\n *\n * The form opens in the element's language (`lang` on the element or the page; Italian by default). Someone who already\n * has a Vimine account need not fill it: the form offers *Continua su Vimine*, which opens the hosted page in a new\n * tab — there their session is recognised and they join in one step (the association's statuto and privacy notice, and\n * nothing they have already told Vimine). It is a hand-off and not a sign-in inside the frame because a browser keeps a\n * framed page's session apart from the same site opened directly; the frame's sandbox lets that tab open as an ordinary\n * page (`allow-popups-to-escape-sandbox`).\n */\nexport class VimineEnroll extends HTMLElement {\n connectedCallback(): void {\n const slug = this.getAttribute(\"slug\");\n const root = shadow(\n this,\n \":host { display: block; } iframe { width: 100%; border: 0; border-radius: var(--vimine-radius, 16px); background: transparent; }\",\n );\n if (!slug) {\n const e = document.createElement(\"div\");\n e.className = \"error\";\n e.textContent = \"vimine-enroll: missing slug\";\n root.appendChild(e);\n return;\n }\n const appUrl = (\n this.getAttribute(\"app-url\") ||\n client().options.appUrl ||\n \"https://app.vimine.network\"\n ).replace(/\\/+$/, \"\");\n const frame = document.createElement(\"iframe\");\n frame.src = enrollUrl(appUrl, slug, langOf(this), appearanceOf(this, root));\n frame.title = \"Vimine\";\n frame.loading = \"lazy\";\n frame.style.height = `${Number(this.getAttribute(\"height\")) || 900}px`;\n frame.setAttribute(\n \"sandbox\",\n \"allow-forms allow-scripts allow-same-origin allow-popups allow-popups-to-escape-sandbox\",\n );\n root.appendChild(frame);\n }\n}\n\nconst money = (amount: number, currency: string, lang: Lang): string => {\n try {\n return new Intl.NumberFormat(lang === \"en\" ? \"en-GB\" : \"it-IT\", {\n style: \"currency\",\n currency: currency || \"EUR\",\n }).format(amount);\n } catch {\n return `${amount.toFixed(2)} ${currency}`;\n }\n};\nconst when = (iso: string, tz: string, lang: Lang): string => {\n try {\n return new Date(iso).toLocaleString(lang === \"en\" ? \"en-GB\" : \"it-IT\", {\n timeZone: tz,\n dateStyle: \"full\",\n timeStyle: \"short\",\n });\n } catch {\n return new Date(iso).toLocaleString();\n }\n};\n\n/**\n * `<vimine-events slug=\"…\" filter=\"upcoming\" limit=\"10\" detail-url=\"/eventi/{slug}\">` — the association's events:\n * the public ones for a visitor (no sign-in), every published one for a signed-in member, each with its registration\n * types (contribution, places left) and a register button (`registrations:write`). Fires `vimine-registration`\n * `{ registration }` after a registration. `detail-url` (with `{slug}`) adds a details link.\n *\n * A VISITOR is offered a way in, not a bare sign-in: *Iscriviti all’associazione e prenota* opens the association's\n * hosted enrolment page with the event (a new tab; `app-url` as on `<vimine-enroll>`) — they join and ask for the place\n * in one go — and *Sono già socio: accedi* signs a member in here. The first is shown while the event has a registration\n * that can be had and the association takes enrolment requests; otherwise the sign-in alone.\n */\nexport class VimineEvents extends HTMLElement {\n private unsubscribe: (() => void) | null = null;\n private state: Record<string, Registration> = {};\n connectedCallback(): void {\n void this.render();\n this.unsubscribe = client().onChange(() => void this.render());\n }\n disconnectedCallback(): void {\n this.unsubscribe?.();\n this.unsubscribe = null;\n }\n private async render(): Promise<void> {\n const mp = client();\n const lang = langOf(this);\n const t = STRINGS[lang];\n const root = shadow(\n this,\n /* CSS */ `:host { display: block; }\n.event { border: 1px solid var(--vimine-border, #e5e5e5); border-radius: var(--vimine-radius, 16px); padding: var(--vimine-padding, 1rem); margin: 0 0 1rem; }\n.event h3 { margin: 0 0 .25rem; font-size: 1.15em; } .event img { width: 100%; border-radius: var(--vimine-radius, 16px); margin-bottom: .75rem; display: block; }\n.type { display: flex; justify-content: space-between; align-items: center; gap: .75rem; padding: .5rem 0; border-top: 1px solid var(--vimine-border, #eee); }\n.type .n { font-weight: 600; } .type button { padding: .45rem .9rem; } a { color: var(--vimine-accent, #0a0e1a); }\n.actions { display: flex; flex-wrap: wrap; align-items: center; gap: .75rem 1rem; padding-top: .75rem; border-top: 1px solid var(--vimine-border, #eee); }\na.button { display: inline-block; text-decoration: none; border-radius: var(--vimine-radius, 999px); padding: var(--vimine-padding, 0.65rem 1.1rem);\n background: var(--vimine-accent, #0a0e1a); color: var(--vimine-accent-contrast, #fff); font-weight: 600; }\nbutton.link { background: none; color: var(--vimine-accent, #0a0e1a); padding: 0; border-radius: 0; text-decoration: underline; font-weight: 400; }`,\n );\n const note = (cls: string, text: string): void => {\n const d = document.createElement(\"div\");\n d.className = cls;\n d.textContent = text;\n root.appendChild(d);\n };\n note(\"muted\", t.loading);\n const slug = this.getAttribute(\"slug\") || \"\";\n const filter = (this.getAttribute(\"filter\") || \"upcoming\") as\n | \"upcoming\"\n | \"past\"\n | \"cancelled\"\n | \"all\";\n const limit = Number(this.getAttribute(\"limit\")) || undefined;\n let items: Event[];\n // For a visitor: does the association take enrolment requests? Only then is joining a way to a place. A side\n // read — a failure leaves the sign-in alone.\n let joinable = false;\n try {\n const params = { filter, ...(limit ? { limit } : {}) };\n items = mp.isSignedIn()\n ? (await mp.events.list(params)).items\n : (await mp.public.events.list(slug, params)).items;\n if (!mp.isSignedIn() && slug)\n joinable = await mp.public\n .association(slug)\n .then((config) => config.aps.accepting_requests === true)\n .catch(() => false);\n } catch {\n root.innerHTML = `<style>${BASE_CSS}</style>`;\n return note(\"error\", t.error);\n }\n root.innerHTML = root.querySelector(\"style\")!.outerHTML;\n if (!items.length) return note(\"muted\", t.noEvents);\n const detailUrl = this.getAttribute(\"detail-url\");\n const join = joinable\n ? {\n slug,\n appUrl: (\n this.getAttribute(\"app-url\") ||\n mp.options.appUrl ||\n \"https://app.vimine.network\"\n ).replace(/\\/+$/, \"\"),\n }\n : null;\n for (const ev of items)\n root.appendChild(this.card(ev, mp, lang, detailUrl, join));\n }\n private card(\n ev: Event,\n mp: Vimine,\n lang: Lang,\n detailUrl: string | null,\n join: { slug: string; appUrl: string } | null,\n ): HTMLElement {\n const t = STRINGS[lang];\n const el = document.createElement(\"article\");\n el.className = \"event\";\n if (ev.cover_url) {\n const img = document.createElement(\"img\");\n img.src = ev.cover_url;\n img.alt = \"\";\n el.appendChild(img);\n }\n const h = document.createElement(\"h3\");\n h.textContent = ev.title;\n el.appendChild(h);\n const meta = document.createElement(\"div\");\n meta.className = \"muted\";\n meta.textContent = `${when(ev.starts_at, ev.timezone, lang)}${ev.location ? ` · ${ev.location.name || ev.location.address || \"\"}` : \"\"}`;\n el.appendChild(meta);\n if (ev.summary) {\n const p = document.createElement(\"p\");\n p.textContent = ev.summary;\n el.appendChild(p);\n }\n if (detailUrl) {\n const a = document.createElement(\"a\");\n a.href = detailUrl.replace(\"{slug}\", encodeURIComponent(ev.slug));\n a.textContent = t.details;\n el.appendChild(a);\n }\n const mine = this.state[ev.id];\n if (mine) {\n const d = document.createElement(\"div\");\n d.className = \"muted\";\n d.textContent = mine.status === \"confirmed\" ? t.registered : t.reserved;\n el.appendChild(d);\n return el;\n }\n if (ev.status === \"published\")\n for (const tp of ev.registration_types)\n el.appendChild(this.typeRow(ev, tp, mp, lang));\n // A visitor: one call for the event, under its registrations — join and book on the hosted page, or sign in here.\n if (\n ev.status === \"published\" &&\n !mp.isSignedIn() &&\n ev.registration_types.some((tp) => tp.open)\n ) {\n const actions = document.createElement(\"div\");\n actions.className = \"actions\";\n const signIn = document.createElement(\"button\");\n signIn.type = \"button\";\n signIn.addEventListener(\n \"click\",\n () =>\n void mp.signIn({\n scopes: [\n \"events:read\",\n \"registrations:read\",\n \"registrations:write\",\n ],\n }),\n );\n if (join) {\n const a = document.createElement(\"a\");\n a.className = \"button\";\n a.href = eventEnrollUrl(join.appUrl, join.slug, ev.slug, lang);\n a.target = \"_blank\";\n a.rel = \"noopener\";\n a.textContent = t.joinAndBook;\n actions.appendChild(a);\n signIn.className = \"link\";\n signIn.textContent = t.alreadyMember;\n } else signIn.textContent = t.signInToRegister;\n actions.appendChild(signIn);\n el.appendChild(actions);\n }\n return el;\n }\n private typeRow(\n ev: Event,\n tp: RegistrationType,\n mp: Vimine,\n lang: Lang,\n ): HTMLElement {\n const t = STRINGS[lang];\n const row = document.createElement(\"div\");\n row.className = \"type\";\n const left = document.createElement(\"div\");\n const n = document.createElement(\"div\");\n n.className = \"n\";\n n.textContent = `${tp.name} · ${tp.amount > 0 ? money(tp.amount, tp.currency, lang) : t.free}`;\n left.appendChild(n);\n const s = document.createElement(\"div\");\n s.className = \"muted\";\n s.textContent = [\n tp.remaining != null ? `${tp.remaining} ${t.places}` : \"\",\n tp.reason ? t.reason[tp.reason] || tp.reason : \"\",\n ]\n .filter(Boolean)\n .join(\" · \");\n left.appendChild(s);\n row.appendChild(left);\n // A visitor has the event's own call below the registrations (`card`): no button per registration.\n if (!mp.isSignedIn()) return row;\n const btn = document.createElement(\"button\");\n btn.type = \"button\";\n btn.textContent = t.register;\n btn.disabled = !tp.open;\n btn.addEventListener(\"click\", async () => {\n btn.disabled = true;\n try {\n const reg = await mp.registrations.create(ev.slug, {\n registration_type: tp.uid,\n });\n this.state[ev.id] = reg;\n this.dispatchEvent(\n new CustomEvent(\"vimine-registration\", {\n detail: { registration: reg },\n bubbles: true,\n }),\n );\n void this.render();\n } catch (err) {\n btn.disabled = false;\n const reasons = (\n (err as { errors?: { code?: string }[] })?.errors || []\n )\n .map((e) => t.reason[e.code || \"\"] || e.code)\n .filter(Boolean);\n s.textContent = reasons.length ? reasons.join(\", \") : t.error;\n s.className = \"error\";\n }\n });\n row.appendChild(btn);\n return row;\n }\n}\n"]}
1
+ {"version":3,"file":"elements.js","sourceRoot":"","sources":["../src/elements.ts"],"names":[],"mappings":"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","sourcesContent":["// @vimine/sdk/elements — the low-code tier: three custom elements over the browser client, Shadow DOM,\n// styled through `--vimine-*` CSS custom properties, Italian by default (`lang=\"en\"` on the element or the page\n// switches the strings). Register them once, then use the tags anywhere (CMS pages, static sites):\n//\n// import { defineVimineElements } from '@vimine/sdk/elements';\n// defineVimineElements({ clientId: 'vmc_…', redirectUri: 'https://www.example.org/callback' });\n//\n// <vimine-sign-in scope=\"membership:read\"></vimine-sign-in> a \"Sign in with Vimine\" button\n// <vimine-card></vimine-card> the signed-in member's card (SVG + QR)\n// <vimine-enroll slug=\"your-slug\"></vimine-enroll> the hosted enrolment form (iframe, Embed v0), in the\n// element's language; someone who already has a\n// Vimine account is offered a hand-off to the hosted\n// page, where they join in one step\n// <vimine-events slug=\"your-slug\"></vimine-events> the association's events (public ones for\n// visitors, every one for a signed-in member) with\n// a register button per type\n//\n// The callback page still calls `client.handleRedirect()` (or `<vimine-sign-in>` does it for you when\n// `handle-redirect` is set on the element and the page is the redirect URI).\nimport { Vimine, type VimineOptions } from \"./index.js\";\nimport type { Event, Registration, RegistrationType, Scope } from \"./types.js\";\n\nlet shared: Vimine | null = null;\n\nconst STRINGS = {\n it: {\n signIn: \"Accedi con Vimine\",\n signOut: \"Esci\",\n loading: \"Caricamento…\",\n notSignedIn: \"Accedi per vedere la tua tessera.\",\n noMembership: \"Nessuna tessera in questa associazione.\",\n notActive:\n \"La tessera non è ancora attiva: il codice compare quando lo diventa.\",\n error: \"Si è verificato un errore.\",\n noEvents: \"Nessun evento in programma.\",\n free: \"gratuita\",\n places: \"posti\",\n register: \"Iscriviti\",\n signInToRegister: \"Accedi per iscriverti\",\n joinAndBook: \"Iscriviti all’associazione e prenota\",\n alreadyMember: \"Sono già socio: accedi\",\n registered: \"Iscrizione confermata\",\n reserved: \"Posto riservato: in attesa del contributo\",\n details: \"Dettagli\",\n reason: {\n sold_out: \"esaurito\",\n event_full: \"al completo\",\n registration_not_open: \"iscrizioni non ancora aperte\",\n registration_closed: \"iscrizioni chiuse\",\n membership_required: \"riservato ai soci\",\n membership_not_active: \"tessera non valida\",\n membership_not_yet_valid:\n \"la tessera non è ancora utilizzabile a quella data\",\n membership_type_not_allowed: \"tipo di tessera non ammesso\",\n max_per_user: \"già iscritto\",\n event_past: \"evento concluso\",\n event_cancelled: \"evento annullato\",\n event_not_published: \"non pubblicato\",\n plan_limit: \"non disponibile\",\n invalid_type: \"tipo non valido\",\n } as Record<string, string>,\n },\n en: {\n signIn: \"Sign in with Vimine\",\n signOut: \"Sign out\",\n loading: \"Loading…\",\n notSignedIn: \"Sign in to see your card.\",\n noMembership: \"No membership in this association.\",\n notActive: \"The card is not active yet: its code appears once it is.\",\n error: \"Something went wrong.\",\n noEvents: \"No upcoming events.\",\n free: \"free\",\n places: \"places\",\n register: \"Register\",\n signInToRegister: \"Sign in to register\",\n joinAndBook: \"Join the association and book\",\n alreadyMember: \"Already a member? Sign in\",\n registered: \"Registration confirmed\",\n reserved: \"Place reserved: awaiting the contribution\",\n details: \"Details\",\n reason: {\n sold_out: \"sold out\",\n event_full: \"full\",\n registration_not_open: \"registrations not open yet\",\n registration_closed: \"registrations closed\",\n membership_required: \"members only\",\n membership_not_active: \"membership not valid\",\n membership_not_yet_valid: \"your card is not usable yet on that date\",\n membership_type_not_allowed: \"membership type not admitted\",\n max_per_user: \"already registered\",\n event_past: \"event over\",\n event_cancelled: \"event cancelled\",\n event_not_published: \"not published\",\n plan_limit: \"not available\",\n invalid_type: \"invalid type\",\n } as Record<string, string>,\n },\n \"zh-Hans\": {\n signIn: \"使用 Vimine 登录\",\n signOut: \"退出\",\n loading: \"加载中…\",\n notSignedIn: \"请登录以查看您的会员卡。\",\n noMembership: \"您在这个协会没有会员卡。\",\n notActive: \"会员卡尚未生效:生效后会显示二维码。\",\n error: \"出现错误。\",\n noEvents: \"暂无安排的活动。\",\n free: \"免费\",\n places: \"个名额\",\n register: \"报名\",\n signInToRegister: \"登录后报名\",\n joinAndBook: \"加入协会并预约\",\n alreadyMember: \"已是会员?请登录\",\n registered: \"报名已确认\",\n reserved: \"名额已保留:等待缴纳参与费\",\n details: \"详情\",\n reason: {\n sold_out: \"名额已满\",\n event_full: \"已满员\",\n registration_not_open: \"报名尚未开始\",\n registration_closed: \"报名已截止\",\n membership_required: \"仅限会员\",\n membership_not_active: \"会员卡无效\",\n membership_not_yet_valid: \"在该日期您的会员卡尚不可用\",\n membership_type_not_allowed: \"该会员卡类型不在允许范围内\",\n max_per_user: \"已报名\",\n event_past: \"活动已结束\",\n event_cancelled: \"活动已取消\",\n event_not_published: \"未发布\",\n plan_limit: \"不可用\",\n invalid_type: \"类型无效\",\n } as Record<string, string>,\n },\n \"zh-Hant\": {\n signIn: \"使用 Vimine 登入\",\n signOut: \"退出\",\n loading: \"載入中…\",\n notSignedIn: \"請登入以檢視您的會員卡。\",\n noMembership: \"您在這個協會沒有會員卡。\",\n notActive: \"會員卡尚未生效:生效後會顯示二維碼。\",\n error: \"出現錯誤。\",\n noEvents: \"暫無安排的活動。\",\n free: \"免費\",\n places: \"個名額\",\n register: \"報名\",\n signInToRegister: \"登入後報名\",\n joinAndBook: \"加入協會並預約\",\n alreadyMember: \"已是會員?請登入\",\n registered: \"報名已確認\",\n reserved: \"名額已保留:等待繳納參與費\",\n details: \"詳情\",\n reason: {\n sold_out: \"名額已滿\",\n event_full: \"已滿員\",\n registration_not_open: \"報名尚未開始\",\n registration_closed: \"報名已截止\",\n membership_required: \"僅限會員\",\n membership_not_active: \"會員卡無效\",\n membership_not_yet_valid: \"在該日期您的會員卡尚不可用\",\n membership_type_not_allowed: \"該會員卡類型不在允許範圍內\",\n max_per_user: \"已報名\",\n event_past: \"活動已結束\",\n event_cancelled: \"活動已取消\",\n event_not_published: \"未釋出\",\n plan_limit: \"不可用\",\n invalid_type: \"類型無效\",\n } as Record<string, string>,\n },\n \"fr\": {\n signIn: \"Se connecter avec Vimine\",\n signOut: \"Se déconnecter\",\n loading: \"Chargement…\",\n notSignedIn: \"Connectez-vous pour voir votre carte.\",\n noMembership: \"Aucune carte dans cette association.\",\n notActive: \"La carte n'est pas encore active : le code apparaîtra lorsqu'elle le sera.\",\n error: \"Une erreur s'est produite.\",\n noEvents: \"Aucun événement prévu.\",\n free: \"gratuite\",\n places: \"places\",\n register: \"S'inscrire\",\n signInToRegister: \"Se connecter pour s'inscrire\",\n joinAndBook: \"Adhérer à l'association et réserver\",\n alreadyMember: \"Déjà membre : se connecter\",\n registered: \"Inscription confirmée\",\n reserved: \"Place réservée : en attente de la contribution\",\n details: \"Détails\",\n reason: {\n sold_out: \"plus de places\",\n event_full: \"complet\",\n registration_not_open: \"inscriptions pas encore ouvertes\",\n registration_closed: \"inscriptions closes\",\n membership_required: \"réservé aux membres\",\n membership_not_active: \"adhésion non valable\",\n membership_not_yet_valid: \"la carte n'est pas encore utilisable à cette date\",\n membership_type_not_allowed: \"type d'adhésion non admis\",\n max_per_user: \"déjà inscrit\",\n event_past: \"événement terminé\",\n event_cancelled: \"événement annulé\",\n event_not_published: \"non publié\",\n plan_limit: \"non disponible\",\n invalid_type: \"type non valide\",\n } as Record<string, string>,\n },\n \"es\": {\n signIn: \"Iniciar sesión con Vimine\",\n signOut: \"Cerrar sesión\",\n loading: \"Cargando…\",\n notSignedIn: \"Inicia sesión para ver tu carné.\",\n noMembership: \"No tienes carné en esta asociación.\",\n notActive: \"El carné aún no está activo: el código aparece cuando lo esté.\",\n error: \"Se ha producido un error.\",\n noEvents: \"No hay eventos programados.\",\n free: \"gratuita\",\n places: \"plazas\",\n register: \"Inscríbete\",\n signInToRegister: \"Inicia sesión para inscribirte\",\n joinAndBook: \"Hazte socio y reserva\",\n alreadyMember: \"¿Ya eres socio? Inicia sesión\",\n registered: \"Inscripción confirmada\",\n reserved: \"Plaza reservada: pendiente de la contribución\",\n details: \"Detalles\",\n reason: {\n sold_out: \"agotado\",\n event_full: \"completo\",\n registration_not_open: \"inscripciones aún no abiertas\",\n registration_closed: \"inscripciones cerradas\",\n membership_required: \"solo para socios\",\n membership_not_active: \"carné no válido\",\n membership_not_yet_valid: \"el carné aún no se puede usar en esa fecha\",\n membership_type_not_allowed: \"tipo de carné no admitido\",\n max_per_user: \"ya inscrito\",\n event_past: \"evento finalizado\",\n event_cancelled: \"evento cancelado\",\n event_not_published: \"no publicado\",\n plan_limit: \"no disponible\",\n invalid_type: \"tipo no válido\",\n } as Record<string, string>,\n },\n \"de\": {\n signIn: \"Mit Vimine anmelden\",\n signOut: \"Abmelden\",\n loading: \"Wird geladen…\",\n notSignedIn: \"Melden Sie sich an, um Ihren Ausweis zu sehen.\",\n noMembership: \"Keine Mitgliedschaft in diesem Verein.\",\n notActive: \"Der Ausweis ist noch nicht aktiv: Der Code erscheint, sobald er es ist.\",\n error: \"Ein Fehler ist aufgetreten.\",\n noEvents: \"Keine Veranstaltungen geplant.\",\n free: \"kostenlos\",\n places: \"Plätze\",\n register: \"Teilnehmen\",\n signInToRegister: \"Zum Teilnehmen anmelden\",\n joinAndBook: \"Dem Verein beitreten und Platz reservieren\",\n alreadyMember: \"Schon Mitglied? Anmelden\",\n registered: \"Anmeldung bestätigt\",\n reserved: \"Platz reserviert: Beitrag ausstehend\",\n details: \"Details\",\n reason: {\n sold_out: \"ausgebucht\",\n event_full: \"voll\",\n registration_not_open: \"Anmeldung noch nicht offen\",\n registration_closed: \"Anmeldung geschlossen\",\n membership_required: \"nur für Mitglieder\",\n membership_not_active: \"Mitgliedschaft nicht gültig\",\n membership_not_yet_valid: \"Ihr Ausweis ist an diesem Datum noch nicht nutzbar\",\n membership_type_not_allowed: \"Mitgliedsart nicht zugelassen\",\n max_per_user: \"bereits angemeldet\",\n event_past: \"Veranstaltung vorbei\",\n event_cancelled: \"Veranstaltung abgesagt\",\n event_not_published: \"nicht veröffentlicht\",\n plan_limit: \"nicht verfügbar\",\n invalid_type: \"ungültige Art\",\n } as Record<string, string>,\n },\n \"pt-BR\": {\n signIn: \"Entrar com Vimine\",\n signOut: \"Sair\",\n loading: \"Carregando…\",\n notSignedIn: \"Entre para ver sua carteirinha.\",\n noMembership: \"Nenhuma carteirinha nesta associação.\",\n notActive: \"A carteirinha ainda não está ativa: o código aparece quando ela for ativada.\",\n error: \"Ocorreu um erro.\",\n noEvents: \"Nenhum evento programado.\",\n free: \"gratuita\",\n places: \"vagas\",\n register: \"Inscrever-se\",\n signInToRegister: \"Entre para se inscrever\",\n joinAndBook: \"Associe-se e reserve\",\n alreadyMember: \"Já sou associado: entrar\",\n registered: \"Inscrição confirmada\",\n reserved: \"Vaga reservada: aguardando a contribuição\",\n details: \"Detalhes\",\n reason: {\n sold_out: \"esgotado\",\n event_full: \"lotado\",\n registration_not_open: \"inscrições ainda não abertas\",\n registration_closed: \"inscrições encerradas\",\n membership_required: \"exclusivo para associados\",\n membership_not_active: \"carteirinha inválida\",\n membership_not_yet_valid: \"a carteirinha ainda não pode ser usada nessa data\",\n membership_type_not_allowed: \"tipo de carteirinha não admitido\",\n max_per_user: \"já inscrito\",\n event_past: \"evento encerrado\",\n event_cancelled: \"evento cancelado\",\n event_not_published: \"não publicado\",\n plan_limit: \"indisponível\",\n invalid_type: \"tipo inválido\",\n } as Record<string, string>,\n },\n};\ntype Lang = keyof typeof STRINGS;\n// Languages drafted and not yet read by a native speaker — as on the platform, which serves a draft only where its preview\n// switch names it. Their strings ship, but an element speaks one only on a page that opted in\n// (`defineVimineElements(options, { previewLanguages: true })`); elsewhere it speaks Italian, as the platform would.\n// A language leaves this list with the platform, in an SDK release. Empty since 2026-10-20: the platform enabled its six\n// drafted languages ahead of their review (the owner's decision), and the elements speak them with it.\nconst DRAFT_LANGS: Lang[] = [];\nlet previewLanguages = false;\n// The page's language → the elements' own: the tag itself, Chinese by script (zh-TW, zh-HK → Traditional; zh, zh-CN →\n// Simplified), any other variant to the language's (en-GB → en, pt-PT → pt-BR); Italian otherwise. The platform's rule.\nconst LANGS = Object.keys(STRINGS) as Lang[];\n/** The elements' language for a page's tag, or null when they do not speak it (`preview`: drafts included). */\nexport const matchLang = (tag: string, preview = previewLanguages): Lang | null => {\n const served = LANGS.filter((l) => preview || !DRAFT_LANGS.includes(l));\n const lower = tag.trim().replace(/_/g, \"-\").toLowerCase();\n const exact = served.find((l) => l.toLowerCase() === lower);\n if (exact) return exact;\n const [lang, ...rest] = lower.split(\"-\");\n if (lang === \"zh\") {\n const script = rest.some((p) => [\"hant\", \"tw\", \"hk\", \"mo\"].includes(p)) ? \"zh-Hant\" : \"zh-Hans\";\n return served.includes(script) ? script : null;\n }\n return served.find((l) => l.toLowerCase().split(\"-\")[0] === lang) || null;\n};\nconst langOf = (el: HTMLElement): Lang =>\n matchLang(\n el.getAttribute(\"lang\") ||\n el.closest(\"[lang]\")?.getAttribute(\"lang\") ||\n document.documentElement.lang ||\n \"it\",\n ) || \"it\";\n// Dates and amounts in the reader's conventions: English with day-month order, Chinese naming its script.\nconst INTL: Record<Lang, string> = {\n it: \"it-IT\",\n en: \"en-GB\",\n \"zh-Hans\": \"zh-Hans-CN\",\n \"zh-Hant\": \"zh-Hant-TW\",\n fr: \"fr-FR\",\n es: \"es-ES\",\n de: \"de-DE\",\n \"pt-BR\": \"pt-BR\",\n};\n\nconst BASE_CSS = /* CSS */ `\n:host { display: inline-block; font-family: var(--vimine-font, system-ui, sans-serif); color: var(--vimine-color, #111); }\nbutton { cursor: pointer; border: 0; border-radius: var(--vimine-radius, 999px); padding: var(--vimine-padding, 0.65rem 1.1rem);\n background: var(--vimine-accent, #0a0e1a); color: var(--vimine-accent-contrast, #fff); font: inherit; font-weight: 600; }\nbutton:disabled { opacity: .6; cursor: default; }\n.muted { color: var(--vimine-muted, #666); font-size: .9em; }\n.error { color: var(--vimine-error, #a33); font-size: .9em; }\n`;\n\nconst shadow = (el: HTMLElement, css: string): ShadowRoot => {\n const root = el.shadowRoot || el.attachShadow({ mode: \"open\" });\n root.innerHTML = `<style>${BASE_CSS}${css}</style>`;\n return root;\n};\n\n/** The client the elements use. Call once; pass your own instance to share it with the rest of the page. */\nexport function defineVimineElements(\n options: VimineOptions | Vimine,\n elements: { previewLanguages?: boolean } = {},\n): Vimine {\n shared = options instanceof Vimine ? options : new Vimine(options);\n previewLanguages = !!elements.previewLanguages;\n if (typeof customElements !== \"undefined\") {\n if (!customElements.get(\"vimine-sign-in\"))\n customElements.define(\"vimine-sign-in\", VimineSignIn);\n if (!customElements.get(\"vimine-card\"))\n customElements.define(\"vimine-card\", VimineCard);\n if (!customElements.get(\"vimine-enroll\"))\n customElements.define(\"vimine-enroll\", VimineEnroll);\n if (!customElements.get(\"vimine-events\"))\n customElements.define(\"vimine-events\", VimineEvents);\n }\n return shared;\n}\n\nconst client = (): Vimine => {\n if (!shared)\n throw new Error(\n \"Vimine elements: call defineVimineElements({ clientId, redirectUri }) first\",\n );\n return shared;\n};\n\n/** `<vimine-sign-in scope=\"…\" return-to=\"/area\" label=\"…\" handle-redirect>` — a sign-in / sign-out button. */\nexport class VimineSignIn extends HTMLElement {\n private unsubscribe: (() => void) | null = null;\n connectedCallback(): void {\n void this.boot();\n }\n disconnectedCallback(): void {\n this.unsubscribe?.();\n this.unsubscribe = null;\n }\n private async boot(): Promise<void> {\n const mp = client();\n if (this.hasAttribute(\"handle-redirect\")) {\n try {\n await mp.handleRedirect();\n } catch (err) {\n this.render(err instanceof Error ? err.message : String(err));\n return;\n }\n }\n this.render();\n this.unsubscribe = mp.onChange(() => this.render());\n }\n private render(error?: string): void {\n const mp = client();\n const t = STRINGS[langOf(this)];\n const root = shadow(this, \"\");\n const btn = document.createElement(\"button\");\n btn.type = \"button\";\n if (mp.isSignedIn()) {\n btn.textContent = this.getAttribute(\"label-signed-in\") || t.signOut;\n btn.addEventListener(\n \"click\",\n () => void mp.signOut({ everywhere: this.hasAttribute(\"everywhere\") }),\n );\n } else {\n btn.textContent = this.getAttribute(\"label\") || t.signIn;\n btn.addEventListener(\"click\", () => {\n const scopes = (this.getAttribute(\"scope\") || \"\")\n .split(/[\\s,]+/)\n .filter(Boolean) as Scope[];\n void mp.signIn({\n ...(scopes.length ? { scopes } : {}),\n ...(this.getAttribute(\"return-to\")\n ? { returnTo: this.getAttribute(\"return-to\")! }\n : {}),\n });\n });\n }\n root.appendChild(btn);\n if (error) {\n const e = document.createElement(\"div\");\n e.className = \"error\";\n e.textContent = error;\n root.appendChild(e);\n }\n this.dispatchEvent(\n new CustomEvent(\"vimine-change\", {\n detail: { signedIn: mp.isSignedIn() },\n bubbles: true,\n }),\n );\n }\n}\n\n/** `<vimine-card>` — the signed-in member's card as SVG (with the live QR); refreshes when the session changes. */\nexport class VimineCard extends HTMLElement {\n private unsubscribe: (() => void) | null = null;\n connectedCallback(): void {\n void this.render();\n this.unsubscribe = client().onChange(() => void this.render());\n }\n disconnectedCallback(): void {\n this.unsubscribe?.();\n this.unsubscribe = null;\n }\n private async render(): Promise<void> {\n const mp = client();\n const t = STRINGS[langOf(this)];\n const root = shadow(\n this,\n \":host { display: block; max-width: var(--vimine-card-width, 600px); } svg { width: 100%; height: auto; display: block; border-radius: 24px; box-shadow: var(--vimine-card-shadow, 0 8px 30px rgba(0,0,0,.12)); }\",\n );\n const note = (cls: string, text: string) => {\n const d = document.createElement(\"div\");\n d.className = cls;\n d.textContent = text;\n root.appendChild(d);\n };\n if (!mp.isSignedIn()) return note(\"muted\", t.notSignedIn);\n note(\"muted\", t.loading);\n try {\n const svg = await mp.membership.cardSvg();\n root.innerHTML = `<style>${BASE_CSS}:host { display: block; max-width: var(--vimine-card-width, 600px); } svg { width: 100%; height: auto; display: block; border-radius: 24px; box-shadow: var(--vimine-card-shadow, 0 8px 30px rgba(0,0,0,.12)); }</style>${svg}`;\n this.dispatchEvent(\n new CustomEvent(\"vimine-card\", {\n detail: { loaded: true },\n bubbles: true,\n }),\n );\n } catch (err) {\n root.innerHTML = `<style>${BASE_CSS}</style>`;\n const code = (err as { code?: string })?.code;\n // `not_active`: the membership exists but has no card (pending, suspended, revoked) — a state, not a failure.\n const quiet = code === \"not_found\" || code === \"not_active\";\n note(\n quiet ? \"muted\" : \"error\",\n code === \"not_found\"\n ? t.noMembership\n : code === \"not_active\"\n ? t.notActive\n : t.error,\n );\n }\n }\n}\n\n/** The hosted enrolment page of an association, in a language: the frame's address, and where a hand-off lands. */\n/**\n * How the hosted enrolment page looks inside the host site: its scheme, the accent of its buttons, links and the\n * association's name, and the ground behind its cards (`transparent`: the host page shows through). The page reads them\n * from its address — a framed page cannot see the host's CSS — and ignores anything that is not a colour or a keyword.\n */\nexport type EnrollAppearance = { scheme?: \"light\" | \"dark\"; accent?: string; background?: string; font?: Typeface };\n\n/** The faces the hosted page offers — served by Vimine itself — or `system`, the device's own. They set everything. */\nexport const TYPEFACES = [\n \"system\",\n \"inter\",\n \"roboto\",\n \"open-sans\",\n \"montserrat\",\n \"nunito\",\n \"lora\",\n \"merriweather\",\n \"roboto-slab\",\n] as const;\nexport type Typeface = (typeof TYPEFACES)[number];\n\nconst HEX = /^#?([0-9a-f]{3}|[0-9a-f]{6})$/i;\nconst appearanceQuery = (a?: EnrollAppearance): string => {\n if (!a) return \"\";\n const out: string[] = [];\n if (a.scheme === \"light\" || a.scheme === \"dark\") out.push(`scheme=${a.scheme}`);\n if (a.accent && HEX.test(a.accent)) out.push(`accent=${encodeURIComponent(a.accent.replace(/^#/, \"\"))}`);\n if (a.background === \"transparent\") out.push(\"background=transparent\");\n else if (a.background && HEX.test(a.background))\n out.push(`background=${encodeURIComponent(a.background.replace(/^#/, \"\"))}`);\n if (a.font && (TYPEFACES as readonly string[]).includes(a.font)) out.push(`font=${a.font}`);\n return out.length ? `&${out.join(\"&\")}` : \"\";\n};\n\nexport const enrollUrl = (appUrl: string, slug: string, lang: string, appearance?: EnrollAppearance): string =>\n `${appUrl.replace(/\\/+$/, \"\")}/enroll/${encodeURIComponent(slug)}?locale=${encodeURIComponent(lang)}${appearanceQuery(appearance)}`;\n\n/**\n * The same page, opened FROM an event: the person joins the association and asks for a place at the event in one go.\n * The request carries the event; the place is confirmed, or held until the membership is active.\n */\nexport const eventEnrollUrl = (\n appUrl: string,\n slug: string,\n event: string,\n lang: string,\n): string =>\n `${enrollUrl(appUrl, slug, lang)}&event=${encodeURIComponent(event)}`;\n\n/** Any CSS colour (a name, `rgb()`, `hsl()`, a hex) as `#rrggbb`, resolved by the browser; null when it is none. */\nconst hexColour = (root: ShadowRoot, value: string): string | null => {\n const v = value.trim();\n if (!v) return null;\n const probe = document.createElement(\"span\");\n probe.style.color = v;\n if (!probe.style.color) return null;\n root.appendChild(probe);\n const m = /rgba?\\(([^)]+)\\)/.exec(getComputedStyle(probe).color);\n probe.remove();\n const parts = (m?.[1] ?? \"\").split(/[\\s,/]+/).filter(Boolean).map(Number);\n if (parts.length < 3) return null;\n const [r = 0, g = 0, b = 0, alpha] = parts;\n if (alpha === 0) return null;\n return `#${[r, g, b].map((n) => Math.round(n).toString(16).padStart(2, \"0\")).join(\"\")}`;\n};\n\n/**\n * The page's look from the host's CSS: `--vimine-scheme` (light | dark), `--vimine-accent` and `--vimine-background` (a\n * colour, or `transparent`), `--vimine-typeface` (one of TYPEFACES) — custom properties inherit, so one rule on `:root`\n * styles every Vimine element at once.\n */\nconst appearanceOf = (el: HTMLElement, root: ShadowRoot): EnrollAppearance => {\n const css = getComputedStyle(el);\n const read = (name: string) => css.getPropertyValue(name).trim();\n const out: EnrollAppearance = {};\n const scheme = read(\"--vimine-scheme\");\n if (scheme === \"light\" || scheme === \"dark\") out.scheme = scheme;\n const accent = hexColour(root, read(\"--vimine-accent\"));\n if (accent) out.accent = accent;\n const background = read(\"--vimine-background\");\n if (background === \"transparent\") out.background = \"transparent\";\n else {\n const bg = hexColour(root, background);\n if (bg) out.background = bg;\n }\n const typeface = read(\"--vimine-typeface\");\n if ((TYPEFACES as readonly string[]).includes(typeface)) out.font = typeface as Typeface;\n return out;\n};\n\n/**\n * `<vimine-enroll slug=\"…\" app-url=\"https://app.vimine.network\" height=\"900\" lang=\"en\">` — the hosted enrolment form.\n *\n * Styled like the other elements, through CSS custom properties on the element or any ancestor:\n *\n * vimine-enroll { --vimine-scheme: light; --vimine-accent: #1e3a5f; --vimine-background: transparent; }\n *\n * `--vimine-scheme` the page's scheme; `--vimine-accent` its buttons, links and the association's name (moved towards\n * the page's ink when it would not read on its cards); `--vimine-background` the ground behind the cards;\n * `--vimine-typeface` the face of the whole page, fields included — one of TYPEFACES, served by Vimine (a framed page\n * cannot use the host's fonts). The frame is styled once, when the element connects.\n *\n * The form opens in the element's language (`lang` on the element or the page; Italian by default). Someone who already\n * has a Vimine account need not fill it: the form offers *Continua su Vimine*, which opens the hosted page in a new\n * tab — there their session is recognised and they join in one step (the association's statuto and privacy notice, and\n * nothing they have already told Vimine). It is a hand-off and not a sign-in inside the frame because a browser keeps a\n * framed page's session apart from the same site opened directly; the frame's sandbox lets that tab open as an ordinary\n * page (`allow-popups-to-escape-sandbox`).\n */\nexport class VimineEnroll extends HTMLElement {\n connectedCallback(): void {\n const slug = this.getAttribute(\"slug\");\n const root = shadow(\n this,\n \":host { display: block; } iframe { width: 100%; border: 0; border-radius: var(--vimine-radius, 16px); background: transparent; }\",\n );\n if (!slug) {\n const e = document.createElement(\"div\");\n e.className = \"error\";\n e.textContent = \"vimine-enroll: missing slug\";\n root.appendChild(e);\n return;\n }\n const appUrl = (\n this.getAttribute(\"app-url\") ||\n client().options.appUrl ||\n \"https://app.vimine.network\"\n ).replace(/\\/+$/, \"\");\n const frame = document.createElement(\"iframe\");\n frame.src = enrollUrl(appUrl, slug, langOf(this), appearanceOf(this, root));\n frame.title = \"Vimine\";\n frame.loading = \"lazy\";\n frame.style.height = `${Number(this.getAttribute(\"height\")) || 900}px`;\n frame.setAttribute(\n \"sandbox\",\n \"allow-forms allow-scripts allow-same-origin allow-popups allow-popups-to-escape-sandbox\",\n );\n root.appendChild(frame);\n }\n}\n\nconst money = (amount: number, currency: string, lang: Lang): string => {\n try {\n return new Intl.NumberFormat(INTL[lang], {\n style: \"currency\",\n currency: currency || \"EUR\",\n }).format(amount);\n } catch {\n return `${amount.toFixed(2)} ${currency}`;\n }\n};\nconst when = (iso: string, tz: string, lang: Lang): string => {\n try {\n return new Date(iso).toLocaleString(INTL[lang], {\n timeZone: tz,\n dateStyle: \"full\",\n timeStyle: \"short\",\n });\n } catch {\n return new Date(iso).toLocaleString();\n }\n};\n\n/**\n * `<vimine-events slug=\"…\" filter=\"upcoming\" limit=\"10\" detail-url=\"/eventi/{slug}\">` — the association's events:\n * the public ones for a visitor (no sign-in), every published one for a signed-in member, each with its registration\n * types (contribution, places left) and a register button (`registrations:write`). Fires `vimine-registration`\n * `{ registration }` after a registration. `detail-url` (with `{slug}`) adds a details link.\n *\n * A VISITOR is offered a way in, not a bare sign-in: *Iscriviti all’associazione e prenota* opens the association's\n * hosted enrolment page with the event (a new tab; `app-url` as on `<vimine-enroll>`) — they join and ask for the place\n * in one go — and *Sono già socio: accedi* signs a member in here. The first is shown while the event has a registration\n * that can be had and the association takes enrolment requests; otherwise the sign-in alone.\n */\nexport class VimineEvents extends HTMLElement {\n private unsubscribe: (() => void) | null = null;\n private state: Record<string, Registration> = {};\n connectedCallback(): void {\n void this.render();\n this.unsubscribe = client().onChange(() => void this.render());\n }\n disconnectedCallback(): void {\n this.unsubscribe?.();\n this.unsubscribe = null;\n }\n private async render(): Promise<void> {\n const mp = client();\n const lang = langOf(this);\n const t = STRINGS[lang];\n const root = shadow(\n this,\n /* CSS */ `:host { display: block; }\n.event { border: 1px solid var(--vimine-border, #e5e5e5); border-radius: var(--vimine-radius, 16px); padding: var(--vimine-padding, 1rem); margin: 0 0 1rem; }\n.event h3 { margin: 0 0 .25rem; font-size: 1.15em; } .event img { width: 100%; border-radius: var(--vimine-radius, 16px); margin-bottom: .75rem; display: block; }\n.type { display: flex; justify-content: space-between; align-items: center; gap: .75rem; padding: .5rem 0; border-top: 1px solid var(--vimine-border, #eee); }\n.type .n { font-weight: 600; } .type button { padding: .45rem .9rem; } a { color: var(--vimine-accent, #0a0e1a); }\n.actions { display: flex; flex-wrap: wrap; align-items: center; gap: .75rem 1rem; padding-top: .75rem; border-top: 1px solid var(--vimine-border, #eee); }\na.button { display: inline-block; text-decoration: none; border-radius: var(--vimine-radius, 999px); padding: var(--vimine-padding, 0.65rem 1.1rem);\n background: var(--vimine-accent, #0a0e1a); color: var(--vimine-accent-contrast, #fff); font-weight: 600; }\nbutton.link { background: none; color: var(--vimine-accent, #0a0e1a); padding: 0; border-radius: 0; text-decoration: underline; font-weight: 400; }`,\n );\n const note = (cls: string, text: string): void => {\n const d = document.createElement(\"div\");\n d.className = cls;\n d.textContent = text;\n root.appendChild(d);\n };\n note(\"muted\", t.loading);\n const slug = this.getAttribute(\"slug\") || \"\";\n const filter = (this.getAttribute(\"filter\") || \"upcoming\") as\n | \"upcoming\"\n | \"past\"\n | \"cancelled\"\n | \"all\";\n const limit = Number(this.getAttribute(\"limit\")) || undefined;\n let items: Event[];\n // For a visitor: does the association take enrolment requests? Only then is joining a way to a place. A side\n // read — a failure leaves the sign-in alone.\n let joinable = false;\n try {\n const params = { filter, ...(limit ? { limit } : {}) };\n items = mp.isSignedIn()\n ? (await mp.events.list(params)).items\n : (await mp.public.events.list(slug, params)).items;\n if (!mp.isSignedIn() && slug)\n joinable = await mp.public\n .association(slug)\n .then((config) => config.aps.accepting_requests === true)\n .catch(() => false);\n } catch {\n root.innerHTML = `<style>${BASE_CSS}</style>`;\n return note(\"error\", t.error);\n }\n root.innerHTML = root.querySelector(\"style\")!.outerHTML;\n if (!items.length) return note(\"muted\", t.noEvents);\n const detailUrl = this.getAttribute(\"detail-url\");\n const join = joinable\n ? {\n slug,\n appUrl: (\n this.getAttribute(\"app-url\") ||\n mp.options.appUrl ||\n \"https://app.vimine.network\"\n ).replace(/\\/+$/, \"\"),\n }\n : null;\n for (const ev of items)\n root.appendChild(this.card(ev, mp, lang, detailUrl, join));\n }\n private card(\n ev: Event,\n mp: Vimine,\n lang: Lang,\n detailUrl: string | null,\n join: { slug: string; appUrl: string } | null,\n ): HTMLElement {\n const t = STRINGS[lang];\n const el = document.createElement(\"article\");\n el.className = \"event\";\n if (ev.cover_url) {\n const img = document.createElement(\"img\");\n img.src = ev.cover_url;\n img.alt = \"\";\n el.appendChild(img);\n }\n const h = document.createElement(\"h3\");\n h.textContent = ev.title;\n el.appendChild(h);\n const meta = document.createElement(\"div\");\n meta.className = \"muted\";\n meta.textContent = `${when(ev.starts_at, ev.timezone, lang)}${ev.location ? ` · ${ev.location.name || ev.location.address || \"\"}` : \"\"}`;\n el.appendChild(meta);\n if (ev.summary) {\n const p = document.createElement(\"p\");\n p.textContent = ev.summary;\n el.appendChild(p);\n }\n if (detailUrl) {\n const a = document.createElement(\"a\");\n a.href = detailUrl.replace(\"{slug}\", encodeURIComponent(ev.slug));\n a.textContent = t.details;\n el.appendChild(a);\n }\n const mine = this.state[ev.id];\n if (mine) {\n const d = document.createElement(\"div\");\n d.className = \"muted\";\n d.textContent = mine.status === \"confirmed\" ? t.registered : t.reserved;\n el.appendChild(d);\n return el;\n }\n if (ev.status === \"published\")\n for (const tp of ev.registration_types)\n el.appendChild(this.typeRow(ev, tp, mp, lang));\n // A visitor: one call for the event, under its registrations — join and book on the hosted page, or sign in here.\n if (\n ev.status === \"published\" &&\n !mp.isSignedIn() &&\n ev.registration_types.some((tp) => tp.open)\n ) {\n const actions = document.createElement(\"div\");\n actions.className = \"actions\";\n const signIn = document.createElement(\"button\");\n signIn.type = \"button\";\n signIn.addEventListener(\n \"click\",\n () =>\n void mp.signIn({\n scopes: [\n \"events:read\",\n \"registrations:read\",\n \"registrations:write\",\n ],\n }),\n );\n if (join) {\n const a = document.createElement(\"a\");\n a.className = \"button\";\n a.href = eventEnrollUrl(join.appUrl, join.slug, ev.slug, lang);\n a.target = \"_blank\";\n a.rel = \"noopener\";\n a.textContent = t.joinAndBook;\n actions.appendChild(a);\n signIn.className = \"link\";\n signIn.textContent = t.alreadyMember;\n } else signIn.textContent = t.signInToRegister;\n actions.appendChild(signIn);\n el.appendChild(actions);\n }\n return el;\n }\n private typeRow(\n ev: Event,\n tp: RegistrationType,\n mp: Vimine,\n lang: Lang,\n ): HTMLElement {\n const t = STRINGS[lang];\n const row = document.createElement(\"div\");\n row.className = \"type\";\n const left = document.createElement(\"div\");\n const n = document.createElement(\"div\");\n n.className = \"n\";\n n.textContent = `${tp.name} · ${tp.amount > 0 ? money(tp.amount, tp.currency, lang) : t.free}`;\n left.appendChild(n);\n const s = document.createElement(\"div\");\n s.className = \"muted\";\n s.textContent = [\n tp.remaining != null ? `${tp.remaining} ${t.places}` : \"\",\n tp.reason ? t.reason[tp.reason] || tp.reason : \"\",\n ]\n .filter(Boolean)\n .join(\" · \");\n left.appendChild(s);\n row.appendChild(left);\n // A visitor has the event's own call below the registrations (`card`): no button per registration.\n if (!mp.isSignedIn()) return row;\n const btn = document.createElement(\"button\");\n btn.type = \"button\";\n btn.textContent = t.register;\n btn.disabled = !tp.open;\n btn.addEventListener(\"click\", async () => {\n btn.disabled = true;\n try {\n const reg = await mp.registrations.create(ev.slug, {\n registration_type: tp.uid,\n });\n this.state[ev.id] = reg;\n this.dispatchEvent(\n new CustomEvent(\"vimine-registration\", {\n detail: { registration: reg },\n bubbles: true,\n }),\n );\n void this.render();\n } catch (err) {\n btn.disabled = false;\n const reasons = (\n (err as { errors?: { code?: string }[] })?.errors || []\n )\n .map((e) => t.reason[e.code || \"\"] || e.code)\n .filter(Boolean);\n s.textContent = reasons.length ? reasons.join(\", \") : t.error;\n s.className = \"error\";\n }\n });\n row.appendChild(btn);\n return row;\n }\n}\n"]}
@@ -152,7 +152,7 @@ export interface SignupRequest {
152
152
  codicefiscale?: string | null;
153
153
  /** The person confirms a code that disagrees with their particulars (422 `codicefiscale_mismatch` with `confirmable: true`) */
154
154
  codicefiscale_confirmed?: boolean;
155
- /** 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 */
155
+ /** The language of the page the person filled in (a platform language — `it`, `en`, …; any other tag is matched to the platform’s own: `en-GB` → `en`, `zh-TW` → `zh-Hant`). 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 */
156
156
  locale?: string | null;
157
157
  /** The account terms (platform_terms) the person accepted on your site — optional, but when given it must name the in-force version */
158
158
  accept_terms?: LegalRef;
@@ -181,7 +181,7 @@ export interface EnrollRequest {
181
181
  birth_country?: string | null;
182
182
  /** One of the association’s membership types (omit when it has exactly one) */
183
183
  membership_type?: string;
184
- /** 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 */
184
+ /** The language of the page the person filled in (a platform language — `it`, `en`, …; any other tag is matched to the platform’s own: `en-GB` → `en`, `zh-TW` → `zh-Hant`). 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 */
185
185
  locale?: string | null;
186
186
  /** The in-force statuto the person accepted on your site (from GET /v1/aps/{slug}) */
187
187
  accept_statuto: {
@@ -217,7 +217,7 @@ export interface Me {
217
217
  /** 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) */
218
218
  codicefiscale_check?: "matched" | "mismatch_confirmed" | "absent" | null;
219
219
  /** The language the person chose for the platform and its mails; null: never chosen — the language of the request, then of the association, applies */
220
- locale?: "it" | "en" | null;
220
+ locale?: "it" | "en" | "zh-Hans" | "zh-Hant" | "fr" | "es" | "de" | "pt-BR" | null;
221
221
  updated_at?: string | null;
222
222
  }
223
223
  export interface Guardian {
@@ -396,7 +396,7 @@ export interface LegalDocumentSummary {
396
396
  uid?: string;
397
397
  /** Document kind (platform_terms, platform_privacy, platform_cookie, aps_terms, aps_dpa, aps_dpa_annex1_processing … developer_terms) */
398
398
  kind: string;
399
- locale: "it" | "en";
399
+ locale: "it" | "en" | "zh-Hans" | "zh-Hant" | "fr" | "es" | "de" | "pt-BR";
400
400
  /** Version label (1.0, 1.1, …) */
401
401
  version: string;
402
402
  title: string;
@@ -1 +1 @@
1
- {"version":3,"file":"generated.js","sourceRoot":"","sources":["../src/generated.ts"],"names":[],"mappings":"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","sourcesContent":["// GENERATED by scripts/gen-types.mjs from openapi/v1.json — do not edit. Regenerate: npm run spec:types\n// Spec version 2026-10-18 · 47 paths · 36 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 aps?: {\n slug?: string;\n name?: string;\n };\n title: string;\n version: number;\n approved_on?: string | null;\n /** Of the uploaded document, when there is one */\n sha256?: string | null;\n /** The text as registered; empty when only a document was uploaded */\n content_md?: string;\n content_html: string;\n /** The uploaded document, a link valid for 15 minutes */\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 picture_url?: string | null;\n citta?: string | null;\n provincia?: string | null;\n enroll_enabled?: boolean;\n /** Whether a membership request would be taken now: enrolment on, a member more fits the plan, the association ready to collect requests, and its public door open. */\n accepting_requests?: boolean;\n /** True while Vimine registers people by invitation only (the private beta) and this association takes only the people it invited: `accepting_requests` is then false, and `POST /v1/enroll` answers 403 `not_available`. */\n invitation_only?: boolean;\n /** True for a sandbox: the test copy of an association that test clients work on, with synthetic members only. It never sends e-mail, takes no payments and is never in the Network. */\n sandbox?: 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 /** Who holds parental responsibility for a minor (under 18 by `dob`). REQUIRED for a minor where the association declared it collects the block (`aps.collects_guardian_data`): 422 `required` on `guardian` otherwise; stored only where it declared so */\n guardian?: Guardian;\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 Guardian {\n first_name: string;\n last_name: string;\n /** Parent, guardian… as the association records it */\n relation: string;\n /** Optional; refused when malformed */\n codicefiscale?: string | null;\n email?: string | null;\n phone?: 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 /** Only after a 409 `address_required`: the association asks every member for an address (`member_address: required` on its public profile). Optional where it declared `optional`; ignored where it collects none */\n address?: MemberAddress;\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 /** Only for a link sent by the association’s hosted enrolment page when that page was opened from one of its public events: what became of the place the person asked for together with the request. `null` for every other link */\n event?: {\n slug?: string;\n title?: string;\n starts_at?: string;\n timezone?: string;\n place?: string | null;\n registration_type?: {\n uid?: string;\n name?: string;\n /** 0 = free */\n amount?: number;\n currency?: string;\n };\n /** `confirmed`: the place is theirs. `reserved`: held, see `waiting`. `held`: the membership request itself still waits for the address to be confirmed, and no place was asked for. `unavailable`: no place, see `reasons` */\n state?: \"confirmed\" | \"reserved\" | \"held\" | \"unavailable\";\n /** What a `reserved` place waits for: the membership to become active (it is then confirmed by itself when free), the contribution, or both */\n waiting?: Array<\"membership\" | \"contribution\">;\n /** Why the place is `unavailable`: the reasons of `GET /v1/events/{slug}/eligibility` */\n reasons?: Array<string>;\n reserved_until?: string | null;\n /** How to pay a contribution that is owed, in the association’s words */\n payment_instructions?: string | null;\n /** The person held this place before the link was used */\n already?: boolean;\n } | null;\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 viewGuestRegistration: ['POST', '/v1/registrations/view'],\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 getApsStatuto: ['GET', '/v1/aps/{slug}/statuto'],\n} as const;\nexport type OperationId = keyof typeof operations;\n"]}
1
+ {"version":3,"file":"generated.js","sourceRoot":"","sources":["../src/generated.ts"],"names":[],"mappings":"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","sourcesContent":["// GENERATED by scripts/gen-types.mjs from openapi/v1.json — do not edit. Regenerate: npm run spec:types\n// Spec version 2026-10-18 · 47 paths · 36 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 aps?: {\n slug?: string;\n name?: string;\n };\n title: string;\n version: number;\n approved_on?: string | null;\n /** Of the uploaded document, when there is one */\n sha256?: string | null;\n /** The text as registered; empty when only a document was uploaded */\n content_md?: string;\n content_html: string;\n /** The uploaded document, a link valid for 15 minutes */\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 picture_url?: string | null;\n citta?: string | null;\n provincia?: string | null;\n enroll_enabled?: boolean;\n /** Whether a membership request would be taken now: enrolment on, a member more fits the plan, the association ready to collect requests, and its public door open. */\n accepting_requests?: boolean;\n /** True while Vimine registers people by invitation only (the private beta) and this association takes only the people it invited: `accepting_requests` is then false, and `POST /v1/enroll` answers 403 `not_available`. */\n invitation_only?: boolean;\n /** True for a sandbox: the test copy of an association that test clients work on, with synthetic members only. It never sends e-mail, takes no payments and is never in the Network. */\n sandbox?: 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 (a platform language — `it`, `en`, …; any other tag is matched to the platform’s own: `en-GB` → `en`, `zh-TW` → `zh-Hant`). 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 /** Who holds parental responsibility for a minor (under 18 by `dob`). REQUIRED for a minor where the association declared it collects the block (`aps.collects_guardian_data`): 422 `required` on `guardian` otherwise; stored only where it declared so */\n guardian?: Guardian;\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 (a platform language — `it`, `en`, …; any other tag is matched to the platform’s own: `en-GB` → `en`, `zh-TW` → `zh-Hant`). 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\" | \"zh-Hans\" | \"zh-Hant\" | \"fr\" | \"es\" | \"de\" | \"pt-BR\" | null;\n updated_at?: string | null;\n}\n\nexport interface Guardian {\n first_name: string;\n last_name: string;\n /** Parent, guardian… as the association records it */\n relation: string;\n /** Optional; refused when malformed */\n codicefiscale?: string | null;\n email?: string | null;\n phone?: 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 /** Only after a 409 `address_required`: the association asks every member for an address (`member_address: required` on its public profile). Optional where it declared `optional`; ignored where it collects none */\n address?: MemberAddress;\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\" | \"zh-Hans\" | \"zh-Hant\" | \"fr\" | \"es\" | \"de\" | \"pt-BR\";\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 /** Only for a link sent by the association’s hosted enrolment page when that page was opened from one of its public events: what became of the place the person asked for together with the request. `null` for every other link */\n event?: {\n slug?: string;\n title?: string;\n starts_at?: string;\n timezone?: string;\n place?: string | null;\n registration_type?: {\n uid?: string;\n name?: string;\n /** 0 = free */\n amount?: number;\n currency?: string;\n };\n /** `confirmed`: the place is theirs. `reserved`: held, see `waiting`. `held`: the membership request itself still waits for the address to be confirmed, and no place was asked for. `unavailable`: no place, see `reasons` */\n state?: \"confirmed\" | \"reserved\" | \"held\" | \"unavailable\";\n /** What a `reserved` place waits for: the membership to become active (it is then confirmed by itself when free), the contribution, or both */\n waiting?: Array<\"membership\" | \"contribution\">;\n /** Why the place is `unavailable`: the reasons of `GET /v1/events/{slug}/eligibility` */\n reasons?: Array<string>;\n reserved_until?: string | null;\n /** How to pay a contribution that is owed, in the association’s words */\n payment_instructions?: string | null;\n /** The person held this place before the link was used */\n already?: boolean;\n } | null;\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 viewGuestRegistration: ['POST', '/v1/registrations/view'],\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 getApsStatuto: ['GET', '/v1/aps/{slug}/statuto'],\n} as const;\nexport type OperationId = keyof typeof operations;\n"]}
package/dist/types.d.ts CHANGED
@@ -32,7 +32,7 @@ export interface ClientInfo {
32
32
  * A language the platform speaks (`it`, `en` today). Wherever the API takes one it also takes a regional tag
33
33
  * (`en-GB`) and reduces it; a language it does not speak is ignored, never an error — except on `PATCH /v1/me`.
34
34
  */
35
- export type Locale = 'it' | 'en';
35
+ export type Locale = 'it' | 'en' | 'zh-Hans' | 'zh-Hant' | 'fr' | 'es' | 'de' | 'pt-BR';
36
36
  /** Ask for the association's copy in a language (`?locale=`). Default: the member's own, then `Accept-Language`, then the association's. */
37
37
  export interface LocaleParam {
38
38
  locale?: Locale | string;
package/dist/types.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,0GAA0G;AAC1G,kGAAkG","sourcesContent":["// Wire types of the Vimine API v1 — hand-kept in sync with openapi/v1.json (the document is the source of\n// truth; a generated file may replace this one later). Field names are the JSON names, unchanged.\n\n/** Permissions a member (user scopes) or an association's own system (client scopes) may hold. */\nexport type Scope =\n | 'profile:read'\n | 'profile:write'\n | 'membership:read'\n | 'membership:request'\n | 'statuto:accept'\n | 'network:manage'\n | 'identity:signup'\n | 'enroll:write'\n | 'verify:read'\n | 'memberships:read'\n | 'checkins:write'\n | 'webhooks:manage'\n | 'events:read'\n | 'registrations:read'\n | 'registrations:write';\n\n/** `rejected`: the request for admission was not accepted (a different act from `revoked`, which excludes a member). */\nexport type MembershipStatus = 'pending' | 'active' | 'suspended' | 'revoked' | 'rejected';\n/** What the card is worth right now: `valid`, `expired`, `statuto_required` (re-acceptance overdue) or `inactive`. */\n/** `not_yet_valid`: active and unexpired, but inside the association's usability delay — see `Membership.valid_from`. */\nexport type MembershipVerdict = 'valid' | 'expired' | 'not_yet_valid' | 'statuto_required' | 'inactive';\n\n// ---- OAuth ------------------------------------------------------------------------------------------\n\nexport interface TokenResponse {\n access_token: string;\n token_type: 'Bearer';\n expires_in: number;\n refresh_token?: string;\n scope: string;\n /** Pairwise subject of the member (per association); absent on client tokens. */\n sub?: string;\n}\n\nexport interface ClientInfo {\n client_id: string;\n name: string;\n kind: 'public' | 'native' | 'confidential' | 'first_party';\n aps: { slug: string; name: string; picture_url: string | null };\n scopes: Array<{ code: Scope; label: string }>;\n}\n\n// ---- member surface (/v1/me*) -------------------------------------------------------------------------\n\n/**\n * A language the platform speaks (`it`, `en` today). Wherever the API takes one it also takes a regional tag\n * (`en-GB`) and reduces it; a language it does not speak is ignored, never an error — except on `PATCH /v1/me`.\n */\nexport type Locale = 'it' | 'en';\n\n/** Ask for the association's copy in a language (`?locale=`). Default: the member's own, then `Accept-Language`, then the association's. */\nexport interface LocaleParam {\n locale?: Locale | string;\n}\n\nexport interface Me {\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 /** ISO date (YYYY-MM-DD) */\n dob: string | null;\n /** Demographic only: it is never cross-checked against a fiscal code. */\n gender: 'M' | 'F' | null;\n /** Comune (born in Italy) or city, free text (born abroad). */\n birthplace: string | null;\n /** Country of birth, 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; `null` = not identified yet (they cannot request a membership). */\n codicefiscale_check: CodiceFiscaleCheck | null;\n /** The language the person chose for the platform and its mails; `null` = never chosen (the request's, then the association's, applies). */\n locale: Locale | null;\n updated_at: string | null;\n}\n\n/**\n * How a person is identified — by a fiscal code OR by their particulars (date, place and country of birth), never\n * neither. `matched`: a fiscal code that agrees with the particulars; `mismatch_confirmed`: a code that disagrees,\n * confirmed by the person as the one on their health card; `absent`: no code, the particulars identify them.\n */\nexport type CodiceFiscaleCheck = 'matched' | 'mismatch_confirmed' | 'absent';\n\nexport interface MeUpdate {\n phone?: string | null;\n dob?: string | null;\n gender?: 'M' | 'F' | null;\n birthplace?: string | null;\n /** ISO 3166-1 alpha-2. For a person born abroad a fiscal code encodes only the STATE: this is what it is compared with. */\n birth_country?: string | null;\n /** May be added later, or set to `null`. Validated and cross-checked when present (422 `codicefiscale_mismatch`). */\n codicefiscale?: string | null;\n /** Write-only: the person confirms a code that disagrees with their particulars (only after a `confirmable: true`). */\n codicefiscale_confirmed?: boolean;\n /** The person's language; `null` clears the choice. 422 `unsupported` for a language the platform does not speak. */\n locale?: Locale | null;\n}\n\nexport interface MembershipTypeRef {\n uid: string;\n cod: string;\n name: string;\n}\n\nexport interface MembershipStatuto {\n current_version: number | null;\n current_sha256: string | null;\n accepted_version_id: string | null;\n accepted_at: string | null;\n /** A newer statuto was published since the member accepted one. */\n pending: boolean;\n /** … and the association's grace window for re-acceptance has elapsed. */\n overdue: boolean;\n}\n\nexport interface CardToken {\n /** The `vmt_…` token: what a QR carries and what `/v1/verify/{card_token}` checks. */\n token: string;\n /** Validity window (unix seconds). */\n nbf: number;\n exp: number;\n}\n\nexport interface Membership {\n id: string;\n status: MembershipStatus;\n verdict: MembershipVerdict;\n subdate: string | null;\n issued_at: string | null;\n expires_at: string | null;\n membership_type: MembershipTypeRef | null;\n statuto: MembershipStatuto;\n /**\n * Why a `pending` membership is still pending, IN ORDER: the association's approval of the request first (when it\n * admits by decision of its board), then the quota of a paid type. Empty when active.\n */\n pending_reasons: PendingReason[];\n /** May the quota be paid yet? `false` while the approval is still pending: approval opens payment. */\n payment_open: boolean;\n /** When the card starts to count at the door (the association's usability delay); `null` = since activation. */\n valid_from: string | null;\n /** Is the card usable right now? `status` may be `active` while this is still `false` (see `valid_from`). */\n usable: boolean;\n /** The quota of a paid membership type and whether it is paid for the current period; `null` for a free type. */\n quota: { amount: number; currency: string; paid: boolean } | null;\n /** The association's instructions for paying the quota, only once the payment is open (`payment_open`). */\n payment_instructions: string | null;\n /** Days to expiry (negative once expired). */\n expires_in_days: number | null;\n /** Self-service renewal: open 60 days before expiry; `requested_at` once the member asked. */\n renewal: { window_open: boolean; requested_at: string | null };\n network_opt_in: boolean;\n /** The signed card token. `null` unless `status` is `active` (a pending, suspended or revoked membership has no card) or when card signing is not configured. */\n card: CardToken | null;\n}\n\nexport type PendingReason = 'approval' | 'payment';\n/** How an association admits its members (`GET /v1/aps/{slug}` → `aps.admission.model`). */\nexport type AdmissionModel = 'board' | 'provisional' | 'automatic';\n\nexport interface MembershipRequest {\n /** Membership type uid; optional when the association offers exactly one. */\n membership_type?: string;\n /** Must name the in-force statuto (see `Statuto.version`; `sha256` when published). */\n accept_statuto: { version: number; sha256?: string };\n /**\n * The association's privacy notice the person read on your page (`ApsPublicConfig.privacy_notice`; add `locale` when\n * you showed a translation). REQUIRED while a notice is in force that the person has not acknowledged yet\n * (`legal.acceptances()` → `pending.privacy_notice`): 422 `validation_failed` on `privacy_notice` without it, 422\n * `privacy_notice_outdated` when it is not the in-force version. Ignored once they stand at the in-force one.\n */\n privacy_notice?: { version: number; sha256?: string; locale?: Locale | string };\n /**\n * Residence or, where different, domicile — kept on the association's own record of the member. REQUIRED where the\n * association declared `member_address: required` (422 `validation_failed` on `address`), stored where it declared\n * `optional`, ignored where it collects none.\n */\n address?: MemberAddress;\n /** The language of the page the person used (`it`, `en`): which translation of the notice they read. */\n locale?: Locale | string;\n}\n\n/** A free type with no approval gate is issued `active` at once; otherwise `pending` with its reasons. */\n/** What every answer about a membership request says about its gates. */\nexport interface MembershipGates {\n /** In order: the association's approval first (board model), then the fee. Empty when active. */\n pending_reasons: PendingReason[];\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 usability delay; `null` otherwise. */\n valid_from: string | null;\n}\nexport type MembershipRequestResult =\n | ({ created: true; status: MembershipStatus; id: string } & MembershipGates)\n | ({ already_requested: true; status: MembershipStatus } & MembershipGates);\n\nexport interface MembershipEvent {\n from: MembershipStatus | null;\n to: MembershipStatus;\n reason: string | null;\n changed_at: string;\n channel: string;\n}\n\nexport interface MembershipEvents {\n items: MembershipEvent[];\n next_cursor: string | null;\n}\n\nexport interface StatutoInfo {\n uid: string;\n version: number;\n approvaldate: string | null;\n sha256: string | null;\n content: string | null;\n document_url: string | null;\n accepted: boolean;\n accepted_at: string | null;\n overdue: boolean;\n}\n\nexport interface StatutoAccept {\n version: number;\n sha256?: string;\n}\n\nexport interface Card extends CardToken {\n status: MembershipStatus;\n}\n\nexport interface Connection {\n client_id: string;\n name: string;\n kind: ClientInfo['kind'];\n scopes: Scope[];\n granted_at: string;\n}\n\n// ---- public surface -------------------------------------------------------------------------------------\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}\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 AssociationPublicConfig {\n /** The language this answer is written in: the one you asked for when the association offers it, its own otherwise. */\n locale: Locale;\n /** The languages the association offers: its own, plus those it enabled. */\n locales: Locale[];\n aps: {\n slug: string;\n name: string;\n picture_url: string | null;\n citta: string | null;\n provincia: string | null;\n enroll_enabled: boolean;\n /** Enrolment is on AND the association can take one more member right now (plan caps are never disclosed). */\n accepting_requests: boolean;\n /**\n * The private beta: the association takes only the people it invited — `accepting_requests` is then false and\n * enrolment answers 403 `not_available`; invitees join from the link they receive by mail.\n */\n invitation_only: boolean;\n /**\n * How the association admits its members — tell an applicant up front. `board`: the request waits for a decision\n * of the association's board, and any fee is paid after it; `provisional`: admitted at once, ratified later;\n * `automatic`: active as soon as the conditions are met. `delay_hours`: hours between admission and a USABLE card\n * (0 = at once) — the membership is active from admission, the card counts at the door only afterwards.\n */\n admission: { model: AdmissionModel; delay_hours: number };\n /** @deprecated Kept for compatibility: `true` when `admission.model` is `board`. Read `admission`. */\n approval_required: boolean;\n /**\n * Whether the association collects its members' address — of every member or of nobody. `none`: do not ask (an\n * `address` sent anyway is not stored); `optional`; `required`: enrolment answers 422 `required` on `address`\n * without one.\n */\n member_address: MemberAddressPolicy;\n /** How to pay the quota (IBAN, causale…), when the association published it. */\n payment_instructions: string | null;\n /**\n * The activities of general interest the association carries out (Italian Third Sector Code, art. 5): `cod` is\n * the letter of the article, `description` its Italian wording; one is marked as prevalent.\n */\n activity_sectors: Array<{ cod: string; description: string; prevalent: boolean }>;\n /**\n * Present when the association is registered in the RUNTS (the Italian national register of Third Sector\n * entities), as checked by the platform against the official public lists; `null` otherwise. Never typed by\n * the association.\n */\n registry: {\n section: 'APS' | 'ODV' | 'EF' | 'IS' | 'RA' | 'SOMS' | 'ALTRI' | 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: MembershipType[];\n statuto: Statuto | null;\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, YYYY-MM-DD. */\n date?: string;\n /** Birthplace: the comune, for a person born in Italy. */\n place?: string;\n /**\n * Birth country, ISO 3166-1 alpha-2. A code encodes the comune for people born in Italy and only the STATE for\n * everybody else: anything but `IT` is compared with that state, and `place` is ignored.\n */\n country?: string;\n}\n\n/** What may disagree with a fiscal code. `gender` only where it is sent: enrolment and the profile never cross-check it. */\nexport type FiscalCodeMismatch = 'lastName' | 'firstName' | 'gender' | 'date' | 'place';\n/** `names_swapped`: the code matches once surname and given name are exchanged. */\nexport type FiscalCodeHint = 'names_swapped';\n\nexport interface FiscalCodeResult {\n valid: boolean;\n /** `invalid`: structure or check character; `mismatch`: a well-formed code that disagrees with the data sent. */\n error: 'invalid' | 'mismatch' | null;\n /** What disagrees with the code, when `error` is `mismatch`. */\n mismatches: FiscalCodeMismatch[];\n hints: FiscalCodeHint[];\n /** The date of birth the code itself encodes (YYYY-MM-DD). */\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<{ kty: string; crv: string; x: string; kid: string; use: string; alg: string }>;\n}\n\n// ---- client (server-side) surface ---------------------------------------------------------------------\n\n// ---- server-side signup + enrolment (client scopes identity:signup / enroll:write) ---------------------\n\n/** A person your system registers on Vimine (`POST /v1/signup`). */\nexport interface SignupInput {\n email: string;\n first_name: string;\n last_name: string;\n phone?: string | null;\n /** YYYY-MM-DD */\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. Send it for a person born abroad: their fiscal code encodes only the state. */\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 account terms (`platform_terms`) the person accepted on your site — optional; when given it must name the in-force version (`GET /v1/legal/platform_terms`). */\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 * The language of the page the person filled in. It decides the language of the mails that follow and becomes the\n * preference of a NEW account; an existing account keeps its own.\n */\n locale?: Locale | string;\n}\n\n/** Whether an association collects its members' address (`GET /v1/aps/{slug}` → `aps.member_address`). */\nexport type MemberAddressPolicy = 'none' | 'optional' | 'required';\n\n/** A member's address, as `POST /v1/enroll`, `POST /v1/me/membership` and `POST /v1/enroll/confirm` take it. */\nexport interface MemberAddress {\n /** `residence` (the default) or, where different, `domicile`. */\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 (default `IT`). */\n country?: string;\n}\n\n/**\n * `POST /v1/enroll/confirm` after a 409 `identification_required`: what the account still lacks — a fiscal code, or\n * date, place and country of birth. It completes the EMPTY fields of the profile, never over what is there.\n */\nexport interface EnrollIdentification {\n /** YYYY-MM-DD */\n dob?: string;\n birthplace?: string;\n /** ISO 3166-1 alpha-2 */\n birth_country?: string;\n codicefiscale?: string;\n codicefiscale_confirmed?: boolean;\n}\n\n/** A published legal text named by version (and hash when published). */\nexport interface LegalRef {\n version: string;\n sha256?: string;\n}\n\n/** A membership request your system submits for a person (`POST /v1/enroll`). */\nexport interface EnrollInput extends SignupInput {\n /**\n * Optional. A person is identified by a fiscal code OR by `dob` + `birthplace` + `birth_country` — never neither\n * (422 `required` on each missing particular). When present it is validated and cross-checked against the names,\n * the date and the place (the state, for people born abroad).\n */\n codicefiscale?: string | null;\n /**\n * Residence or, where different, domicile. Asked of every member or of nobody: the public profile says what the\n * association declared (`aps.member_address`).\n */\n address?: MemberAddress;\n /** Membership type uid; optional when the association offers exactly one. */\n membership_type?: string;\n /** The in-force statuto the person accepted on your site (see `Statuto.version`; `sha256` when published). */\n accept_statuto: { version: number; sha256?: string };\n /**\n * The association's privacy notice the person read on your site (`ApsPublicConfig.privacy_notice`). REQUIRED when the\n * association publishes one; 422 `privacy_notice_outdated` when it is not the in-force version.\n */\n privacy_notice?: { version: number; sha256?: string; locale?: Locale | string };\n}\n\n/** One acceptance, acknowledgement or consent the person recorded (`GET /v1/me/acceptances`). */\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\n/** A document the person has not acted on at its in-force version. */\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: AcceptanceRecord[];\n pending: {\n /** Account-layer documents still to accept / acknowledge. */\n platform: PendingDocument[];\n /** This association's notice to members, when not yet acknowledged. */\n privacy_notice: PendingDocument | null;\n };\n}\n\n/** `POST /v1/me/acceptances`: the in-force version your app showed. */\nexport interface AcceptanceInput {\n /** `platform_terms` | `platform_privacy` | `network_consent` | `privacy_notice` */\n kind: string;\n version: string | number;\n sha256?: string;\n}\n\nexport interface AcceptanceResult {\n recorded: true;\n kind: string;\n action: string;\n version: string;\n at: string;\n}\n\n/** The uniform answer of the creating routes: whatever happened behind the address, it was accepted. */\nexport interface Accepted {\n status: 'accepted';\n}\n\n/** `POST /v1/enroll/confirm` — the outcome of the confirmation link an existing account's owner uses. */\nexport interface EnrollConfirmResult {\n status: MembershipStatus;\n /** The person already had a membership request or membership here; nothing new was created. */\n already: boolean;\n /** In order: the association's approval first (board model), then the fee. */\n pending_reasons: PendingReason[];\n payment_open: boolean;\n valid_from: string | null;\n association: { name: string; slug: string };\n /**\n * Only for a link sent by the association's hosted enrolment page when that page was opened from one of its public\n * events: what became of the place asked for together with the request. `null` for every other link.\n */\n event?: EnrolledPlace | null;\n}\n\n/** The place asked for with a membership request made from an event's page (`EnrollConfirmResult.event`). */\nexport interface EnrolledPlace {\n slug: string;\n title: string;\n starts_at: string;\n timezone: string;\n place: string | null;\n registration_type: { uid: string; name: string; amount: number; currency: string };\n /**\n * `confirmed`: the place is theirs. `reserved`: held, see `waiting`. `held`: the membership request itself still\n * waits for the address to be confirmed, and no place was asked for. `unavailable`: no place, see `reasons`.\n */\n state: 'confirmed' | 'reserved' | 'held' | 'unavailable';\n /** What a `reserved` place waits for: the membership to become active, the contribution, or both. */\n waiting: ('membership' | 'contribution')[];\n /** Why the place is `unavailable`: the reasons of the eligibility endpoint. */\n reasons: string[];\n reserved_until: string | null;\n /** How to pay a contribution that is owed, in the association's words. */\n payment_instructions: string | null;\n /** The person held this place before the link was used. */\n already: boolean;\n}\n\n/** `POST /v1/me/membership/renew` — renewed at once (free type, no approval gate) or turned into a request. */\nexport interface RenewResult {\n renewed: boolean;\n requested: boolean;\n status: MembershipStatus;\n expires_at: string | null;\n renewal_requested_at: string | null;\n}\n\n/** `PATCH /v1/me/membership/network-opt-in` */\nexport interface NetworkOptIn {\n network_opt_in: boolean;\n network_opt_in_at: string | null;\n}\n\n/** `POST /v1/checkins` — a door check-in from a scanned card token. No personal data. */\n/** `POST /v1/checkins` for a CARD token. */\nexport interface CardCheckinResult {\n kind: 'card';\n verdict: MembershipVerdict;\n status: MembershipStatus;\n membership_id: string;\n valid_until: string | null;\n /** With `verdict: 'not_yet_valid'`: when the card becomes usable. The scan is recorded all the same. */\n valid_from: string | null;\n /**\n * A note for whoever staffs the gate, never part of `verdict`: it restricts nothing. `pending`: the member has no\n * verifiable fiscal code and nobody of the association has looked at a document yet — show it. Cleared from the\n * association's console. `null`: nothing to check. The public `verifyCard` never carries it.\n */\n identity_check: IdentityCheck | null;\n checked_in_at: string;\n}\n/**\n * The identity check at first presence (`CardCheckinResult.identity_check`). `pending`: a document is still to be\n * looked at; `verified`: somebody of the association looked at one; `flagged`: somebody did, and it did not agree —\n * a matter for the association's office, which revokes nothing by itself.\n */\nexport type IdentityCheck = 'pending' | 'verified' | 'flagged';\nexport type RegistrationCheckinVerdict = 'valid' | 'already_checked_in' | 'not_confirmed' | 'cancelled' | 'event_cancelled' | 'membership_invalid';\n/** `POST /v1/checkins` for an event REGISTRATION token (`k:'reg'` in the payload). */\nexport interface RegistrationCheckinResult {\n kind: 'registration';\n verdict: RegistrationCheckinVerdict;\n status: RegistrationStatus;\n registration_id: string;\n event: { slug: string; title: string; starts_at: string };\n registration_type: string | null;\n membership_id: string | null;\n membership_verdict: MembershipVerdict | null;\n /** True the first time this registration is checked in. */\n first: boolean;\n checked_in_at: string | null;\n}\nexport type CheckinResult = CardCheckinResult | RegistrationCheckinResult;\n\n/** One row of `GET /v1/memberships` — ids and status only. */\nexport interface MembershipListItem {\n id: string;\n status: MembershipStatus;\n verdict: MembershipVerdict;\n membership_type: { cod: string } | null;\n issued_at: string | null;\n valid_until: string | null;\n updated_at: string;\n}\nexport interface MembershipList {\n items: MembershipListItem[];\n next_cursor: string | null;\n}\nexport interface MembershipListParams {\n status?: MembershipStatus;\n /** RFC 3339: only rows changed after this instant (incremental sync). */\n updated_since?: string;\n limit?: number;\n cursor?: string;\n}\n\nexport interface MembershipStatusInfo {\n id: string;\n status: MembershipStatus;\n verdict: MembershipVerdict;\n valid_until: string | null;\n membership_type: { cod: string } | null;\n}\n\nexport interface SandboxMember {\n email: string;\n name: string;\n status: MembershipStatus;\n expires_at: string | null;\n statuto_accepted: boolean;\n}\n\nexport interface SandboxMembers {\n slug: string;\n members: SandboxMember[];\n}\n\nexport interface SandboxReset {\n /** The synthetic members' shared password — shown only here. */\n password: string;\n members: Array<Pick<SandboxMember, 'email' | 'name' | 'status'>>;\n}\n\n// ---- events & registrations (/v1/aps/{slug}/events, /v1/events*, /v1/me/registrations*) ---------------------\n// Vocabulary: registration (iscrizione) and contribution (contributo) — never \"ticket\".\n\nexport type EventStatus = 'published' | 'completed' | 'cancelled';\nexport type EventVisibility = 'members_only' | 'public';\nexport type RegistrationStatus = 'reserved' | 'confirmed' | 'cancelled' | 'refunded';\n/** Why a registration was cancelled. */\nexport type RegistrationCancelReason =\n /** The member cancelled it, inside the event's cancellation window. */\n | 'user'\n /** The association's secretariat cancelled it. */\n | 'staff'\n /** A reserved place whose contribution did not arrive before the hold ran out. */\n | 'expired'\n | 'event_cancelled'\n /** A place held while the membership request was pending, for an event that starts before the new card is usable. */\n | 'card_not_valid_yet'\n /** The association did not accept the membership request (or the provisional admission) the place was held under. */\n | 'membership_rejected'\n /** The association revoked the membership the place needed. */\n | 'membership_revoked';\n/** Why a registration type is not open right now. */\nexport type RegistrationTypeReason = 'sold_out' | 'registration_not_open' | 'registration_closed';\n/** Why the member may not register (`GET /v1/events/{slug}/eligibility`, `422 not_eligible`). */\nexport type EligibilityReason =\n | 'membership_required'\n | 'membership_not_active'\n /** The event starts before the member's card is usable (the association's usability delay). */\n | 'membership_not_yet_valid'\n | 'membership_type_not_allowed'\n | 'sold_out'\n | 'event_full'\n | 'registration_not_open'\n | 'registration_closed'\n | 'max_per_user'\n | 'event_past'\n | 'event_cancelled'\n | 'event_not_published'\n | 'plan_limit'\n | 'invalid_type';\n\nexport interface EventLocation {\n name: string | null;\n address: string | null;\n lat: number | null;\n lng: number | null;\n}\n\n/** An admission class of an event: free (`amount` 0) or a contribution; places and window are live. */\nexport interface RegistrationType {\n uid: string;\n cod: string;\n name: string;\n description: string | null;\n amount: number;\n currency: string;\n quantity: number | null;\n /** Places left (never who holds them); null = unlimited. */\n remaining: number | null;\n max_per_user: number;\n requires_active_membership: boolean;\n open: boolean;\n reason: RegistrationTypeReason | null;\n opens_at: string | null;\n closes_at: string | null;\n}\n\n/** An event as the API describes it: headless copy, dates, place, images, live availability per type. */\nexport interface Event {\n id: string;\n slug: string;\n /**\n * The language the `title` was served in. When it is not the one you asked for, the association wrote no\n * translation: you got its own text — never a machine translation. Each text falls back on its own.\n */\n locale: Locale;\n /** The languages in which this event has a title. */\n locales: Locale[];\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: EventStatus;\n visibility: EventVisibility;\n location: EventLocation | null;\n cover_url: string | null;\n gallery: { url: string; alt: string | null; order: number }[];\n links: { label: string; url: string }[];\n registration: { opens_at: string | null; closes_at: string | null; capacity: number | null; remaining: number | null; cancellation_hours: number };\n registration_types: RegistrationType[];\n published_at: string | null;\n cancelled_at: string | null;\n cancel_reason: string | null;\n}\nexport interface EventList {\n items: Event[];\n}\nexport interface EventListParams extends LocaleParam {\n /** `upcoming` (default) | `past` | `cancelled` | `all` */\n filter?: 'upcoming' | 'past' | 'cancelled' | 'all';\n /** RFC 3339 bounds on `starts_at`. */\n from?: string;\n to?: string;\n limit?: number;\n}\n\nexport interface Eligibility {\n can_register: boolean;\n membership_verdict: MembershipVerdict | null;\n types: { uid: string; cod: string; can_register: boolean; reasons: EligibilityReason[]; pending_membership: boolean }[];\n}\n\nexport interface RegistrationRequest {\n registration_type: string;\n note?: string | null;\n quantity?: number;\n /** The language the registration was made in: the fallback for a member who never chose one. */\n locale?: Locale | string;\n}\n\n/** A person's registration (the member's own, or a guest's after the confirmation link). */\nexport interface Registration {\n id: string;\n status: RegistrationStatus;\n event: { id: string; slug: string; title: string; starts_at: string; ends_at: string | null; timezone: string; status: EventStatus; location: string | null; cancel_reason: string | null } | null;\n registration_type: { uid: string; cod: string; name: string; amount: number; currency: string } | null;\n quantity: number;\n reserved_until: string | null;\n checked_in_at: string | null;\n cancelled_at: string | null;\n cancel_reason: RegistrationCancelReason | null;\n can_cancel: boolean;\n payment: { status: 'recorded' | 'refunded' | 'void'; amount: number; currency: string; method: string; paid_at: string } | null;\n /** How to pay the contribution while `reserved` (the association's own text). */\n payment_instructions?: string | null;\n note: string | null;\n created_at: string;\n /** The registration QR payload (`vmt_…`), confirmed registrations only — draw it as a QR code. */\n token?: string | null;\n}\nexport interface RegistrationList {\n items: Registration[];\n}\n\n/** `POST /v1/events/{slug}/registrations/guest` (client scope `registrations:write`, public events only). */\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 — for a guest, the language of every mail they receive. */\n locale?: Locale | string;\n}\n\n/** One row of `GET /v1/events/{slug}/registrations` — no personal data. */\nexport interface RegistrationListItem {\n id: string;\n status: RegistrationStatus;\n registration_type: string | null;\n membership_id: string | null;\n quantity: number;\n checked_in_at: string | null;\n created_at: string;\n}\nexport interface EventRegistrationList {\n items: RegistrationListItem[];\n next_cursor: string | null;\n}\nexport interface EventRegistrationListParams {\n status?: RegistrationStatus;\n limit?: number;\n cursor?: string;\n}\n\n"]}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,0GAA0G;AAC1G,kGAAkG","sourcesContent":["// Wire types of the Vimine API v1 — hand-kept in sync with openapi/v1.json (the document is the source of\n// truth; a generated file may replace this one later). Field names are the JSON names, unchanged.\n\n/** Permissions a member (user scopes) or an association's own system (client scopes) may hold. */\nexport type Scope =\n | 'profile:read'\n | 'profile:write'\n | 'membership:read'\n | 'membership:request'\n | 'statuto:accept'\n | 'network:manage'\n | 'identity:signup'\n | 'enroll:write'\n | 'verify:read'\n | 'memberships:read'\n | 'checkins:write'\n | 'webhooks:manage'\n | 'events:read'\n | 'registrations:read'\n | 'registrations:write';\n\n/** `rejected`: the request for admission was not accepted (a different act from `revoked`, which excludes a member). */\nexport type MembershipStatus = 'pending' | 'active' | 'suspended' | 'revoked' | 'rejected';\n/** What the card is worth right now: `valid`, `expired`, `statuto_required` (re-acceptance overdue) or `inactive`. */\n/** `not_yet_valid`: active and unexpired, but inside the association's usability delay — see `Membership.valid_from`. */\nexport type MembershipVerdict = 'valid' | 'expired' | 'not_yet_valid' | 'statuto_required' | 'inactive';\n\n// ---- OAuth ------------------------------------------------------------------------------------------\n\nexport interface TokenResponse {\n access_token: string;\n token_type: 'Bearer';\n expires_in: number;\n refresh_token?: string;\n scope: string;\n /** Pairwise subject of the member (per association); absent on client tokens. */\n sub?: string;\n}\n\nexport interface ClientInfo {\n client_id: string;\n name: string;\n kind: 'public' | 'native' | 'confidential' | 'first_party';\n aps: { slug: string; name: string; picture_url: string | null };\n scopes: Array<{ code: Scope; label: string }>;\n}\n\n// ---- member surface (/v1/me*) -------------------------------------------------------------------------\n\n/**\n * A language the platform speaks (`it`, `en` today). Wherever the API takes one it also takes a regional tag\n * (`en-GB`) and reduces it; a language it does not speak is ignored, never an error — except on `PATCH /v1/me`.\n */\n// The platform's languages. A request in one the platform does not serve yet (a language still in review) gets the\n// platform's default, and the answer's `locale` says so.\nexport type Locale = 'it' | 'en' | 'zh-Hans' | 'zh-Hant' | 'fr' | 'es' | 'de' | 'pt-BR';\n\n/** Ask for the association's copy in a language (`?locale=`). Default: the member's own, then `Accept-Language`, then the association's. */\nexport interface LocaleParam {\n locale?: Locale | string;\n}\n\nexport interface Me {\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 /** ISO date (YYYY-MM-DD) */\n dob: string | null;\n /** Demographic only: it is never cross-checked against a fiscal code. */\n gender: 'M' | 'F' | null;\n /** Comune (born in Italy) or city, free text (born abroad). */\n birthplace: string | null;\n /** Country of birth, 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; `null` = not identified yet (they cannot request a membership). */\n codicefiscale_check: CodiceFiscaleCheck | null;\n /** The language the person chose for the platform and its mails; `null` = never chosen (the request's, then the association's, applies). */\n locale: Locale | null;\n updated_at: string | null;\n}\n\n/**\n * How a person is identified — by a fiscal code OR by their particulars (date, place and country of birth), never\n * neither. `matched`: a fiscal code that agrees with the particulars; `mismatch_confirmed`: a code that disagrees,\n * confirmed by the person as the one on their health card; `absent`: no code, the particulars identify them.\n */\nexport type CodiceFiscaleCheck = 'matched' | 'mismatch_confirmed' | 'absent';\n\nexport interface MeUpdate {\n phone?: string | null;\n dob?: string | null;\n gender?: 'M' | 'F' | null;\n birthplace?: string | null;\n /** ISO 3166-1 alpha-2. For a person born abroad a fiscal code encodes only the STATE: this is what it is compared with. */\n birth_country?: string | null;\n /** May be added later, or set to `null`. Validated and cross-checked when present (422 `codicefiscale_mismatch`). */\n codicefiscale?: string | null;\n /** Write-only: the person confirms a code that disagrees with their particulars (only after a `confirmable: true`). */\n codicefiscale_confirmed?: boolean;\n /** The person's language; `null` clears the choice. 422 `unsupported` for a language the platform does not speak. */\n locale?: Locale | null;\n}\n\nexport interface MembershipTypeRef {\n uid: string;\n cod: string;\n name: string;\n}\n\nexport interface MembershipStatuto {\n current_version: number | null;\n current_sha256: string | null;\n accepted_version_id: string | null;\n accepted_at: string | null;\n /** A newer statuto was published since the member accepted one. */\n pending: boolean;\n /** … and the association's grace window for re-acceptance has elapsed. */\n overdue: boolean;\n}\n\nexport interface CardToken {\n /** The `vmt_…` token: what a QR carries and what `/v1/verify/{card_token}` checks. */\n token: string;\n /** Validity window (unix seconds). */\n nbf: number;\n exp: number;\n}\n\nexport interface Membership {\n id: string;\n status: MembershipStatus;\n verdict: MembershipVerdict;\n subdate: string | null;\n issued_at: string | null;\n expires_at: string | null;\n membership_type: MembershipTypeRef | null;\n statuto: MembershipStatuto;\n /**\n * Why a `pending` membership is still pending, IN ORDER: the association's approval of the request first (when it\n * admits by decision of its board), then the quota of a paid type. Empty when active.\n */\n pending_reasons: PendingReason[];\n /** May the quota be paid yet? `false` while the approval is still pending: approval opens payment. */\n payment_open: boolean;\n /** When the card starts to count at the door (the association's usability delay); `null` = since activation. */\n valid_from: string | null;\n /** Is the card usable right now? `status` may be `active` while this is still `false` (see `valid_from`). */\n usable: boolean;\n /** The quota of a paid membership type and whether it is paid for the current period; `null` for a free type. */\n quota: { amount: number; currency: string; paid: boolean } | null;\n /** The association's instructions for paying the quota, only once the payment is open (`payment_open`). */\n payment_instructions: string | null;\n /** Days to expiry (negative once expired). */\n expires_in_days: number | null;\n /** Self-service renewal: open 60 days before expiry; `requested_at` once the member asked. */\n renewal: { window_open: boolean; requested_at: string | null };\n network_opt_in: boolean;\n /** The signed card token. `null` unless `status` is `active` (a pending, suspended or revoked membership has no card) or when card signing is not configured. */\n card: CardToken | null;\n}\n\nexport type PendingReason = 'approval' | 'payment';\n/** How an association admits its members (`GET /v1/aps/{slug}` → `aps.admission.model`). */\nexport type AdmissionModel = 'board' | 'provisional' | 'automatic';\n\nexport interface MembershipRequest {\n /** Membership type uid; optional when the association offers exactly one. */\n membership_type?: string;\n /** Must name the in-force statuto (see `Statuto.version`; `sha256` when published). */\n accept_statuto: { version: number; sha256?: string };\n /**\n * The association's privacy notice the person read on your page (`ApsPublicConfig.privacy_notice`; add `locale` when\n * you showed a translation). REQUIRED while a notice is in force that the person has not acknowledged yet\n * (`legal.acceptances()` → `pending.privacy_notice`): 422 `validation_failed` on `privacy_notice` without it, 422\n * `privacy_notice_outdated` when it is not the in-force version. Ignored once they stand at the in-force one.\n */\n privacy_notice?: { version: number; sha256?: string; locale?: Locale | string };\n /**\n * Residence or, where different, domicile — kept on the association's own record of the member. REQUIRED where the\n * association declared `member_address: required` (422 `validation_failed` on `address`), stored where it declared\n * `optional`, ignored where it collects none.\n */\n address?: MemberAddress;\n /** The language of the page the person used (`it`, `en`): which translation of the notice they read. */\n locale?: Locale | string;\n}\n\n/** A free type with no approval gate is issued `active` at once; otherwise `pending` with its reasons. */\n/** What every answer about a membership request says about its gates. */\nexport interface MembershipGates {\n /** In order: the association's approval first (board model), then the fee. Empty when active. */\n pending_reasons: PendingReason[];\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 usability delay; `null` otherwise. */\n valid_from: string | null;\n}\nexport type MembershipRequestResult =\n | ({ created: true; status: MembershipStatus; id: string } & MembershipGates)\n | ({ already_requested: true; status: MembershipStatus } & MembershipGates);\n\nexport interface MembershipEvent {\n from: MembershipStatus | null;\n to: MembershipStatus;\n reason: string | null;\n changed_at: string;\n channel: string;\n}\n\nexport interface MembershipEvents {\n items: MembershipEvent[];\n next_cursor: string | null;\n}\n\nexport interface StatutoInfo {\n uid: string;\n version: number;\n approvaldate: string | null;\n sha256: string | null;\n content: string | null;\n document_url: string | null;\n accepted: boolean;\n accepted_at: string | null;\n overdue: boolean;\n}\n\nexport interface StatutoAccept {\n version: number;\n sha256?: string;\n}\n\nexport interface Card extends CardToken {\n status: MembershipStatus;\n}\n\nexport interface Connection {\n client_id: string;\n name: string;\n kind: ClientInfo['kind'];\n scopes: Scope[];\n granted_at: string;\n}\n\n// ---- public surface -------------------------------------------------------------------------------------\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}\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 AssociationPublicConfig {\n /** The language this answer is written in: the one you asked for when the association offers it, its own otherwise. */\n locale: Locale;\n /** The languages the association offers: its own, plus those it enabled. */\n locales: Locale[];\n aps: {\n slug: string;\n name: string;\n picture_url: string | null;\n citta: string | null;\n provincia: string | null;\n enroll_enabled: boolean;\n /** Enrolment is on AND the association can take one more member right now (plan caps are never disclosed). */\n accepting_requests: boolean;\n /**\n * The private beta: the association takes only the people it invited — `accepting_requests` is then false and\n * enrolment answers 403 `not_available`; invitees join from the link they receive by mail.\n */\n invitation_only: boolean;\n /**\n * How the association admits its members — tell an applicant up front. `board`: the request waits for a decision\n * of the association's board, and any fee is paid after it; `provisional`: admitted at once, ratified later;\n * `automatic`: active as soon as the conditions are met. `delay_hours`: hours between admission and a USABLE card\n * (0 = at once) — the membership is active from admission, the card counts at the door only afterwards.\n */\n admission: { model: AdmissionModel; delay_hours: number };\n /** @deprecated Kept for compatibility: `true` when `admission.model` is `board`. Read `admission`. */\n approval_required: boolean;\n /**\n * Whether the association collects its members' address — of every member or of nobody. `none`: do not ask (an\n * `address` sent anyway is not stored); `optional`; `required`: enrolment answers 422 `required` on `address`\n * without one.\n */\n member_address: MemberAddressPolicy;\n /** How to pay the quota (IBAN, causale…), when the association published it. */\n payment_instructions: string | null;\n /**\n * The activities of general interest the association carries out (Italian Third Sector Code, art. 5): `cod` is\n * the letter of the article, `description` its Italian wording; one is marked as prevalent.\n */\n activity_sectors: Array<{ cod: string; description: string; prevalent: boolean }>;\n /**\n * Present when the association is registered in the RUNTS (the Italian national register of Third Sector\n * entities), as checked by the platform against the official public lists; `null` otherwise. Never typed by\n * the association.\n */\n registry: {\n section: 'APS' | 'ODV' | 'EF' | 'IS' | 'RA' | 'SOMS' | 'ALTRI' | 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: MembershipType[];\n statuto: Statuto | null;\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, YYYY-MM-DD. */\n date?: string;\n /** Birthplace: the comune, for a person born in Italy. */\n place?: string;\n /**\n * Birth country, ISO 3166-1 alpha-2. A code encodes the comune for people born in Italy and only the STATE for\n * everybody else: anything but `IT` is compared with that state, and `place` is ignored.\n */\n country?: string;\n}\n\n/** What may disagree with a fiscal code. `gender` only where it is sent: enrolment and the profile never cross-check it. */\nexport type FiscalCodeMismatch = 'lastName' | 'firstName' | 'gender' | 'date' | 'place';\n/** `names_swapped`: the code matches once surname and given name are exchanged. */\nexport type FiscalCodeHint = 'names_swapped';\n\nexport interface FiscalCodeResult {\n valid: boolean;\n /** `invalid`: structure or check character; `mismatch`: a well-formed code that disagrees with the data sent. */\n error: 'invalid' | 'mismatch' | null;\n /** What disagrees with the code, when `error` is `mismatch`. */\n mismatches: FiscalCodeMismatch[];\n hints: FiscalCodeHint[];\n /** The date of birth the code itself encodes (YYYY-MM-DD). */\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<{ kty: string; crv: string; x: string; kid: string; use: string; alg: string }>;\n}\n\n// ---- client (server-side) surface ---------------------------------------------------------------------\n\n// ---- server-side signup + enrolment (client scopes identity:signup / enroll:write) ---------------------\n\n/** A person your system registers on Vimine (`POST /v1/signup`). */\nexport interface SignupInput {\n email: string;\n first_name: string;\n last_name: string;\n phone?: string | null;\n /** YYYY-MM-DD */\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. Send it for a person born abroad: their fiscal code encodes only the state. */\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 account terms (`platform_terms`) the person accepted on your site — optional; when given it must name the in-force version (`GET /v1/legal/platform_terms`). */\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 * The language of the page the person filled in. It decides the language of the mails that follow and becomes the\n * preference of a NEW account; an existing account keeps its own.\n */\n locale?: Locale | string;\n}\n\n/** Whether an association collects its members' address (`GET /v1/aps/{slug}` → `aps.member_address`). */\nexport type MemberAddressPolicy = 'none' | 'optional' | 'required';\n\n/** A member's address, as `POST /v1/enroll`, `POST /v1/me/membership` and `POST /v1/enroll/confirm` take it. */\nexport interface MemberAddress {\n /** `residence` (the default) or, where different, `domicile`. */\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 (default `IT`). */\n country?: string;\n}\n\n/**\n * `POST /v1/enroll/confirm` after a 409 `identification_required`: what the account still lacks — a fiscal code, or\n * date, place and country of birth. It completes the EMPTY fields of the profile, never over what is there.\n */\nexport interface EnrollIdentification {\n /** YYYY-MM-DD */\n dob?: string;\n birthplace?: string;\n /** ISO 3166-1 alpha-2 */\n birth_country?: string;\n codicefiscale?: string;\n codicefiscale_confirmed?: boolean;\n}\n\n/** A published legal text named by version (and hash when published). */\nexport interface LegalRef {\n version: string;\n sha256?: string;\n}\n\n/** A membership request your system submits for a person (`POST /v1/enroll`). */\nexport interface EnrollInput extends SignupInput {\n /**\n * Optional. A person is identified by a fiscal code OR by `dob` + `birthplace` + `birth_country` — never neither\n * (422 `required` on each missing particular). When present it is validated and cross-checked against the names,\n * the date and the place (the state, for people born abroad).\n */\n codicefiscale?: string | null;\n /**\n * Residence or, where different, domicile. Asked of every member or of nobody: the public profile says what the\n * association declared (`aps.member_address`).\n */\n address?: MemberAddress;\n /** Membership type uid; optional when the association offers exactly one. */\n membership_type?: string;\n /** The in-force statuto the person accepted on your site (see `Statuto.version`; `sha256` when published). */\n accept_statuto: { version: number; sha256?: string };\n /**\n * The association's privacy notice the person read on your site (`ApsPublicConfig.privacy_notice`). REQUIRED when the\n * association publishes one; 422 `privacy_notice_outdated` when it is not the in-force version.\n */\n privacy_notice?: { version: number; sha256?: string; locale?: Locale | string };\n}\n\n/** One acceptance, acknowledgement or consent the person recorded (`GET /v1/me/acceptances`). */\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\n/** A document the person has not acted on at its in-force version. */\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: AcceptanceRecord[];\n pending: {\n /** Account-layer documents still to accept / acknowledge. */\n platform: PendingDocument[];\n /** This association's notice to members, when not yet acknowledged. */\n privacy_notice: PendingDocument | null;\n };\n}\n\n/** `POST /v1/me/acceptances`: the in-force version your app showed. */\nexport interface AcceptanceInput {\n /** `platform_terms` | `platform_privacy` | `network_consent` | `privacy_notice` */\n kind: string;\n version: string | number;\n sha256?: string;\n}\n\nexport interface AcceptanceResult {\n recorded: true;\n kind: string;\n action: string;\n version: string;\n at: string;\n}\n\n/** The uniform answer of the creating routes: whatever happened behind the address, it was accepted. */\nexport interface Accepted {\n status: 'accepted';\n}\n\n/** `POST /v1/enroll/confirm` — the outcome of the confirmation link an existing account's owner uses. */\nexport interface EnrollConfirmResult {\n status: MembershipStatus;\n /** The person already had a membership request or membership here; nothing new was created. */\n already: boolean;\n /** In order: the association's approval first (board model), then the fee. */\n pending_reasons: PendingReason[];\n payment_open: boolean;\n valid_from: string | null;\n association: { name: string; slug: string };\n /**\n * Only for a link sent by the association's hosted enrolment page when that page was opened from one of its public\n * events: what became of the place asked for together with the request. `null` for every other link.\n */\n event?: EnrolledPlace | null;\n}\n\n/** The place asked for with a membership request made from an event's page (`EnrollConfirmResult.event`). */\nexport interface EnrolledPlace {\n slug: string;\n title: string;\n starts_at: string;\n timezone: string;\n place: string | null;\n registration_type: { uid: string; name: string; amount: number; currency: string };\n /**\n * `confirmed`: the place is theirs. `reserved`: held, see `waiting`. `held`: the membership request itself still\n * waits for the address to be confirmed, and no place was asked for. `unavailable`: no place, see `reasons`.\n */\n state: 'confirmed' | 'reserved' | 'held' | 'unavailable';\n /** What a `reserved` place waits for: the membership to become active, the contribution, or both. */\n waiting: ('membership' | 'contribution')[];\n /** Why the place is `unavailable`: the reasons of the eligibility endpoint. */\n reasons: string[];\n reserved_until: string | null;\n /** How to pay a contribution that is owed, in the association's words. */\n payment_instructions: string | null;\n /** The person held this place before the link was used. */\n already: boolean;\n}\n\n/** `POST /v1/me/membership/renew` — renewed at once (free type, no approval gate) or turned into a request. */\nexport interface RenewResult {\n renewed: boolean;\n requested: boolean;\n status: MembershipStatus;\n expires_at: string | null;\n renewal_requested_at: string | null;\n}\n\n/** `PATCH /v1/me/membership/network-opt-in` */\nexport interface NetworkOptIn {\n network_opt_in: boolean;\n network_opt_in_at: string | null;\n}\n\n/** `POST /v1/checkins` — a door check-in from a scanned card token. No personal data. */\n/** `POST /v1/checkins` for a CARD token. */\nexport interface CardCheckinResult {\n kind: 'card';\n verdict: MembershipVerdict;\n status: MembershipStatus;\n membership_id: string;\n valid_until: string | null;\n /** With `verdict: 'not_yet_valid'`: when the card becomes usable. The scan is recorded all the same. */\n valid_from: string | null;\n /**\n * A note for whoever staffs the gate, never part of `verdict`: it restricts nothing. `pending`: the member has no\n * verifiable fiscal code and nobody of the association has looked at a document yet — show it. Cleared from the\n * association's console. `null`: nothing to check. The public `verifyCard` never carries it.\n */\n identity_check: IdentityCheck | null;\n checked_in_at: string;\n}\n/**\n * The identity check at first presence (`CardCheckinResult.identity_check`). `pending`: a document is still to be\n * looked at; `verified`: somebody of the association looked at one; `flagged`: somebody did, and it did not agree —\n * a matter for the association's office, which revokes nothing by itself.\n */\nexport type IdentityCheck = 'pending' | 'verified' | 'flagged';\nexport type RegistrationCheckinVerdict = 'valid' | 'already_checked_in' | 'not_confirmed' | 'cancelled' | 'event_cancelled' | 'membership_invalid';\n/** `POST /v1/checkins` for an event REGISTRATION token (`k:'reg'` in the payload). */\nexport interface RegistrationCheckinResult {\n kind: 'registration';\n verdict: RegistrationCheckinVerdict;\n status: RegistrationStatus;\n registration_id: string;\n event: { slug: string; title: string; starts_at: string };\n registration_type: string | null;\n membership_id: string | null;\n membership_verdict: MembershipVerdict | null;\n /** True the first time this registration is checked in. */\n first: boolean;\n checked_in_at: string | null;\n}\nexport type CheckinResult = CardCheckinResult | RegistrationCheckinResult;\n\n/** One row of `GET /v1/memberships` — ids and status only. */\nexport interface MembershipListItem {\n id: string;\n status: MembershipStatus;\n verdict: MembershipVerdict;\n membership_type: { cod: string } | null;\n issued_at: string | null;\n valid_until: string | null;\n updated_at: string;\n}\nexport interface MembershipList {\n items: MembershipListItem[];\n next_cursor: string | null;\n}\nexport interface MembershipListParams {\n status?: MembershipStatus;\n /** RFC 3339: only rows changed after this instant (incremental sync). */\n updated_since?: string;\n limit?: number;\n cursor?: string;\n}\n\nexport interface MembershipStatusInfo {\n id: string;\n status: MembershipStatus;\n verdict: MembershipVerdict;\n valid_until: string | null;\n membership_type: { cod: string } | null;\n}\n\nexport interface SandboxMember {\n email: string;\n name: string;\n status: MembershipStatus;\n expires_at: string | null;\n statuto_accepted: boolean;\n}\n\nexport interface SandboxMembers {\n slug: string;\n members: SandboxMember[];\n}\n\nexport interface SandboxReset {\n /** The synthetic members' shared password — shown only here. */\n password: string;\n members: Array<Pick<SandboxMember, 'email' | 'name' | 'status'>>;\n}\n\n// ---- events & registrations (/v1/aps/{slug}/events, /v1/events*, /v1/me/registrations*) ---------------------\n// Vocabulary: registration (iscrizione) and contribution (contributo) — never \"ticket\".\n\nexport type EventStatus = 'published' | 'completed' | 'cancelled';\nexport type EventVisibility = 'members_only' | 'public';\nexport type RegistrationStatus = 'reserved' | 'confirmed' | 'cancelled' | 'refunded';\n/** Why a registration was cancelled. */\nexport type RegistrationCancelReason =\n /** The member cancelled it, inside the event's cancellation window. */\n | 'user'\n /** The association's secretariat cancelled it. */\n | 'staff'\n /** A reserved place whose contribution did not arrive before the hold ran out. */\n | 'expired'\n | 'event_cancelled'\n /** A place held while the membership request was pending, for an event that starts before the new card is usable. */\n | 'card_not_valid_yet'\n /** The association did not accept the membership request (or the provisional admission) the place was held under. */\n | 'membership_rejected'\n /** The association revoked the membership the place needed. */\n | 'membership_revoked';\n/** Why a registration type is not open right now. */\nexport type RegistrationTypeReason = 'sold_out' | 'registration_not_open' | 'registration_closed';\n/** Why the member may not register (`GET /v1/events/{slug}/eligibility`, `422 not_eligible`). */\nexport type EligibilityReason =\n | 'membership_required'\n | 'membership_not_active'\n /** The event starts before the member's card is usable (the association's usability delay). */\n | 'membership_not_yet_valid'\n | 'membership_type_not_allowed'\n | 'sold_out'\n | 'event_full'\n | 'registration_not_open'\n | 'registration_closed'\n | 'max_per_user'\n | 'event_past'\n | 'event_cancelled'\n | 'event_not_published'\n | 'plan_limit'\n | 'invalid_type';\n\nexport interface EventLocation {\n name: string | null;\n address: string | null;\n lat: number | null;\n lng: number | null;\n}\n\n/** An admission class of an event: free (`amount` 0) or a contribution; places and window are live. */\nexport interface RegistrationType {\n uid: string;\n cod: string;\n name: string;\n description: string | null;\n amount: number;\n currency: string;\n quantity: number | null;\n /** Places left (never who holds them); null = unlimited. */\n remaining: number | null;\n max_per_user: number;\n requires_active_membership: boolean;\n open: boolean;\n reason: RegistrationTypeReason | null;\n opens_at: string | null;\n closes_at: string | null;\n}\n\n/** An event as the API describes it: headless copy, dates, place, images, live availability per type. */\nexport interface Event {\n id: string;\n slug: string;\n /**\n * The language the `title` was served in. When it is not the one you asked for, the association wrote no\n * translation: you got its own text — never a machine translation. Each text falls back on its own.\n */\n locale: Locale;\n /** The languages in which this event has a title. */\n locales: Locale[];\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: EventStatus;\n visibility: EventVisibility;\n location: EventLocation | null;\n cover_url: string | null;\n gallery: { url: string; alt: string | null; order: number }[];\n links: { label: string; url: string }[];\n registration: { opens_at: string | null; closes_at: string | null; capacity: number | null; remaining: number | null; cancellation_hours: number };\n registration_types: RegistrationType[];\n published_at: string | null;\n cancelled_at: string | null;\n cancel_reason: string | null;\n}\nexport interface EventList {\n items: Event[];\n}\nexport interface EventListParams extends LocaleParam {\n /** `upcoming` (default) | `past` | `cancelled` | `all` */\n filter?: 'upcoming' | 'past' | 'cancelled' | 'all';\n /** RFC 3339 bounds on `starts_at`. */\n from?: string;\n to?: string;\n limit?: number;\n}\n\nexport interface Eligibility {\n can_register: boolean;\n membership_verdict: MembershipVerdict | null;\n types: { uid: string; cod: string; can_register: boolean; reasons: EligibilityReason[]; pending_membership: boolean }[];\n}\n\nexport interface RegistrationRequest {\n registration_type: string;\n note?: string | null;\n quantity?: number;\n /** The language the registration was made in: the fallback for a member who never chose one. */\n locale?: Locale | string;\n}\n\n/** A person's registration (the member's own, or a guest's after the confirmation link). */\nexport interface Registration {\n id: string;\n status: RegistrationStatus;\n event: { id: string; slug: string; title: string; starts_at: string; ends_at: string | null; timezone: string; status: EventStatus; location: string | null; cancel_reason: string | null } | null;\n registration_type: { uid: string; cod: string; name: string; amount: number; currency: string } | null;\n quantity: number;\n reserved_until: string | null;\n checked_in_at: string | null;\n cancelled_at: string | null;\n cancel_reason: RegistrationCancelReason | null;\n can_cancel: boolean;\n payment: { status: 'recorded' | 'refunded' | 'void'; amount: number; currency: string; method: string; paid_at: string } | null;\n /** How to pay the contribution while `reserved` (the association's own text). */\n payment_instructions?: string | null;\n note: string | null;\n created_at: string;\n /** The registration QR payload (`vmt_…`), confirmed registrations only — draw it as a QR code. */\n token?: string | null;\n}\nexport interface RegistrationList {\n items: Registration[];\n}\n\n/** `POST /v1/events/{slug}/registrations/guest` (client scope `registrations:write`, public events only). */\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 — for a guest, the language of every mail they receive. */\n locale?: Locale | string;\n}\n\n/** One row of `GET /v1/events/{slug}/registrations` — no personal data. */\nexport interface RegistrationListItem {\n id: string;\n status: RegistrationStatus;\n registration_type: string | null;\n membership_id: string | null;\n quantity: number;\n checked_in_at: string | null;\n created_at: string;\n}\nexport interface EventRegistrationList {\n items: RegistrationListItem[];\n next_cursor: string | null;\n}\nexport interface EventRegistrationListParams {\n status?: RegistrationStatus;\n limit?: number;\n cursor?: string;\n}\n\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vimine/sdk",
3
- "version": "0.3.2",
3
+ "version": "0.3.3",
4
4
  "description": "Sign in with Vimine and the Vimine API, for websites and apps of associations on vimine.network.",
5
5
  "license": "MIT",
6
6
  "repository": {