@kohost/api-client 1.0.0-alpha.3 → 1.0.0-beta.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.
Files changed (61) hide show
  1. package/commands/CheckInReservationCommand.js +23 -0
  2. package/commands/DiscoverReservationsCommand.js +24 -0
  3. package/commands/DiscoverRoomsCommand.js +21 -0
  4. package/commands/DiscoverUsersCommand.js +21 -0
  5. package/commands/{VerifyDocumentCommand.js → OCRDocumentCommand.js} +4 -8
  6. package/commands/SendEmailCommand.js +24 -0
  7. package/commands/SendSMSCommand.js +21 -0
  8. package/commands/index.js +12 -2
  9. package/defs/http.js +1 -1
  10. package/events/EmailSentEvent.js +17 -0
  11. package/events/Event.js +20 -1
  12. package/events/SMSSentEvent.js +17 -0
  13. package/events/ShortLinkCreatedEvent.js +17 -0
  14. package/events/index.js +7 -0
  15. package/http/handleResponseError.js +9 -29
  16. package/http/handleResponseSuccess.js +2 -2
  17. package/http/index.js +53 -43
  18. package/index.js +2 -2
  19. package/models/credential.js +29 -0
  20. package/models/gateway.js +0 -8
  21. package/models/identification.js +32 -0
  22. package/models/index.js +9 -9
  23. package/models/kohost.js +4 -3
  24. package/models/product.js +30 -0
  25. package/models/reservation.js +47 -0
  26. package/models/room.js +1 -12
  27. package/models/shortLink.js +29 -0
  28. package/models/space.js +1 -1
  29. package/models/thermostat.js +3 -3
  30. package/models/user.js +0 -2
  31. package/models/windowCovering.js +1 -1
  32. package/package.json +11 -10
  33. package/schemas/admin/property.json +127 -1
  34. package/schemas/camera.json +3 -3
  35. package/schemas/courtesy.json +3 -3
  36. package/schemas/credential.json +28 -0
  37. package/schemas/definitions/common.json +53 -0
  38. package/schemas/definitions/device.json +13 -2
  39. package/schemas/dimmer.json +3 -3
  40. package/schemas/gateway.json +16 -47
  41. package/schemas/identification.json +18 -4
  42. package/schemas/lock.json +6 -3
  43. package/schemas/mediaSource.json +3 -3
  44. package/schemas/motionSensor.json +3 -3
  45. package/schemas/payment.json +3 -1
  46. package/schemas/product.json +36 -0
  47. package/schemas/reservation.json +11 -6
  48. package/schemas/room.json +1 -8
  49. package/schemas/shortLink.json +30 -0
  50. package/schemas/switch.json +3 -3
  51. package/schemas/thermostat.json +11 -10
  52. package/schemas/user.json +65 -13
  53. package/schemas/windowCovering.json +3 -3
  54. package/tests/unit/models/user.test.js +28 -0
  55. package/useCases/http.json +345 -41
  56. package/utils/schema.js +2 -2
  57. package/vite.config.js +22 -0
  58. package/models/iotGateway.js +0 -29
  59. package/models/sceneController.js +0 -29
  60. package/schemas/iotGateway.json +0 -29
  61. package/schemas/sceneController.json +0 -58
