apimo.js 1.0.1

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.
Files changed (73) hide show
  1. package/.github/workflows/ci.yml +37 -0
  2. package/.github/workflows/publish.yml +69 -0
  3. package/.idea/apimo.js.iml +13 -0
  4. package/.idea/copilotDiffState.xml +43 -0
  5. package/.idea/inspectionProfiles/Project_Default.xml +6 -0
  6. package/.idea/jsLinters/eslint.xml +6 -0
  7. package/.idea/modules.xml +8 -0
  8. package/.idea/prettier.xml +6 -0
  9. package/.idea/vcs.xml +6 -0
  10. package/README.md +91 -0
  11. package/dist/src/consts/catalogs.d.ts +2 -0
  12. package/dist/src/consts/catalogs.js +53 -0
  13. package/dist/src/consts/languages.d.ts +2 -0
  14. package/dist/src/consts/languages.js +20 -0
  15. package/dist/src/core/api.d.ts +389 -0
  16. package/dist/src/core/api.js +157 -0
  17. package/dist/src/core/api.test.d.ts +1 -0
  18. package/dist/src/core/api.test.js +246 -0
  19. package/dist/src/core/converters.d.ts +4 -0
  20. package/dist/src/core/converters.js +4 -0
  21. package/dist/src/schemas/agency.d.ts +416 -0
  22. package/dist/src/schemas/agency.js +61 -0
  23. package/dist/src/schemas/common.d.ts +153 -0
  24. package/dist/src/schemas/common.js +47 -0
  25. package/dist/src/schemas/internal.d.ts +3 -0
  26. package/dist/src/schemas/internal.js +11 -0
  27. package/dist/src/schemas/property.d.ts +1500 -0
  28. package/dist/src/schemas/property.js +238 -0
  29. package/dist/src/services/storage/dummy.cache.d.ts +10 -0
  30. package/dist/src/services/storage/dummy.cache.js +28 -0
  31. package/dist/src/services/storage/dummy.cache.test.d.ts +1 -0
  32. package/dist/src/services/storage/dummy.cache.test.js +96 -0
  33. package/dist/src/services/storage/filesystem.cache.d.ts +18 -0
  34. package/dist/src/services/storage/filesystem.cache.js +85 -0
  35. package/dist/src/services/storage/filesystem.cache.test.d.ts +1 -0
  36. package/dist/src/services/storage/filesystem.cache.test.js +197 -0
  37. package/dist/src/services/storage/memory.cache.d.ts +20 -0
  38. package/dist/src/services/storage/memory.cache.js +62 -0
  39. package/dist/src/services/storage/memory.cache.test.d.ts +1 -0
  40. package/dist/src/services/storage/memory.cache.test.js +80 -0
  41. package/dist/src/services/storage/types.d.ts +16 -0
  42. package/dist/src/services/storage/types.js +4 -0
  43. package/dist/src/types/index.d.ts +4 -0
  44. package/dist/src/types/index.js +1 -0
  45. package/dist/src/utils/url.d.ts +14 -0
  46. package/dist/src/utils/url.js +11 -0
  47. package/dist/src/utils/url.test.d.ts +1 -0
  48. package/dist/src/utils/url.test.js +18 -0
  49. package/dist/vitest.config.d.ts +2 -0
  50. package/dist/vitest.config.js +6 -0
  51. package/eslint.config.mjs +3 -0
  52. package/package.json +45 -0
  53. package/src/consts/catalogs.ts +55 -0
  54. package/src/consts/languages.ts +22 -0
  55. package/src/core/api.test.ts +308 -0
  56. package/src/core/api.ts +230 -0
  57. package/src/core/converters.ts +7 -0
  58. package/src/schemas/agency.ts +66 -0
  59. package/src/schemas/common.ts +67 -0
  60. package/src/schemas/internal.ts +13 -0
  61. package/src/schemas/property.ts +257 -0
  62. package/src/services/storage/dummy.cache.test.ts +110 -0
  63. package/src/services/storage/dummy.cache.ts +21 -0
  64. package/src/services/storage/filesystem.cache.test.ts +243 -0
  65. package/src/services/storage/filesystem.cache.ts +94 -0
  66. package/src/services/storage/memory.cache.test.ts +94 -0
  67. package/src/services/storage/memory.cache.ts +69 -0
  68. package/src/services/storage/types.ts +20 -0
  69. package/src/types/index.ts +5 -0
  70. package/src/utils/url.test.ts +21 -0
  71. package/src/utils/url.ts +27 -0
  72. package/tsconfig.json +13 -0
  73. package/vitest.config.ts +7 -0
