@coldsmirk/inkstone-elasticsearch 0.22.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,1241 @@
1
+ //#region src/api.ts
2
+ const API_ENDPOINTS = [
3
+ {
4
+ path: "/",
5
+ methods: ["GET"],
6
+ summary: "The cluster's name, its version and its tagline."
7
+ },
8
+ {
9
+ path: "/_search",
10
+ methods: ["GET", "POST"],
11
+ summary: "Search every index; the query in the body."
12
+ },
13
+ {
14
+ path: "/{index}/_search",
15
+ methods: ["GET", "POST"],
16
+ summary: "Search the index (a pattern, a list, an alias); the query in the body."
17
+ },
18
+ {
19
+ path: "/_count",
20
+ methods: ["GET", "POST"],
21
+ summary: "Count the documents a query matches, across every index."
22
+ },
23
+ {
24
+ path: "/{index}/_count",
25
+ methods: ["GET", "POST"],
26
+ summary: "Count the documents a query matches in the index."
27
+ },
28
+ {
29
+ path: "/_msearch",
30
+ methods: ["GET", "POST"],
31
+ summary: "Several searches in one request: a header line and a body line per search, newline-delimited."
32
+ },
33
+ {
34
+ path: "/{index}/_msearch",
35
+ methods: ["GET", "POST"],
36
+ summary: "Several searches of the index in one request, newline-delimited."
37
+ },
38
+ {
39
+ path: "/_bulk",
40
+ methods: ["POST", "PUT"],
41
+ summary: "Index, create, update and delete in one request: an action line and a document line each, newline-delimited."
42
+ },
43
+ {
44
+ path: "/{index}/_bulk",
45
+ methods: ["POST", "PUT"],
46
+ summary: "Bulk actions on the index, newline-delimited."
47
+ },
48
+ {
49
+ path: "/_sql",
50
+ methods: ["GET", "POST"],
51
+ summary: "Run an SQL query over indices."
52
+ },
53
+ {
54
+ path: "/{index}",
55
+ methods: [
56
+ "GET",
57
+ "PUT",
58
+ "DELETE",
59
+ "HEAD"
60
+ ],
61
+ summary: "The index whole: read it, create it (settings, mappings, aliases in the body), delete it, or ask whether it exists."
62
+ },
63
+ {
64
+ path: "/{index}/_mapping",
65
+ methods: ["GET", "PUT"],
66
+ summary: "The index's field mappings; PUT adds fields."
67
+ },
68
+ {
69
+ path: "/{index}/_settings",
70
+ methods: ["GET", "PUT"],
71
+ summary: "The index's settings; PUT changes the dynamic ones."
72
+ },
73
+ {
74
+ path: "/{index}/_doc",
75
+ methods: ["POST"],
76
+ summary: "Index a document under a generated id."
77
+ },
78
+ {
79
+ path: "/{index}/_doc/{id}",
80
+ methods: [
81
+ "GET",
82
+ "PUT",
83
+ "DELETE",
84
+ "HEAD"
85
+ ],
86
+ summary: "One document by id: read, index (create or replace), delete, or ask whether it exists."
87
+ },
88
+ {
89
+ path: "/{index}/_create/{id}",
90
+ methods: ["PUT", "POST"],
91
+ summary: "Index a document only where no document has the id."
92
+ },
93
+ {
94
+ path: "/{index}/_update/{id}",
95
+ methods: ["POST"],
96
+ summary: "Update a document in place: a partial `doc`, or a `script`."
97
+ },
98
+ {
99
+ path: "/{index}/_source/{id}",
100
+ methods: ["GET", "HEAD"],
101
+ summary: "A document's source alone."
102
+ },
103
+ {
104
+ path: "/{index}/_mget",
105
+ methods: ["GET", "POST"],
106
+ summary: "Several documents by id."
107
+ },
108
+ {
109
+ path: "/_mget",
110
+ methods: ["GET", "POST"],
111
+ summary: "Several documents by index and id."
112
+ },
113
+ {
114
+ path: "/{index}/_update_by_query",
115
+ methods: ["POST"],
116
+ summary: "Update every document a query matches, with a script."
117
+ },
118
+ {
119
+ path: "/{index}/_delete_by_query",
120
+ methods: ["POST"],
121
+ summary: "Delete every document a query matches."
122
+ },
123
+ {
124
+ path: "/_reindex",
125
+ methods: ["POST"],
126
+ summary: "Copy documents from one index into another."
127
+ },
128
+ {
129
+ path: "/{index}/_refresh",
130
+ methods: ["GET", "POST"],
131
+ summary: "Make the index's recent writes searchable now."
132
+ },
133
+ {
134
+ path: "/_refresh",
135
+ methods: ["GET", "POST"],
136
+ summary: "Refresh every index."
137
+ },
138
+ {
139
+ path: "/{index}/_stats",
140
+ methods: ["GET"],
141
+ summary: "The index's statistics: documents, store, indexing, search."
142
+ },
143
+ {
144
+ path: "/_stats",
145
+ methods: ["GET"],
146
+ summary: "Every index's statistics."
147
+ },
148
+ {
149
+ path: "/{index}/_analyze",
150
+ methods: ["GET", "POST"],
151
+ summary: "Run the index's analyzer over a text and see the tokens."
152
+ },
153
+ {
154
+ path: "/_analyze",
155
+ methods: ["GET", "POST"],
156
+ summary: "Run an analyzer over a text and see the tokens."
157
+ },
158
+ {
159
+ path: "/{index}/_explain/{id}",
160
+ methods: ["GET", "POST"],
161
+ summary: "Why a document scores as it does under a query."
162
+ },
163
+ {
164
+ path: "/{index}/_field_caps",
165
+ methods: ["GET", "POST"],
166
+ summary: "The fields of the index and their types across indices."
167
+ },
168
+ {
169
+ path: "/{index}/_termvectors/{id}",
170
+ methods: ["GET", "POST"],
171
+ summary: "The terms of a document's fields, with their statistics."
172
+ },
173
+ {
174
+ path: "/{index}/_open",
175
+ methods: ["POST"],
176
+ summary: "Open a closed index."
177
+ },
178
+ {
179
+ path: "/{index}/_close",
180
+ methods: ["POST"],
181
+ summary: "Close the index."
182
+ },
183
+ {
184
+ path: "/{index}/_forcemerge",
185
+ methods: ["POST"],
186
+ summary: "Merge the index's segments."
187
+ },
188
+ {
189
+ path: "/{index}/_cache/clear",
190
+ methods: ["POST"],
191
+ summary: "Clear the index's caches."
192
+ },
193
+ {
194
+ path: "/{index}/_alias/{name}",
195
+ methods: [
196
+ "GET",
197
+ "PUT",
198
+ "DELETE",
199
+ "HEAD"
200
+ ],
201
+ summary: "One alias of the index."
202
+ },
203
+ {
204
+ path: "/_alias",
205
+ methods: ["GET"],
206
+ summary: "Every alias."
207
+ },
208
+ {
209
+ path: "/_aliases",
210
+ methods: ["POST"],
211
+ summary: "Add and remove aliases in one atomic step: `actions` in the body."
212
+ },
213
+ {
214
+ path: "/_cat/indices",
215
+ methods: ["GET"],
216
+ summary: "The indices as a table: health, status, documents, size (`?v` for headers, `?format=json`)."
217
+ },
218
+ {
219
+ path: "/_cat/aliases",
220
+ methods: ["GET"],
221
+ summary: "The aliases as a table."
222
+ },
223
+ {
224
+ path: "/_cat/health",
225
+ methods: ["GET"],
226
+ summary: "The cluster's health as a row."
227
+ },
228
+ {
229
+ path: "/_cat/nodes",
230
+ methods: ["GET"],
231
+ summary: "The nodes as a table: load, heap, roles."
232
+ },
233
+ {
234
+ path: "/_cat/shards",
235
+ methods: ["GET"],
236
+ summary: "Every shard as a row: index, state, node."
237
+ },
238
+ {
239
+ path: "/_cat/count",
240
+ methods: ["GET"],
241
+ summary: "The document count of the cluster, or of an index after it."
242
+ },
243
+ {
244
+ path: "/_cluster/health",
245
+ methods: ["GET"],
246
+ summary: "The cluster's health: status, nodes, shards."
247
+ },
248
+ {
249
+ path: "/_cluster/stats",
250
+ methods: ["GET"],
251
+ summary: "The cluster's statistics."
252
+ },
253
+ {
254
+ path: "/_cluster/settings",
255
+ methods: ["GET", "PUT"],
256
+ summary: "The cluster's settings; PUT changes `persistent` or `transient` ones."
257
+ },
258
+ {
259
+ path: "/_cluster/state",
260
+ methods: ["GET"],
261
+ summary: "The cluster's state whole."
262
+ },
263
+ {
264
+ path: "/_nodes",
265
+ methods: ["GET"],
266
+ summary: "The nodes and their settings."
267
+ },
268
+ {
269
+ path: "/_nodes/stats",
270
+ methods: ["GET"],
271
+ summary: "The nodes' statistics."
272
+ },
273
+ {
274
+ path: "/_tasks",
275
+ methods: ["GET"],
276
+ summary: "The tasks running on the cluster."
277
+ },
278
+ {
279
+ path: "/_index_template/{name}",
280
+ methods: [
281
+ "GET",
282
+ "PUT",
283
+ "DELETE",
284
+ "HEAD"
285
+ ],
286
+ summary: "An index template: patterns, settings, mappings for indices to come."
287
+ },
288
+ {
289
+ path: "/_index_template",
290
+ methods: ["GET"],
291
+ summary: "Every index template."
292
+ },
293
+ {
294
+ path: "/_component_template/{name}",
295
+ methods: [
296
+ "GET",
297
+ "PUT",
298
+ "DELETE"
299
+ ],
300
+ summary: "A component template for index templates to compose."
301
+ },
302
+ {
303
+ path: "/_ingest/pipeline/{id}",
304
+ methods: [
305
+ "GET",
306
+ "PUT",
307
+ "DELETE"
308
+ ],
309
+ summary: "An ingest pipeline: processors run on documents as they are indexed."
310
+ },
311
+ {
312
+ path: "/_ingest/pipeline",
313
+ methods: ["GET"],
314
+ summary: "Every ingest pipeline."
315
+ },
316
+ {
317
+ path: "/_scripts/{id}",
318
+ methods: [
319
+ "GET",
320
+ "PUT",
321
+ "DELETE"
322
+ ],
323
+ summary: "A stored script."
324
+ },
325
+ {
326
+ path: "/_data_stream/{name}",
327
+ methods: [
328
+ "GET",
329
+ "PUT",
330
+ "DELETE"
331
+ ],
332
+ summary: "A data stream."
333
+ },
334
+ {
335
+ path: "/_snapshot",
336
+ methods: ["GET"],
337
+ summary: "The snapshot repositories."
338
+ },
339
+ {
340
+ path: "/_license",
341
+ methods: ["GET"],
342
+ summary: "The licence the cluster runs under."
343
+ },
344
+ {
345
+ path: "/_xpack",
346
+ methods: ["GET"],
347
+ summary: "The features the build carries and which are enabled."
348
+ }
349
+ ];
350
+ function endpointOf(path) {
351
+ const [pathname] = path.split("?");
352
+ const segments = pathname.split("/").filter((segment) => segment !== "");
353
+ for (const endpoint of API_ENDPOINTS) {
354
+ const pattern = endpoint.path.split("/").filter((segment) => segment !== "");
355
+ if (pattern.length === segments.length && pattern.every((part, index) => part.startsWith("{") || part === segments[index])) return endpoint;
356
+ }
357
+ return null;
358
+ }
359
+ function bodyKindOf(method, path) {
360
+ const [pathname] = path.split("?");
361
+ const segments = pathname.split("/").filter((segment) => segment !== "");
362
+ const last = segments.at(-1) ?? "";
363
+ if (last === "_search" || last === "_msearch") return "search";
364
+ if (last === "_count" || last === "_delete_by_query") return "count";
365
+ if (last === "_update_by_query") return "update-by-query";
366
+ if (segments[1] === "_explain") return "explain";
367
+ if (last === "_mget") return "mget";
368
+ if (segments[1] === "_update") return "update";
369
+ if (segments[1] === "_doc" || segments[1] === "_create") return "document";
370
+ if (last === "_mapping") return "mapping";
371
+ if (last === "_settings" && segments.length === 2) return "settings";
372
+ const first = segments[0] ?? "";
373
+ if (first === "_reindex") return "reindex";
374
+ if (first === "_aliases") return "aliases";
375
+ if (last === "_analyze") return "analyze";
376
+ if (first === "_sql") return "sql";
377
+ if (first === "_cluster" && last === "settings") return "cluster-settings";
378
+ if (first === "_index_template" || first === "_component_template") return "template";
379
+ if (segments.length === 1 && !first.startsWith("_") && method === "PUT") return "index";
380
+ return "other";
381
+ }
382
+ const TOP_LEVEL = {
383
+ search: [
384
+ "query",
385
+ "aggs",
386
+ "size",
387
+ "from",
388
+ "sort",
389
+ "_source",
390
+ "track_total_hits",
391
+ "highlight",
392
+ "timeout",
393
+ "min_score",
394
+ "post_filter",
395
+ "collapse",
396
+ "search_after",
397
+ "pit",
398
+ "suggest",
399
+ "explain",
400
+ "profile",
401
+ "stored_fields",
402
+ "docvalue_fields",
403
+ "script_fields",
404
+ "runtime_mappings",
405
+ "knn",
406
+ "rescore",
407
+ "terminate_after",
408
+ "version",
409
+ "seq_no_primary_term",
410
+ "indices_boost",
411
+ "track_scores"
412
+ ],
413
+ count: ["query"],
414
+ index: [
415
+ "settings",
416
+ "mappings",
417
+ "aliases"
418
+ ],
419
+ mapping: [
420
+ "properties",
421
+ "dynamic",
422
+ "_source",
423
+ "_routing",
424
+ "_meta",
425
+ "dynamic_templates",
426
+ "runtime"
427
+ ],
428
+ settings: [
429
+ "index",
430
+ "number_of_replicas",
431
+ "refresh_interval",
432
+ "analysis"
433
+ ],
434
+ document: [],
435
+ update: [
436
+ "doc",
437
+ "script",
438
+ "upsert",
439
+ "doc_as_upsert",
440
+ "scripted_upsert",
441
+ "detect_noop",
442
+ "_source"
443
+ ],
444
+ "update-by-query": [
445
+ "query",
446
+ "script",
447
+ "conflicts",
448
+ "max_docs"
449
+ ],
450
+ reindex: [
451
+ "source",
452
+ "dest",
453
+ "conflicts",
454
+ "script",
455
+ "max_docs"
456
+ ],
457
+ aliases: ["actions"],
458
+ analyze: [
459
+ "analyzer",
460
+ "text",
461
+ "tokenizer",
462
+ "filter",
463
+ "char_filter",
464
+ "field",
465
+ "explain",
466
+ "normalizer"
467
+ ],
468
+ sql: [
469
+ "query",
470
+ "fetch_size",
471
+ "filter",
472
+ "params",
473
+ "field_multi_value_leniency",
474
+ "time_zone"
475
+ ],
476
+ "cluster-settings": ["persistent", "transient"],
477
+ template: [
478
+ "index_patterns",
479
+ "template",
480
+ "priority",
481
+ "composed_of",
482
+ "version",
483
+ "_meta",
484
+ "data_stream"
485
+ ],
486
+ explain: ["query"],
487
+ mget: ["docs", "ids"],
488
+ other: []
489
+ };
490
+ const QUERY_CLAUSES = [
491
+ "match",
492
+ "match_all",
493
+ "match_none",
494
+ "match_phrase",
495
+ "match_phrase_prefix",
496
+ "multi_match",
497
+ "term",
498
+ "terms",
499
+ "terms_set",
500
+ "range",
501
+ "exists",
502
+ "prefix",
503
+ "wildcard",
504
+ "regexp",
505
+ "fuzzy",
506
+ "ids",
507
+ "bool",
508
+ "boosting",
509
+ "constant_score",
510
+ "dis_max",
511
+ "function_score",
512
+ "nested",
513
+ "has_child",
514
+ "has_parent",
515
+ "parent_id",
516
+ "query_string",
517
+ "simple_query_string",
518
+ "combined_fields",
519
+ "intervals",
520
+ "span_near",
521
+ "span_term",
522
+ "geo_distance",
523
+ "geo_bounding_box",
524
+ "geo_shape",
525
+ "script",
526
+ "script_score",
527
+ "knn",
528
+ "semantic",
529
+ "sparse_vector",
530
+ "text_expansion",
531
+ "percolate",
532
+ "more_like_this",
533
+ "rank_feature",
534
+ "distance_feature",
535
+ "pinned",
536
+ "wrapper"
537
+ ];
538
+ const BOOL_KEYS = [
539
+ "must",
540
+ "should",
541
+ "must_not",
542
+ "filter",
543
+ "minimum_should_match",
544
+ "boost",
545
+ "_name"
546
+ ];
547
+ const AGG_TYPES = [
548
+ "terms",
549
+ "avg",
550
+ "sum",
551
+ "min",
552
+ "max",
553
+ "cardinality",
554
+ "value_count",
555
+ "stats",
556
+ "extended_stats",
557
+ "percentiles",
558
+ "percentile_ranks",
559
+ "date_histogram",
560
+ "histogram",
561
+ "range",
562
+ "date_range",
563
+ "ip_range",
564
+ "filter",
565
+ "filters",
566
+ "nested",
567
+ "reverse_nested",
568
+ "top_hits",
569
+ "composite",
570
+ "missing",
571
+ "significant_terms",
572
+ "significant_text",
573
+ "rare_terms",
574
+ "multi_terms",
575
+ "auto_date_histogram",
576
+ "variable_width_histogram",
577
+ "geo_distance",
578
+ "geohash_grid",
579
+ "geotile_grid",
580
+ "global",
581
+ "sampler",
582
+ "diversified_sampler",
583
+ "scripted_metric",
584
+ "bucket_sort",
585
+ "bucket_selector",
586
+ "bucket_script",
587
+ "cumulative_sum",
588
+ "derivative",
589
+ "moving_fn",
590
+ "serial_diff",
591
+ "sum_bucket",
592
+ "avg_bucket",
593
+ "min_bucket",
594
+ "max_bucket",
595
+ "stats_bucket",
596
+ "aggs",
597
+ "meta"
598
+ ];
599
+ const FIELD_KEYS = [
600
+ "type",
601
+ "properties",
602
+ "fields",
603
+ "analyzer",
604
+ "search_analyzer",
605
+ "format",
606
+ "index",
607
+ "doc_values",
608
+ "store",
609
+ "ignore_above",
610
+ "null_value",
611
+ "copy_to",
612
+ "dynamic",
613
+ "enabled",
614
+ "normalizer",
615
+ "coerce",
616
+ "ignore_malformed",
617
+ "boost",
618
+ "similarity",
619
+ "term_vector",
620
+ "norms",
621
+ "index_options",
622
+ "eager_global_ordinals",
623
+ "meta",
624
+ "dims",
625
+ "element_type",
626
+ "index_options"
627
+ ];
628
+ const CLAUSE_KEYS = {
629
+ bool: BOOL_KEYS,
630
+ multi_match: [
631
+ "query",
632
+ "fields",
633
+ "type",
634
+ "operator",
635
+ "fuzziness",
636
+ "tie_breaker",
637
+ "minimum_should_match",
638
+ "analyzer",
639
+ "boost"
640
+ ],
641
+ query_string: [
642
+ "query",
643
+ "default_field",
644
+ "fields",
645
+ "default_operator",
646
+ "analyze_wildcard",
647
+ "fuzziness",
648
+ "lenient",
649
+ "boost"
650
+ ],
651
+ simple_query_string: [
652
+ "query",
653
+ "fields",
654
+ "default_operator",
655
+ "analyzer",
656
+ "flags",
657
+ "fuzzy_max_expansions",
658
+ "lenient"
659
+ ],
660
+ combined_fields: [
661
+ "query",
662
+ "fields",
663
+ "operator",
664
+ "minimum_should_match",
665
+ "zero_terms_query"
666
+ ],
667
+ exists: ["field"],
668
+ ids: ["values"],
669
+ nested: [
670
+ "path",
671
+ "query",
672
+ "score_mode",
673
+ "ignore_unmapped",
674
+ "inner_hits"
675
+ ],
676
+ has_child: [
677
+ "type",
678
+ "query",
679
+ "score_mode",
680
+ "min_children",
681
+ "max_children",
682
+ "inner_hits"
683
+ ],
684
+ has_parent: [
685
+ "parent_type",
686
+ "query",
687
+ "score",
688
+ "inner_hits"
689
+ ],
690
+ boosting: [
691
+ "positive",
692
+ "negative",
693
+ "negative_boost"
694
+ ],
695
+ constant_score: ["filter", "boost"],
696
+ dis_max: ["queries", "tie_breaker"],
697
+ function_score: [
698
+ "query",
699
+ "functions",
700
+ "score_mode",
701
+ "boost_mode",
702
+ "max_boost",
703
+ "min_score",
704
+ "boost",
705
+ "field_value_factor",
706
+ "random_score",
707
+ "script_score",
708
+ "weight"
709
+ ],
710
+ script: ["script"],
711
+ script_score: [
712
+ "query",
713
+ "script",
714
+ "min_score"
715
+ ],
716
+ knn: [
717
+ "field",
718
+ "query_vector",
719
+ "k",
720
+ "num_candidates",
721
+ "filter",
722
+ "similarity",
723
+ "boost"
724
+ ],
725
+ more_like_this: [
726
+ "fields",
727
+ "like",
728
+ "unlike",
729
+ "min_term_freq",
730
+ "max_query_terms",
731
+ "min_doc_freq"
732
+ ],
733
+ pinned: [
734
+ "ids",
735
+ "docs",
736
+ "organic"
737
+ ],
738
+ match_all: ["boost"],
739
+ match_none: [],
740
+ geo_distance: [
741
+ "distance",
742
+ "distance_type",
743
+ "validation_method"
744
+ ],
745
+ span_near: [
746
+ "clauses",
747
+ "slop",
748
+ "in_order"
749
+ ],
750
+ percolate: [
751
+ "field",
752
+ "document",
753
+ "documents",
754
+ "index",
755
+ "id"
756
+ ],
757
+ wrapper: ["query"],
758
+ intervals: []
759
+ };
760
+ const FIELD_CLAUSE_OPTIONS = {
761
+ match: [
762
+ "query",
763
+ "operator",
764
+ "fuzziness",
765
+ "analyzer",
766
+ "minimum_should_match",
767
+ "boost",
768
+ "prefix_length",
769
+ "max_expansions",
770
+ "zero_terms_query",
771
+ "lenient"
772
+ ],
773
+ match_phrase: [
774
+ "query",
775
+ "analyzer",
776
+ "slop",
777
+ "zero_terms_query",
778
+ "boost"
779
+ ],
780
+ match_phrase_prefix: [
781
+ "query",
782
+ "analyzer",
783
+ "slop",
784
+ "max_expansions",
785
+ "zero_terms_query",
786
+ "boost"
787
+ ],
788
+ term: [
789
+ "value",
790
+ "boost",
791
+ "case_insensitive"
792
+ ],
793
+ terms: ["boost"],
794
+ terms_set: [
795
+ "terms",
796
+ "minimum_should_match_field",
797
+ "minimum_should_match_script",
798
+ "boost"
799
+ ],
800
+ range: [
801
+ "gte",
802
+ "gt",
803
+ "lte",
804
+ "lt",
805
+ "format",
806
+ "time_zone",
807
+ "relation",
808
+ "boost"
809
+ ],
810
+ prefix: [
811
+ "value",
812
+ "boost",
813
+ "rewrite",
814
+ "case_insensitive"
815
+ ],
816
+ wildcard: [
817
+ "value",
818
+ "boost",
819
+ "rewrite",
820
+ "case_insensitive"
821
+ ],
822
+ regexp: [
823
+ "value",
824
+ "flags",
825
+ "max_determinized_states",
826
+ "rewrite",
827
+ "case_insensitive",
828
+ "boost"
829
+ ],
830
+ fuzzy: [
831
+ "value",
832
+ "fuzziness",
833
+ "max_expansions",
834
+ "prefix_length",
835
+ "transpositions",
836
+ "rewrite",
837
+ "boost"
838
+ ],
839
+ rank_feature: [
840
+ "saturation",
841
+ "log",
842
+ "sigmoid",
843
+ "linear",
844
+ "boost"
845
+ ],
846
+ distance_feature: [
847
+ "origin",
848
+ "pivot",
849
+ "boost"
850
+ ],
851
+ span_term: ["value", "boost"],
852
+ sparse_vector: [
853
+ "inference_id",
854
+ "query",
855
+ "query_vector",
856
+ "prune"
857
+ ],
858
+ semantic: ["query", "boost"],
859
+ text_expansion: [
860
+ "model_id",
861
+ "model_text",
862
+ "pruning_config"
863
+ ]
864
+ };
865
+ const QUERY_HOLDERS = /* @__PURE__ */ new Set([
866
+ "query",
867
+ "must",
868
+ "should",
869
+ "must_not",
870
+ "filter",
871
+ "post_filter",
872
+ "positive",
873
+ "negative",
874
+ "queries",
875
+ "organic",
876
+ "rescore_query",
877
+ "clauses"
878
+ ]);
879
+ function keysUnder(last, kind) {
880
+ if (QUERY_HOLDERS.has(last)) return QUERY_CLAUSES;
881
+ if (last === "aggs" || last === "aggregations" || last === "properties") return [];
882
+ switch (last) {
883
+ case "highlight": return [
884
+ "fields",
885
+ "pre_tags",
886
+ "post_tags",
887
+ "fragment_size",
888
+ "number_of_fragments",
889
+ "type",
890
+ "require_field_match",
891
+ "order",
892
+ "encoder"
893
+ ];
894
+ case "_source": return ["includes", "excludes"];
895
+ case "collapse": return [
896
+ "field",
897
+ "inner_hits",
898
+ "max_concurrent_group_searches"
899
+ ];
900
+ case "inner_hits": return [
901
+ "name",
902
+ "size",
903
+ "from",
904
+ "sort",
905
+ "_source",
906
+ "highlight"
907
+ ];
908
+ case "mappings": return TOP_LEVEL.mapping;
909
+ case "settings": return TOP_LEVEL.settings;
910
+ case "analysis": return [
911
+ "analyzer",
912
+ "tokenizer",
913
+ "filter",
914
+ "char_filter",
915
+ "normalizer"
916
+ ];
917
+ case "template": return [
918
+ "settings",
919
+ "mappings",
920
+ "aliases",
921
+ "lifecycle"
922
+ ];
923
+ case "script": return [
924
+ "source",
925
+ "id",
926
+ "lang",
927
+ "params"
928
+ ];
929
+ case "sort": return ["_score", "_doc"];
930
+ case "source": return kind === "reindex" ? [
931
+ "index",
932
+ "query",
933
+ "size",
934
+ "_source",
935
+ "remote",
936
+ "slice"
937
+ ] : null;
938
+ case "dest": return kind === "reindex" ? [
939
+ "index",
940
+ "op_type",
941
+ "pipeline",
942
+ "routing",
943
+ "version_type"
944
+ ] : null;
945
+ default: return CLAUSE_KEYS[last] ?? null;
946
+ }
947
+ }
948
+ function bodyKeys(kind, path) {
949
+ const last = path.at(-1);
950
+ if (last === void 0) return TOP_LEVEL[kind];
951
+ const under = keysUnder(last, kind);
952
+ if (under !== null) return under;
953
+ const parent = path.at(-2);
954
+ if (parent === "aggs" || parent === "aggregations") return AGG_TYPES;
955
+ if (parent === "properties") return FIELD_KEYS;
956
+ if (last === "index" && parent === "settings") return [
957
+ "number_of_shards",
958
+ "number_of_replicas",
959
+ "refresh_interval",
960
+ "analysis",
961
+ "max_result_window",
962
+ "codec",
963
+ "lifecycle",
964
+ "routing"
965
+ ];
966
+ return (parent === void 0 ? void 0 : FIELD_CLAUSE_OPTIONS[parent]) ?? [];
967
+ }
968
+ //#endregion
969
+ //#region src/request.ts
970
+ const REQUEST_METHODS = [
971
+ "GET",
972
+ "POST",
973
+ "PUT",
974
+ "DELETE",
975
+ "HEAD",
976
+ "PATCH"
977
+ ];
978
+ const METHOD_SET = new Set(REQUEST_METHODS);
979
+ function takesLines(path) {
980
+ return path.includes("/_bulk") || path.includes("/_msearch");
981
+ }
982
+ function readRequest(text) {
983
+ const start = text.length - text.trimStart().length;
984
+ const end = text.trimEnd().length;
985
+ if (start >= end) return {
986
+ method: "",
987
+ path: "",
988
+ body: "",
989
+ bodyKind: "none",
990
+ line: {
991
+ from: start,
992
+ to: start
993
+ },
994
+ bodySpan: null,
995
+ refusal: "empty"
996
+ };
997
+ const stripped = text.slice(start, end);
998
+ const lineBreak = stripped.indexOf("\n");
999
+ const lineText = (lineBreak === -1 ? stripped : stripped.slice(0, lineBreak)).trimEnd();
1000
+ const line = {
1001
+ from: start,
1002
+ to: start + lineText.length
1003
+ };
1004
+ const rest = lineBreak === -1 ? "" : stripped.slice(lineBreak + 1);
1005
+ const bodyStart = rest.length - rest.trimStart().length;
1006
+ const body = rest.trim();
1007
+ const bodySpan = body === "" ? null : {
1008
+ from: start + lineBreak + 1 + bodyStart,
1009
+ to: start + lineBreak + 1 + bodyStart + body.length
1010
+ };
1011
+ const blank = lineText.search(/\s/u);
1012
+ const method = (blank === -1 ? lineText : lineText.slice(0, blank)).toUpperCase();
1013
+ const path = blank === -1 ? "" : lineText.slice(blank).trim();
1014
+ const bodyKind = body === "" ? "none" : takesLines(path) ? "ndjson" : "json";
1015
+ let refusal = null;
1016
+ if (path === "") refusal = "no-request-line";
1017
+ else if (!METHOD_SET.has(method)) refusal = "unknown-method";
1018
+ else if (!path.startsWith("/")) refusal = "path-without-slash";
1019
+ return {
1020
+ method,
1021
+ path,
1022
+ body,
1023
+ bodyKind,
1024
+ line,
1025
+ bodySpan,
1026
+ refusal
1027
+ };
1028
+ }
1029
+ const REQUEST_LINE = /^\s*[a-z]+\s+\S/iu;
1030
+ function requestStarts(text) {
1031
+ const starts = [];
1032
+ let lineStart = 0;
1033
+ for (const line of text.split("\n")) {
1034
+ if (REQUEST_LINE.test(line)) starts.push(lineStart);
1035
+ lineStart += line.length + 1;
1036
+ }
1037
+ return starts;
1038
+ }
1039
+ function requestSpans(text) {
1040
+ const starts = requestStarts(text);
1041
+ if (starts.length === 0) return [trimmed(text, 0, text.length)];
1042
+ return starts.map((start, index) => trimmed(text, start, starts[index + 1] ?? text.length));
1043
+ }
1044
+ function requestAt(text, offset) {
1045
+ const spans = requestSpans(text);
1046
+ const lineStart = text.lastIndexOf("\n", offset - 1) + 1;
1047
+ return spans.findLast((span) => span.from <= lineStart) ?? spans[0];
1048
+ }
1049
+ function runnableRequest(text, from, to) {
1050
+ const span = from < to ? trimmed(text, from, to) : requestAt(text, from);
1051
+ return span.from >= span.to ? { kind: "none" } : {
1052
+ kind: "one",
1053
+ text: text.slice(span.from, span.to),
1054
+ ...span
1055
+ };
1056
+ }
1057
+ function trimmed(text, from, to) {
1058
+ const span = text.slice(from, to);
1059
+ return {
1060
+ from: from + (span.length - span.trimStart().length),
1061
+ to: to - (span.length - span.trimEnd().length)
1062
+ };
1063
+ }
1064
+ function caretContext(text, offset) {
1065
+ const span = requestAt(text, offset);
1066
+ const request = readRequest(text.slice(span.from, span.to));
1067
+ const lineFrom = span.from + request.line.from;
1068
+ const lineTo = span.from + request.line.to;
1069
+ if (offset >= lineFrom && offset <= lineTo) {
1070
+ const before = text.slice(lineFrom, offset);
1071
+ const blank = before.search(/\s/u);
1072
+ if (blank === -1) return {
1073
+ kind: "method",
1074
+ typed: before
1075
+ };
1076
+ const pathTyped = before.slice(blank).trimStart();
1077
+ if (!pathTyped.startsWith("/") || pathTyped.includes("?") || /\s/u.test(pathTyped)) return { kind: "none" };
1078
+ const segments = pathTyped.slice(1).split("/");
1079
+ return {
1080
+ kind: "path",
1081
+ segments: segments.slice(0, -1),
1082
+ typed: segments.at(-1)
1083
+ };
1084
+ }
1085
+ if (request.refusal !== null) return { kind: "none" };
1086
+ if (request.bodySpan === null || offset < request.bodySpan.from + span.from) return offset > lineTo ? {
1087
+ kind: "body-key",
1088
+ path: [],
1089
+ request,
1090
+ typed: "",
1091
+ quoted: false
1092
+ } : { kind: "none" };
1093
+ const bodyFrom = span.from + request.bodySpan.from;
1094
+ const position = keyPosition(text.slice(bodyFrom, offset));
1095
+ return position === null ? { kind: "none" } : {
1096
+ kind: "body-key",
1097
+ request,
1098
+ ...position
1099
+ };
1100
+ }
1101
+ function structure(frames, character, pending) {
1102
+ const top = frames.at(-1);
1103
+ if (character === "}" || character === "]") {
1104
+ frames.pop();
1105
+ return;
1106
+ }
1107
+ switch (character) {
1108
+ case "{":
1109
+ frames.push({
1110
+ array: false,
1111
+ key: null,
1112
+ expectingKey: true
1113
+ });
1114
+ break;
1115
+ case "[":
1116
+ frames.push({
1117
+ array: true,
1118
+ key: null,
1119
+ expectingKey: false
1120
+ });
1121
+ break;
1122
+ case ":":
1123
+ if (top !== void 0 && !top.array) {
1124
+ top.key = pending;
1125
+ top.expectingKey = false;
1126
+ }
1127
+ break;
1128
+ case ",": if (top !== void 0 && !top.array) {
1129
+ top.key = null;
1130
+ top.expectingKey = true;
1131
+ }
1132
+ }
1133
+ }
1134
+ function atKey(frames) {
1135
+ const top = frames.at(-1);
1136
+ return top !== void 0 && !top.array && top.expectingKey;
1137
+ }
1138
+ function keyPosition(body) {
1139
+ const frames = [];
1140
+ let i = 0;
1141
+ let pending = "";
1142
+ while (i < body.length) {
1143
+ const c = body[i];
1144
+ if (c === "\"") {
1145
+ const end = closingQuote(body, i + 1);
1146
+ if (end === -1) return atKey(frames) ? {
1147
+ path: pathOf(frames),
1148
+ typed: body.slice(i + 1),
1149
+ quoted: true
1150
+ } : null;
1151
+ pending = body.slice(i + 1, end);
1152
+ i = end + 1;
1153
+ continue;
1154
+ }
1155
+ structure(frames, c, pending);
1156
+ i++;
1157
+ }
1158
+ return atKey(frames) ? {
1159
+ path: pathOf(frames),
1160
+ typed: "",
1161
+ quoted: false
1162
+ } : null;
1163
+ }
1164
+ function closingQuote(body, from) {
1165
+ let i = from;
1166
+ while (i < body.length) {
1167
+ if (body[i] === "\\") {
1168
+ i += 2;
1169
+ continue;
1170
+ }
1171
+ if (body[i] === "\"") return i;
1172
+ i++;
1173
+ }
1174
+ return -1;
1175
+ }
1176
+ function pathOf(frames) {
1177
+ const path = [];
1178
+ const enclosing = frames.slice(0, -1);
1179
+ for (const frame of enclosing) if (!frame.array && frame.key !== null) path.push(frame.key);
1180
+ return path;
1181
+ }
1182
+ //#endregion
1183
+ //#region src/markers.ts
1184
+ function isJson(text) {
1185
+ try {
1186
+ JSON.parse(text);
1187
+ return true;
1188
+ } catch {
1189
+ return false;
1190
+ }
1191
+ }
1192
+ function requestMarkers(text) {
1193
+ const markers = [];
1194
+ for (const span of requestSpans(text)) {
1195
+ const request = readRequest(text.slice(span.from, span.to));
1196
+ if (request.refusal === "empty") continue;
1197
+ const lineFrom = span.from + request.line.from;
1198
+ const lineTo = span.from + request.line.to;
1199
+ if (request.refusal !== null) {
1200
+ markers.push({
1201
+ from: lineFrom,
1202
+ to: lineTo,
1203
+ code: request.refusal,
1204
+ severity: "error"
1205
+ });
1206
+ continue;
1207
+ }
1208
+ const endpoint = endpointOf(request.path);
1209
+ if (endpoint !== null && !endpoint.methods.includes(request.method)) markers.push({
1210
+ from: lineFrom,
1211
+ to: lineFrom + request.method.length,
1212
+ code: "method-not-taken",
1213
+ severity: "hint"
1214
+ });
1215
+ if (request.bodySpan === null) continue;
1216
+ const bodyFrom = span.from + request.bodySpan.from;
1217
+ if (request.bodyKind === "json") {
1218
+ if (!isJson(request.body)) markers.push({
1219
+ from: bodyFrom,
1220
+ to: span.from + request.bodySpan.to,
1221
+ code: "body-not-json",
1222
+ severity: "warning"
1223
+ });
1224
+ continue;
1225
+ }
1226
+ let at = bodyFrom;
1227
+ for (const raw of request.body.split("\n")) {
1228
+ const line = raw.endsWith("\r") ? raw.slice(0, -1) : raw;
1229
+ if (line.trim() !== "" && !isJson(line)) markers.push({
1230
+ from: at,
1231
+ to: at + line.length,
1232
+ code: "body-not-json",
1233
+ severity: "warning"
1234
+ });
1235
+ at += raw.length + 1;
1236
+ }
1237
+ }
1238
+ return markers;
1239
+ }
1240
+ //#endregion
1241
+ export { requestAt as a, takesLines as c, bodyKindOf as d, endpointOf as f, readRequest as i, API_ENDPOINTS as l, REQUEST_METHODS as n, requestSpans as o, caretContext as r, runnableRequest as s, requestMarkers as t, bodyKeys as u };