@@ -0,0 +1,23 @@
1
+ const Command = require("./Command");
2
+ const RequestError = require("../errors/RequestError");
3
+
4
+ class CheckInReservationCommand extends Command {
5
+ constructor({ id }) {
6
+ if (!id) throw new RequestError("document type is required");
7
+ super({ id });
8
+ }
9
+
10
+ get name() {
11
+ return "CheckInReservation";
12
+ }
13
+
14
+ get routingKey() {
15
+ return `reservation.${this.data.id}.checkin`;
16
+ }
17
+
18
+ get replyTo() {
19
+ return "system.response.reservations";
20
+ }
21
+ }
22
+
23
+ module.exports = CheckInReservationCommand;
@@ -0,0 +1,24 @@
1
+ const { RequestError } = require("../errors");
2
+ const Command = require("./Command");
3
+
4
+ class DiscoverReservationsCommand extends Command {
5
+ constructor(options) {
6
+ if (!options) throw new RequestError("options are required");
7
+ const { id, startDate, endDate, status } = options;
8
+ super({ id, startDate, endDate, status });
9
+ }
10
+
11
+ get name() {
12
+ return "DiscoverReservations";
13
+ }
14
+
15
+ get routingKey() {
16
+ return "reservation.discover";
17
+ }
18
+
19
+ get replyTo() {
20
+ return "system.response.reservations";
21
+ }
22
+ }
23
+
24
+ module.exports = DiscoverReservationsCommand;
@@ -0,0 +1,21 @@
1
+ const Command = require("./Command");
2
+
3
+ class DiscoverRoomsCommand extends Command {
4
+ constructor({ id }) {
5
+ super({ id });
6
+ }
7
+
8
+ get name() {
9
+ return "DiscoverRooms";
10
+ }
11
+
12
+ get routingKey() {
13
+ return `rooms.${this.data.id}.get`;
14
+ }
15
+
16
+ get replyTo() {
17
+ return "system.response.users";
18
+ }
19
+ }
20
+
21
+ module.exports = DiscoverRoomsCommand;
@@ -0,0 +1,21 @@
1
+ const Command = require("./Command");
2
+
3
+ class DiscoverUsersCommand extends Command {
4
+ constructor({ id }) {
5
+ super({ id });
6
+ }
7
+
8
+ get name() {
9
+ return "DiscoverUsers";
10
+ }
11
+
12
+ get routingKey() {
13
+ return `users.${this.data.id}.get`;
14
+ }
15
+
16
+ get replyTo() {
17
+ return "system.response.users";
18
+ }
19
+ }
20
+
21
+ module.exports = DiscoverUsersCommand;
@@ -1,7 +1,7 @@
1
1
  const Command = require("./Command");
2
2
  const RequestError = require("../errors/RequestError");
3
3
 