@@ -0,0 +1,389 @@
1
+ import type { CatalogName } from '../consts/catalogs';
2
+ import type { ApiCulture } from '../consts/languages';
3
+ import type { CatalogDefinition, CatalogEntry, CatalogTransformer } from '../schemas/common';
4
+ import type { ApiCacheAdapter, CatalogEntryName } from '../services/storage/types';
5
+ import type { DeepPartial } from '../types';
6
+ import type { ApiSearchParams } from '../utils/url';
7
+ import Bottleneck from 'bottleneck';
8
+ import { z } from 'zod';
9
+ /**
10
+ * ApiConfig
11
+ * ---
12
+ *
13
+ * The general config, used to create an API wrapper. It exports major endpoints as methods.
14
+ * Internally, it's a simple wrapper to node:fetch with a neater syntax.
15
+ */
16
+ export interface AdditionalConfig {
17
+ baseUrl: string;
18
+ culture: ApiCulture;
19
+ catalogs: {
20
+ cache: {
21
+ active: boolean;
22
+ adapter: ApiCacheAdapter;
23
+ };
24
+ transform: {
25
+ active: boolean;
26
+ transformFn?: CatalogTransformer;
27
+ };
28
+ };
29
+ }
30
+ export declare const DEFAULT_BASE_URL = "https://api.apimo.pro";
31
+ export declare const DEFAULT_ADDITIONAL_CONFIG: AdditionalConfig;
32
+ export declare class Api {
33
+ private readonly provider;
34
+ private readonly token;
35
+ readonly config: AdditionalConfig;
36
+ readonly cache: ApiCacheAdapter;
37
+ readonly limiter: Bottleneck;
38
+ constructor(provider: string, token: string, config?: DeepPartial<AdditionalConfig>);
39
+ /**
40
+ * An override of fetch that adds the required Authorization header to every request.
41
+ */
42
+ fetch(...parameters: Parameters<typeof fetch>): Promise<Response>;
43
+ get<S extends z.Schema>(path: string[], schema: S, options?: Partial<ApiSearchParams>): Promise<z.infer<S>>;
44
+ fetchCatalogs(): Promise<CatalogDefinition[]>;
45
+ populateCache(catalogName: CatalogName, culture: ApiCulture): Promise<void>;
46
+ populateCache(catalogName: CatalogName, culture: ApiCulture, id: number): Promise<CatalogEntryName | null>;
47
+ getCatalogEntries(catalogName: CatalogName, options?: Pick<ApiSearchParams, 'culture'>): Promise<CatalogEntry[]>;
48
+ fetchCatalog(catalogName: CatalogName, options?: Pick<ApiSearchParams, 'culture'>): Promise<CatalogEntry[]>;
49
+ fetchAgencies(options?: Pick<ApiSearchParams, 'culture' | 'limit' | 'offset'>): Promise<{
50
+ timestamp: number;
51
+ agencies: {
52
+ id: number;
53
+ name: string;
54
+ active: boolean;
55
+ created_at: Date;
56
+ updated_at: Date;
57
+ email: string;
58
+ phone: string;
59
+ fax: string | null;
60
+ city: {
61
+ id: number;
62
+ name: string;
63
+ zipcode: string;
64
+ };
65
+ picture: string;
66
+ partners: {
67
+ name: string | null;
68
+ type: number;
69
+ partner: number | null;
70
+ reference: string;
71
+ amount: number;
72
+ currency: string;
73
+ }[];
74
+ stories: unknown[];
75
+ rates: {
76
+ id: number;
77
+ category: string | CatalogEntryName | null;
78
+ range_min: number | null;
79
+ range_max: number | null;
80
+ commission_price: number | null;
81
+ commission_rate: number | null;
82
+ comment: string;
83
+ url: string | null;
84
+ }[];
85
+ url: string;
86
+ reference: number;
87
+ currency: string;
88
+ company: {
89
+ id: number;
90
+ name: string;
91
+ };
92
+ networks: unknown[];
93
+ address: string;
94
+ address_more: string | null;
95
+ country: string;
96
+ region: string;
97
+ latitude: number;
98
+ longitude: number;
99
+ logo: string;
100
+ logo_svg: string | null;
101
+ timetable: string;
102
+ providers: string;
103
+ users: {
104
+ id: number;
105
+ agency: number;
106
+ active: boolean;
107
+ created_at: Date;
108
+ updated_at: Date;
109
+ firstname: string;
110
+ lastname: string;
111
+ language: string;
112
+ group: string | CatalogEntryName | null;
113
+ email: string;
114
+ phone: string | null;
115
+ mobile: string;
116
+ fax: string | null;
117
+ birthday_at: Date;
118
+ timezone: string | null;
119
+ picture: string | null;
120
+ username?: string | undefined;
121
+ password?: string | undefined;
122
+ spoken_languages?: string[] | undefined;
123
+ city?: {
124
+ id: number;
125
+ name: string;
126
+ } | null | undefined;
127
+ partners?: unknown[] | undefined;
128
+ stories?: unknown[] | undefined;
129
+ rates?: unknown;
130
+ }[];
131
+ sectors: unknown[];
132
+ parameters: string;
133
+ subscription: string;
134
+ brand?: unknown;
135
+ district?: unknown;
136
+ }[];
137
+ total_items: number;
138
+ }>;
139
+ fetchProperties(agencyId: number, options?: Pick<ApiSearchParams, 'culture' | 'limit' | 'offset' | 'timestamp' | 'step' | 'status' | 'group'>): Promise<{
140
+ timestamp: number;
141
+ total_items: number;
142
+ properties: {
143
+ tags: (string | CatalogEntryName | null)[];
144
+ id: number;
145
+ name: string | null;
146
+ options: unknown[];
147
+ type: string | CatalogEntryName | null;
148
+ length: number | null;
149
+ status: string | CatalogEntryName | null;
150
+ agency: number;
151
+ created_at: Date;
152
+ updated_at: Date;
153
+ city: {
154
+ id: number;
155
+ name: string;
156
+ zipcode: string;
157
+ };
158
+ rates: unknown[];
159
+ step: string | CatalogEntryName | null;
160
+ category: string | CatalogEntryName | null;
161
+ url: string | null;
162
+ reference: number;
163
+ address: string | null;
164
+ address_more: string | null;
165
+ district: {
166
+ id: number;
167
+ name: string;
168
+ } | null;
169
+ country: string;
170
+ region: {
171
+ id: number;
172
+ name: string;
173
+ };
174
+ latitude: number;
175
+ longitude: number;
176
+ height: number | null;
177
+ comments: {
178
+ language: string;
179
+ comment: string;
180
+ title?: string | null | undefined;
181
+ subtitle?: string | null | undefined;
182
+ hook?: unknown;
183
+ comment_full?: string | null | undefined;
184
+ }[];
185
+ area: {
186
+ value: number;
187
+ unit: string | CatalogEntryName | null;
188
+ total: number;
189
+ weighted: number;
190
+ };
191
+ floor: {
192
+ value: number;
193
+ type: string | CatalogEntryName | null;
194
+ levels: number;
195
+ floors: number;
196
+ };
197
+ orientations: (string | CatalogEntryName | null)[];
198
+ user: {
199
+ id: number;
200
+ agency: number;
201
+ active: boolean;
202
+ created_at: Date;
203
+ updated_at: Date;
204
+ firstname: string;
205
+ lastname: string;
206
+ language: string;
207
+ group: string | CatalogEntryName | null;
208
+ email: string;
209
+ phone: string | null;
210
+ mobile: string;
211
+ fax: string | null;
212
+ birthday_at: Date;
213
+ timezone: string | null;
214
+ picture: string | null;
215
+ username?: string | undefined;
216
+ password?: string | undefined;
217
+ spoken_languages?: string[] | undefined;
218
+ city?: {
219
+ id: number;
220
+ name: string;
221
+ } | null | undefined;
222
+ partners?: unknown[] | undefined;
223
+ stories?: unknown[] | undefined;
224
+ rates?: unknown;
225
+ };
226
+ parent: number | null;
227
+ subtype: string | CatalogEntryName | null;
228
+ agreement: {
229
+ type: string | CatalogEntryName | null;
230
+ reference: string;
231
+ start_at: Date;
232
+ end_at: Date;
233
+ } | null;
234
+ block_name: string | null;
235
+ lot_reference: string | null;
236
+ cadastre_reference: string | null;
237
+ stairs_reference: string | null;
238
+ publish_address: boolean;
239
+ radius: number;
240
+ altitude: number;
241
+ plot: {
242
+ net_floor: number;
243
+ land_type: string | CatalogEntryName | null;
244
+ width: number;
245
+ serviced_plot: boolean;
246
+ height?: number | undefined;
247
+ };
248
+ rooms: number;
249
+ bedrooms: number;
250
+ sleeps: number;
251
+ price: {
252
+ fees: number;
253
+ value: number;
254
+ currency: string;
255
+ max: number;
256
+ period: string | CatalogEntryName | null;
257
+ hide: boolean;
258
+ inventory: number | null;
259
+ deposit: number | null;
260
+ commission: number | null;
261
+ tenant: number | null;
262
+ vat: boolean | null;
263
+ unit?: unknown;
264
+ transfer_tax?: unknown;
265
+ contribution?: unknown;
266
+ pension?: unknown;
267
+ };
268
+ residence: {
269
+ fees: number;
270
+ id: number;
271
+ type: string | CatalogEntryName | null;
272
+ period: string | CatalogEntryName | null;
273
+ lots: number;
274
+ } | null;
275
+ view: {
276
+ type: string | CatalogEntryName | null;
277
+ landscape: (string | CatalogEntryName | null)[];
278
+ } | null;
279
+ construction: {
280
+ construction_step: string | CatalogEntryName | null;
281
+ construction_year: number;
282
+ renovation_year: number;
283
+ renovation_cost: number;
284
+ type?: (string | CatalogEntryName | null)[] | undefined;
285
+ };
286
+ heating: {
287
+ type: string | CatalogEntryName | null;
288
+ device: string | CatalogEntryName | null;
289
+ devices: (string | CatalogEntryName | null)[] | null;
290
+ access: string | CatalogEntryName | null;
291
+ types: (string | CatalogEntryName | null)[] | null;
292
+ };
293
+ water: {
294
+ hot_device: string | CatalogEntryName | null;
295
+ hot_access: string | CatalogEntryName | null;
296
+ waste: string | CatalogEntryName | null;
297
+ };
298
+ condition: string | CatalogEntryName | null;
299
+ standing: string | CatalogEntryName | null;
300
+ style: {
301
+ name: string | null;
302
+ };
303
+ twinned: number | null;
304
+ facades: number;
305
+ availability: string | CatalogEntryName | null;
306
+ delivered_at: Date | null;
307
+ activities: (string | CatalogEntryName | null)[];
308
+ services: (string | CatalogEntryName | null)[];
309
+ proximities: (string | CatalogEntryName | null)[];
310
+ tags_customized: unknown[];
311
+ pictures: {
312
+ id: number;
313
+ url: string;
314
+ rank: number;
315
+ width_max: number;
316
+ height_max: number;
317
+ internet: boolean;
318
+ print: boolean;
319
+ panorama: boolean;
320
+ child: number;
321
+ comments: {
322
+ language: string;
323
+ comment: string;
324
+ title?: string | null | undefined;
325
+ subtitle?: string | null | undefined;
326
+ hook?: unknown;
327
+ comment_full?: string | null | undefined;
328
+ }[];
329
+ reference?: unknown;
330
+ }[];
331
+ medias: unknown[];
332
+ documents: unknown[];
333
+ areas: {
334
+ number: number;
335
+ type: string | CatalogEntryName | null;
336
+ comments: {
337
+ language: string;
338
+ comment: string;
339
+ title?: string | null | undefined;
340
+ subtitle?: string | null | undefined;
341
+ hook?: unknown;
342
+ comment_full?: string | null | undefined;
343
+ }[];
344
+ area: number;
345
+ flooring: string | CatalogEntryName | null;
346
+ ceiling_height: number | null;
347
+ floor: {
348
+ value: number;
349
+ type: string | CatalogEntryName | null;
350
+ };
351
+ orientations: (string | CatalogEntryName | null)[];
352
+ lot: {
353
+ name: unknown[];
354
+ type?: unknown;
355
+ rank?: unknown;
356
+ };
357
+ }[];
358
+ regulations: {
359
+ value: number[];
360
+ type: string | CatalogEntryName | null;
361
+ date: Date | null;
362
+ graph: string | null;
363
+ }[];
364
+ financial: unknown[];
365
+ exchanges: unknown[];
366
+ logs: unknown[];
367
+ referrals: unknown[];
368
+ created_by: number;
369
+ updated_by: number;
370
+ referral?: unknown;
371
+ brand?: unknown;
372
+ sector?: unknown;
373
+ ranking?: unknown;
374
+ original_city?: unknown;
375
+ original_district?: unknown;
376
+ location?: unknown;
377
+ subreferral?: unknown;
378
+ owner?: unknown;
379
+ visit?: unknown;
380
+ available_at?: unknown;
381
+ filling_rate?: unknown;
382
+ private_comment?: unknown;
383
+ interagency_comment?: unknown;
384
+ status_comment?: unknown;
385
+ }[];
386
+ }>;
387
+ private getLocalizedCatalogTransformer;
388
+ private catalogTransformer;
389
+ }
@@ -0,0 +1,157 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ import Bottleneck from 'bottleneck';
11
+ import { merge } from 'merge-anything';
12
+ import { z } from 'zod';
13
+ import { getAgencySchema } from '../schemas/agency';
14
+ import { CatalogDefinitionSchema, CatalogEntrySchema } from '../schemas/common';
15
+ import { getPropertySchema } from '../schemas/property';
16
+ import { DummyCache } from '../services/storage/dummy.cache';
17
+ import { MemoryCache } from '../services/storage/memory.cache';
18
+ import { CacheExpiredError } from '../services/storage/types';
19
+ import { makeApiUrl } from '../utils/url';
20
+ export const DEFAULT_BASE_URL = 'https://api.apimo.pro';
21
+ export const DEFAULT_ADDITIONAL_CONFIG = {
22
+ baseUrl: DEFAULT_BASE_URL,
23
+ culture: 'en',
24
+ catalogs: {
25
+ cache: {
26
+ active: true,
27
+ adapter: new MemoryCache(),
28
+ },
29
+ transform: {
30
+ active: true,
31
+ },
32
+ },
33
+ };
34
+ export class Api {
35
+ constructor(
36
+ // The site identifier, in a string of numbers format. You can request yours by contacting Apimo.net customer service.
37
+ provider,
38
+ // The secret token for API authentication
39
+ token,
40
+ // Additional config, to tweak how the API is handled
41
+ config = DEFAULT_ADDITIONAL_CONFIG) {
42
+ this.provider = provider;
43
+ this.token = token;
44
+ this.config = merge(DEFAULT_ADDITIONAL_CONFIG, config);
45
+ this.cache = this.config.catalogs.cache.active ? this.config.catalogs.cache.adapter : new DummyCache();
46
+ this.limiter = new Bottleneck({
47
+ reservoir: 10,
48
+ reservoirRefreshAmount: 10,
49
+ reservoirRefreshInterval: 1000,
50
+ });
51
+ }
52
+ /**
53
+ * An override of fetch that adds the required Authorization header to every request.
54
+ */
55
+ fetch(...parameters) {
56
+ const [input, init] = parameters;
57
+ const extendedInit = Object.assign(Object.assign({}, init), { headers: Object.assign({ Authorization: `Basic ${btoa(`${this.provider}:${this.token}`)}` }, init === null || init === void 0 ? void 0 : init.headers) });
58
+ return this.limiter.schedule(() => fetch(input, extendedInit));
59
+ }
60
+ get(path, schema, options) {
61
+ return __awaiter(this, void 0, void 0, function* () {
62
+ const response = yield this.fetch(makeApiUrl(path, this.config, Object.assign({ culture: this.config.culture }, options)));
63
+ if (!response.ok) {
64
+ throw new Error(yield response.json());
65
+ }
66
+ return schema.parseAsync(yield response.json());
67
+ });
68
+ }
69
+ fetchCatalogs() {
70
+ return __awaiter(this, void 0, void 0, function* () {
71
+ return this.get(['catalogs'], z.array(CatalogDefinitionSchema));
72
+ });
73
+ }
74
+ populateCache(catalogName, culture, id) {
75
+ return __awaiter(this, void 0, void 0, function* () {
76
+ const catalog = yield this.fetchCatalog(catalogName, { culture });
77
+ yield this.cache.setEntries(catalogName, culture, catalog);
78
+ if (id !== undefined) {
79
+ const queriedKey = catalog.find(({ id: entryId }) => entryId === id);
80
+ return queriedKey
81
+ ? {
82
+ name: queriedKey.name,
83
+ namePlural: queriedKey.name_plurial,
84
+ }
85
+ : null;
86
+ }
87
+ });
88
+ }
89
+ getCatalogEntries(catalogName, options) {
90
+ return __awaiter(this, void 0, void 0, function* () {
91
+ var _a, _b, _c;
92
+ try {
93
+ return yield this.cache.getEntries(catalogName, (_a = options === null || options === void 0 ? void 0 : options.culture) !== null && _a !== void 0 ? _a : this.config.culture);
94
+ }
95
+ catch (e) {
96
+ if (e instanceof CacheExpiredError) {
97
+ yield this.populateCache(catalogName, (_b = options === null || options === void 0 ? void 0 : options.culture) !== null && _b !== void 0 ? _b : this.config.culture);
98
+ return this.cache.getEntries(catalogName, (_c = options === null || options === void 0 ? void 0 : options.culture) !== null && _c !== void 0 ? _c : this.config.culture);
99
+ }
100
+ else {
101
+ throw e;
102
+ }
103
+ }
104
+ });
105
+ }
106
+ fetchCatalog(catalogName, options) {
107
+ return __awaiter(this, void 0, void 0, function* () {
108
+ return this.get(['catalogs', catalogName], z.array(CatalogEntrySchema), options);
109
+ });
110
+ }
111
+ fetchAgencies(options) {
112
+ return __awaiter(this, void 0, void 0, function* () {
113
+ var _a;
114
+ return this.get(['agencies'], z.object({
115
+ total_items: z.number(),
116
+ agencies: getAgencySchema(this.getLocalizedCatalogTransformer((_a = options === null || options === void 0 ? void 0 : options.culture) !== null && _a !== void 0 ? _a : this.config.culture), this.config).array(),
117
+ timestamp: z.number(),
118
+ }));
119
+ });
120
+ }
121
+ fetchProperties(agencyId, options) {
122
+ return __awaiter(this, void 0, void 0, function* () {
123
+ var _a;
124
+ return this.get(['agencies', agencyId.toString(), 'properties'], z.object({
125
+ total_items: z.number(),
126
+ timestamp: z.number(),
127
+ properties: getPropertySchema(this.getLocalizedCatalogTransformer((_a = options === null || options === void 0 ? void 0 : options.culture) !== null && _a !== void 0 ? _a : this.config.culture)).array(),
128
+ }), options);
129
+ });
130
+ }
131
+ getLocalizedCatalogTransformer(culture) {
132
+ return (catalogName, id) => __awaiter(this, void 0, void 0, function* () {
133
+ if (!this.config.catalogs.transform.active) {
134
+ return `${catalogName}.${id}`;
135
+ }
136
+ if (this.config.catalogs.transform.transformFn) {
137
+ return this.config.catalogs.transform.transformFn(catalogName, culture, id);
138
+ }
139
+ return this.catalogTransformer(catalogName, culture, id);
140
+ });
141
+ }
142
+ catalogTransformer(catalogName, culture, id) {
143
+ return __awaiter(this, void 0, void 0, function* () {
144
+ try {
145
+ return yield this.cache.getEntry(catalogName, culture, id);
146
+ }
147
+ catch (e) {
148
+ if (e instanceof CacheExpiredError) {
149
+ return yield this.populateCache(catalogName, culture, id);
150
+ }
151
+ else {
152
+ throw e;
153
+ }
154
+ }
155
+ });
156
+ }
157
+ }
@@ -0,0 +1 @@
1
+ export {};