@ecosplay/e-brocante 1.0.2
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.
- package/AGENTS.md +141 -0
- package/CHANGELOG.md +76 -0
- package/LICENSE +64 -0
- package/README.md +246 -0
- package/dist/EBrocanteClient.d.ts +38 -0
- package/dist/EBrocanteClient.d.ts.map +1 -0
- package/dist/EBrocanteClient.js +99 -0
- package/dist/EBrocanteClient.js.map +1 -0
- package/dist/cache/CacheBackend.d.ts +20 -0
- package/dist/cache/CacheBackend.d.ts.map +1 -0
- package/dist/cache/CacheBackend.js +6 -0
- package/dist/cache/CacheBackend.js.map +1 -0
- package/dist/cache/LocalCache.d.ts +22 -0
- package/dist/cache/LocalCache.d.ts.map +1 -0
- package/dist/cache/LocalCache.js +53 -0
- package/dist/cache/LocalCache.js.map +1 -0
- package/dist/cache/NullCache.d.ts +17 -0
- package/dist/cache/NullCache.d.ts.map +1 -0
- package/dist/cache/NullCache.js +26 -0
- package/dist/cache/NullCache.js.map +1 -0
- package/dist/cache/RedisCache.d.ts +39 -0
- package/dist/cache/RedisCache.d.ts.map +1 -0
- package/dist/cache/RedisCache.js +104 -0
- package/dist/cache/RedisCache.js.map +1 -0
- package/dist/cache/RedisConfig.d.ts +17 -0
- package/dist/cache/RedisConfig.d.ts.map +1 -0
- package/dist/cache/RedisConfig.js +13 -0
- package/dist/cache/RedisConfig.js.map +1 -0
- package/dist/cache/stableHashKey.d.ts +11 -0
- package/dist/cache/stableHashKey.d.ts.map +1 -0
- package/dist/cache/stableHashKey.js +27 -0
- package/dist/cache/stableHashKey.js.map +1 -0
- package/dist/exceptions/index.d.ts +41 -0
- package/dist/exceptions/index.d.ts.map +1 -0
- package/dist/exceptions/index.js +62 -0
- package/dist/exceptions/index.js.map +1 -0
- package/dist/http/HttpClient.d.ts +41 -0
- package/dist/http/HttpClient.d.ts.map +1 -0
- package/dist/http/HttpClient.js +222 -0
- package/dist/http/HttpClient.js.map +1 -0
- package/dist/index.d.ts +22 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +17 -0
- package/dist/index.js.map +1 -0
- package/dist/internal/safeStrings.d.ts +52 -0
- package/dist/internal/safeStrings.d.ts.map +1 -0
- package/dist/internal/safeStrings.js +156 -0
- package/dist/internal/safeStrings.js.map +1 -0
- package/dist/logger/DebugWriter.d.ts +24 -0
- package/dist/logger/DebugWriter.d.ts.map +1 -0
- package/dist/logger/DebugWriter.js +62 -0
- package/dist/logger/DebugWriter.js.map +1 -0
- package/dist/logger/FileLogger.d.ts +26 -0
- package/dist/logger/FileLogger.d.ts.map +1 -0
- package/dist/logger/FileLogger.js +96 -0
- package/dist/logger/FileLogger.js.map +1 -0
- package/dist/logger/Logger.d.ts +12 -0
- package/dist/logger/Logger.d.ts.map +1 -0
- package/dist/logger/Logger.js +6 -0
- package/dist/logger/Logger.js.map +1 -0
- package/dist/logger/NullLogger.d.ts +13 -0
- package/dist/logger/NullLogger.d.ts.map +1 -0
- package/dist/logger/NullLogger.js +20 -0
- package/dist/logger/NullLogger.js.map +1 -0
- package/dist/models/Event.d.ts +37 -0
- package/dist/models/Event.d.ts.map +1 -0
- package/dist/models/Event.js +42 -0
- package/dist/models/Event.js.map +1 -0
- package/dist/models/Orga.d.ts +33 -0
- package/dist/models/Orga.d.ts.map +1 -0
- package/dist/models/Orga.js +39 -0
- package/dist/models/Orga.js.map +1 -0
- package/dist/models/PaginatedResult.d.ts +27 -0
- package/dist/models/PaginatedResult.d.ts.map +1 -0
- package/dist/models/PaginatedResult.js +46 -0
- package/dist/models/PaginatedResult.js.map +1 -0
- package/dist/resources/EventsResource.d.ts +20 -0
- package/dist/resources/EventsResource.d.ts.map +1 -0
- package/dist/resources/EventsResource.js +46 -0
- package/dist/resources/EventsResource.js.map +1 -0
- package/dist/resources/OrgaResource.d.ts +20 -0
- package/dist/resources/OrgaResource.d.ts.map +1 -0
- package/dist/resources/OrgaResource.js +51 -0
- package/dist/resources/OrgaResource.js.map +1 -0
- package/dist/types.d.ts +81 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +8 -0
- package/dist/types.js.map +1 -0
- package/package.json +72 -0
- package/src/EBrocanteClient.ts +110 -0
- package/src/cache/CacheBackend.ts +20 -0
- package/src/cache/LocalCache.ts +64 -0
- package/src/cache/NullCache.ts +32 -0
- package/src/cache/RedisCache.ts +123 -0
- package/src/cache/RedisConfig.ts +23 -0
- package/src/cache/stableHashKey.ts +28 -0
- package/src/exceptions/index.ts +75 -0
- package/src/http/HttpClient.ts +266 -0
- package/src/index.ts +42 -0
- package/src/internal/safeStrings.ts +154 -0
- package/src/logger/DebugWriter.ts +61 -0
- package/src/logger/FileLogger.ts +106 -0
- package/src/logger/Logger.ts +13 -0
- package/src/logger/NullLogger.ts +22 -0
- package/src/models/Event.ts +92 -0
- package/src/models/Orga.ts +76 -0
- package/src/models/PaginatedResult.ts +62 -0
- package/src/resources/EventsResource.ts +48 -0
- package/src/resources/OrgaResource.ts +53 -0
- package/src/types.ts +86 -0
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @copyright 2026 Association E-Cosplay
|
|
3
|
+
* @license Proprietary — see LICENSE
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import {
|
|
7
|
+
asBoolean,
|
|
8
|
+
asDate,
|
|
9
|
+
asNullableInt,
|
|
10
|
+
asNullableString,
|
|
11
|
+
asNumber,
|
|
12
|
+
asRecord,
|
|
13
|
+
asString,
|
|
14
|
+
} from '../internal/safeStrings.js';
|
|
15
|
+
|
|
16
|
+
export interface EventDto {
|
|
17
|
+
id: string;
|
|
18
|
+
slug: string;
|
|
19
|
+
name: string;
|
|
20
|
+
/** Free-form category. The platform currently emits one of:
|
|
21
|
+
* `'brocante'`, `'vide_grenier'`, `'marche_aux_puces'`, `'bourse_collection'`. */
|
|
22
|
+
category: string;
|
|
23
|
+
description: string;
|
|
24
|
+
address: string;
|
|
25
|
+
zipcode: string;
|
|
26
|
+
city: string;
|
|
27
|
+
department: string;
|
|
28
|
+
region: string;
|
|
29
|
+
lat: number;
|
|
30
|
+
long: number;
|
|
31
|
+
mainPictureUrl: string | null;
|
|
32
|
+
startAt: Date;
|
|
33
|
+
endAt: Date;
|
|
34
|
+
outside: boolean;
|
|
35
|
+
inside: boolean;
|
|
36
|
+
tarifOutsideCents: number | null;
|
|
37
|
+
tarifInsideCents: number | null;
|
|
38
|
+
/** Pricing scheme — typically `'per_meter'` or `'flat'`. */
|
|
39
|
+
pricingMode: string;
|
|
40
|
+
availableBooths: number;
|
|
41
|
+
totalBooths: number;
|
|
42
|
+
/** Lifecycle — typically `'published'`, `'cancelled'`, or `'completed'`. */
|
|
43
|
+
state: string;
|
|
44
|
+
organizerSlug: string | null;
|
|
45
|
+
updatedAt: Date | null;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
interface RawEvent {
|
|
49
|
+
id?: unknown;
|
|
50
|
+
type?: unknown;
|
|
51
|
+
attributes?: Record<string, unknown>;
|
|
52
|
+
relationships?: { organizer?: { slug?: unknown } };
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function resolveOrganizerSlug(raw: RawEvent, attr: Record<string, unknown>): string | null {
|
|
56
|
+
const rel = raw.relationships?.organizer?.slug;
|
|
57
|
+
return asNullableString(rel) ?? asNullableString(attr.organizer_slug);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export function eventFromApi(raw: unknown): EventDto {
|
|
61
|
+
const r = asRecord(raw) as RawEvent;
|
|
62
|
+
const attr = asRecord(r.attributes ?? r);
|
|
63
|
+
|
|
64
|
+
const epoch = new Date(0);
|
|
65
|
+
return {
|
|
66
|
+
id: asString(r.id, asString(attr.id)),
|
|
67
|
+
slug: asString(attr.slug),
|
|
68
|
+
name: asString(attr.name),
|
|
69
|
+
category: asString(attr.category, 'brocante'),
|
|
70
|
+
description: asString(attr.description),
|
|
71
|
+
address: asString(attr.address),
|
|
72
|
+
zipcode: asString(attr.zipcode),
|
|
73
|
+
city: asString(attr.city),
|
|
74
|
+
department: asString(attr.department),
|
|
75
|
+
region: asString(attr.region),
|
|
76
|
+
lat: asNumber(attr.lat),
|
|
77
|
+
long: asNumber(attr.long),
|
|
78
|
+
mainPictureUrl: asNullableString(attr.main_picture_url),
|
|
79
|
+
startAt: asDate(attr.start_at) ?? epoch,
|
|
80
|
+
endAt: asDate(attr.end_at) ?? epoch,
|
|
81
|
+
outside: asBoolean(attr.outside),
|
|
82
|
+
inside: asBoolean(attr.inside),
|
|
83
|
+
tarifOutsideCents: asNullableInt(attr.tarif_outside_cents),
|
|
84
|
+
tarifInsideCents: asNullableInt(attr.tarif_inside_cents),
|
|
85
|
+
pricingMode: asString(attr.pricing_mode, 'per_meter'),
|
|
86
|
+
availableBooths: asNumber(attr.available_booths),
|
|
87
|
+
totalBooths: asNumber(attr.total_booths),
|
|
88
|
+
state: asString(attr.state, 'published'),
|
|
89
|
+
organizerSlug: resolveOrganizerSlug(r, attr),
|
|
90
|
+
updatedAt: asDate(attr.updated_at),
|
|
91
|
+
};
|
|
92
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @copyright 2026 Association E-Cosplay
|
|
3
|
+
* @license Proprietary — see LICENSE
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { asDate, asNullableString, asNumber, asRecord, asString } from '../internal/safeStrings.js';
|
|
7
|
+
import { type EventDto, eventFromApi } from './Event.js';
|
|
8
|
+
|
|
9
|
+
export interface OrgaDto {
|
|
10
|
+
id: string;
|
|
11
|
+
slug: string;
|
|
12
|
+
name: string;
|
|
13
|
+
/** Legal form — typically `'asso'`, `'sarl'`, `'sas'`, or `'ei'`. */
|
|
14
|
+
legalForm: string;
|
|
15
|
+
siren: string | null;
|
|
16
|
+
rna: string | null;
|
|
17
|
+
address: string;
|
|
18
|
+
zipcode: string;
|
|
19
|
+
city: string;
|
|
20
|
+
department: string;
|
|
21
|
+
region: string;
|
|
22
|
+
lat: number;
|
|
23
|
+
long: number;
|
|
24
|
+
emailPublic: string | null;
|
|
25
|
+
phonePublic: string | null;
|
|
26
|
+
website: string | null;
|
|
27
|
+
rcProInsurer: string | null;
|
|
28
|
+
mediatorName: string | null;
|
|
29
|
+
totalEventsOrganized: number;
|
|
30
|
+
/** Lifecycle — currently always `'active'` for entries returned by the public API. */
|
|
31
|
+
state: string;
|
|
32
|
+
createdAt: Date | null;
|
|
33
|
+
upcomingEvents: EventDto[];
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
interface RawOrga {
|
|
37
|
+
id?: unknown;
|
|
38
|
+
attributes?: Record<string, unknown>;
|
|
39
|
+
included?: { upcoming_events?: unknown[] };
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export function orgaFromApi(raw: unknown, upcomingOverride?: EventDto[]): OrgaDto {
|
|
43
|
+
const r = asRecord(raw) as RawOrga;
|
|
44
|
+
const attr = asRecord(r.attributes ?? r);
|
|
45
|
+
|
|
46
|
+
const upcoming =
|
|
47
|
+
upcomingOverride ??
|
|
48
|
+
(Array.isArray(r.included?.upcoming_events)
|
|
49
|
+
? r.included.upcoming_events.map((e) => eventFromApi(e))
|
|
50
|
+
: []);
|
|
51
|
+
|
|
52
|
+
return {
|
|
53
|
+
id: asString(r.id, asString(attr.id)),
|
|
54
|
+
slug: asString(attr.slug),
|
|
55
|
+
name: asString(attr.name),
|
|
56
|
+
legalForm: asString(attr.legal_form, 'asso'),
|
|
57
|
+
siren: asNullableString(attr.siren),
|
|
58
|
+
rna: asNullableString(attr.rna),
|
|
59
|
+
address: asString(attr.address),
|
|
60
|
+
zipcode: asString(attr.zipcode),
|
|
61
|
+
city: asString(attr.city),
|
|
62
|
+
department: asString(attr.department),
|
|
63
|
+
region: asString(attr.region),
|
|
64
|
+
lat: asNumber(attr.lat),
|
|
65
|
+
long: asNumber(attr.long),
|
|
66
|
+
emailPublic: asNullableString(attr.email_public),
|
|
67
|
+
phonePublic: asNullableString(attr.phone_public),
|
|
68
|
+
website: asNullableString(attr.website),
|
|
69
|
+
rcProInsurer: asNullableString(attr.rc_pro_insurer),
|
|
70
|
+
mediatorName: asNullableString(attr.mediator_name),
|
|
71
|
+
totalEventsOrganized: asNumber(attr.total_events_organized),
|
|
72
|
+
state: asString(attr.state, 'active'),
|
|
73
|
+
createdAt: asDate(attr.created_at),
|
|
74
|
+
upcomingEvents: upcoming,
|
|
75
|
+
};
|
|
76
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @copyright 2026 Association E-Cosplay
|
|
3
|
+
* @license Proprietary — see LICENSE
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
export interface PaginationMeta {
|
|
7
|
+
page: number;
|
|
8
|
+
perPage: number;
|
|
9
|
+
totalPages: number;
|
|
10
|
+
totalCount: number;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export class PaginatedResult<T> implements Iterable<T> {
|
|
14
|
+
constructor(
|
|
15
|
+
readonly data: T[],
|
|
16
|
+
readonly page: number,
|
|
17
|
+
readonly perPage: number,
|
|
18
|
+
readonly totalPages: number,
|
|
19
|
+
readonly totalCount: number,
|
|
20
|
+
readonly requestId: string | null,
|
|
21
|
+
readonly now: string | null,
|
|
22
|
+
readonly links: Record<string, string>,
|
|
23
|
+
) {}
|
|
24
|
+
|
|
25
|
+
static fromApi<T>(
|
|
26
|
+
items: T[],
|
|
27
|
+
meta: Record<string, unknown>,
|
|
28
|
+
links: Record<string, unknown>,
|
|
29
|
+
): PaginatedResult<T> {
|
|
30
|
+
const pagination = (meta.pagination as Record<string, unknown> | undefined) ?? {};
|
|
31
|
+
const stringLinks: Record<string, string> = {};
|
|
32
|
+
for (const [k, v] of Object.entries(links)) {
|
|
33
|
+
if (typeof v === 'string' && v !== '') stringLinks[k] = v;
|
|
34
|
+
}
|
|
35
|
+
return new PaginatedResult<T>(
|
|
36
|
+
items,
|
|
37
|
+
Number(pagination.page ?? 1),
|
|
38
|
+
Number(pagination.per_page ?? items.length),
|
|
39
|
+
Number(pagination.total_pages ?? 1),
|
|
40
|
+
Number(pagination.total_count ?? items.length),
|
|
41
|
+
typeof meta.request_id === 'string' ? meta.request_id : null,
|
|
42
|
+
typeof meta.now === 'string' ? meta.now : null,
|
|
43
|
+
stringLinks,
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
get length(): number {
|
|
48
|
+
return this.data.length;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
isEmpty(): boolean {
|
|
52
|
+
return this.data.length === 0;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
hasNextPage(): boolean {
|
|
56
|
+
return this.page < this.totalPages;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
[Symbol.iterator](): Iterator<T> {
|
|
60
|
+
return this.data[Symbol.iterator]();
|
|
61
|
+
}
|
|
62
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @copyright 2026 Association E-Cosplay
|
|
3
|
+
* @license Proprietary — see LICENSE
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { ServerError } from '../exceptions/index.js';
|
|
7
|
+
import type { HttpClient } from '../http/HttpClient.js';
|
|
8
|
+
import { type EventDto, eventFromApi } from '../models/Event.js';
|
|
9
|
+
import { PaginatedResult } from '../models/PaginatedResult.js';
|
|
10
|
+
import type { EventFilters, RequestOptions } from '../types.js';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Read-only resource wrapping `GET /api/{mode}/events` and
|
|
14
|
+
* `GET /api/{mode}/event/{slug}`.
|
|
15
|
+
*/
|
|
16
|
+
export class EventsResource {
|
|
17
|
+
constructor(private readonly http: HttpClient) {}
|
|
18
|
+
|
|
19
|
+
async list(filters: EventFilters = {}, options: RequestOptions = {}): Promise<PaginatedResult<EventDto>> {
|
|
20
|
+
const payload = await this.http.get('events', filters as Record<string, unknown>, options);
|
|
21
|
+
const data = Array.isArray(payload.data) ? payload.data : [];
|
|
22
|
+
const items = data.map((raw: unknown) => eventFromApi(raw));
|
|
23
|
+
const meta = (payload.meta as Record<string, unknown>) ?? {};
|
|
24
|
+
const links = (payload.links as Record<string, unknown>) ?? {};
|
|
25
|
+
return PaginatedResult.fromApi(items, meta, links);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
async get(slug: string, options: RequestOptions = {}): Promise<EventDto> {
|
|
29
|
+
const payload = await this.http.get(`event/${encodeURIComponent(slug)}`, {}, options);
|
|
30
|
+
const data = payload.data;
|
|
31
|
+
if (!data || typeof data !== 'object' || Array.isArray(data)) {
|
|
32
|
+
throw new ServerError(`Unexpected response shape for event/${slug}`, 0);
|
|
33
|
+
}
|
|
34
|
+
return eventFromApi(data);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
async *iter(filters: EventFilters = {}): AsyncIterable<EventDto> {
|
|
38
|
+
let page = filters.page ?? 1;
|
|
39
|
+
const perPage = filters.per_page ?? 50;
|
|
40
|
+
let totalPages = Number.POSITIVE_INFINITY;
|
|
41
|
+
while (page <= totalPages) {
|
|
42
|
+
const result = await this.list({ ...filters, page, per_page: perPage });
|
|
43
|
+
totalPages = result.totalPages;
|
|
44
|
+
for (const event of result.data) yield event;
|
|
45
|
+
page++;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @copyright 2026 Association E-Cosplay
|
|
3
|
+
* @license Proprietary — see LICENSE
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { ServerError } from '../exceptions/index.js';
|
|
7
|
+
import type { HttpClient } from '../http/HttpClient.js';
|
|
8
|
+
import { type EventDto, eventFromApi } from '../models/Event.js';
|
|
9
|
+
import { type OrgaDto, orgaFromApi } from '../models/Orga.js';
|
|
10
|
+
import { PaginatedResult } from '../models/PaginatedResult.js';
|
|
11
|
+
import type { OrgaFilters, RequestOptions } from '../types.js';
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Read-only resource wrapping `GET /api/{mode}/orga` and
|
|
15
|
+
* `GET /api/{mode}/orga/{slug}`.
|
|
16
|
+
*/
|
|
17
|
+
export class OrgaResource {
|
|
18
|
+
constructor(private readonly http: HttpClient) {}
|
|
19
|
+
|
|
20
|
+
async list(filters: OrgaFilters = {}, options: RequestOptions = {}): Promise<PaginatedResult<OrgaDto>> {
|
|
21
|
+
const payload = await this.http.get('orga', filters as Record<string, unknown>, options);
|
|
22
|
+
const data = Array.isArray(payload.data) ? payload.data : [];
|
|
23
|
+
const items = data.map((raw: unknown) => orgaFromApi(raw));
|
|
24
|
+
const meta = (payload.meta as Record<string, unknown>) ?? {};
|
|
25
|
+
const links = (payload.links as Record<string, unknown>) ?? {};
|
|
26
|
+
return PaginatedResult.fromApi(items, meta, links);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
async get(slug: string, options: RequestOptions = {}): Promise<OrgaDto> {
|
|
30
|
+
const payload = await this.http.get(`orga/${encodeURIComponent(slug)}`, {}, options);
|
|
31
|
+
const data = payload.data;
|
|
32
|
+
if (!data || typeof data !== 'object' || Array.isArray(data)) {
|
|
33
|
+
throw new ServerError(`Unexpected response shape for orga/${slug}`, 0);
|
|
34
|
+
}
|
|
35
|
+
const included = (data as { included?: { upcoming_events?: unknown[] } }).included;
|
|
36
|
+
const upcoming: EventDto[] = Array.isArray(included?.upcoming_events)
|
|
37
|
+
? included.upcoming_events.map((raw) => eventFromApi(raw))
|
|
38
|
+
: [];
|
|
39
|
+
return orgaFromApi(data, upcoming);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
async *iter(filters: OrgaFilters = {}): AsyncIterable<OrgaDto> {
|
|
43
|
+
let page = filters.page ?? 1;
|
|
44
|
+
const perPage = filters.per_page ?? 50;
|
|
45
|
+
let totalPages = Number.POSITIVE_INFINITY;
|
|
46
|
+
while (page <= totalPages) {
|
|
47
|
+
const result = await this.list({ ...filters, page, per_page: perPage });
|
|
48
|
+
totalPages = result.totalPages;
|
|
49
|
+
for (const orga of result.data) yield orga;
|
|
50
|
+
page++;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
package/src/types.ts
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @copyright 2026 Association E-Cosplay
|
|
3
|
+
* @license Proprietary — see LICENSE
|
|
4
|
+
*
|
|
5
|
+
* Public type definitions exposed by the SDK.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import type { CacheBackend } from './cache/CacheBackend.js';
|
|
9
|
+
import type { RedisConfig } from './cache/RedisConfig.js';
|
|
10
|
+
import type { Logger } from './logger/Logger.js';
|
|
11
|
+
|
|
12
|
+
export type Mode = 'prod' | 'test';
|
|
13
|
+
export type CacheType = 'local' | 'redis';
|
|
14
|
+
|
|
15
|
+
export interface EBrocanteClientOptions {
|
|
16
|
+
/** API key (eb_prod_…, eb_test_…, eb_mock_…). */
|
|
17
|
+
apiKey: string;
|
|
18
|
+
/** Account email sent in the X-BROC header. */
|
|
19
|
+
brocEmail: string;
|
|
20
|
+
/** prod (live data) or test (sandbox). Defaults to 'prod'. */
|
|
21
|
+
mode?: Mode;
|
|
22
|
+
/** API base URL (override for the bundled mock server). */
|
|
23
|
+
baseUrl?: string;
|
|
24
|
+
/** HTTP timeout in milliseconds. Default: 10_000. */
|
|
25
|
+
timeoutMs?: number;
|
|
26
|
+
/** Enable response cache. Default: true. */
|
|
27
|
+
cache?: boolean;
|
|
28
|
+
/** Cache backend. Default: 'local'. */
|
|
29
|
+
cacheType?: CacheType;
|
|
30
|
+
/** Cache entry TTL in seconds. Default: 300. */
|
|
31
|
+
cacheTtl?: number;
|
|
32
|
+
/** Redis config (required when cacheType='redis'). */
|
|
33
|
+
cacheRedis?: RedisConfig;
|
|
34
|
+
/** Cache key prefix. Default: 'ebrocante:'. */
|
|
35
|
+
cacheKeyPrefix?: string;
|
|
36
|
+
/** Custom backend implementation (full override). */
|
|
37
|
+
cacheImpl?: CacheBackend;
|
|
38
|
+
/** Directory to write JSON-lines log files (one per day). */
|
|
39
|
+
logPath?: string;
|
|
40
|
+
/** Custom Logger implementation (overrides logPath). */
|
|
41
|
+
logger?: Logger;
|
|
42
|
+
/** Append one line per SDK action to a debug file. Default: false. */
|
|
43
|
+
debug?: boolean;
|
|
44
|
+
/** Debug file path when `debug` is true. Default: './DEBUG.TXT'. */
|
|
45
|
+
debugFile?: string;
|
|
46
|
+
/** Number of retries on 429 / 5xx. Default: 3. */
|
|
47
|
+
maxRetries?: number;
|
|
48
|
+
/** Custom fetch implementation (defaults to global fetch). */
|
|
49
|
+
fetch?: typeof fetch;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export interface EventFilters {
|
|
53
|
+
city?: string;
|
|
54
|
+
department?: string;
|
|
55
|
+
region?: string;
|
|
56
|
+
from?: string;
|
|
57
|
+
to?: string;
|
|
58
|
+
category?: string;
|
|
59
|
+
has_available_booths?: boolean;
|
|
60
|
+
outside?: boolean;
|
|
61
|
+
inside?: boolean;
|
|
62
|
+
since?: string;
|
|
63
|
+
q?: string;
|
|
64
|
+
sort?: string;
|
|
65
|
+
page?: number;
|
|
66
|
+
per_page?: number;
|
|
67
|
+
lat?: number;
|
|
68
|
+
lng?: number;
|
|
69
|
+
radius?: number;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export interface OrgaFilters {
|
|
73
|
+
city?: string;
|
|
74
|
+
legal_form?: string;
|
|
75
|
+
q?: string;
|
|
76
|
+
has_upcoming_events?: boolean;
|
|
77
|
+
since?: string;
|
|
78
|
+
sort?: string;
|
|
79
|
+
page?: number;
|
|
80
|
+
per_page?: number;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export interface RequestOptions {
|
|
84
|
+
skipCache?: boolean;
|
|
85
|
+
ttl?: number;
|
|
86
|
+
}
|