4
- class VerifyDocumentCommand extends Command {
4
+ class OCRDocumentCommand extends Command {
5
5
  constructor({ type, image }) {
6
6
  if (!type) throw new RequestError("document type is required");
7
7
  if (!image) throw new RequestError("document image is required");
@@ -9,16 +9,12 @@ class VerifyDocumentCommand extends Command {
9
9
  }
10
10
 
11
11
  get name() {
12
- return "VerifyDocument";
12
+ return "OCRDocument";
13
13
  }
14
14
 
15
15
  get routingKey() {
16
- return `document.${this.data.type}.verify`;
17
- }
18
-
19
- get replyTo() {
20
- return "system.response.documents";
16
+ return `document.${this.data.type}.ocr`;
21
17
  }
22
18
  }
23
19
 
24
- module.exports = VerifyDocumentCommand;
20
+ module.exports = OCRDocumentCommand;
@@ -0,0 +1,24 @@
1
+ const Command = require("./Command");
2
+ const RequestError = require("../errors/RequestError");
3
+
4
+ class SendEmailCommand extends Command {
5
+ constructor({ text, html, to, from, subject, eventData }) {
6
+ if (!to) throw new RequestError("email to is required");
7
+ if (!from) throw new RequestError("email from is required");
8
+ if (!subject) throw new RequestError("email subject is required");
9
+ if (!text && !html)
10
+ throw new RequestError("email text or html is required");
11
+
12
+ super({ text, html, to, from, subject, eventData });
13
+ }
14
+
15
+ get name() {
16
+ return "SendEmail";
17
+ }
18
+
19
+ get routingKey() {
20
+ return "comm.email.send";
21
+ }
22
+ }
23
+
24
+ module.exports = SendEmailCommand;
@@ -0,0 +1,21 @@
1
+ const Command = require("./Command");
2
+ const RequestError = require("../errors/RequestError");
3
+
4
+ class SendSMSCommand extends Command {
5
+ constructor({ body, to, from, metaData }) {
6
+ if (!body) throw new RequestError("sms body is required");
7
+ if (!to) throw new RequestError("sms to is required");
8
+ if (!from) throw new RequestError("sms from is required");
9
+ super({ body, to, from, metaData });
10
+ }
11
+
12
+ get name() {
13
+ return "SendSMS";
14
+ }
15
+
16
+ get routingKey() {
17
+ return "comm.sms.send";
18
+ }
19
+ }
20
+
21
+ module.exports = SendSMSCommand;
package/commands/index.js CHANGED
@@ -6,7 +6,12 @@ const SetLockCommand = require("./SetLockCommand");
6
6
  const SetSceneControllerCommand = require("./SetSceneControllerCommand");
7
7
  const SetWindowCoveringCommand = require("./SetWindowCoveringCommand");
8
8
  const SetCourtesyCommand = require("./SetCourtesyCommand");
9
- const VerifyDocumentCommand = require("./VerifyDocumentCommand");
9
+ const DiscoverUsersCommand = require("./DiscoverUsersCommand");
10
+ const OCRDocumentCommand = require("./OCRDocumentCommand");
11
+ const CheckInReservationCommand = require("./CheckInReservationCommand");
12
+ const SendSMSCommand = require("./SendSMSCommand");
13
+ const DiscoverReservationsCommand = require("./DiscoverReservationsCommand");
14
+ const DiscoverRoomsCommand = require("./DiscoverRoomsCommand");
10
15
 
11
16
  module.exports = {
12
17
  SetAlarmCommand,
@@ -17,5 +22,10 @@ module.exports = {
17
22
  SetSceneControllerCommand,
18
23
  SetWindowCoveringCommand,
19
24
  SetCourtesyCommand,
20
- VerifyDocumentCommand,
25
+ OCRDocumentCommand,
26
+ DiscoverUsersCommand,
27
+ CheckInReservationCommand,
28
+ SendSMSCommand,
29
+ DiscoverReservationsCommand,
30
+ DiscoverRoomsCommand,
21
31
  };
package/defs/http.js CHANGED
@@ -1,7 +1,7 @@
1
1
  const http = {
2
2
  authTokenHeader: "X-Auth-Token",
3
3
  refreshTokenHeader: "X-Refresh-Token",
4
- tenantHeader: "X-Tenant-Id",
4
+ propertyHeader: "X-Property-Id",
5
5
  };
6
6
 
7
7
  module.exports = http;
@@ -0,0 +1,17 @@
1
+ const Event = require("./Event");
2
+
3
+ class EmailSentEvent extends Event {
4
+ constructor(email, context) {
5
+ super(email, context);
6
+ }
7
+
8
+ get name() {
9
+ return "EmailSent";
10
+ }
11
+
12
+ get routingKey() {
13
+ return "comm.email.sent";
14
+ }
15
+ }
16
+
17
+ module.exports = EmailSentEvent;
package/events/Event.js CHANGED
@@ -1,13 +1,32 @@
1
1
  class Event {
2
- constructor(data) {
2
+ constructor(data, context) {
3
3
  this.data = {};
4
+ this.context = {};
4
5
  if (!data) throw new Error("Event data is required");
5
6
  if (typeof data !== "object")
6
7
  throw new Error("Event data must be an object");
7
8
 
9
+ if (!data.name) this.data.name = this.name;
10
+ if (!data.type) this.data.type = this.type;
11
+
8
12
  for (const key in data) {
9
13
  this.data[key] = data[key];
10
14
  }
15
+
16
+ if (data.eventData) {
17
+ for (const key in data.eventData) {
18
+ this.data[key] = data.eventData[key];
19
+ }
20
+ delete this.data.eventData;
21
+ }
22
+
23
+ if (context) {
24
+ for (const key in context) {
25
+ this.context[key] = context[key];
26
+ }
27
+ }
28
+
29
+ if (!this.data.timestamp) this.data.timestamp = new Date();
11
30
  }
12
31
  get name() {
13
32
  throw new Error("Event name is required");
@@ -0,0 +1,17 @@
1
+ const Event = require("./Event");
2
+
3
+ class SMSSentEvent extends Event {
4
+ constructor(email, context) {
5
+ super(email, context);
6
+ }
7
+
8
+ get name() {
9
+ return "SMSSent";
10
+ }
11
+
12
+ get routingKey() {
13
+ return "comm.sms.sent";
14
+ }
15
+ }
16
+
17
+ module.exports = SMSSentEvent;
@@ -0,0 +1,17 @@
1
+ const Event = require("./Event");
2
+
3
+ class ShortLinkCreatedEvent extends Event {
4
+ constructor(shortLink, context) {
5
+ super(shortLink, context);
6
+ }
7
+
8
+ get name() {
9
+ return "ShortLinkCreated";
10
+ }
11
+
12
+ get routingKey() {
13
+ return `shortlink.${this.data.id}.created`;
14
+ }
15
+ }
16
+
17
+ module.exports = ShortLinkCreatedEvent;
package/events/index.js CHANGED
@@ -12,6 +12,10 @@ const SystemUserUpdatedEvent = require("./SystemUserUpdatedEvent");
12
12
  const SystemSpaceUpdatedEvent = require("./SystemSpaceUpdatedEvent");
13
13
  const SystemReservationUpdatedEvent = require("./SystemReservationUpdatedEvent");
14
14
 
15
+ const SMSSentEvent = require("./SMSSentEvent");
16
+ const EmailSentEvent = require("./EmailSentEvent");
17
+ const ShortLinkCreatedEvent = require("./ShortLinkCreatedEvent");
18
+
15
19
  module.exports = {
16
20
  SystemThermostatUpdatedEvent,
17
21
  SystemDimmerUpdatedEvent,
@@ -25,4 +29,7 @@ module.exports = {
25
29
  SystemUserUpdatedEvent,
26
30
  SystemSpaceUpdatedEvent,
27
31
  SystemReservationUpdatedEvent,
32
+ SMSSentEvent,
33
+ EmailSentEvent,
34
+ ShortLinkCreatedEvent,
28
35
  };
@@ -1,48 +1,28 @@
1
- const defs = require("../defs").http;
2
-
3
1
  module.exports = function handleResponseError(error) {
4
2
  const { config: originalReq } = error;
5
3
  if (!error.response) return Promise.reject(error);
6
4
  const { status, data } = error.response;
7
- const errorCode = data && data.error && data.error.code;
8
- const errorMessage = data && data.error && data.error.message;
5
+ const errorType = data?.error?.type;
6
+ const errorMessage = data?.error?.message;
9
7
 
10
8
  try {
11
9
  const expectedError = status >= 400 && status < 500;
10
+ const newTokensNeeded = expectedError && errorType === "TokenExpiredError";
12
11
 
13
- if (errorMessage && errorMessage === "Login Required") {
12
+ if (expectedError && errorMessage === "Login Required") {
14
13
  this.onLoginRequired();
15
14
  return Promise.reject(error);
16
15
  }
17
16
 
18
- // prettier-ignore
19
- const newTokensNeeded = expectedError && errorCode === 1004 && status === 401;
20
-
21
- if (status === 401 && !newTokensNeeded) {
22
- return Promise.reject(error);
23
- }
24
- if (status === 400 && errorCode === 1010) {
17
+ if (expectedError && errorMessage === "No token provided") {
25
18
  this.onLoginRequired();
26
19
  return Promise.reject(error);
27
20
  }
28
21
 
29
- if (newTokensNeeded) {
30
- return this.RefreshToken({
31
- headers: {
32
- [defs.refreshTokenHeader]: this.refreshToken,
33
- },
34
- }).then((response) => {
35
- // update headers with the new tokens
36
- if (
37
- response &&
38
- response.headers &&
39
- response.headers[this.authTokenHeaderKey]
40
- ) {
41
- const newToken = response.headers[this.authTokenHeaderKey];
42
- originalReq.headers[defs.authTokenHeader] = newToken;
43
- this.authToken = newToken;
44
- return this.http(originalReq);
45
- }
22
+ if (expectedError && newTokensNeeded) {
23
+ return this.RefreshToken().then(() => {
24
+ // retry the original request with the new token
25
+ return this.http(originalReq);
46
26
  });
47
27
  }
48
28
  } catch (error) {
@@ -4,11 +4,11 @@ module.exports = function handleResponseSuccess(response) {
4
4
  response.pagination = response.data.pagination;
5
5
  response.data = response.data.data;
6
6
  }
7
- if (response.headers[this.authTokenHeaderKey]) {
7
+ if (!this.isBrowser && response.headers[this.authTokenHeaderKey]) {
8
8
  this.authToken = response.headers[this.authTokenHeaderKey];
9
9
  }
10
10
 
11
- if (response.headers[this.refreshTokenHeaderKey]) {
11
+ if (!this.isBrowser && response.headers[this.refreshTokenHeaderKey]) {
12
12
  this.refreshToken = response.headers[this.refreshTokenHeaderKey];
13
13
  }
14
14
  return response;
package/http/index.js CHANGED
@@ -1,5 +1,4 @@
1
1
  const { EventEmitter } = require("events");
2
- const axios = require("axios");
3
2
  const defs = require("../defs").http;
4
3
  const handleResponseError = require("./handleResponseError");
5
4
  const handleResponseSuccess = require("./handleResponseSuccess");
@@ -30,20 +29,28 @@ function useCaseMethodFactory(Client) {
30
29
  */
31
30
 
32
31
  //eslint-disable-next-line no-inner-declarations
33
- function UseCase(options) {
34
- if (!options) options = {};
32
+ function UseCase(requestData, options = {}) {
33
+ if (!this._init) {
34
+ // wait a second for the client to initialize
35
+ return new Promise((resolve) => {
36
+ setTimeout(() => {
37
+ resolve(UseCase.call(this, requestData));
38
+ }, 500);
39
+ });
40
+ }
41
+ if (!requestData) requestData = {};
35
42
 
36
43
  // get parameters from path
37
44
  const pathParams = path.match(/:[a-zA-Z0-9]+/g);
38
45
 
39
- const { data, params, query, headers } = options;
46
+ const { data, query, headers } = requestData;
40
47
 
41
48
  // replace path parameters with values from params
42
49
  let url = path;
43
- if (pathParams && params) {
50
+ if (pathParams && data) {
44
51
  for (const param of pathParams) {
45
52
  const paramName = param.replace(":", "");
46
- url = url.replace(param, params[paramName]);
53
+ url = url.replace(param, data[paramName]);
47
54
  }
48
55
  }
49
56
 
@@ -60,6 +67,7 @@ function useCaseMethodFactory(Client) {
60
67
  const config = {
61
68
  method: method.toLowerCase(),
62
69
  url: url,
70
+ ...options,
63
71
  };
64
72
 
65
73
  if (data) config.data = data;
@@ -77,7 +85,7 @@ function useCaseMethodFactory(Client) {
77
85
  class KohostApiClient extends EventEmitter {
78
86
  /*
79
87
  @param {Object} options - The options to create the client
80
- @param {String} options.tenantId - The tenant ID
88
+ @param {String} options.propertyId - The property ID
81
89
  @param {String} options.url - The base URL for the API endpint
82
90
  @param {Object} options.headers - Additional headers to send with each request
83
91
 
@@ -85,35 +93,44 @@ class KohostApiClient extends EventEmitter {
85
93
  constructor(
86
94
  options = {
87
95
  url: "",
88
- tenantId: "",
96
+ propertyId: "",
89
97
  headers: {},
90
98
  }
91
99
  ) {
92
100
  super();
93
101
  if (!options.url) throw new Error("options.url is required");
94
- if (!options.tenantId) throw new Error("options.tenant is required");
102
+ if (!options.propertyId) throw new Error("options.property is required");
95
103
  this.options = options;
96
104
  // eslint-disable-next-line no-undef
97
- this.isBrower = typeof window !== "undefined";
98
- this._http = axios.create({
99
- baseURL: options.url,
100
- responseType: "json",
101
- headers: {
102
- "Content-Type": "application/json",
103
- Accept: "application/json",
104
- [defs.tenantHeader]: options.tenantId,
105
- ...options.headers,
106
- },
107
- });
108
-
109
- this._http.interceptors.response.use(
110
- handleResponseSuccess.bind(this),
111
- handleResponseError.bind(this)
112
- );
113
-
114
- this._http.interceptors.request.use((config) => {
115
- config.headers[defs.authTokenHeader] = this.authToken;
116
- return config;
105
+ this.isBrowser = typeof window !== "undefined";
106
+ this._init = false;
107
+
108
+ import("axios").then((axiosModule) => {
109
+ const axios = axiosModule.default;
110
+ this._http = axios.create({
111
+ baseURL: options.url,
112
+ responseType: "json",
113
+ withCredentials: true,
114
+ headers: {
115
+ "Content-Type": "application/json",
116
+ Accept: "application/json",
117
+ [defs.propertyHeader]: options.propertyId,
118
+ ...options.headers,
119
+ },
120
+ });
121
+
122
+ this._http.interceptors.response.use(
123
+ handleResponseSuccess.bind(this),
124
+ handleResponseError.bind(this)
125
+ );
126
+
127
+ this._http.interceptors.request.use((config) => {
128
+ if (!this.isBrowser) {
129
+ config.headers[defs.authTokenHeader] = this.authToken;
130
+ }
131
+ return config;
132
+ });
133
+ this._init = true;
117
134
  });
118
135
  }
119
136
 
@@ -126,17 +143,11 @@ class KohostApiClient extends EventEmitter {
126
143
  }
127
144
 
128
145
  get lsTokenKey() {
129
- return `${this.options.tenantId}_${defs.authTokenHeader}`;
146
+ return `${this.options.propertyId}_${defs.authTokenHeader}`;
130
147
  }
131
148
 
132
149
  get authToken() {
133
- if (this.isBrower) {
134
- // get token from localStorage
135
- // eslint-disable-next-line no-undef
136
- return window.localStorage.getItem(this.lsTokenKey);
137
- } else {
138
- return this._authToken;
139
- }
150
+ return this._authToken;
140
151
  }
141
152
 
142
153
  /*
@@ -145,12 +156,11 @@ class KohostApiClient extends EventEmitter {
145
156
  */
146
157
 
147
158
  set authToken(token) {
148
- if (this.isBrower) {
149
- // eslint-disable-next-line no-undef
150
- window.localStorage.setItem(this.lsTokenKey, token);
151
- } else {
152
- this._authToken = token;
153
- }
159
+ this._authToken = token;
160
+ }
161
+
162
+ onLoginRequired() {
163
+ this.emit("LoginRequired");
154
164
  }
155
165
  }
156
166
 
package/index.js CHANGED
@@ -15,8 +15,8 @@ const Kohost = {
15
15
  defs,
16
16
  Client: HttpClient,
17
17
  utils: {
18
- getFormalDeviceType,
19
- getDeviceTypes,
18
+ getFormalDeviceType: getFormalDeviceType,
19
+ getDeviceTypes: getDeviceTypes,
20
20
  },
21
21
  };
22
22
 
@@ -0,0 +1,29 @@
1
+ // create the Credential Model
2
+ const schemas = require("../utils/schema");
3
+ const schema = require("../schemas/credential.json");
4
+ const Kohost = require("./kohost");
5
+
6
+ schemas.add(schema);
7
+ const validator = schemas.compile(schema);
8
+
9
+ class Credential extends Kohost {
10
+ constructor(data) {
11
+ super(data);
12
+ }
13
+ }
14
+
15
+ Object.defineProperty(Credential.prototype, "schema", {
16
+ value: schema,
17
+ });
18
+
19
+ Object.defineProperty(Credential.prototype, "validator", {
20
+ get: function () {
21
+ return validator;
22
+ },
23
+ });
24
+
25
+ Object.defineProperty(Credential, "validProperties", {
26
+ value: Object.keys(schema.properties),
27
+ });
28
+
29
+ module.exports = Credential;
package/models/gateway.js CHANGED
@@ -6,18 +6,10 @@ const Kohost = require("./kohost");
6
6
  schemas.add(schema);
7
7
  const validator = schemas.compile(schema);
8
8
 
9
- const { customAlphabet } = require("nanoid/async");
10
- const characters =
11
- "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
12
-
13
9
  class Gateway extends Kohost {
14
10
  constructor(data) {
15
11
  super(data);
16
12
  }
17
-
18
- static async generateAuthKey(length = 64) {
19
- return await customAlphabet(characters, length)();
20
- }
21
13
  }
22
14
 
23
15
  Object.defineProperty(Gateway.prototype, "schema", {
@@ -0,0 +1,32 @@
1
+ const schemas = require("../utils/schema");
2
+ const schema = require("../schemas/identification.json");
3
+ const Kohost = require("./kohost");
4
+
5
+ schemas.add(schema);
6
+ const validator = schemas.compile(schema);
7
+
8
+ class Identification extends Kohost {
9
+ constructor(data) {
10
+ super(data);
11
+ }
12
+
13
+ get isExpired() {
14
+ return new Date(this.expirationDate) < new Date();
15
+ }
16
+ }
17
+
18
+ Object.defineProperty(Identification.prototype, "schema", {
19
+ value: schema,
20
+ });
21
+
22
+ Object.defineProperty(Identification.prototype, "validator", {
23
+ get: function () {
24
+ return validator;
25
+ },
26
+ });
27
+
28
+ Object.defineProperty(Identification, "validProperties", {
29
+ value: Object.keys(schema.properties),
30
+ });
31
+
32
+ module.exports = Identification;