@biblioteksentralen/bmdb-search 0.0.0-beta.2 → 0.0.0-beta.4

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/README.md CHANGED
@@ -1,25 +1,32 @@
1
1
  # @biblioteksentralen/bmdb-search
2
2
 
3
- TypeScript client for searching Bibliotekenes metadatabrønn (BMDB).
3
+ TypeScript client for searching Bibliotekenes metadatabrønn (BMDB) using [openapi-fetch](https://openapi-ts.dev/openapi-fetch/).
4
4
 
5
- ## Setup
5
+ ## Options
6
+
7
+ ### Client identification policy
8
+
9
+ The API does not require authentication, but clients should identify themselves using a descriptive
10
+ name and a contact address in the `clientIdentifier` string. We will only contact you about usage of the API.
6
11
 
7
- ### Server context
12
+ ## Usage examples
8
13
 
9
- When used in a non-browser context, the `baseUrl` can be supplied directly, e.g.
14
+ ### Search works
10
15
 
11
16
  ```typescript
12
- import { createBmdbSearchClient } from "@biblioteksentralen/bmdb-search";
17
+ import { createBmdbFetchClient } from "@biblioteksentralen/bmdb-search";
13
18
 
14
- const bmdbSearchClient = createBmdbSearchClient({
15
- clientIdentifier: "client-unique-description",
16
- baseUrl: "https://search.data.bs.no",
17
- });
19
+ const bmdbSearchClient = createBmdbFetchClient({ clientIdentifier: "client-unique-description" });
20
+ const { data, error } = await bmdbSearchClient.GET("/works/search", { params: { query: { query: "test" } } });
18
21
  ```
19
22
 
20
- ### Browser context
23
+ The arguments and response are fully typed.
24
+
25
+ ### Usage with tanstack-query, openapi-react-query and next.js
26
+
27
+ Using [tanstack](https://tanstack.com/query/latest) for fetching with state management and [openapi-react-query](https://openapi-ts.dev/openapi-react-query/) for typing.
21
28
 
22
- In browsers, a content security policy typically has to be taken into account. One approach is to use URL rewrites. If for example using Next.js, this can be achieved using the config file:
29
+ Add a rewrite in the next.js config file to be able to use the frontend host without violating the content service policy:
23
30
 
24
31
  ```typescript
25
32
  // next.config.js or similar
@@ -36,14 +43,9 @@ const config = {
36
43
  ];
37
44
  },
38
45
  };
39
-
40
- // File utilizing search client
41
- import { createBmdbSearchClient } from "@biblioteksentralen/bmdb-search";
42
-
43
- const bmdbSearchClient = createBmdbSearchClient({ clientIdentifier: "client-unique-description" });
44
46
  ```
45
47
 
46
- For Next.js it might also have to be exempt from handling in middleware (e.g. internationalization):
48
+ If necessary, skip in middleware to exempt the API paths from internationalization etc:
47
49
 
48
50
  ```typescript
49
51
  // middleware.ts
@@ -55,41 +57,20 @@ export const config = {
55
57
  };
56
58
  ```
57
59
 
58
- ## Usage examples
59
-
60
- ### Search works using client
61
-
62
- Uses [openapi-fetch](https://openapi-ts.dev/openapi-fetch/) to generate a typed search client.
60
+ Create hooks and fetch data:
63
61
 
64
62
  ```typescript
65
- import { createBmdbSearchClient } from "@biblioteksentralen/bmdb-search";
63
+ import { createBmdbFetchClient } from "@biblioteksentralen/bmdb-search";
64
+ import createReactQueryClient from "openapi-react-query";
66
65
 
67
- const bmdbSearchClient = createBmdbSearchClient({ clientIdentifier: "client-unique-description" });
68
- const { data, error } = await bmdbSearchClient.GET("/works/search", { query: { query: "test" } });
69
- ```
66
+ const bmdbSearchClient = createBmdbFetchClient({ clientIdentifier: "client-unique-description" });
67
+ const { useQuery } = createReactQueryClient(bmdbSearchClient);
70
68
 
71
- The arguments and response are fully typed.
72
-
73
- ### Search works using react hooks
74
-
75
- Uses [tanstack](https://tanstack.com/query/latest) for fetch management and [openapi-react-query](https://openapi-ts.dev/openapi-react-query/) for typing.
76
-
77
- ```typescript
78
- import { createBmdbSearchHooks } from "@biblioteksentralen/bmdb-search";
79
-
80
- const { useQuery, useInfiniteQuery, useSuspenseQuery, queryOptions } = createBmdbSearchHooks({
81
- clientIdentifier: "client-unique-description",
82
- });
83
-
84
- const Component = (props) => {
85
- const { data, error, isLoading } = useQuery("/works/search", { query: { query: "test" } });
86
- return <div>Hello</div>
69
+ const Component = () => {
70
+ const { data, error, isLoading } = useQuery("get", "/works/search", { params: { query: { query: "test" } } });
71
+ if (isLoading) return <div>Loading</div>;
72
+ if (error) return <div>Something went wrong</div>;
73
+ return <div>Found {data?.total} works</div>;
87
74
  };
88
- ```
89
75
 
90
- ## Options
91
-
92
- ### Client identification policy
93
-
94
- The API does not require authentication, but clients should identify themselves using a descriptive
95
- name and a contact address in the `clientIdentifier` string. We will only contact you about usage of the API.
76
+ ```
package/dist/index.cjs CHANGED
@@ -1,21 +1,23 @@
1
1
  'use strict';
2
2
 
3
3
  var createFetchClient = require('openapi-fetch');
4
- var createReactQueryClient = require('openapi-react-query');
5
4
 
6
5
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
7
6
 
8
7
  var createFetchClient__default = /*#__PURE__*/_interopDefault(createFetchClient);
9
- var createReactQueryClient__default = /*#__PURE__*/_interopDefault(createReactQueryClient);
10
8
 
11
9
  // src/client.ts
12
- var createBmdbSearchClient = ({
10
+ var createBmdbFetchClient = ({
13
11
  clientIdentifier,
14
- version = "v2",
12
+ version = "v1",
15
13
  ...options
16
14
  }) => {
17
15
  const baseUrl = `${options.baseUrl?.replace(/(.*)\/$/, "$1") ?? ""}/bmdb/api/${version}/`;
18
- const client = createFetchClient__default.default({ ...options, baseUrl });
16
+ const client = createFetchClient__default.default({
17
+ baseUrl,
18
+ querySerializer: { array: { style: "form", explode: false } },
19
+ ...options
20
+ });
19
21
  client.use({
20
22
  onRequest({ request }) {
21
23
  request.headers.set("client-identifier", clientIdentifier);
@@ -24,7 +26,5 @@ var createBmdbSearchClient = ({
24
26
  });
25
27
  return client;
26
28
  };
27
- var createBmdbSearchHooks = (args) => createReactQueryClient__default.default("searchClient" in args ? args.searchClient : createBmdbSearchClient(args));
28
29
 
29
- exports.createBmdbSearchClient = createBmdbSearchClient;
30
- exports.createBmdbSearchHooks = createBmdbSearchHooks;
30
+ exports.createBmdbFetchClient = createBmdbFetchClient;
package/dist/index.d.cts CHANGED
@@ -1,5 +1,4 @@
1
1
  import { ClientOptions, Client } from 'openapi-fetch';
2
- import { OpenapiQueryClient } from 'openapi-react-query';
3
2
 
4
3
  /**
5
4
  * This file was auto-generated by openapi-typescript.
@@ -30,24 +29,84 @@ interface paths {
30
29
  }
31
30
  interface components {
32
31
  schemas: {
33
- /** @enum {string} */
34
- SearchFacetTypeEnumV2: "work_type" | "expression_type" | "manifestation_medium" | "work_origin" | "origin" | "creator" | "collection" | "subject";
35
- /** @enum {string} */
36
- SearchSortingTypeEnumV2: "relevance.desc" | "updateTime.desc";
37
- WorkFilterSchema: {
38
- identifier?: string[];
39
- work_id?: string[];
40
- expression_id?: string[];
41
- manifestation_id?: string[];
42
- work_type?: string[];
43
- expression_type?: string[];
44
- manifestation_medium?: string[];
45
- work_origin?: string[];
46
- origin?: string[];
47
- title?: string[];
48
- creator?: string[];
49
- collection?: string[];
50
- subject?: string[];
32
+ /**
33
+ * @description Facet type, this is the value given to the search facet parameter. The facet should always exists in as a corresponding filter.
34
+ *
35
+ * @enum {string}
36
+ */
37
+ WorkFacetType: "work_type" | "expression_type" | "manifestation_medium" | "creator" | "collection" | "subject" | "original_language" | "genre" | "age_limit" | "age_group" | "grep_subject" | "kulturfond" | "fiction";
38
+ /**
39
+ * @description Sorting type, this is the value given to the search facet parameter.
40
+ *
41
+ * @enum {string}
42
+ */
43
+ WorkSort: "relevance.desc" | "updateTime.desc" | "updateTime.asc" | "publicationDate.desc" | "publicationDate.asc" | "firstPublicationDate.desc" | "firstPublicationDate.asc";
44
+ WorkFilter: {
45
+ identifier?: string;
46
+ work_id?: string;
47
+ expression_id?: string;
48
+ manifestation_id?: string;
49
+ work_type?: string;
50
+ expression_type?: string;
51
+ manifestation_medium?: string;
52
+ title?: string;
53
+ creator?: string;
54
+ collection?: string;
55
+ subject?: string;
56
+ kulturfond?: boolean;
57
+ original_language?: string;
58
+ genre?: string;
59
+ age_limit?: string;
60
+ age_group?: string;
61
+ grep_subject?: string;
62
+ fiction?: boolean;
63
+ abridger?: string;
64
+ actor?: string;
65
+ antecedent?: string;
66
+ arranger?: string;
67
+ artist?: string;
68
+ author?: string;
69
+ book_designer?: string;
70
+ colorist?: string;
71
+ commentary_writer?: string;
72
+ commenter?: string;
73
+ compilation_editor?: string;
74
+ compiler?: string;
75
+ composer?: string;
76
+ conceptor?: string;
77
+ conductor?: string;
78
+ consultant?: string;
79
+ contributor?: string;
80
+ copyright_holder?: string;
81
+ cover_designer?: string;
82
+ curator?: string;
83
+ degree_granting_institution?: string;
84
+ designer?: string;
85
+ director?: string;
86
+ editor?: string;
87
+ enacting_jurisdiction?: string;
88
+ game_developer?: string;
89
+ honoree?: string;
90
+ illustrator?: string;
91
+ instrumentalist?: string;
92
+ interviewee?: string;
93
+ interviewer?: string;
94
+ issuing_body?: string;
95
+ lead?: string;
96
+ librettist?: string;
97
+ lyricist?: string;
98
+ musician?: string;
99
+ narrator?: string;
100
+ other?: string;
101
+ performer?: string;
102
+ photographer?: string;
103
+ project_director?: string;
104
+ publisher?: string;
105
+ reteller?: string;
106
+ screenwriter?: string;
107
+ singer?: string;
108
+ translator?: string;
109
+ voice_actor?: string;
51
110
  };
52
111
  /** @enum {string} */
53
112
  LanguageCode: "abk" | "ach" | "afr" | "akk" | "alb" | "amh" | "ang" | "ara" | "arc" | "arm" | "aze" | "bam" | "baq" | "bel" | "bem" | "ben" | "bis" | "bnt" | "bos" | "bre" | "bul" | "bur" | "byn" | "cat" | "ceb" | "che" | "chi" | "chu" | "cic" | "ckb" | "cmn" | "cnr" | "cop" | "cze" | "dan" | "dut" | "egy" | "eng" | "enm" | "epo" | "est" | "ewe" | "fao" | "fat" | "fij" | "fin" | "fiu" | "fkv" | "fre" | "frm" | "fro" | "fry" | "ful" | "gaa" | "geo" | "ger" | "gez" | "gla" | "gle" | "glg" | "gmh" | "got" | "grc" | "gre" | "guj" | "hau" | "heb" | "hil" | "hin" | "hrv" | "hun" | "ibo" | "ice" | "iku" | "ilo" | "ind" | "ipk" | "ira" | "ita" | "jpn" | "kal" | "kan" | "kaz" | "khm" | "kho" | "kik" | "kin" | "kmr" | "kon" | "kor" | "kua" | "kur" | "lao" | "lat" | "lav" | "lin" | "lit" | "lkt" | "lug" | "mac" | "mao" | "mar" | "may" | "mlg" | "mlt" | "mnk" | "mol" | "mon" | "mul" | "myn" | "nds" | "nep" | "nic" | "nno" | "nob" | "nom" | "non" | "nor" | "nso" | "oci" | "orm" | "pan" | "per" | "pli" | "pol" | "por" | "pra" | "pro" | "prs" | "pus" | "roh" | "rom" | "rum" | "run" | "rus" | "sah" | "san" | "sat" | "sco" | "sgn" | "sin" | "sit" | "sjd" | "sje" | "sjk" | "sjt" | "sju" | "slo" | "slv" | "sma" | "sme" | "smi" | "smj" | "smn" | "smo" | "sms" | "som" | "sot" | "spa" | "srp" | "sux" | "swa" | "swe" | "syr" | "tam" | "tay" | "tel" | "tgl" | "tha" | "tib" | "tir" | "tkl" | "tmh" | "ton" | "tur" | "ukr" | "urd" | "uzb" | "vie" | "wel" | "wen" | "wol" | "xho" | "yid" | "yor" | "ypk" | "yue" | "zul" | "und" | "zxx";
@@ -334,7 +393,6 @@ interface components {
334
393
  name: components["schemas"]["LanguageMap"];
335
394
  /** @description The qualifier is used to anchor the subject to a specific category in the Dewey hierarchy when the focus term is a phenomenon which appears in more than one place in the hierarchy, e.g. "Kjærlighet : psykologi" */
336
395
  qualifier?: components["schemas"]["LanguageMap"];
337
- specification?: components["schemas"]["LanguageMap"];
338
396
  /** @description Internal note on the entity, e.g. field of use. */
339
397
  scopeNote?: string;
340
398
  /** @description {@link https://deweyno.pansoft.de Norsk WebDewey } classification number. */
@@ -638,72 +696,12 @@ interface components {
638
696
  /** @description URI for the corresponding concept in National Library's [Vocabulary of target groups (nortarget)](https://www.nb.no/nbvok/tg/nb/). */
639
697
  nortargetUri: string;
640
698
  };
641
- /** @enum {string} */
642
- LibrarySystem: "bibliofil" | "cicero" | "quria" | "mikromarc";
643
- Origin: {
644
- id: string;
645
- /** @constant */
646
- name: "promus";
647
- } | {
648
- id: string;
649
- /** @constant */
650
- name: "ax";
651
- } | {
652
- id: string;
653
- catalogue: string;
654
- librarySystem: components["schemas"]["LibrarySystem"];
655
- /** @constant */
656
- name: "catalogueHarvester";
657
- } | {
658
- id: string;
659
- /** @constant */
660
- name: "filmoteket";
661
- } | {
662
- id: string;
663
- /** @constant */
664
- name: "mediastore";
665
- } | {
666
- id: string;
667
- /** @constant */
668
- name: "nmbf";
669
- } | {
670
- id: string;
671
- /** @constant */
672
- name: "bokbasen";
673
- } | {
674
- id: string;
675
- /** @constant */
676
- name: "ingram";
677
- } | {
678
- id: string;
679
- /** @constant */
680
- name: "gardners";
681
- } | {
682
- /** @constant */
683
- name: "katt";
684
- } | {
685
- id: string;
686
- /** @constant */
687
- name: "kulturradet";
688
- } | {
689
- id: string;
690
- /** @constant */
691
- name: "grep";
692
- } | {
693
- id: string;
694
- /** @constant */
695
- name: "noraf";
696
- } | {
697
- id?: string;
698
- /** @constant */
699
- name: "script";
700
- };
701
699
  /** @description A Work is defined as "The intellectual or artistic content of a distinct creation" (Library Reference Model)
702
700
  *
703
701
  * It is the top level and most abstract entity in the WEMI stack (Work, Expression, Manifestation, Item), and serves to cluster all expressions of what one could consider "the same book" (or e.g. same play, film, game, etc.) in different formats and languages.
704
702
  *
705
703
  * While the work is an abstract entity, convention is to assign it a title, language and year in order to aid with identifying the work. */
706
- Work: {
704
+ BaseWork: {
707
705
  /** @constant */
708
706
  type: "Work";
709
707
  /** @description Cordata work ID. */
@@ -767,8 +765,6 @@ interface components {
767
765
  /** @description Whether the work has been created or adapted for users with special needs. */
768
766
  accessibleContentFeature?: components["schemas"]["AccessibleContentFeature"];
769
767
  biographicContent?: string;
770
- /** @description Original data source */
771
- origin: components["schemas"]["Origin"];
772
768
  };
773
769
  NumberOfPlayers: {
774
770
  local?: {
@@ -853,10 +849,51 @@ interface components {
853
849
  numberOfPerformers?: number;
854
850
  }[];
855
851
  };
852
+ ExpressionIllustrationsOptions: {
853
+ /** @constant */
854
+ code: "color_illustrations";
855
+ /** @constant */
856
+ name: "Illustrasjoner i farger";
857
+ preferred_name: components["schemas"]["LanguageMapWithEnglish"];
858
+ /** @constant */
859
+ type: "expression_illustrations_option";
860
+ } | {
861
+ /** @constant */
862
+ code: "illustrations";
863
+ /** @constant */
864
+ name: "Illustrasjoner";
865
+ preferred_name: components["schemas"]["LanguageMapWithEnglish"];
866
+ /** @constant */
867
+ type: "expression_illustrations_option";
868
+ } | {
869
+ /** @constant */
870
+ code: "not_illustrated";
871
+ /** @constant */
872
+ name: "Ikke illustrert";
873
+ preferred_name: components["schemas"]["LanguageMapWithEnglish"];
874
+ /** @constant */
875
+ type: "expression_illustrations_option";
876
+ } | {
877
+ /** @constant */
878
+ code: "tactile_color_illustrations";
879
+ /** @constant */
880
+ name: "Taktile illustrasjoner i farger";
881
+ preferred_name: components["schemas"]["LanguageMapWithEnglish"];
882
+ /** @constant */
883
+ type: "expression_illustrations_option";
884
+ } | {
885
+ /** @constant */
886
+ code: "tactile_illustrations";
887
+ /** @constant */
888
+ name: "Taktile illustrasjoner";
889
+ preferred_name: components["schemas"]["LanguageMapWithEnglish"];
890
+ /** @constant */
891
+ type: "expression_illustrations_option";
892
+ };
856
893
  /** @description An Expression is defined as "A distinct combination of signs conveying intellectual or artistic content" {@link https://www.iflastandards.info/lrm/lrmer#E3 Library Reference Model }
857
894
  *
858
895
  * It is the second level entity in the WEMI stack (Work, Expression, Manifestation, Item), and serves to group Manifestations of the same language and type - that is to say all manifestations using the same semiotic signs to convey the content. */
859
- Expression: {
896
+ BaseExpression: {
860
897
  /** @constant */
861
898
  type: "Expression";
862
899
  id: string;
@@ -888,8 +925,7 @@ interface components {
888
925
  instrumentations?: components["schemas"]["Instrumentation"][];
889
926
  /** @description If the expression is a translation and the translation was not carried out directly from the original language(s) of the work, but via one or more intermediate languages, this field contains the intermediate languages. */
890
927
  intermediateTranslationLanguages?: components["schemas"]["Language"][];
891
- /** @description Original data source */
892
- origin: components["schemas"]["Origin"];
928
+ illustrations?: components["schemas"]["ExpressionIllustrationsOptions"];
893
929
  };
894
930
  /** @description A Manifestation is defined as "A set of all carriers that are assumed to share the same characteristics as to intellectual or artistic content and aspects of physical form. That set is defined by both the overall content and the production plan for its carrier or carriers" {@link https://www.iflastandards.info/lrm/lrmer#E4 Library Reference Model }
895
931
  *
@@ -993,21 +1029,19 @@ interface components {
993
1029
  * itself is considered to be a work on its own, so this work is found under `work`, and the corresponding
994
1030
  * expression under `expression`. */
995
1031
  containedWorks?: {
996
- work: components["schemas"]["Work"];
997
- expression: components["schemas"]["Expression"];
1032
+ work: components["schemas"]["BaseWork"];
1033
+ expression: components["schemas"]["BaseExpression"];
998
1034
  }[];
999
- /** @description Original data source */
1000
- origin: components["schemas"]["Origin"];
1001
1035
  };
1002
1036
  /** ExpressionWithManifestations */
1003
- ExpressionWithManifestation: {
1037
+ Expression: {
1004
1038
  manifestations?: components["schemas"]["Manifestation"][];
1005
1039
  aggregateManifestations?: components["schemas"]["Manifestation"][];
1006
- } & components["schemas"]["Expression"];
1007
- /** WorkWithExpression */
1008
- WorkWithExpression: {
1009
- expressions?: components["schemas"]["ExpressionWithManifestation"][];
1010
- } & components["schemas"]["Work"];
1040
+ } & components["schemas"]["BaseExpression"];
1041
+ /** Work */
1042
+ Work: {
1043
+ expressions?: components["schemas"]["Expression"][];
1044
+ } & components["schemas"]["BaseWork"];
1011
1045
  FacetTerm: {
1012
1046
  /** @description The facet terms searchable value. */
1013
1047
  value: string;
@@ -1016,28 +1050,36 @@ interface components {
1016
1050
  /** @description The number of occurrences in the search result, based on works. */
1017
1051
  occurrences?: number;
1018
1052
  };
1019
- FacetV2: {
1020
- type: components["schemas"]["SearchFacetTypeEnumV2"];
1053
+ WorkFacet: {
1054
+ type: components["schemas"]["WorkFacetType"];
1021
1055
  /** @description A displayable (human readable) facet name. */
1022
1056
  name?: string;
1023
1057
  terms: components["schemas"]["FacetTerm"][];
1024
1058
  };
1059
+ AdvanvedQueryError: {
1060
+ /** @enum {string} */
1061
+ code: "field_unknown" | "field_unspecified" | "binary_operator_invalid" | "query_invalid";
1062
+ message: string;
1063
+ };
1025
1064
  GetWorkSearch200ResponseV2: {
1026
1065
  /** @description The total number of results in the whole search result. */
1027
1066
  total?: number;
1028
1067
  results: {
1029
- work: components["schemas"]["WorkWithExpression"];
1068
+ work: components["schemas"]["Work"];
1030
1069
  representativeManifestationId: string;
1031
1070
  }[];
1032
1071
  /** @description If this is false, we haven't reached the end of the search result yet, if it's false we have, and if it's missing or null we don't know. */
1033
1072
  endOfResults: boolean;
1034
1073
  /** @description This array contains the requested facets, and their terms. Each facet type should only appear once in the array. */
1035
- facets?: components["schemas"]["FacetV2"][];
1074
+ facets?: components["schemas"]["WorkFacet"][];
1036
1075
  /**
1037
1076
  * @description Indicates what kind of search was performed, based on parsed input query.
1038
1077
  * @enum {string}
1039
1078
  */
1040
1079
  queryType?: "empty" | "standard" | "advanced";
1080
+ /** @description Parsing errors from advanced query. When they occur, the request is treated as a standard search. */
1081
+ advancedQueryErrors?: components["schemas"]["AdvanvedQueryError"][];
1082
+ sorting: components["schemas"]["WorkSort"];
1041
1083
  };
1042
1084
  };
1043
1085
  responses: never;
@@ -1059,15 +1101,15 @@ interface operations {
1059
1101
  size?: number;
1060
1102
  /** @description Page number (deafult 1). */
1061
1103
  page?: number;
1062
- facet?: components["schemas"]["SearchFacetTypeEnumV2"][];
1104
+ facet?: components["schemas"]["WorkFacetType"][];
1063
1105
  /** @description Retun this number of facet terms for each requested facet (deafult 10). */
1064
1106
  facet_terms_size?: number;
1065
1107
  /** @description Sorting */
1066
- sort?: components["schemas"]["SearchSortingTypeEnumV2"];
1108
+ sort?: components["schemas"]["WorkSort"];
1067
1109
  /** @description Each filter accepts multiple comma-separated values that are OR'ed together.
1068
1110
  * The filters themselves are AND'ed together.
1069
1111
  * */
1070
- filter?: components["schemas"]["WorkFilterSchema"];
1112
+ filter?: components["schemas"]["WorkFilter"];
1071
1113
  };
1072
1114
  header?: never;
1073
1115
  path?: never;
@@ -1093,19 +1135,13 @@ type BmdbApiPaths = paths;
1093
1135
 
1094
1136
  type BmdbSearchClientOptions = ClientOptions & {
1095
1137
  clientIdentifier: string;
1096
- version?: "v2";
1138
+ version?: "v1";
1097
1139
  };
1098
1140
  type BmdbSearchClient = Client<BmdbApiPaths>;
1099
- declare const createBmdbSearchClient: ({ clientIdentifier, version, ...options }: BmdbSearchClientOptions) => BmdbSearchClient;
1100
-
1101
- type BmdbSearchHooks = OpenapiQueryClient<BmdbApiPaths>;
1102
- type BmdbSearchHooksArgs = {
1103
- searchClient: BmdbSearchClient;
1104
- } | BmdbSearchClientOptions;
1105
- declare const createBmdbSearchHooks: (args: BmdbSearchHooksArgs) => BmdbSearchHooks;
1141
+ declare const createBmdbFetchClient: ({ clientIdentifier, version, ...options }: BmdbSearchClientOptions) => BmdbSearchClient;
1106
1142
 
1107
- type BmdbWork = BmdbApiSchemas["WorkWithExpression"];
1108
- type BmdbExpression = BmdbApiSchemas["ExpressionWithManifestation"];
1143
+ type BmdbWork = BmdbApiSchemas["Work"];
1144
+ type BmdbExpression = BmdbApiSchemas["Expression"];
1109
1145
  type BmdbManifestation = BmdbApiSchemas["Manifestation"];
1110
1146
 
1111
- export { type BmdbExpression, type BmdbManifestation, type BmdbSearchClient, type BmdbSearchClientOptions, type BmdbSearchHooks, type BmdbWork, createBmdbSearchClient, createBmdbSearchHooks };
1147
+ export { type BmdbExpression, type BmdbManifestation, type BmdbSearchClient, type BmdbSearchClientOptions, type BmdbWork, createBmdbFetchClient };
package/dist/index.d.ts CHANGED
@@ -1,5 +1,4 @@
1
1
  import { ClientOptions, Client } from 'openapi-fetch';
2
- import { OpenapiQueryClient } from 'openapi-react-query';
3
2
 
4
3
  /**
5
4
  * This file was auto-generated by openapi-typescript.
@@ -30,24 +29,84 @@ interface paths {
30
29
  }
31
30
  interface components {
32
31
  schemas: {
33
- /** @enum {string} */
34
- SearchFacetTypeEnumV2: "work_type" | "expression_type" | "manifestation_medium" | "work_origin" | "origin" | "creator" | "collection" | "subject";
35
- /** @enum {string} */
36
- SearchSortingTypeEnumV2: "relevance.desc" | "updateTime.desc";
37
- WorkFilterSchema: {
38
- identifier?: string[];
39
- work_id?: string[];
40
- expression_id?: string[];
41
- manifestation_id?: string[];
42
- work_type?: string[];
43
- expression_type?: string[];
44
- manifestation_medium?: string[];
45
- work_origin?: string[];
46
- origin?: string[];
47
- title?: string[];
48
- creator?: string[];
49
- collection?: string[];
50
- subject?: string[];
32
+ /**
33
+ * @description Facet type, this is the value given to the search facet parameter. The facet should always exists in as a corresponding filter.
34
+ *
35
+ * @enum {string}
36
+ */
37
+ WorkFacetType: "work_type" | "expression_type" | "manifestation_medium" | "creator" | "collection" | "subject" | "original_language" | "genre" | "age_limit" | "age_group" | "grep_subject" | "kulturfond" | "fiction";
38
+ /**
39
+ * @description Sorting type, this is the value given to the search facet parameter.
40
+ *
41
+ * @enum {string}
42
+ */
43
+ WorkSort: "relevance.desc" | "updateTime.desc" | "updateTime.asc" | "publicationDate.desc" | "publicationDate.asc" | "firstPublicationDate.desc" | "firstPublicationDate.asc";
44
+ WorkFilter: {
45
+ identifier?: string;
46
+ work_id?: string;
47
+ expression_id?: string;
48
+ manifestation_id?: string;
49
+ work_type?: string;
50
+ expression_type?: string;
51
+ manifestation_medium?: string;
52
+ title?: string;
53
+ creator?: string;
54
+ collection?: string;
55
+ subject?: string;
56
+ kulturfond?: boolean;
57
+ original_language?: string;
58
+ genre?: string;
59
+ age_limit?: string;
60
+ age_group?: string;
61
+ grep_subject?: string;
62
+ fiction?: boolean;
63
+ abridger?: string;
64
+ actor?: string;
65
+ antecedent?: string;
66
+ arranger?: string;
67
+ artist?: string;
68
+ author?: string;
69
+ book_designer?: string;
70
+ colorist?: string;
71
+ commentary_writer?: string;
72
+ commenter?: string;
73
+ compilation_editor?: string;
74
+ compiler?: string;
75
+ composer?: string;
76
+ conceptor?: string;
77
+ conductor?: string;
78
+ consultant?: string;
79
+ contributor?: string;
80
+ copyright_holder?: string;
81
+ cover_designer?: string;
82
+ curator?: string;
83
+ degree_granting_institution?: string;
84
+ designer?: string;
85
+ director?: string;
86
+ editor?: string;
87
+ enacting_jurisdiction?: string;
88
+ game_developer?: string;
89
+ honoree?: string;
90
+ illustrator?: string;
91
+ instrumentalist?: string;
92
+ interviewee?: string;
93
+ interviewer?: string;
94
+ issuing_body?: string;
95
+ lead?: string;
96
+ librettist?: string;
97
+ lyricist?: string;
98
+ musician?: string;
99
+ narrator?: string;
100
+ other?: string;
101
+ performer?: string;
102
+ photographer?: string;
103
+ project_director?: string;
104
+ publisher?: string;
105
+ reteller?: string;
106
+ screenwriter?: string;
107
+ singer?: string;
108
+ translator?: string;
109
+ voice_actor?: string;
51
110
  };
52
111
  /** @enum {string} */
53
112
  LanguageCode: "abk" | "ach" | "afr" | "akk" | "alb" | "amh" | "ang" | "ara" | "arc" | "arm" | "aze" | "bam" | "baq" | "bel" | "bem" | "ben" | "bis" | "bnt" | "bos" | "bre" | "bul" | "bur" | "byn" | "cat" | "ceb" | "che" | "chi" | "chu" | "cic" | "ckb" | "cmn" | "cnr" | "cop" | "cze" | "dan" | "dut" | "egy" | "eng" | "enm" | "epo" | "est" | "ewe" | "fao" | "fat" | "fij" | "fin" | "fiu" | "fkv" | "fre" | "frm" | "fro" | "fry" | "ful" | "gaa" | "geo" | "ger" | "gez" | "gla" | "gle" | "glg" | "gmh" | "got" | "grc" | "gre" | "guj" | "hau" | "heb" | "hil" | "hin" | "hrv" | "hun" | "ibo" | "ice" | "iku" | "ilo" | "ind" | "ipk" | "ira" | "ita" | "jpn" | "kal" | "kan" | "kaz" | "khm" | "kho" | "kik" | "kin" | "kmr" | "kon" | "kor" | "kua" | "kur" | "lao" | "lat" | "lav" | "lin" | "lit" | "lkt" | "lug" | "mac" | "mao" | "mar" | "may" | "mlg" | "mlt" | "mnk" | "mol" | "mon" | "mul" | "myn" | "nds" | "nep" | "nic" | "nno" | "nob" | "nom" | "non" | "nor" | "nso" | "oci" | "orm" | "pan" | "per" | "pli" | "pol" | "por" | "pra" | "pro" | "prs" | "pus" | "roh" | "rom" | "rum" | "run" | "rus" | "sah" | "san" | "sat" | "sco" | "sgn" | "sin" | "sit" | "sjd" | "sje" | "sjk" | "sjt" | "sju" | "slo" | "slv" | "sma" | "sme" | "smi" | "smj" | "smn" | "smo" | "sms" | "som" | "sot" | "spa" | "srp" | "sux" | "swa" | "swe" | "syr" | "tam" | "tay" | "tel" | "tgl" | "tha" | "tib" | "tir" | "tkl" | "tmh" | "ton" | "tur" | "ukr" | "urd" | "uzb" | "vie" | "wel" | "wen" | "wol" | "xho" | "yid" | "yor" | "ypk" | "yue" | "zul" | "und" | "zxx";
@@ -334,7 +393,6 @@ interface components {
334
393
  name: components["schemas"]["LanguageMap"];
335
394
  /** @description The qualifier is used to anchor the subject to a specific category in the Dewey hierarchy when the focus term is a phenomenon which appears in more than one place in the hierarchy, e.g. "Kjærlighet : psykologi" */
336
395
  qualifier?: components["schemas"]["LanguageMap"];
337
- specification?: components["schemas"]["LanguageMap"];
338
396
  /** @description Internal note on the entity, e.g. field of use. */
339
397
  scopeNote?: string;
340
398
  /** @description {@link https://deweyno.pansoft.de Norsk WebDewey } classification number. */
@@ -638,72 +696,12 @@ interface components {
638
696
  /** @description URI for the corresponding concept in National Library's [Vocabulary of target groups (nortarget)](https://www.nb.no/nbvok/tg/nb/). */
639
697
  nortargetUri: string;
640
698
  };
641
- /** @enum {string} */
642
- LibrarySystem: "bibliofil" | "cicero" | "quria" | "mikromarc";
643
- Origin: {
644
- id: string;
645
- /** @constant */
646
- name: "promus";
647
- } | {
648
- id: string;
649
- /** @constant */
650
- name: "ax";
651
- } | {
652
- id: string;
653
- catalogue: string;
654
- librarySystem: components["schemas"]["LibrarySystem"];
655
- /** @constant */
656
- name: "catalogueHarvester";
657
- } | {
658
- id: string;
659
- /** @constant */
660
- name: "filmoteket";
661
- } | {
662
- id: string;
663
- /** @constant */
664
- name: "mediastore";
665
- } | {
666
- id: string;
667
- /** @constant */
668
- name: "nmbf";
669
- } | {
670
- id: string;
671
- /** @constant */
672
- name: "bokbasen";
673
- } | {
674
- id: string;
675
- /** @constant */
676
- name: "ingram";
677
- } | {
678
- id: string;
679
- /** @constant */
680
- name: "gardners";
681
- } | {
682
- /** @constant */
683
- name: "katt";
684
- } | {
685
- id: string;
686
- /** @constant */
687
- name: "kulturradet";
688
- } | {
689
- id: string;
690
- /** @constant */
691
- name: "grep";
692
- } | {
693
- id: string;
694
- /** @constant */
695
- name: "noraf";
696
- } | {
697
- id?: string;
698
- /** @constant */
699
- name: "script";
700
- };
701
699
  /** @description A Work is defined as "The intellectual or artistic content of a distinct creation" (Library Reference Model)
702
700
  *
703
701
  * It is the top level and most abstract entity in the WEMI stack (Work, Expression, Manifestation, Item), and serves to cluster all expressions of what one could consider "the same book" (or e.g. same play, film, game, etc.) in different formats and languages.
704
702
  *
705
703
  * While the work is an abstract entity, convention is to assign it a title, language and year in order to aid with identifying the work. */
706
- Work: {
704
+ BaseWork: {
707
705
  /** @constant */
708
706
  type: "Work";
709
707
  /** @description Cordata work ID. */
@@ -767,8 +765,6 @@ interface components {
767
765
  /** @description Whether the work has been created or adapted for users with special needs. */
768
766
  accessibleContentFeature?: components["schemas"]["AccessibleContentFeature"];
769
767
  biographicContent?: string;
770
- /** @description Original data source */
771
- origin: components["schemas"]["Origin"];
772
768
  };
773
769
  NumberOfPlayers: {
774
770
  local?: {
@@ -853,10 +849,51 @@ interface components {
853
849
  numberOfPerformers?: number;
854
850
  }[];
855
851
  };
852
+ ExpressionIllustrationsOptions: {
853
+ /** @constant */
854
+ code: "color_illustrations";
855
+ /** @constant */
856
+ name: "Illustrasjoner i farger";
857
+ preferred_name: components["schemas"]["LanguageMapWithEnglish"];
858
+ /** @constant */
859
+ type: "expression_illustrations_option";
860
+ } | {
861
+ /** @constant */
862
+ code: "illustrations";
863
+ /** @constant */
864
+ name: "Illustrasjoner";
865
+ preferred_name: components["schemas"]["LanguageMapWithEnglish"];
866
+ /** @constant */
867
+ type: "expression_illustrations_option";
868
+ } | {
869
+ /** @constant */
870
+ code: "not_illustrated";
871
+ /** @constant */
872
+ name: "Ikke illustrert";
873
+ preferred_name: components["schemas"]["LanguageMapWithEnglish"];
874
+ /** @constant */
875
+ type: "expression_illustrations_option";
876
+ } | {
877
+ /** @constant */
878
+ code: "tactile_color_illustrations";
879
+ /** @constant */
880
+ name: "Taktile illustrasjoner i farger";
881
+ preferred_name: components["schemas"]["LanguageMapWithEnglish"];
882
+ /** @constant */
883
+ type: "expression_illustrations_option";
884
+ } | {
885
+ /** @constant */
886
+ code: "tactile_illustrations";
887
+ /** @constant */
888
+ name: "Taktile illustrasjoner";
889
+ preferred_name: components["schemas"]["LanguageMapWithEnglish"];
890
+ /** @constant */
891
+ type: "expression_illustrations_option";
892
+ };
856
893
  /** @description An Expression is defined as "A distinct combination of signs conveying intellectual or artistic content" {@link https://www.iflastandards.info/lrm/lrmer#E3 Library Reference Model }
857
894
  *
858
895
  * It is the second level entity in the WEMI stack (Work, Expression, Manifestation, Item), and serves to group Manifestations of the same language and type - that is to say all manifestations using the same semiotic signs to convey the content. */
859
- Expression: {
896
+ BaseExpression: {
860
897
  /** @constant */
861
898
  type: "Expression";
862
899
  id: string;
@@ -888,8 +925,7 @@ interface components {
888
925
  instrumentations?: components["schemas"]["Instrumentation"][];
889
926
  /** @description If the expression is a translation and the translation was not carried out directly from the original language(s) of the work, but via one or more intermediate languages, this field contains the intermediate languages. */
890
927
  intermediateTranslationLanguages?: components["schemas"]["Language"][];
891
- /** @description Original data source */
892
- origin: components["schemas"]["Origin"];
928
+ illustrations?: components["schemas"]["ExpressionIllustrationsOptions"];
893
929
  };
894
930
  /** @description A Manifestation is defined as "A set of all carriers that are assumed to share the same characteristics as to intellectual or artistic content and aspects of physical form. That set is defined by both the overall content and the production plan for its carrier or carriers" {@link https://www.iflastandards.info/lrm/lrmer#E4 Library Reference Model }
895
931
  *
@@ -993,21 +1029,19 @@ interface components {
993
1029
  * itself is considered to be a work on its own, so this work is found under `work`, and the corresponding
994
1030
  * expression under `expression`. */
995
1031
  containedWorks?: {
996
- work: components["schemas"]["Work"];
997
- expression: components["schemas"]["Expression"];
1032
+ work: components["schemas"]["BaseWork"];
1033
+ expression: components["schemas"]["BaseExpression"];
998
1034
  }[];
999
- /** @description Original data source */
1000
- origin: components["schemas"]["Origin"];
1001
1035
  };
1002
1036
  /** ExpressionWithManifestations */
1003
- ExpressionWithManifestation: {
1037
+ Expression: {
1004
1038
  manifestations?: components["schemas"]["Manifestation"][];
1005
1039
  aggregateManifestations?: components["schemas"]["Manifestation"][];
1006
- } & components["schemas"]["Expression"];
1007
- /** WorkWithExpression */
1008
- WorkWithExpression: {
1009
- expressions?: components["schemas"]["ExpressionWithManifestation"][];
1010
- } & components["schemas"]["Work"];
1040
+ } & components["schemas"]["BaseExpression"];
1041
+ /** Work */
1042
+ Work: {
1043
+ expressions?: components["schemas"]["Expression"][];
1044
+ } & components["schemas"]["BaseWork"];
1011
1045
  FacetTerm: {
1012
1046
  /** @description The facet terms searchable value. */
1013
1047
  value: string;
@@ -1016,28 +1050,36 @@ interface components {
1016
1050
  /** @description The number of occurrences in the search result, based on works. */
1017
1051
  occurrences?: number;
1018
1052
  };
1019
- FacetV2: {
1020
- type: components["schemas"]["SearchFacetTypeEnumV2"];
1053
+ WorkFacet: {
1054
+ type: components["schemas"]["WorkFacetType"];
1021
1055
  /** @description A displayable (human readable) facet name. */
1022
1056
  name?: string;
1023
1057
  terms: components["schemas"]["FacetTerm"][];
1024
1058
  };
1059
+ AdvanvedQueryError: {
1060
+ /** @enum {string} */
1061
+ code: "field_unknown" | "field_unspecified" | "binary_operator_invalid" | "query_invalid";
1062
+ message: string;
1063
+ };
1025
1064
  GetWorkSearch200ResponseV2: {
1026
1065
  /** @description The total number of results in the whole search result. */
1027
1066
  total?: number;
1028
1067
  results: {
1029
- work: components["schemas"]["WorkWithExpression"];
1068
+ work: components["schemas"]["Work"];
1030
1069
  representativeManifestationId: string;
1031
1070
  }[];
1032
1071
  /** @description If this is false, we haven't reached the end of the search result yet, if it's false we have, and if it's missing or null we don't know. */
1033
1072
  endOfResults: boolean;
1034
1073
  /** @description This array contains the requested facets, and their terms. Each facet type should only appear once in the array. */
1035
- facets?: components["schemas"]["FacetV2"][];
1074
+ facets?: components["schemas"]["WorkFacet"][];
1036
1075
  /**
1037
1076
  * @description Indicates what kind of search was performed, based on parsed input query.
1038
1077
  * @enum {string}
1039
1078
  */
1040
1079
  queryType?: "empty" | "standard" | "advanced";
1080
+ /** @description Parsing errors from advanced query. When they occur, the request is treated as a standard search. */
1081
+ advancedQueryErrors?: components["schemas"]["AdvanvedQueryError"][];
1082
+ sorting: components["schemas"]["WorkSort"];
1041
1083
  };
1042
1084
  };
1043
1085
  responses: never;
@@ -1059,15 +1101,15 @@ interface operations {
1059
1101
  size?: number;
1060
1102
  /** @description Page number (deafult 1). */
1061
1103
  page?: number;
1062
- facet?: components["schemas"]["SearchFacetTypeEnumV2"][];
1104
+ facet?: components["schemas"]["WorkFacetType"][];
1063
1105
  /** @description Retun this number of facet terms for each requested facet (deafult 10). */
1064
1106
  facet_terms_size?: number;
1065
1107
  /** @description Sorting */
1066
- sort?: components["schemas"]["SearchSortingTypeEnumV2"];
1108
+ sort?: components["schemas"]["WorkSort"];
1067
1109
  /** @description Each filter accepts multiple comma-separated values that are OR'ed together.
1068
1110
  * The filters themselves are AND'ed together.
1069
1111
  * */
1070
- filter?: components["schemas"]["WorkFilterSchema"];
1112
+ filter?: components["schemas"]["WorkFilter"];
1071
1113
  };
1072
1114
  header?: never;
1073
1115
  path?: never;
@@ -1093,19 +1135,13 @@ type BmdbApiPaths = paths;
1093
1135
 
1094
1136
  type BmdbSearchClientOptions = ClientOptions & {
1095
1137
  clientIdentifier: string;
1096
- version?: "v2";
1138
+ version?: "v1";
1097
1139
  };
1098
1140
  type BmdbSearchClient = Client<BmdbApiPaths>;
1099
- declare const createBmdbSearchClient: ({ clientIdentifier, version, ...options }: BmdbSearchClientOptions) => BmdbSearchClient;
1100
-
1101
- type BmdbSearchHooks = OpenapiQueryClient<BmdbApiPaths>;
1102
- type BmdbSearchHooksArgs = {
1103
- searchClient: BmdbSearchClient;
1104
- } | BmdbSearchClientOptions;
1105
- declare const createBmdbSearchHooks: (args: BmdbSearchHooksArgs) => BmdbSearchHooks;
1141
+ declare const createBmdbFetchClient: ({ clientIdentifier, version, ...options }: BmdbSearchClientOptions) => BmdbSearchClient;
1106
1142
 
1107
- type BmdbWork = BmdbApiSchemas["WorkWithExpression"];
1108
- type BmdbExpression = BmdbApiSchemas["ExpressionWithManifestation"];
1143
+ type BmdbWork = BmdbApiSchemas["Work"];
1144
+ type BmdbExpression = BmdbApiSchemas["Expression"];
1109
1145
  type BmdbManifestation = BmdbApiSchemas["Manifestation"];
1110
1146
 
1111
- export { type BmdbExpression, type BmdbManifestation, type BmdbSearchClient, type BmdbSearchClientOptions, type BmdbSearchHooks, type BmdbWork, createBmdbSearchClient, createBmdbSearchHooks };
1147
+ export { type BmdbExpression, type BmdbManifestation, type BmdbSearchClient, type BmdbSearchClientOptions, type BmdbWork, createBmdbFetchClient };
package/dist/index.js CHANGED
@@ -1,14 +1,17 @@
1
1
  import createFetchClient from 'openapi-fetch';
2
- import createReactQueryClient from 'openapi-react-query';
3
2
 
4
3
  // src/client.ts
5
- var createBmdbSearchClient = ({
4
+ var createBmdbFetchClient = ({
6
5
  clientIdentifier,
7
- version = "v2",
6
+ version = "v1",
8
7
  ...options
9
8
  }) => {
10
9
  const baseUrl = `${options.baseUrl?.replace(/(.*)\/$/, "$1") ?? ""}/bmdb/api/${version}/`;
11
- const client = createFetchClient({ ...options, baseUrl });
10
+ const client = createFetchClient({
11
+ baseUrl,
12
+ querySerializer: { array: { style: "form", explode: false } },
13
+ ...options
14
+ });
12
15
  client.use({
13
16
  onRequest({ request }) {
14
17
  request.headers.set("client-identifier", clientIdentifier);
@@ -17,6 +20,5 @@ var createBmdbSearchClient = ({
17
20
  });
18
21
  return client;
19
22
  };
20
- var createBmdbSearchHooks = (args) => createReactQueryClient("searchClient" in args ? args.searchClient : createBmdbSearchClient(args));
21
23
 
22
- export { createBmdbSearchClient, createBmdbSearchHooks };
24
+ export { createBmdbFetchClient };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@biblioteksentralen/bmdb-search",
3
- "version": "0.0.0-beta.2",
3
+ "version": "0.0.0-beta.4",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "description": "Client for searching Bibliotekenes metadatabrønn (BMDB)",
@@ -28,8 +28,7 @@
28
28
  "author": "Biblioteksentralen",
29
29
  "license": "MIT",
30
30
  "dependencies": {
31
- "openapi-fetch": "^0.13.4",
32
- "openapi-react-query": "^0.5.1"
31
+ "openapi-fetch": "^0.13.4"
33
32
  },
34
33
  "devDependencies": {
35
34
  "@dataplattform/api-specifications": "x",
@@ -51,7 +50,6 @@
51
50
  "clean": "rimraf dist src/generated",
52
51
  "lint": "eslint .",
53
52
  "lint:package": "attw --pack",
54
- "test": "pnpm vitest -w=false",
55
53
  "build": "tsup src/index.ts --format cjs,esm --dts --dts-resolve --treeshake"
56
54
  }
57
55
  }