@entifix/next-shell 0.4.2 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/lib/back-office/group-by-screen-type.d.ts +2 -2
- package/dist/lib/back-office/group-by-screen-type.js +2 -2
- package/dist/lib/back-office/group-by-screen-type.js.map +1 -1
- package/dist/lib/back-office/nav.d.ts +1 -2
- package/dist/lib/back-office/nav.d.ts.map +1 -1
- package/dist/lib/back-office/nav.js.map +1 -1
- package/dist/lib/back-office/sidebar-nav.d.ts +2 -2
- package/dist/lib/back-office/sidebar-nav.js +2 -2
- package/dist/lib/back-office/sidebar-nav.js.map +1 -1
- package/dist/lib/command-palette/command-palette-host.js +1 -1
- package/dist/lib/command-palette/command-palette-host.js.map +1 -1
- package/dist/lib/command-palette/use-command-recency.d.ts +1 -1
- package/dist/lib/command-palette/use-command-recency.js +1 -1
- package/dist/lib/command-palette/use-command-recency.js.map +1 -1
- package/dist/lib/command-palette/use-nav-source.d.ts +4 -3
- package/dist/lib/command-palette/use-nav-source.d.ts.map +1 -1
- package/dist/lib/command-palette/use-nav-source.js +4 -3
- package/dist/lib/command-palette/use-nav-source.js.map +1 -1
- package/dist/lib/command-palette/use-records-source.d.ts +1 -1
- package/dist/lib/command-palette/use-records-source.js +2 -2
- package/dist/lib/command-palette/use-records-source.js.map +1 -1
- package/dist/lib/command-palette/use-tabs-source.d.ts +1 -1
- package/dist/lib/command-palette/use-tabs-source.js +1 -1
- package/dist/lib/command-palette/use-tabs-source.js.map +1 -1
- package/dist/lib/command-palette/use-use-cases-source.js +2 -2
- package/dist/lib/command-palette/use-use-cases-source.js.map +1 -1
- package/dist/lib/config/config-route.d.ts +6 -19
- package/dist/lib/config/config-route.d.ts.map +1 -1
- package/dist/lib/config/config-route.js +6 -23
- package/dist/lib/config/config-route.js.map +1 -1
- package/dist/lib/config/configuration-source.d.ts +18 -0
- package/dist/lib/config/configuration-source.d.ts.map +1 -0
- package/dist/lib/config/configuration-source.js +15 -0
- package/dist/lib/config/configuration-source.js.map +1 -0
- package/dist/lib/config/service-proxy-route.d.ts +11 -2
- package/dist/lib/config/service-proxy-route.d.ts.map +1 -1
- package/dist/lib/config/service-proxy-route.js +27 -4
- package/dist/lib/config/service-proxy-route.js.map +1 -1
- package/dist/lib/crud/entity-crud-form.js +3 -3
- package/dist/lib/crud/entity-crud-form.js.map +1 -1
- package/dist/lib/crud/hand-off-write.d.ts +1 -1
- package/dist/lib/crud/hand-off-write.js +1 -1
- package/dist/lib/crud/hand-off-write.js.map +1 -1
- package/dist/lib/crud/make-entity-crud.d.ts +7 -9
- package/dist/lib/crud/make-entity-crud.d.ts.map +1 -1
- package/dist/lib/crud/make-entity-crud.js +15 -18
- package/dist/lib/crud/make-entity-crud.js.map +1 -1
- package/dist/lib/crud/make-entity-crud.types.d.ts +9 -12
- package/dist/lib/crud/make-entity-crud.types.d.ts.map +1 -1
- package/dist/lib/crud/make-entity-crud.types.js.map +1 -1
- package/dist/lib/crud/pending-notice.d.ts +2 -2
- package/dist/lib/crud/pending-notice.js +2 -2
- package/dist/lib/crud/pending-notice.js.map +1 -1
- package/dist/lib/crud/use-entity-affordances.d.ts +1 -1
- package/dist/lib/crud/use-entity-affordances.js +1 -1
- package/dist/lib/crud/use-entity-affordances.js.map +1 -1
- package/dist/lib/crud/use-entity-bulk.d.ts +2 -2
- package/dist/lib/crud/use-entity-bulk.js +2 -2
- package/dist/lib/crud/use-entity-bulk.js.map +1 -1
- package/dist/lib/health/health-routes.d.ts +3 -4
- package/dist/lib/health/health-routes.d.ts.map +1 -1
- package/dist/lib/health/health-routes.js +7 -9
- package/dist/lib/health/health-routes.js.map +1 -1
- package/dist/lib/i18n/catalog/en.d.ts.map +1 -1
- package/dist/lib/i18n/catalog/en.js +1 -264
- package/dist/lib/i18n/catalog/en.js.map +1 -1
- package/dist/lib/i18n/catalog/es.d.ts +2 -290
- package/dist/lib/i18n/catalog/es.d.ts.map +1 -1
- package/dist/lib/i18n/catalog/es.js +2 -296
- package/dist/lib/i18n/catalog/es.js.map +1 -1
- package/dist/lib/i18n/catalog/index.d.ts +0 -508
- package/dist/lib/i18n/catalog/index.d.ts.map +1 -1
- package/dist/lib/i18n/spec-catalog.js +4 -4
- package/dist/lib/i18n/spec-catalog.js.map +1 -1
- package/dist/lib/search/record-search-route.d.ts +1 -1
- package/dist/lib/search/record-search-route.js +1 -1
- package/dist/lib/search/record-search-route.js.map +1 -1
- package/dist/lib/search/record-search-source.d.ts +1 -2
- package/dist/lib/search/record-search-source.d.ts.map +1 -1
- package/dist/lib/search/record-search-source.js.map +1 -1
- package/dist/lib/search/record-search.types.d.ts +1 -1
- package/dist/lib/search/record-search.types.js +1 -1
- package/dist/lib/search/record-search.types.js.map +1 -1
- package/dist/lib/session/account-links.js +1 -1
- package/dist/lib/session/account-links.js.map +1 -1
- package/dist/lib/session/session-keepalive.d.ts +2 -4
- package/dist/lib/session/session-keepalive.d.ts.map +1 -1
- package/dist/lib/session/session-keepalive.js +2 -4
- package/dist/lib/session/session-keepalive.js.map +1 -1
- package/dist/lib/session/use-session-refresh.js +1 -1
- package/dist/lib/session/use-session-refresh.js.map +1 -1
- package/dist/lib/wizard/wizard-tab-kind.d.ts +1 -2
- package/dist/lib/wizard/wizard-tab-kind.d.ts.map +1 -1
- package/dist/lib/wizard/wizard-tab-kind.js +1 -2
- package/dist/lib/wizard/wizard-tab-kind.js.map +1 -1
- package/dist/lib/workspace/drafts-state.d.ts.map +1 -1
- package/dist/lib/workspace/drafts-state.js +3 -2
- package/dist/lib/workspace/drafts-state.js.map +1 -1
- package/dist/lib/workspace/entity-tab-kind.d.ts +1 -2
- package/dist/lib/workspace/entity-tab-kind.d.ts.map +1 -1
- package/dist/lib/workspace/entity-tab-kind.js +1 -2
- package/dist/lib/workspace/entity-tab-kind.js.map +1 -1
- package/dist/lib/workspace/pending-state.d.ts +5 -4
- package/dist/lib/workspace/pending-state.d.ts.map +1 -1
- package/dist/lib/workspace/pending-state.js +1 -1
- package/dist/lib/workspace/pending-state.js.map +1 -1
- package/dist/lib/workspace/tabs-state.js +1 -1
- package/dist/lib/workspace/tabs-state.js.map +1 -1
- package/dist/server.d.ts +1 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +2 -2
- package/dist/server.js.map +1 -1
- package/package.json +9 -9
- package/dist/lib/config/service-token.d.ts +0 -5
- package/dist/lib/config/service-token.d.ts.map +0 -1
- package/dist/lib/config/service-token.js +0 -18
- package/dist/lib/config/service-token.js.map +0 -1
|
@@ -6,184 +6,6 @@
|
|
|
6
6
|
export declare const shellCatalogs: {
|
|
7
7
|
readonly es: {
|
|
8
8
|
readonly shell: {
|
|
9
|
-
auth: {
|
|
10
|
-
nav: {
|
|
11
|
-
identity: string;
|
|
12
|
-
users: string;
|
|
13
|
-
accountSection: string;
|
|
14
|
-
};
|
|
15
|
-
account: {
|
|
16
|
-
overline: string;
|
|
17
|
-
title: string;
|
|
18
|
-
subtitle: string;
|
|
19
|
-
menu: string;
|
|
20
|
-
identifiers: string;
|
|
21
|
-
noIdentifiers: string;
|
|
22
|
-
userId: string;
|
|
23
|
-
subject: string;
|
|
24
|
-
session: string;
|
|
25
|
-
roles: string;
|
|
26
|
-
none: string;
|
|
27
|
-
failed: string;
|
|
28
|
-
};
|
|
29
|
-
sessions: {
|
|
30
|
-
overline: string;
|
|
31
|
-
title: string;
|
|
32
|
-
subtitle: string;
|
|
33
|
-
current: string;
|
|
34
|
-
unknownDevice: string;
|
|
35
|
-
startedAt: string;
|
|
36
|
-
expiresAt: string;
|
|
37
|
-
lastIp: string;
|
|
38
|
-
revoke: string;
|
|
39
|
-
revoking: string;
|
|
40
|
-
revokeOthers: string;
|
|
41
|
-
empty: string;
|
|
42
|
-
failed: string;
|
|
43
|
-
loading: string;
|
|
44
|
-
};
|
|
45
|
-
security: {
|
|
46
|
-
overline: string;
|
|
47
|
-
title: string;
|
|
48
|
-
subtitle: string;
|
|
49
|
-
explain: string;
|
|
50
|
-
manage: string;
|
|
51
|
-
};
|
|
52
|
-
fields: {
|
|
53
|
-
displayName: string;
|
|
54
|
-
email: string;
|
|
55
|
-
username: string;
|
|
56
|
-
role: string;
|
|
57
|
-
};
|
|
58
|
-
submit: {
|
|
59
|
-
wait: string;
|
|
60
|
-
creating: string;
|
|
61
|
-
createUser: string;
|
|
62
|
-
};
|
|
63
|
-
users: {
|
|
64
|
-
title: string;
|
|
65
|
-
newTitle: string;
|
|
66
|
-
fallbackName: string;
|
|
67
|
-
sessionsTitle: string;
|
|
68
|
-
sessionsEmpty: string;
|
|
69
|
-
sessionsFailed: string;
|
|
70
|
-
kick: string;
|
|
71
|
-
kicking: string;
|
|
72
|
-
};
|
|
73
|
-
};
|
|
74
|
-
stock: {
|
|
75
|
-
nav: {
|
|
76
|
-
stock: string;
|
|
77
|
-
items: string;
|
|
78
|
-
movements: string;
|
|
79
|
-
reservations: string;
|
|
80
|
-
};
|
|
81
|
-
};
|
|
82
|
-
order: {
|
|
83
|
-
nav: {
|
|
84
|
-
orders: string;
|
|
85
|
-
};
|
|
86
|
-
};
|
|
87
|
-
settlement: {
|
|
88
|
-
nav: {
|
|
89
|
-
settlement: string;
|
|
90
|
-
agreements: string;
|
|
91
|
-
entries: string;
|
|
92
|
-
runs: string;
|
|
93
|
-
payouts: string;
|
|
94
|
-
};
|
|
95
|
-
agreement: {
|
|
96
|
-
channelRatesHint: string;
|
|
97
|
-
channelRateDefault: string;
|
|
98
|
-
noChannelRates: string;
|
|
99
|
-
};
|
|
100
|
-
};
|
|
101
|
-
sales: {
|
|
102
|
-
nav: {
|
|
103
|
-
sales: string;
|
|
104
|
-
channels: string;
|
|
105
|
-
guided: string;
|
|
106
|
-
counterSale: string;
|
|
107
|
-
};
|
|
108
|
-
counterSale: {
|
|
109
|
-
title: string;
|
|
110
|
-
steps: {
|
|
111
|
-
channel: string;
|
|
112
|
-
lines: string;
|
|
113
|
-
payment: string;
|
|
114
|
-
summary: string;
|
|
115
|
-
};
|
|
116
|
-
channelHint: string;
|
|
117
|
-
linesHint: string;
|
|
118
|
-
addLine: string;
|
|
119
|
-
removeLine: string;
|
|
120
|
-
quantity: string;
|
|
121
|
-
offering: string;
|
|
122
|
-
total: string;
|
|
123
|
-
paymentMethod: string;
|
|
124
|
-
charge: string;
|
|
125
|
-
sold: string;
|
|
126
|
-
soldDetail: string;
|
|
127
|
-
newSale: string;
|
|
128
|
-
emptyLines: string;
|
|
129
|
-
};
|
|
130
|
-
};
|
|
131
|
-
marketplaceAdmin: {
|
|
132
|
-
nav: {
|
|
133
|
-
catalog: string;
|
|
134
|
-
products: string;
|
|
135
|
-
brands: string;
|
|
136
|
-
categories: string;
|
|
137
|
-
offerings: string;
|
|
138
|
-
offeringPrices: string;
|
|
139
|
-
guided: string;
|
|
140
|
-
};
|
|
141
|
-
wizard: {
|
|
142
|
-
productSetup: {
|
|
143
|
-
title: string;
|
|
144
|
-
launch: string;
|
|
145
|
-
steps: {
|
|
146
|
-
start: string;
|
|
147
|
-
source: string;
|
|
148
|
-
identity: string;
|
|
149
|
-
classification: string;
|
|
150
|
-
summary: string;
|
|
151
|
-
};
|
|
152
|
-
start: {
|
|
153
|
-
question: string;
|
|
154
|
-
blank: string;
|
|
155
|
-
blankHint: string;
|
|
156
|
-
duplicate: string;
|
|
157
|
-
duplicateHint: string;
|
|
158
|
-
};
|
|
159
|
-
source: {
|
|
160
|
-
prompt: string;
|
|
161
|
-
chosen: string;
|
|
162
|
-
required: string;
|
|
163
|
-
};
|
|
164
|
-
summary: {
|
|
165
|
-
prompt: string;
|
|
166
|
-
origin: string;
|
|
167
|
-
originBlank: string;
|
|
168
|
-
originDuplicate: string;
|
|
169
|
-
empty: string;
|
|
170
|
-
};
|
|
171
|
-
recap: string;
|
|
172
|
-
};
|
|
173
|
-
};
|
|
174
|
-
};
|
|
175
|
-
systemManagement: {
|
|
176
|
-
nav: {
|
|
177
|
-
section: string;
|
|
178
|
-
configuration: string;
|
|
179
|
-
};
|
|
180
|
-
configuration: {
|
|
181
|
-
title: string;
|
|
182
|
-
description: string;
|
|
183
|
-
secretPlaceholder: string;
|
|
184
|
-
secretHint: string;
|
|
185
|
-
};
|
|
186
|
-
};
|
|
187
9
|
nav: {
|
|
188
10
|
primary: string;
|
|
189
11
|
openInWorkspace: string;
|
|
@@ -256,264 +78,10 @@ export declare const shellCatalogs: {
|
|
|
256
78
|
saveFailed: string;
|
|
257
79
|
saveFailedDismiss: string;
|
|
258
80
|
};
|
|
259
|
-
storefront: {
|
|
260
|
-
nav: {
|
|
261
|
-
catalog: string;
|
|
262
|
-
};
|
|
263
|
-
home: {
|
|
264
|
-
overline: string;
|
|
265
|
-
heading: string;
|
|
266
|
-
lead: string;
|
|
267
|
-
featured: string;
|
|
268
|
-
};
|
|
269
|
-
category: {
|
|
270
|
-
overline: string;
|
|
271
|
-
empty: string;
|
|
272
|
-
sort: string;
|
|
273
|
-
sortByName: string;
|
|
274
|
-
sortByCode: string;
|
|
275
|
-
results: string;
|
|
276
|
-
previous: string;
|
|
277
|
-
next: string;
|
|
278
|
-
pageOf: string;
|
|
279
|
-
};
|
|
280
|
-
product: {
|
|
281
|
-
addToCart: string;
|
|
282
|
-
view: string;
|
|
283
|
-
brand: string;
|
|
284
|
-
category: string;
|
|
285
|
-
reference: string;
|
|
286
|
-
related: string;
|
|
287
|
-
available: string;
|
|
288
|
-
unavailable: string;
|
|
289
|
-
};
|
|
290
|
-
search: {
|
|
291
|
-
heading: string;
|
|
292
|
-
label: string;
|
|
293
|
-
placeholder: string;
|
|
294
|
-
submit: string;
|
|
295
|
-
resultsFor: string;
|
|
296
|
-
empty: string;
|
|
297
|
-
prompt: string;
|
|
298
|
-
};
|
|
299
|
-
cart: {
|
|
300
|
-
heading: string;
|
|
301
|
-
empty: string;
|
|
302
|
-
remove: string;
|
|
303
|
-
units: string;
|
|
304
|
-
total: string;
|
|
305
|
-
keepShopping: string;
|
|
306
|
-
checkout: string;
|
|
307
|
-
};
|
|
308
|
-
checkout: {
|
|
309
|
-
placed: string;
|
|
310
|
-
unavailable: string;
|
|
311
|
-
empty: string;
|
|
312
|
-
failed: string;
|
|
313
|
-
};
|
|
314
|
-
order: {
|
|
315
|
-
heading: string;
|
|
316
|
-
placed: string;
|
|
317
|
-
reference: string;
|
|
318
|
-
units: string;
|
|
319
|
-
total: string;
|
|
320
|
-
tooManyLines: string;
|
|
321
|
-
keepShopping: string;
|
|
322
|
-
expiredHeading: string;
|
|
323
|
-
expired: string;
|
|
324
|
-
cancel: string;
|
|
325
|
-
cancelWindow: string;
|
|
326
|
-
cancelPending: string;
|
|
327
|
-
cancelledHeading: string;
|
|
328
|
-
cancelled: string;
|
|
329
|
-
cancelFailed: string;
|
|
330
|
-
};
|
|
331
|
-
footer: {
|
|
332
|
-
note: string;
|
|
333
|
-
};
|
|
334
|
-
};
|
|
335
81
|
};
|
|
336
82
|
};
|
|
337
83
|
readonly en: {
|
|
338
84
|
readonly shell: {
|
|
339
|
-
auth: {
|
|
340
|
-
nav: {
|
|
341
|
-
identity: string;
|
|
342
|
-
users: string;
|
|
343
|
-
accountSection: string;
|
|
344
|
-
};
|
|
345
|
-
account: {
|
|
346
|
-
overline: string;
|
|
347
|
-
title: string;
|
|
348
|
-
subtitle: string;
|
|
349
|
-
menu: string;
|
|
350
|
-
identifiers: string;
|
|
351
|
-
noIdentifiers: string;
|
|
352
|
-
userId: string;
|
|
353
|
-
subject: string;
|
|
354
|
-
session: string;
|
|
355
|
-
roles: string;
|
|
356
|
-
none: string;
|
|
357
|
-
failed: string;
|
|
358
|
-
};
|
|
359
|
-
sessions: {
|
|
360
|
-
overline: string;
|
|
361
|
-
title: string;
|
|
362
|
-
subtitle: string;
|
|
363
|
-
current: string;
|
|
364
|
-
unknownDevice: string;
|
|
365
|
-
startedAt: string;
|
|
366
|
-
expiresAt: string;
|
|
367
|
-
lastIp: string;
|
|
368
|
-
revoke: string;
|
|
369
|
-
revoking: string;
|
|
370
|
-
revokeOthers: string;
|
|
371
|
-
empty: string;
|
|
372
|
-
failed: string;
|
|
373
|
-
loading: string;
|
|
374
|
-
};
|
|
375
|
-
security: {
|
|
376
|
-
overline: string;
|
|
377
|
-
title: string;
|
|
378
|
-
subtitle: string;
|
|
379
|
-
explain: string;
|
|
380
|
-
manage: string;
|
|
381
|
-
};
|
|
382
|
-
fields: {
|
|
383
|
-
displayName: string;
|
|
384
|
-
email: string;
|
|
385
|
-
username: string;
|
|
386
|
-
role: string;
|
|
387
|
-
};
|
|
388
|
-
submit: {
|
|
389
|
-
wait: string;
|
|
390
|
-
creating: string;
|
|
391
|
-
createUser: string;
|
|
392
|
-
};
|
|
393
|
-
users: {
|
|
394
|
-
title: string;
|
|
395
|
-
newTitle: string;
|
|
396
|
-
fallbackName: string;
|
|
397
|
-
sessionsTitle: string;
|
|
398
|
-
sessionsEmpty: string;
|
|
399
|
-
sessionsFailed: string;
|
|
400
|
-
kick: string;
|
|
401
|
-
kicking: string;
|
|
402
|
-
};
|
|
403
|
-
};
|
|
404
|
-
stock: {
|
|
405
|
-
nav: {
|
|
406
|
-
stock: string;
|
|
407
|
-
items: string;
|
|
408
|
-
movements: string;
|
|
409
|
-
reservations: string;
|
|
410
|
-
};
|
|
411
|
-
};
|
|
412
|
-
order: {
|
|
413
|
-
nav: {
|
|
414
|
-
orders: string;
|
|
415
|
-
};
|
|
416
|
-
};
|
|
417
|
-
settlement: {
|
|
418
|
-
nav: {
|
|
419
|
-
settlement: string;
|
|
420
|
-
agreements: string;
|
|
421
|
-
entries: string;
|
|
422
|
-
runs: string;
|
|
423
|
-
payouts: string;
|
|
424
|
-
};
|
|
425
|
-
agreement: {
|
|
426
|
-
channelRatesHint: string;
|
|
427
|
-
channelRateDefault: string;
|
|
428
|
-
noChannelRates: string;
|
|
429
|
-
};
|
|
430
|
-
};
|
|
431
|
-
sales: {
|
|
432
|
-
nav: {
|
|
433
|
-
sales: string;
|
|
434
|
-
channels: string;
|
|
435
|
-
guided: string;
|
|
436
|
-
counterSale: string;
|
|
437
|
-
};
|
|
438
|
-
counterSale: {
|
|
439
|
-
title: string;
|
|
440
|
-
steps: {
|
|
441
|
-
channel: string;
|
|
442
|
-
lines: string;
|
|
443
|
-
payment: string;
|
|
444
|
-
summary: string;
|
|
445
|
-
};
|
|
446
|
-
channelHint: string;
|
|
447
|
-
linesHint: string;
|
|
448
|
-
addLine: string;
|
|
449
|
-
removeLine: string;
|
|
450
|
-
quantity: string;
|
|
451
|
-
offering: string;
|
|
452
|
-
total: string;
|
|
453
|
-
paymentMethod: string;
|
|
454
|
-
charge: string;
|
|
455
|
-
sold: string;
|
|
456
|
-
soldDetail: string;
|
|
457
|
-
newSale: string;
|
|
458
|
-
emptyLines: string;
|
|
459
|
-
};
|
|
460
|
-
};
|
|
461
|
-
marketplaceAdmin: {
|
|
462
|
-
nav: {
|
|
463
|
-
catalog: string;
|
|
464
|
-
products: string;
|
|
465
|
-
brands: string;
|
|
466
|
-
categories: string;
|
|
467
|
-
offerings: string;
|
|
468
|
-
offeringPrices: string;
|
|
469
|
-
guided: string;
|
|
470
|
-
};
|
|
471
|
-
wizard: {
|
|
472
|
-
productSetup: {
|
|
473
|
-
title: string;
|
|
474
|
-
launch: string;
|
|
475
|
-
steps: {
|
|
476
|
-
start: string;
|
|
477
|
-
source: string;
|
|
478
|
-
identity: string;
|
|
479
|
-
classification: string;
|
|
480
|
-
summary: string;
|
|
481
|
-
};
|
|
482
|
-
start: {
|
|
483
|
-
question: string;
|
|
484
|
-
blank: string;
|
|
485
|
-
blankHint: string;
|
|
486
|
-
duplicate: string;
|
|
487
|
-
duplicateHint: string;
|
|
488
|
-
};
|
|
489
|
-
source: {
|
|
490
|
-
prompt: string;
|
|
491
|
-
chosen: string;
|
|
492
|
-
required: string;
|
|
493
|
-
};
|
|
494
|
-
summary: {
|
|
495
|
-
prompt: string;
|
|
496
|
-
origin: string;
|
|
497
|
-
originBlank: string;
|
|
498
|
-
originDuplicate: string;
|
|
499
|
-
empty: string;
|
|
500
|
-
};
|
|
501
|
-
recap: string;
|
|
502
|
-
};
|
|
503
|
-
};
|
|
504
|
-
};
|
|
505
|
-
systemManagement: {
|
|
506
|
-
nav: {
|
|
507
|
-
section: string;
|
|
508
|
-
configuration: string;
|
|
509
|
-
};
|
|
510
|
-
configuration: {
|
|
511
|
-
title: string;
|
|
512
|
-
description: string;
|
|
513
|
-
secretPlaceholder: string;
|
|
514
|
-
secretHint: string;
|
|
515
|
-
};
|
|
516
|
-
};
|
|
517
85
|
nav: {
|
|
518
86
|
primary: string;
|
|
519
87
|
openInWorkspace: string;
|
|
@@ -586,82 +154,6 @@ export declare const shellCatalogs: {
|
|
|
586
154
|
saveFailed: string;
|
|
587
155
|
saveFailedDismiss: string;
|
|
588
156
|
};
|
|
589
|
-
storefront: {
|
|
590
|
-
nav: {
|
|
591
|
-
catalog: string;
|
|
592
|
-
};
|
|
593
|
-
home: {
|
|
594
|
-
overline: string;
|
|
595
|
-
heading: string;
|
|
596
|
-
lead: string;
|
|
597
|
-
featured: string;
|
|
598
|
-
};
|
|
599
|
-
category: {
|
|
600
|
-
overline: string;
|
|
601
|
-
empty: string;
|
|
602
|
-
sort: string;
|
|
603
|
-
sortByName: string;
|
|
604
|
-
sortByCode: string;
|
|
605
|
-
results: string;
|
|
606
|
-
previous: string;
|
|
607
|
-
next: string;
|
|
608
|
-
pageOf: string;
|
|
609
|
-
};
|
|
610
|
-
product: {
|
|
611
|
-
addToCart: string;
|
|
612
|
-
view: string;
|
|
613
|
-
brand: string;
|
|
614
|
-
category: string;
|
|
615
|
-
reference: string;
|
|
616
|
-
related: string;
|
|
617
|
-
available: string;
|
|
618
|
-
unavailable: string;
|
|
619
|
-
};
|
|
620
|
-
search: {
|
|
621
|
-
heading: string;
|
|
622
|
-
label: string;
|
|
623
|
-
placeholder: string;
|
|
624
|
-
submit: string;
|
|
625
|
-
resultsFor: string;
|
|
626
|
-
empty: string;
|
|
627
|
-
prompt: string;
|
|
628
|
-
};
|
|
629
|
-
cart: {
|
|
630
|
-
heading: string;
|
|
631
|
-
empty: string;
|
|
632
|
-
remove: string;
|
|
633
|
-
units: string;
|
|
634
|
-
total: string;
|
|
635
|
-
keepShopping: string;
|
|
636
|
-
checkout: string;
|
|
637
|
-
};
|
|
638
|
-
checkout: {
|
|
639
|
-
placed: string;
|
|
640
|
-
unavailable: string;
|
|
641
|
-
empty: string;
|
|
642
|
-
failed: string;
|
|
643
|
-
};
|
|
644
|
-
order: {
|
|
645
|
-
heading: string;
|
|
646
|
-
placed: string;
|
|
647
|
-
reference: string;
|
|
648
|
-
units: string;
|
|
649
|
-
total: string;
|
|
650
|
-
tooManyLines: string;
|
|
651
|
-
keepShopping: string;
|
|
652
|
-
expiredHeading: string;
|
|
653
|
-
expired: string;
|
|
654
|
-
cancel: string;
|
|
655
|
-
cancelWindow: string;
|
|
656
|
-
cancelPending: string;
|
|
657
|
-
cancelledHeading: string;
|
|
658
|
-
cancelled: string;
|
|
659
|
-
cancelFailed: string;
|
|
660
|
-
};
|
|
661
|
-
footer: {
|
|
662
|
-
note: string;
|
|
663
|
-
};
|
|
664
|
-
};
|
|
665
157
|
};
|
|
666
158
|
};
|
|
667
159
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/lib/i18n/catalog/index.ts"],"names":[],"mappings":"AAKA;;;;GAIG;AACH,eAAO,MAAM,aAAa
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/lib/i18n/catalog/index.ts"],"names":[],"mappings":"AAKA;;;;GAIG;AACH,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAGhB,CAAC;AAEX,qEAAqE;AACrE,MAAM,MAAM,cAAc,GAAG,CAAC,OAAO,aAAa,CAAC,CAAC,IAAI,CAAC,CAAC;AAE1D,eAAO,MAAM,gBAAgB,oBAAqB,CAAC"}
|
|
@@ -3,11 +3,11 @@ import { registerFallbackCatalog } from '@entifix/react-controls';
|
|
|
3
3
|
* An `entity` catalog for this package's own specs.
|
|
4
4
|
*
|
|
5
5
|
* ⚠️ **A fixture, not a shipped catalog.** `entity` names the *host's* entities,
|
|
6
|
-
* so a framework shipping one would be shipping product copy — which
|
|
7
|
-
* [ADR
|
|
8
|
-
*
|
|
6
|
+
* so a framework shipping one would be shipping product copy — which
|
|
7
|
+
* [ADR 0001](../../../../../../docs/adr/0001-the-tier-contract-and-the-host-seam.md)
|
|
8
|
+
* calls a defect. These specs assert that a nav entry, a palette command and a
|
|
9
9
|
* workspace tab name a record in the catalog's own words; a fixture proves that
|
|
10
|
-
* as well as
|
|
10
|
+
* as well as a host's copy would, and keeps the assertions readable as sentences.
|
|
11
11
|
*/ const es = {
|
|
12
12
|
product: {
|
|
13
13
|
label: 'Producto',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/lib/i18n/spec-catalog.ts"],"sourcesContent":["import { registerFallbackCatalog } from '@entifix/react-controls';\n\n/**\n * An `entity` catalog for this package's own specs.\n *\n * ⚠️ **A fixture, not a shipped catalog.** `entity` names the *host's* entities,\n * so a framework shipping one would be shipping product copy — which
|
|
1
|
+
{"version":3,"sources":["../../../src/lib/i18n/spec-catalog.ts"],"sourcesContent":["import { registerFallbackCatalog } from '@entifix/react-controls';\n\n/**\n * An `entity` catalog for this package's own specs.\n *\n * ⚠️ **A fixture, not a shipped catalog.** `entity` names the *host's* entities,\n * so a framework shipping one would be shipping product copy — which\n * [ADR 0001](../../../../../../docs/adr/0001-the-tier-contract-and-the-host-seam.md)\n * calls a defect. These specs assert that a nav entry, a palette command and a\n * workspace tab name a record in the catalog's own words; a fixture proves that\n * as well as a host's copy would, and keeps the assertions readable as sentences.\n */\nconst es = {\n product: { label: 'Producto', plural: 'Productos' },\n thing: { label: 'Cosa', plural: 'Cosas' },\n widget: { label: 'Artilugio', plural: 'Artilugios' },\n 'product-category': { label: 'Categoría', plural: 'Categorías' },\n 'product-brand': {\n label: 'Marca',\n plural: 'Marcas',\n form: { newTitle: 'Nueva marca', editTitle: 'Editar marca' },\n fields: {\n id: 'Id',\n code: 'Código',\n name: 'Nombre',\n website: 'Sitio web',\n },\n // No `archive` on purpose — a CRUD spec asserts that a verb the\n // catalog does not name still renders, as its key.\n useCases: { retire: 'Retirar' },\n },\n 'product-specification': {\n label: 'Producto',\n plural: 'Productos',\n fields: { id: 'Id', name: 'Nombre', brand: 'Marca' },\n },\n 'user-identity': {\n label: 'Usuario',\n plural: 'Usuarios',\n useCases: {\n signOutOthers: 'Cerrar mis otras sesiones',\n signOutOthersConfirm:\n 'Se cerrarán todas tus sesiones en otros dispositivos y navegadores. ' +\n 'Ésta seguirá abierta.',\n signOutOthersKeywords: 'cerrar sesión, dispositivos, logout',\n },\n },\n} as const;\n\nregisterFallbackCatalog('entity', { es, en: es });\n\n/**\n * The same for `errors` — the code vocabulary a host's services answer with.\n * The palette renders a scope refusal through it, so it needs the two codes\n * these specs actually raise.\n */\nconst errors = {\n noActiveOrganization: 'Selecciona una organización para ver estos registros.',\n alreadyRetired: 'El registro ya estaba retirado.',\n unexpected: 'Ocurrió un error inesperado.',\n} as const;\n\nregisterFallbackCatalog('errors', { es: errors, en: errors });\n"],"names":["registerFallbackCatalog","es","product","label","plural","thing","widget","form","newTitle","editTitle","fields","id","code","name","website","useCases","retire","brand","signOutOthers","signOutOthersConfirm","signOutOthersKeywords","en","errors","noActiveOrganization","alreadyRetired","unexpected"],"mappings":"AAAA,SAASA,uBAAuB,QAAQ,0BAA0B;AAElE;;;;;;;;;CASC,GACD,MAAMC,KAAK;IACTC,SAAS;QAAEC,OAAO;QAAYC,QAAQ;IAAY;IAClDC,OAAO;QAAEF,OAAO;QAAQC,QAAQ;IAAQ;IACxCE,QAAQ;QAAEH,OAAO;QAAaC,QAAQ;IAAa;IACnD,oBAAoB;QAAED,OAAO;QAAaC,QAAQ;IAAa;IAC/D,iBAAiB;QACfD,OAAO;QACPC,QAAQ;QACRG,MAAM;YAAEC,UAAU;YAAeC,WAAW;QAAe;QAC3DC,QAAQ;YACNC,IAAI;YACJC,MAAM;YACNC,MAAM;YACNC,SAAS;QACX;QACA,gEAAgE;QAChE,mDAAmD;QACnDC,UAAU;YAAEC,QAAQ;QAAU;IAChC;IACA,yBAAyB;QACvBb,OAAO;QACPC,QAAQ;QACRM,QAAQ;YAAEC,IAAI;YAAME,MAAM;YAAUI,OAAO;QAAQ;IACrD;IACA,iBAAiB;QACfd,OAAO;QACPC,QAAQ;QACRW,UAAU;YACRG,eAAe;YACfC,sBACE,yEACA;YACFC,uBAAuB;QACzB;IACF;AACF;AAEApB,wBAAwB,UAAU;IAAEC;IAAIoB,IAAIpB;AAAG;AAE/C;;;;CAIC,GACD,MAAMqB,SAAS;IACbC,sBAAsB;IACtBC,gBAAgB;IAChBC,YAAY;AACd;AAEAzB,wBAAwB,UAAU;IAAEC,IAAIqB;IAAQD,IAAIC;AAAO"}
|
|
@@ -28,7 +28,7 @@ export interface RecordSearchRouteOptions {
|
|
|
28
28
|
}
|
|
29
29
|
/**
|
|
30
30
|
* `GET /api/search` — records matching a term, across every source this host
|
|
31
|
-
* mounts
|
|
31
|
+
* mounts.
|
|
32
32
|
*
|
|
33
33
|
* The caller's own session is the only credential that crosses: each source is
|
|
34
34
|
* asked over the same guarded route its screens use, so what comes back is
|
|
@@ -76,7 +76,7 @@ const clampLimit = (raw, fallback)=>{
|
|
|
76
76
|
};
|
|
77
77
|
/**
|
|
78
78
|
* `GET /api/search` — records matching a term, across every source this host
|
|
79
|
-
* mounts
|
|
79
|
+
* mounts.
|
|
80
80
|
*
|
|
81
81
|
* The caller's own session is the only credential that crosses: each source is
|
|
82
82
|
* asked over the same guarded route its screens use, so what comes back is
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/lib/search/record-search-route.ts"],"sourcesContent":["import { NextResponse } from 'next/server';\n\nimport { bearerHeader, sessionToken } from '../session/bearer.js';\nimport type {\n RecordSearchGroup,\n RecordSearchResponse,\n RecordSearchUnavailable,\n RecordSearchUnavailableReason,\n} from './record-search.types.js';\nimport type { RecordSearchSource } from './record-search-source.js';\n\nexport const SEARCH_TERM_PARAM = 'q';\nexport const SEARCH_SOURCES_PARAM = 'sources';\nexport const SEARCH_LIMIT_PARAM = 'limit';\n\n/**\n * Below this, nothing is queried at all.\n *\n * A `like` becomes an unanchored, case-insensitive `$regex`, which no index can\n * serve — so this endpoint is a collection scan by construction. One character\n * matches most of every collection and is worth nothing to the person typing, so\n * the floor costs them nothing and saves four scans per keystroke.\n */\nexport const MIN_TERM_LENGTH = 2;\nexport const DEFAULT_GROUP_LIMIT = 5;\nexport const MAX_GROUP_LIMIT = 20;\nexport const DEFAULT_SOURCE_TIMEOUT_MS = 1_500;\n\n/** Upstream statuses that mean something other than \"we could not reach it\". */\nconst REASON_FOR_STATUS: Readonly<\n Record<number, RecordSearchUnavailableReason>\n> = {\n 400: 'invalidQuery',\n 401: 'unauthenticated',\n 403: 'forbidden',\n 404: 'notFound',\n 409: 'noActiveOrganization',\n};\n\nexport interface RecordSearchRouteOptions {\n /**\n * The sources to fan out over, **in the order results are presented**. That\n * order is the ranking: an operator learns where a kind of record lands, which\n * a relevance score across four unrelated entities cannot offer.\n */\n readonly sources: readonly RecordSearchSource[];\n /** Per-source budget. Concurrent, so this also bounds the whole request. */\n readonly timeoutMs?: number;\n /** Records per group. */\n readonly limit?: number;\n}\n\ntype SourceOutcome =\n | { readonly ok: true; readonly group: RecordSearchGroup }\n | { readonly ok: false; readonly unavailable: RecordSearchUnavailable };\n\nconst unavailable = (\n source: RecordSearchSource,\n reason: RecordSearchUnavailableReason,\n status?: number,\n): SourceOutcome => ({\n ok: false,\n unavailable: {\n source: source.key,\n entity: source.entity,\n reason,\n ...(status === undefined ? {} : { status }),\n },\n});\n\n/**\n * Ask one source, and **never reject**.\n *\n * Returning a typed outcome rather than throwing is what makes the fan-out a\n * plain `Promise.all`: isolation comes from this catch, not from\n * `allSettled` — whose rejected arm would then be unreachable and untestable.\n */\nconst runSource = async (\n source: RecordSearchSource,\n term: string,\n limit: number,\n token: string | undefined,\n timeoutMs: number,\n): Promise<SourceOutcome> => {\n let upstream: Response;\n try {\n upstream = await fetch(source.url(term, limit), {\n headers: bearerHeader(token),\n cache: 'no-store',\n signal: AbortSignal.timeout(timeoutMs),\n });\n } catch (error) {\n // `AbortSignal.timeout` rejects with a `DOMException` named `TimeoutError`;\n // branching on the name rather than the class keeps this reachable from a\n // test without fabricating a platform error.\n return unavailable(\n source,\n (error as { name?: string }).name === 'TimeoutError'\n ? 'timeout'\n : 'network',\n );\n }\n\n if (!upstream.ok) {\n return unavailable(\n source,\n REASON_FOR_STATUS[upstream.status] ?? 'unexpected',\n upstream.status,\n );\n }\n\n const body = await upstream.json().catch(() => undefined);\n const page = source.read(body);\n return page === undefined\n ? unavailable(source, 'unexpected', upstream.status)\n : {\n ok: true,\n group: {\n source: source.key,\n entity: source.entity,\n labelKey: source.labelKey,\n items: page.items,\n total: page.total,\n },\n };\n};\n\nconst clampLimit = (raw: string | null, fallback: number): number => {\n const asked = Number(raw);\n if (!Number.isInteger(asked) || asked < 1) return fallback;\n return Math.min(asked, MAX_GROUP_LIMIT);\n};\n\n/**\n * `GET /api/search` — records matching a term, across every source this host\n * mounts (ADR 0040).\n *\n * The caller's own session is the only credential that crosses: each source is\n * asked over the same guarded route its screens use, so what comes back is\n * already authorized for this principal and this organization. There is no\n * index, and there must never be one — a prefetched index is a tenant leak, and\n * it is the reason this is a fan-out rather than a search service.\n *\n * A source that fails is **named** in `unavailable` rather than dropped. An\n * absent group renders as \"no matches\", which is a confident claim the server is\n * in no position to make about a service it could not reach.\n */\nexport const createRecordSearchRoute = ({\n sources,\n timeoutMs = DEFAULT_SOURCE_TIMEOUT_MS,\n limit: defaultLimit = DEFAULT_GROUP_LIMIT,\n}: RecordSearchRouteOptions) => {\n const byKey = new Map(sources.map(source => [source.key, source]));\n\n return async function GET(request: Request): Promise<Response> {\n // The services decide what this caller may read; this only carries the\n // token. But the gate is not redundant: `catalog-reference` reads are\n // unauthenticated at the service by design, so without it a signed-out\n // caller gets brand matches back and the answer reads as a real search —\n // and the endpoint becomes an anonymous amplifier against that service.\n const token = await sessionToken();\n if (token === undefined) {\n return NextResponse.json(\n { error: 'unauthenticated', code: 'unauthenticated' },\n { status: 401 },\n );\n }\n\n const params = new URL(request.url).searchParams;\n\n const asked = (params.get(SEARCH_SOURCES_PARAM) ?? '')\n .split(',')\n .filter(name => name !== '');\n const unknown = asked.find(name => !byKey.has(name));\n if (unknown !== undefined) {\n // Loud rather than ignored: no keystroke can produce this, only a caller\n // naming a source that does not exist — and silently searching everything\n // instead would answer a question nobody asked.\n return NextResponse.json(\n {\n error: 'invalid query',\n code: 'invalidQuery',\n detail: `unknown search source \"${unknown}\"`,\n },\n { status: 400 },\n );\n }\n const selected =\n asked.length === 0\n ? sources\n : sources.filter(source => asked.includes(source.key));\n\n const term = (params.get(SEARCH_TERM_PARAM) ?? '').trim();\n const answer = (body: RecordSearchResponse) =>\n // The body is scoped to one principal and one organization. `no-store` is\n // correctness here, not tuning.\n NextResponse.json(body, { headers: { 'cache-control': 'no-store' } });\n\n if (term.length < MIN_TERM_LENGTH) {\n return answer({ term, groups: [], unavailable: [] });\n }\n\n const limit = clampLimit(params.get(SEARCH_LIMIT_PARAM), defaultLimit);\n const outcomes = await Promise.all(\n selected.map(source => runSource(source, term, limit, token, timeoutMs)),\n );\n\n return answer({\n term,\n // Declared order, never completion order — otherwise the list reshuffles\n // with the network and nobody can learn where anything lands.\n groups: outcomes.flatMap(outcome => (outcome.ok ? [outcome.group] : [])),\n unavailable: outcomes.flatMap(outcome =>\n outcome.ok ? [] : [outcome.unavailable],\n ),\n });\n };\n};\n"],"names":["NextResponse","bearerHeader","sessionToken","SEARCH_TERM_PARAM","SEARCH_SOURCES_PARAM","SEARCH_LIMIT_PARAM","MIN_TERM_LENGTH","DEFAULT_GROUP_LIMIT","MAX_GROUP_LIMIT","DEFAULT_SOURCE_TIMEOUT_MS","REASON_FOR_STATUS","unavailable","source","reason","status","ok","key","entity","undefined","runSource","term","limit","token","timeoutMs","upstream","fetch","url","headers","cache","signal","AbortSignal","timeout","error","name","body","json","catch","page","read","group","labelKey","items","total","clampLimit","raw","fallback","asked","Number","isInteger","Math","min","createRecordSearchRoute","sources","defaultLimit","byKey","Map","map","GET","request","params","code","URL","searchParams","get","split","filter","unknown","find","has","detail","selected","length","includes","trim","answer","groups","outcomes","Promise","all","flatMap","outcome"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../src/lib/search/record-search-route.ts"],"sourcesContent":["import { NextResponse } from 'next/server';\n\nimport { bearerHeader, sessionToken } from '../session/bearer.js';\nimport type {\n RecordSearchGroup,\n RecordSearchResponse,\n RecordSearchUnavailable,\n RecordSearchUnavailableReason,\n} from './record-search.types.js';\nimport type { RecordSearchSource } from './record-search-source.js';\n\nexport const SEARCH_TERM_PARAM = 'q';\nexport const SEARCH_SOURCES_PARAM = 'sources';\nexport const SEARCH_LIMIT_PARAM = 'limit';\n\n/**\n * Below this, nothing is queried at all.\n *\n * A `like` becomes an unanchored, case-insensitive `$regex`, which no index can\n * serve — so this endpoint is a collection scan by construction. One character\n * matches most of every collection and is worth nothing to the person typing, so\n * the floor costs them nothing and saves four scans per keystroke.\n */\nexport const MIN_TERM_LENGTH = 2;\nexport const DEFAULT_GROUP_LIMIT = 5;\nexport const MAX_GROUP_LIMIT = 20;\nexport const DEFAULT_SOURCE_TIMEOUT_MS = 1_500;\n\n/** Upstream statuses that mean something other than \"we could not reach it\". */\nconst REASON_FOR_STATUS: Readonly<\n Record<number, RecordSearchUnavailableReason>\n> = {\n 400: 'invalidQuery',\n 401: 'unauthenticated',\n 403: 'forbidden',\n 404: 'notFound',\n 409: 'noActiveOrganization',\n};\n\nexport interface RecordSearchRouteOptions {\n /**\n * The sources to fan out over, **in the order results are presented**. That\n * order is the ranking: an operator learns where a kind of record lands, which\n * a relevance score across four unrelated entities cannot offer.\n */\n readonly sources: readonly RecordSearchSource[];\n /** Per-source budget. Concurrent, so this also bounds the whole request. */\n readonly timeoutMs?: number;\n /** Records per group. */\n readonly limit?: number;\n}\n\ntype SourceOutcome =\n | { readonly ok: true; readonly group: RecordSearchGroup }\n | { readonly ok: false; readonly unavailable: RecordSearchUnavailable };\n\nconst unavailable = (\n source: RecordSearchSource,\n reason: RecordSearchUnavailableReason,\n status?: number,\n): SourceOutcome => ({\n ok: false,\n unavailable: {\n source: source.key,\n entity: source.entity,\n reason,\n ...(status === undefined ? {} : { status }),\n },\n});\n\n/**\n * Ask one source, and **never reject**.\n *\n * Returning a typed outcome rather than throwing is what makes the fan-out a\n * plain `Promise.all`: isolation comes from this catch, not from\n * `allSettled` — whose rejected arm would then be unreachable and untestable.\n */\nconst runSource = async (\n source: RecordSearchSource,\n term: string,\n limit: number,\n token: string | undefined,\n timeoutMs: number,\n): Promise<SourceOutcome> => {\n let upstream: Response;\n try {\n upstream = await fetch(source.url(term, limit), {\n headers: bearerHeader(token),\n cache: 'no-store',\n signal: AbortSignal.timeout(timeoutMs),\n });\n } catch (error) {\n // `AbortSignal.timeout` rejects with a `DOMException` named `TimeoutError`;\n // branching on the name rather than the class keeps this reachable from a\n // test without fabricating a platform error.\n return unavailable(\n source,\n (error as { name?: string }).name === 'TimeoutError'\n ? 'timeout'\n : 'network',\n );\n }\n\n if (!upstream.ok) {\n return unavailable(\n source,\n REASON_FOR_STATUS[upstream.status] ?? 'unexpected',\n upstream.status,\n );\n }\n\n const body = await upstream.json().catch(() => undefined);\n const page = source.read(body);\n return page === undefined\n ? unavailable(source, 'unexpected', upstream.status)\n : {\n ok: true,\n group: {\n source: source.key,\n entity: source.entity,\n labelKey: source.labelKey,\n items: page.items,\n total: page.total,\n },\n };\n};\n\nconst clampLimit = (raw: string | null, fallback: number): number => {\n const asked = Number(raw);\n if (!Number.isInteger(asked) || asked < 1) return fallback;\n return Math.min(asked, MAX_GROUP_LIMIT);\n};\n\n/**\n * `GET /api/search` — records matching a term, across every source this host\n * mounts.\n *\n * The caller's own session is the only credential that crosses: each source is\n * asked over the same guarded route its screens use, so what comes back is\n * already authorized for this principal and this organization. There is no\n * index, and there must never be one — a prefetched index is a tenant leak, and\n * it is the reason this is a fan-out rather than a search service.\n *\n * A source that fails is **named** in `unavailable` rather than dropped. An\n * absent group renders as \"no matches\", which is a confident claim the server is\n * in no position to make about a service it could not reach.\n */\nexport const createRecordSearchRoute = ({\n sources,\n timeoutMs = DEFAULT_SOURCE_TIMEOUT_MS,\n limit: defaultLimit = DEFAULT_GROUP_LIMIT,\n}: RecordSearchRouteOptions) => {\n const byKey = new Map(sources.map(source => [source.key, source]));\n\n return async function GET(request: Request): Promise<Response> {\n // The services decide what this caller may read; this only carries the\n // token. But the gate is not redundant: `catalog-reference` reads are\n // unauthenticated at the service by design, so without it a signed-out\n // caller gets brand matches back and the answer reads as a real search —\n // and the endpoint becomes an anonymous amplifier against that service.\n const token = await sessionToken();\n if (token === undefined) {\n return NextResponse.json(\n { error: 'unauthenticated', code: 'unauthenticated' },\n { status: 401 },\n );\n }\n\n const params = new URL(request.url).searchParams;\n\n const asked = (params.get(SEARCH_SOURCES_PARAM) ?? '')\n .split(',')\n .filter(name => name !== '');\n const unknown = asked.find(name => !byKey.has(name));\n if (unknown !== undefined) {\n // Loud rather than ignored: no keystroke can produce this, only a caller\n // naming a source that does not exist — and silently searching everything\n // instead would answer a question nobody asked.\n return NextResponse.json(\n {\n error: 'invalid query',\n code: 'invalidQuery',\n detail: `unknown search source \"${unknown}\"`,\n },\n { status: 400 },\n );\n }\n const selected =\n asked.length === 0\n ? sources\n : sources.filter(source => asked.includes(source.key));\n\n const term = (params.get(SEARCH_TERM_PARAM) ?? '').trim();\n const answer = (body: RecordSearchResponse) =>\n // The body is scoped to one principal and one organization. `no-store` is\n // correctness here, not tuning.\n NextResponse.json(body, { headers: { 'cache-control': 'no-store' } });\n\n if (term.length < MIN_TERM_LENGTH) {\n return answer({ term, groups: [], unavailable: [] });\n }\n\n const limit = clampLimit(params.get(SEARCH_LIMIT_PARAM), defaultLimit);\n const outcomes = await Promise.all(\n selected.map(source => runSource(source, term, limit, token, timeoutMs)),\n );\n\n return answer({\n term,\n // Declared order, never completion order — otherwise the list reshuffles\n // with the network and nobody can learn where anything lands.\n groups: outcomes.flatMap(outcome => (outcome.ok ? [outcome.group] : [])),\n unavailable: outcomes.flatMap(outcome =>\n outcome.ok ? [] : [outcome.unavailable],\n ),\n });\n };\n};\n"],"names":["NextResponse","bearerHeader","sessionToken","SEARCH_TERM_PARAM","SEARCH_SOURCES_PARAM","SEARCH_LIMIT_PARAM","MIN_TERM_LENGTH","DEFAULT_GROUP_LIMIT","MAX_GROUP_LIMIT","DEFAULT_SOURCE_TIMEOUT_MS","REASON_FOR_STATUS","unavailable","source","reason","status","ok","key","entity","undefined","runSource","term","limit","token","timeoutMs","upstream","fetch","url","headers","cache","signal","AbortSignal","timeout","error","name","body","json","catch","page","read","group","labelKey","items","total","clampLimit","raw","fallback","asked","Number","isInteger","Math","min","createRecordSearchRoute","sources","defaultLimit","byKey","Map","map","GET","request","params","code","URL","searchParams","get","split","filter","unknown","find","has","detail","selected","length","includes","trim","answer","groups","outcomes","Promise","all","flatMap","outcome"],"mappings":"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"}
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { type Entity, type EntityConstructor } from '@entifix/core';
|
|
2
2
|
import type { RecordSearchOption } from './record-search.types.js';
|
|
3
3
|
/**
|
|
4
|
-
* What a host declares in order to make one entity searchable from the palette
|
|
5
|
-
* (ADR 0040).
|
|
4
|
+
* What a host declares in order to make one entity searchable from the palette.
|
|
6
5
|
*
|
|
7
6
|
* The search and label members are **declared**, not derived, and that is not an
|
|
8
7
|
* oversight in the metadata: `linkSearchProperty`/`linkLabelProperty` are
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"record-search-source.d.ts","sourceRoot":"","sources":["../../../src/lib/search/record-search-source.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,MAAM,EACX,KAAK,iBAAiB,EAMvB,MAAM,eAAe,CAAC;AAGvB,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAEnE
|
|
1
|
+
{"version":3,"file":"record-search-source.d.ts","sourceRoot":"","sources":["../../../src/lib/search/record-search-source.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,MAAM,EACX,KAAK,iBAAiB,EAMvB,MAAM,eAAe,CAAC;AAGvB,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAEnE;;;;;;;;;GASG;AACH,MAAM,WAAW,wBAAwB,CAAC,OAAO,SAAS,MAAM;IAC9D,sEAAsE;IACtE,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,iBAAiB,EAAE,iBAAiB,CAAC,OAAO,CAAC,CAAC;IACvD,uEAAuE;IACvE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,4EAA4E;IAC5E,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,sDAAsD;IACtD,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,mDAAmD;IACnD,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IACnC,0DAA0D;IAC1D,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,2EAA2E;IAC3E,QAAQ,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,MAAM,CAAC;CACvC;AAED,qEAAqE;AACrE,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,qCAAqC;IACrC,QAAQ,CAAC,GAAG,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;IACtD,yEAAyE;IACzE,QAAQ,CAAC,IAAI,EAAE,CACb,IAAI,EAAE,OAAO,KACV;QAAE,KAAK,EAAE,kBAAkB,EAAE,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,GAAG,SAAS,CAAC;CACjE;AAoBD;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,wBAAwB,GAAI,OAAO,SAAS,MAAM,EAAE,uGAS9D,wBAAwB,CAAC,OAAO,CAAC,KAAG,kBA2ItC,CAAC"}
|