@kohost/api-client 7.16.0 → 7.18.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 (59) hide show
  1. package/dist/.tsbuildinfo +1 -1
  2. package/dist/commands/getGroups.d.ts +8 -0
  3. package/dist/commands/getGroups.js +17 -0
  4. package/dist/commands/getGroups.js.map +1 -0
  5. package/dist/commands/index.d.ts +1 -0
  6. package/dist/commands/index.js +3 -1
  7. package/dist/commands/index.js.map +1 -1
  8. package/dist/httpClient.js.map +1 -1
  9. package/dist/lib/emergencyContacts.d.ts +10 -0
  10. package/dist/lib/index.d.ts +1 -0
  11. package/dist/lib/index.js +3 -1
  12. package/dist/lib/index.js.map +1 -1
  13. package/dist/lib/sis.d.ts +108 -0
  14. package/dist/lib/sis.js +11 -0
  15. package/dist/lib/sis.js.map +1 -0
  16. package/dist/models/entity.js.map +1 -1
  17. package/dist/models/group.js +1 -0
  18. package/dist/models/group.js.map +1 -1
  19. package/dist/models/system.js +3 -0
  20. package/dist/models/system.js.map +1 -1
  21. package/dist/models/systemUser.js +1 -1
  22. package/dist/models/systemUser.js.map +1 -1
  23. package/dist/schemas/announcement.d.ts +16 -1
  24. package/dist/schemas/announcement.js +16 -1
  25. package/dist/schemas/announcement.js.map +1 -1
  26. package/dist/schemas/definitions.d.ts +96 -3
  27. package/dist/schemas/definitions.js +58 -3
  28. package/dist/schemas/definitions.js.map +1 -1
  29. package/dist/schemas/group.d.ts +4 -0
  30. package/dist/schemas/group.js +4 -0
  31. package/dist/schemas/group.js.map +1 -1
  32. package/dist/schemas/system.d.ts +27 -0
  33. package/dist/schemas/system.js +33 -1
  34. package/dist/schemas/system.js.map +1 -1
  35. package/dist/schemas/systemUser.d.ts +2 -3
  36. package/dist/schemas/systemUser.js +1 -4
  37. package/dist/schemas/systemUser.js.map +1 -1
  38. package/dist/schemas/ticket.d.ts +33 -5
  39. package/dist/schemas/ticket.js +35 -10
  40. package/dist/schemas/ticket.js.map +1 -1
  41. package/dist/useCases/describeSISSync.d.ts +27 -0
  42. package/dist/useCases/describeSISSync.js +47 -0
  43. package/dist/useCases/describeSISSync.js.map +1 -0
  44. package/dist/useCases/index.d.ts +5 -0
  45. package/dist/useCases/index.js +11 -1
  46. package/dist/useCases/index.js.map +1 -1
  47. package/dist/useCases/listSISHouseholds.d.ts +27 -0
  48. package/dist/useCases/listSISHouseholds.js +47 -0
  49. package/dist/useCases/listSISHouseholds.js.map +1 -0
  50. package/dist/useCases/listSISPeople.d.ts +27 -0
  51. package/dist/useCases/listSISPeople.js +47 -0
  52. package/dist/useCases/listSISPeople.js.map +1 -0
  53. package/dist/useCases/previewAnnouncement.d.ts +27 -0
  54. package/dist/useCases/previewAnnouncement.js +47 -0
  55. package/dist/useCases/previewAnnouncement.js.map +1 -0
  56. package/dist/useCases/syncSISRoster.d.ts +27 -0
  57. package/dist/useCases/syncSISRoster.js +47 -0
  58. package/dist/useCases/syncSISRoster.js.map +1 -0
  59. package/package.json +5 -5
@@ -0,0 +1,8 @@
1
+ import { Command } from "./command.js";
2
+ export declare class GetGroups extends Command {
3
+ constructor({ id, ...rest }: {
4
+ [x: string]: any;
5
+ id: any;
6
+ });
7
+ get name(): string;
8
+ }
@@ -0,0 +1,17 @@
1
+ import { Command } from "./command.js";
2
+ //#region .generated/commands/getGroups.js
3
+ var GetGroups = class extends Command {
4
+ constructor({ id, ...rest }) {
5
+ super({
6
+ id,
7
+ ...rest
8
+ });
9
+ }
10
+ get name() {
11
+ return "GetGroups";
12
+ }
13
+ };
14
+ //#endregion
15
+ export { GetGroups };
16
+
17
+ //# sourceMappingURL=getGroups.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getGroups.js","names":[],"sources":["../../.generated/commands/getGroups.js"],"sourcesContent":["import { Command } from \"./command\";\n\nexport class GetGroups extends Command {\n constructor({ id, ...rest }) {\n super({ id, ...rest });\n }\n\n get name() {\n return \"GetGroups\";\n }\n}\n"],"mappings":";;AAEA,IAAa,YAAb,cAA+B,QAAQ;CACrC,YAAY,EAAE,IAAI,GAAG,QAAQ;EAC3B,MAAM;GAAE;GAAI,GAAG;EAAK,CAAC;CACvB;CAEA,IAAI,OAAO;EACT,OAAO;CACT;AACF"}
@@ -2,6 +2,7 @@ export * from "./command.js";
2
2
  export * from "./createImageUploadEndpoint.js";
3
3
  export * from "./createShortLink.js";
4
4
  export * from "./getCategories.js";
5
+ export * from "./getGroups.js";
5
6
  export * from "./getMobileKey.js";
6
7
  export * from "./getProducts.js";
7
8
  export * from "./getRooms.js";
@@ -3,6 +3,7 @@ import { Command } from "./command.js";
3
3
  import { CreateImageUploadEndpoint } from "./createImageUploadEndpoint.js";
4
4
  import { CreateShortLink } from "./createShortLink.js";
5
5
  import { GetCategories } from "./getCategories.js";
6
+ import { GetGroups } from "./getGroups.js";
6
7
  import { GetMobileKey } from "./getMobileKey.js";
7
8
  import { GetProducts } from "./getProducts.js";
8
9
  import { GetRooms } from "./getRooms.js";
@@ -27,6 +28,7 @@ var commands_exports = /* @__PURE__ */ __exportAll({
27
28
  CreateImageUploadEndpoint: () => CreateImageUploadEndpoint,
28
29
  CreateShortLink: () => CreateShortLink,
29
30
  GetCategories: () => GetCategories,
31
+ GetGroups: () => GetGroups,
30
32
  GetMobileKey: () => GetMobileKey,
31
33
  GetProducts: () => GetProducts,
32
34
  GetRooms: () => GetRooms,
@@ -47,6 +49,6 @@ var commands_exports = /* @__PURE__ */ __exportAll({
47
49
  UploadImage: () => UploadImage
48
50
  });
49
51
  //#endregion
50
- export { Command, CreateImageUploadEndpoint, CreateShortLink, GetCategories, GetMobileKey, GetProducts, GetRooms, GetUsers, OCRDocument, SendEmail, SendSMS, SetAlarm, SetCourtesy, SetDimmer, SetLock, SetMedia, SetScene, SetSwitch, SetThermostat, SetWindowCovering, UpdateUser, UploadImage, commands_exports };
52
+ export { Command, CreateImageUploadEndpoint, CreateShortLink, GetCategories, GetGroups, GetMobileKey, GetProducts, GetRooms, GetUsers, OCRDocument, SendEmail, SendSMS, SetAlarm, SetCourtesy, SetDimmer, SetLock, SetMedia, SetScene, SetSwitch, SetThermostat, SetWindowCovering, UpdateUser, UploadImage, commands_exports };
51
53
 
52
54
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../.generated/commands/index.js"],"sourcesContent":["// This file is auto-generated. Do not edit this file manually.\n// Generated on: 2025-12-09T17:25:44.156Z\n\nexport * from \"./command.js\";\nexport * from \"./createImageUploadEndpoint.js\";\nexport * from \"./createShortLink.js\";\nexport * from \"./getCategories.js\";\nexport * from \"./getMobileKey.js\";\nexport * from \"./getProducts.js\";\nexport * from \"./getRooms.js\";\nexport * from \"./getUsers.js\";\nexport * from \"./ocrDocument.js\";\nexport * from \"./sendEmail.js\";\nexport * from \"./sendSMS.js\";\nexport * from \"./setAlarm.js\";\nexport * from \"./setCourtesy.js\";\nexport * from \"./setDimmer.js\";\nexport * from \"./setLock.js\";\nexport * from \"./setMedia.js\";\nexport * from \"./setScene.js\";\nexport * from \"./setSwitch.js\";\nexport * from \"./setThermostat.js\";\nexport * from \"./setWindowCovering.js\";\nexport * from \"./updateUser.js\";\nexport * from \"./uploadImage.js\";\n"],"mappings":""}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../.generated/commands/index.js"],"sourcesContent":["// This file is auto-generated. Do not edit this file manually.\n// Generated on: 2025-12-09T17:25:44.156Z\n\nexport * from \"./command.js\";\nexport * from \"./createImageUploadEndpoint.js\";\nexport * from \"./createShortLink.js\";\nexport * from \"./getCategories.js\";\nexport * from \"./getGroups.js\";\nexport * from \"./getMobileKey.js\";\nexport * from \"./getProducts.js\";\nexport * from \"./getRooms.js\";\nexport * from \"./getUsers.js\";\nexport * from \"./ocrDocument.js\";\nexport * from \"./sendEmail.js\";\nexport * from \"./sendSMS.js\";\nexport * from \"./setAlarm.js\";\nexport * from \"./setCourtesy.js\";\nexport * from \"./setDimmer.js\";\nexport * from \"./setLock.js\";\nexport * from \"./setMedia.js\";\nexport * from \"./setScene.js\";\nexport * from \"./setSwitch.js\";\nexport * from \"./setThermostat.js\";\nexport * from \"./setWindowCovering.js\";\nexport * from \"./updateUser.js\";\nexport * from \"./uploadImage.js\";\n"],"mappings":""}
@@ -1 +1 @@
1
- {"version":3,"file":"httpClient.js","names":["#onSuccess","#onError","#onPhoneVerificationRequired","#onLoginRequired"],"sources":["../.generated/httpClient.js"],"sourcesContent":["export class KohostHTTPClient {\n #onSuccess;\n #onError;\n\n /** \n @param {Object} options - The options to create the client\n @param {String} options.organizationId - The organization ID\n @param {String} options.propertyId - The property ID\n @param {String | URL} options.url - The base URL for the API endpint\n @param {String} options.apiKey - The API key to use for requests\n @param {Headers} options.headers - Additional headers to send with each request\n @param {Function} options.onSuccess - A callback to handle successful responses\n @param {Function} options.onError - A callback to handle errors\n */\n constructor(\n options = {\n url: \"\",\n propertyId: \"\",\n organizationId: \"\",\n apiKey: \"\",\n headers: new Headers({}),\n onSuccess: (response) => response,\n onError: (error) => error,\n },\n ) {\n if (!options.url) throw new Error(\"options.url is required\");\n this.options = options;\n\n this.baseUrl = new URL(options.url);\n this.headers = new Headers({\n \"Content-Type\": \"application/json\",\n Accept: \"application/json\",\n ...options.headers,\n });\n\n if (options.apiKey) {\n this.headers.set(KohostHTTPClient.defs.apiKeyHeader, options.apiKey);\n }\n\n if (options.propertyId) {\n this.propertyId = options.propertyId;\n }\n\n if (options.organizationId) {\n this.organizationId = options.organizationId;\n }\n\n this.#onSuccess = options.onSuccess\n ? options.onSuccess\n : (response) => response;\n\n this.#onError = options.onError ? options.onError : (error) => error;\n\n this.callbacks = {};\n }\n\n /**\n *\n * @param {\"LoginRequired\" | \"PhoneVerificationRequired\"} event\n * @param {Function} callback\n */\n on(event, callback) {\n if (typeof callback !== \"function\") {\n throw new Error(\"Callback must be a function\");\n }\n if (!this.callbacks[event]) {\n this.callbacks[event] = [];\n }\n this.callbacks[event].push(callback);\n }\n\n emit(event, ...args) {\n if (this.callbacks[event]) {\n this.callbacks[event].forEach((callback) => callback(...args));\n }\n }\n\n /**\n * @param {string} orgId\n * @returns {void}\n * @memberof KohostApiClient\n * @example\n * client.organizationId = \"1234\";\n */\n set organizationId(orgId) {\n const key = KohostHTTPClient.defs.organizationHeader;\n this.headers.set(key, orgId);\n }\n\n get organizationId() {\n const key = KohostHTTPClient.defs.organizationHeader;\n return this.headers.get(key);\n }\n\n /**\n * @param {string} propertyId\n * @returns {void}\n * @memberof KohostApiClient\n * @example\n * client.propertyId = \"1234\";\n */\n\n set propertyId(propertyId) {\n const key = KohostHTTPClient.defs.propertyHeader;\n this.headers.set(key, propertyId);\n }\n\n get propertyId() {\n const key = KohostHTTPClient.defs.propertyHeader;\n return this.headers.get(key);\n }\n\n static get defs() {\n return {\n apiKeyHeader: \"X-Api-Key\",\n propertyHeader: \"X-Property-Id\",\n organizationHeader: \"X-Organization-Id\",\n };\n }\n\n /**\n * @typedef {keyof typeof import('./useCases')} CommandName\n * @typedef {import('./useCases')[CommandName]} Command\n *\n * @param {Command} command\n */\n async send(command) {\n const commandConfig = command.config;\n const request = this.createRequest(commandConfig);\n\n const response = await fetch(request);\n\n const isJsonResponse =\n response.headers.get(\"Content-Type\")?.includes(\"application/json\") ||\n false;\n\n const responseData = isJsonResponse ? await response.json() : response.body;\n\n if (!response.ok) {\n let error = responseData?.error || new Error(response.statusText);\n\n const status = response.status;\n const errorMessage = responseData?.error?.message;\n\n const expectedError = status >= 400 && status < 500;\n\n if (expectedError && errorMessage === \"Phone Verification is required\") {\n this.#onPhoneVerificationRequired();\n return Promise.reject(error);\n }\n\n if (expectedError && errorMessage === \"Login Required\") {\n this.#onLoginRequired();\n return Promise.reject(error);\n }\n\n if (\n expectedError &&\n errorMessage === \"No auth header or cookie provided\"\n ) {\n this.#onLoginRequired();\n return Promise.reject(error);\n }\n\n error = this.#onError(error);\n\n return Promise.reject(error);\n }\n\n return this.#onSuccess(responseData);\n }\n\n #onLoginRequired() {\n this.emit(\"LoginRequired\");\n }\n\n #onPhoneVerificationRequired() {\n this.emit(\"PhoneVerificationRequired\");\n }\n\n /**\n * @param {Command} config\n * @returns {Request}\n */\n createRequest(config) {\n if (typeof config.headers !== \"object\") {\n config.headers = {};\n }\n\n let apiPath = config.url;\n\n if (apiPath.startsWith(\"/\")) {\n apiPath = `.${apiPath}`;\n }\n const url = new URL(apiPath, this.baseUrl);\n const method = config.method?.toUpperCase() || \"GET\";\n\n // Add parameters to URL if they exist\n if (config.params && typeof config.params === \"object\") {\n Object.entries(config.params).forEach(([key, value]) => {\n // Handle array values\n if (Array.isArray(value)) {\n value.forEach((item) => {\n if (typeof item === \"object\" && item !== null) {\n Object.entries(item).forEach(([itemKey, itemValue]) => {\n url.searchParams.append(`${key}[][${itemKey}]`, itemValue);\n });\n } else {\n url.searchParams.append(`${key}[]`, item);\n }\n });\n }\n // Handle null/undefined\n else if (value === null || value === undefined) {\n url.searchParams.append(key, \"\");\n }\n // Handle nested objects\n else if (typeof value === \"object\") {\n Object.entries(value).forEach(([nestedKey, nestedValue]) => {\n if (Array.isArray(nestedValue)) {\n nestedValue.forEach((item) => {\n url.searchParams.append(`${key}[${nestedKey}][]`, item);\n });\n } else {\n url.searchParams.append(`${key}[${nestedKey}]`, nestedValue);\n }\n });\n }\n // Handle primitive values\n else {\n url.searchParams.append(key, value);\n }\n });\n }\n\n const headers = new Headers(this.headers);\n // Add any additional headers\n if (config.headers) {\n Object.keys(config.headers).forEach((key) => {\n headers.set(key, config.headers[key]);\n });\n }\n\n const body =\n config.data !== null && [\"POST\", \"PUT\", \"PATCH\"].includes(method)\n ? headers.get(\"Content-Type\") === \"application/json\"\n ? JSON.stringify(config.data)\n : config.data\n : undefined;\n\n const request = new Request(url, {\n method: method,\n headers: headers,\n credentials: \"include\",\n body: body,\n });\n\n return request;\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"httpClient.js","names":[],"sources":["../.generated/httpClient.js"],"sourcesContent":["export class KohostHTTPClient {\n #onSuccess;\n #onError;\n\n /** \n @param {Object} options - The options to create the client\n @param {String} options.organizationId - The organization ID\n @param {String} options.propertyId - The property ID\n @param {String | URL} options.url - The base URL for the API endpint\n @param {String} options.apiKey - The API key to use for requests\n @param {Headers} options.headers - Additional headers to send with each request\n @param {Function} options.onSuccess - A callback to handle successful responses\n @param {Function} options.onError - A callback to handle errors\n */\n constructor(\n options = {\n url: \"\",\n propertyId: \"\",\n organizationId: \"\",\n apiKey: \"\",\n headers: new Headers({}),\n onSuccess: (response) => response,\n onError: (error) => error,\n },\n ) {\n if (!options.url) throw new Error(\"options.url is required\");\n this.options = options;\n\n this.baseUrl = new URL(options.url);\n this.headers = new Headers({\n \"Content-Type\": \"application/json\",\n Accept: \"application/json\",\n ...options.headers,\n });\n\n if (options.apiKey) {\n this.headers.set(KohostHTTPClient.defs.apiKeyHeader, options.apiKey);\n }\n\n if (options.propertyId) {\n this.propertyId = options.propertyId;\n }\n\n if (options.organizationId) {\n this.organizationId = options.organizationId;\n }\n\n this.#onSuccess = options.onSuccess\n ? options.onSuccess\n : (response) => response;\n\n this.#onError = options.onError ? options.onError : (error) => error;\n\n this.callbacks = {};\n }\n\n /**\n *\n * @param {\"LoginRequired\" | \"PhoneVerificationRequired\"} event\n * @param {Function} callback\n */\n on(event, callback) {\n if (typeof callback !== \"function\") {\n throw new Error(\"Callback must be a function\");\n }\n if (!this.callbacks[event]) {\n this.callbacks[event] = [];\n }\n this.callbacks[event].push(callback);\n }\n\n emit(event, ...args) {\n if (this.callbacks[event]) {\n this.callbacks[event].forEach((callback) => callback(...args));\n }\n }\n\n /**\n * @param {string} orgId\n * @returns {void}\n * @memberof KohostApiClient\n * @example\n * client.organizationId = \"1234\";\n */\n set organizationId(orgId) {\n const key = KohostHTTPClient.defs.organizationHeader;\n this.headers.set(key, orgId);\n }\n\n get organizationId() {\n const key = KohostHTTPClient.defs.organizationHeader;\n return this.headers.get(key);\n }\n\n /**\n * @param {string} propertyId\n * @returns {void}\n * @memberof KohostApiClient\n * @example\n * client.propertyId = \"1234\";\n */\n\n set propertyId(propertyId) {\n const key = KohostHTTPClient.defs.propertyHeader;\n this.headers.set(key, propertyId);\n }\n\n get propertyId() {\n const key = KohostHTTPClient.defs.propertyHeader;\n return this.headers.get(key);\n }\n\n static get defs() {\n return {\n apiKeyHeader: \"X-Api-Key\",\n propertyHeader: \"X-Property-Id\",\n organizationHeader: \"X-Organization-Id\",\n };\n }\n\n /**\n * @typedef {keyof typeof import('./useCases')} CommandName\n * @typedef {import('./useCases')[CommandName]} Command\n *\n * @param {Command} command\n */\n async send(command) {\n const commandConfig = command.config;\n const request = this.createRequest(commandConfig);\n\n const response = await fetch(request);\n\n const isJsonResponse =\n response.headers.get(\"Content-Type\")?.includes(\"application/json\") ||\n false;\n\n const responseData = isJsonResponse ? await response.json() : response.body;\n\n if (!response.ok) {\n let error = responseData?.error || new Error(response.statusText);\n\n const status = response.status;\n const errorMessage = responseData?.error?.message;\n\n const expectedError = status >= 400 && status < 500;\n\n if (expectedError && errorMessage === \"Phone Verification is required\") {\n this.#onPhoneVerificationRequired();\n return Promise.reject(error);\n }\n\n if (expectedError && errorMessage === \"Login Required\") {\n this.#onLoginRequired();\n return Promise.reject(error);\n }\n\n if (\n expectedError &&\n errorMessage === \"No auth header or cookie provided\"\n ) {\n this.#onLoginRequired();\n return Promise.reject(error);\n }\n\n error = this.#onError(error);\n\n return Promise.reject(error);\n }\n\n return this.#onSuccess(responseData);\n }\n\n #onLoginRequired() {\n this.emit(\"LoginRequired\");\n }\n\n #onPhoneVerificationRequired() {\n this.emit(\"PhoneVerificationRequired\");\n }\n\n /**\n * @param {Command} config\n * @returns {Request}\n */\n createRequest(config) {\n if (typeof config.headers !== \"object\") {\n config.headers = {};\n }\n\n let apiPath = config.url;\n\n if (apiPath.startsWith(\"/\")) {\n apiPath = `.${apiPath}`;\n }\n const url = new URL(apiPath, this.baseUrl);\n const method = config.method?.toUpperCase() || \"GET\";\n\n // Add parameters to URL if they exist\n if (config.params && typeof config.params === \"object\") {\n Object.entries(config.params).forEach(([key, value]) => {\n // Handle array values\n if (Array.isArray(value)) {\n value.forEach((item) => {\n if (typeof item === \"object\" && item !== null) {\n Object.entries(item).forEach(([itemKey, itemValue]) => {\n url.searchParams.append(`${key}[][${itemKey}]`, itemValue);\n });\n } else {\n url.searchParams.append(`${key}[]`, item);\n }\n });\n }\n // Handle null/undefined\n else if (value === null || value === undefined) {\n url.searchParams.append(key, \"\");\n }\n // Handle nested objects\n else if (typeof value === \"object\") {\n Object.entries(value).forEach(([nestedKey, nestedValue]) => {\n if (Array.isArray(nestedValue)) {\n nestedValue.forEach((item) => {\n url.searchParams.append(`${key}[${nestedKey}][]`, item);\n });\n } else {\n url.searchParams.append(`${key}[${nestedKey}]`, nestedValue);\n }\n });\n }\n // Handle primitive values\n else {\n url.searchParams.append(key, value);\n }\n });\n }\n\n const headers = new Headers(this.headers);\n // Add any additional headers\n if (config.headers) {\n Object.keys(config.headers).forEach((key) => {\n headers.set(key, config.headers[key]);\n });\n }\n\n const body =\n config.data !== null && [\"POST\", \"PUT\", \"PATCH\"].includes(method)\n ? headers.get(\"Content-Type\") === \"application/json\"\n ? JSON.stringify(config.data)\n : config.data\n : undefined;\n\n const request = new Request(url, {\n method: method,\n headers: headers,\n credentials: \"include\",\n body: body,\n });\n\n return request;\n }\n}\n"],"mappings":"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"}
@@ -7,7 +7,12 @@ export interface EmergencyContactRoleGroup {
7
7
  }
8
8
  export interface ExternalGroupCounts {
9
9
  total: number;
10
+ /** Contacts with a phone or an email. */
10
11
  reachable: number;
12
+ /** Contacts with a phone, the SMS-only reach. */
13
+ sms: number;
14
+ /** Contacts with an email, the email-only reach. */
15
+ email: number;
11
16
  }
12
17
  export interface EmergencyContactAudience {
13
18
  driver: SISDriver;
@@ -30,6 +35,11 @@ export interface EmergencyContactPerson {
30
35
  relationship: string | null;
31
36
  group: ExternalAudienceGroup;
32
37
  reachable: boolean;
38
+ /** Per-channel opt-out state; a routine send skips the channels marked true. */
39
+ optedOut?: {
40
+ sms: boolean;
41
+ email: boolean;
42
+ };
33
43
  }
34
44
  export interface EmergencyContactPeople {
35
45
  driver: SISDriver;
@@ -6,6 +6,7 @@ export { SOS_AUDIENCES, type SOSAudience } from "./sosAudiences.js";
6
6
  export { MESSAGE_ERROR_CATEGORIES, categoryForMessageErrorCode, isMessageErrorCategory, type MessageErrorCategory, } from "./messageErrorCodes.js";
7
7
  export { DELIVERY_OUTCOMES, deliveryOutcomeForStatus, type DeliveryOutcome, } from "./deliveryStatus.js";
8
8
  export type { EmergencyContactAudience, EmergencyContactPeople, EmergencyContactPerson, EmergencyContactRoleGroup, ExternalGroupCounts, } from "./emergencyContacts.js";
9
+ export { SIS_BUCKETS, type SISBucket, type SISHousehold, type SISHouseholdMember, type SISHouseholds, type SISHouseholdsQuery, type SISPage, type SISPeople, type SISPeopleQuery, type SISPeopleSort, type SISPerson, type SISSortDirection, type SISSyncResult, type SISSyncState, } from "./sis.js";
9
10
  export { MAX_MESSAGE_ATTACHMENTS } from "./messageAttachments.js";
10
11
  export { DEFAULT_MARKUP_TIERS, DEFAULT_DNE_AMOUNT, resolveMarkupTierTable, keyedMarkupPercent, DEFAULT_TAX_RATE, derivePrice, markupPercentFromPrice, signedMarkupPercent, billTotal, billTaxAmount, billGrandTotal, formatMoney, } from "./money.js";
11
12
  export { effectiveTaxRate, taxableSubtotal, billTotals, resolveBillTaxExempt, settledBillTotal, billEffectiveDate, type BillTaxFields, type TaxableLine, type SettledBillTotalSource, type BillEffectiveDateSource, } from "./bills.js";
package/dist/lib/index.js CHANGED
@@ -6,6 +6,7 @@ import { SIS_DRIVERS, isSISDriver } from "./sisDrivers.js";
6
6
  import { SOS_AUDIENCES } from "./sosAudiences.js";
7
7
  import { MESSAGE_ERROR_CATEGORIES, categoryForMessageErrorCode, isMessageErrorCategory } from "./messageErrorCodes.js";
8
8
  import { DELIVERY_OUTCOMES, deliveryOutcomeForStatus } from "./deliveryStatus.js";
9
+ import { SIS_BUCKETS } from "./sis.js";
9
10
  import { MAX_MESSAGE_ATTACHMENTS } from "./messageAttachments.js";
10
11
  import { DEFAULT_DNE_AMOUNT, DEFAULT_MARKUP_TIERS, DEFAULT_TAX_RATE, billGrandTotal, billTaxAmount, billTotal, derivePrice, formatMoney, keyedMarkupPercent, markupPercentFromPrice, resolveMarkupTierTable, signedMarkupPercent } from "./money.js";
11
12
  import { billEffectiveDate, billTotals, effectiveTaxRate, resolveBillTaxExempt, settledBillTotal, taxableSubtotal } from "./bills.js";
@@ -22,6 +23,7 @@ var lib_exports = /* @__PURE__ */ __exportAll({
22
23
  KFC_STATS_TIMEZONE: () => KFC_STATS_TIMEZONE,
23
24
  MAX_MESSAGE_ATTACHMENTS: () => 15,
24
25
  MESSAGE_ERROR_CATEGORIES: () => MESSAGE_ERROR_CATEGORIES,
26
+ SIS_BUCKETS: () => SIS_BUCKETS,
25
27
  SIS_DRIVERS: () => SIS_DRIVERS,
26
28
  SOS_AUDIENCES: () => SOS_AUDIENCES,
27
29
  SYSTEM_CATEGORIES: () => SYSTEM_CATEGORIES,
@@ -55,6 +57,6 @@ var lib_exports = /* @__PURE__ */ __exportAll({
55
57
  taxableSubtotal: () => taxableSubtotal
56
58
  });
57
59
  //#endregion
58
- export { DEFAULT_DNE_AMOUNT, DEFAULT_MARKUP_TIERS, DEFAULT_TAX_RATE, DELIVERY_OUTCOMES, KFC_STATS_DEFAULT_WINDOW_DAYS, KFC_STATS_MAX_RANGE_DAYS, KFC_STATS_TIMEZONE, MAX_MESSAGE_ATTACHMENTS, MESSAGE_ERROR_CATEGORIES, SIS_DRIVERS, SOS_AUDIENCES, SYSTEM_CATEGORIES, SYSTEM_CATEGORY_LABELS, billEffectiveDate, billGrandTotal, billTaxAmount, billTotal, billTotals, categoryForDevice, categoryForMessageErrorCode, deliveryOutcomeForStatus, derivePrice, effectiveTaxRate, formatMoney, getAllowedDeviceTypes, getAllowedFeatures, getAllowedResourceIds, inferDeviceNotifications, isMessageErrorCategory, isSISDriver, isWellFormedRichText, keyedMarkupPercent, lib_exports, markupPercentFromPrice, resolveBillTaxExempt, resolveKfcStatsWindowBounds, resolveMarkupTierTable, serializeRichTextBody, settledBillTotal, signedMarkupPercent, taxableSubtotal };
60
+ export { DEFAULT_DNE_AMOUNT, DEFAULT_MARKUP_TIERS, DEFAULT_TAX_RATE, DELIVERY_OUTCOMES, KFC_STATS_DEFAULT_WINDOW_DAYS, KFC_STATS_MAX_RANGE_DAYS, KFC_STATS_TIMEZONE, MAX_MESSAGE_ATTACHMENTS, MESSAGE_ERROR_CATEGORIES, SIS_BUCKETS, SIS_DRIVERS, SOS_AUDIENCES, SYSTEM_CATEGORIES, SYSTEM_CATEGORY_LABELS, billEffectiveDate, billGrandTotal, billTaxAmount, billTotal, billTotals, categoryForDevice, categoryForMessageErrorCode, deliveryOutcomeForStatus, derivePrice, effectiveTaxRate, formatMoney, getAllowedDeviceTypes, getAllowedFeatures, getAllowedResourceIds, inferDeviceNotifications, isMessageErrorCategory, isSISDriver, isWellFormedRichText, keyedMarkupPercent, lib_exports, markupPercentFromPrice, resolveBillTaxExempt, resolveKfcStatsWindowBounds, resolveMarkupTierTable, serializeRichTextBody, settledBillTotal, signedMarkupPercent, taxableSubtotal };
59
61
 
60
62
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../.generated/lib/index.ts"],"sourcesContent":["export {\n inferDeviceNotifications,\n type DeviceNotificationName,\n type InferDeviceNotificationsInput,\n} from \"./deviceNotifications.js\";\nexport {\n categoryForDevice,\n SYSTEM_CATEGORIES,\n SYSTEM_CATEGORY_LABELS,\n type SystemCategory,\n type CategoryForDeviceInput,\n} from \"./systemCategories.js\";\nexport {\n getAllowedResourceIds,\n getAllowedDeviceTypes,\n getAllowedFeatures,\n type PolicyLike,\n type PolicyPermissionLike,\n} from \"./policy-resolvers.js\";\nexport { SIS_DRIVERS, isSISDriver, type SISDriver } from \"./sisDrivers.js\";\nexport { SOS_AUDIENCES, type SOSAudience } from \"./sosAudiences.js\";\nexport {\n MESSAGE_ERROR_CATEGORIES,\n categoryForMessageErrorCode,\n isMessageErrorCategory,\n type MessageErrorCategory,\n} from \"./messageErrorCodes.js\";\nexport {\n DELIVERY_OUTCOMES,\n deliveryOutcomeForStatus,\n type DeliveryOutcome,\n} from \"./deliveryStatus.js\";\nexport type {\n EmergencyContactAudience,\n EmergencyContactPeople,\n EmergencyContactPerson,\n EmergencyContactRoleGroup,\n ExternalGroupCounts,\n} from \"./emergencyContacts.js\";\nexport { MAX_MESSAGE_ATTACHMENTS } from \"./messageAttachments.js\";\nexport {\n DEFAULT_MARKUP_TIERS,\n DEFAULT_DNE_AMOUNT,\n resolveMarkupTierTable,\n keyedMarkupPercent,\n DEFAULT_TAX_RATE,\n derivePrice,\n markupPercentFromPrice,\n signedMarkupPercent,\n billTotal,\n billTaxAmount,\n billGrandTotal,\n formatMoney,\n} from \"./money.js\";\nexport {\n effectiveTaxRate,\n taxableSubtotal,\n billTotals,\n resolveBillTaxExempt,\n settledBillTotal,\n billEffectiveDate,\n type BillTaxFields,\n type TaxableLine,\n type SettledBillTotalSource,\n type BillEffectiveDateSource,\n} from \"./bills.js\";\nexport {\n KFC_STATS_TIMEZONE,\n KFC_STATS_DEFAULT_WINDOW_DAYS,\n KFC_STATS_MAX_RANGE_DAYS,\n resolveKfcStatsWindowBounds,\n type KfcStatsWindowBounds,\n} from \"./kfcStatsWindow.js\";\nexport {\n serializeRichTextBody,\n isWellFormedRichText,\n type RichTextContent,\n type RichTextBlockNode,\n type RichTextInlineNode,\n type RichTextListItemNode,\n type RichTextMentionNode,\n} from \"./ticketRichText.js\";\n"],"mappings":""}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../.generated/lib/index.ts"],"sourcesContent":["export {\n inferDeviceNotifications,\n type DeviceNotificationName,\n type InferDeviceNotificationsInput,\n} from \"./deviceNotifications.js\";\nexport {\n categoryForDevice,\n SYSTEM_CATEGORIES,\n SYSTEM_CATEGORY_LABELS,\n type SystemCategory,\n type CategoryForDeviceInput,\n} from \"./systemCategories.js\";\nexport {\n getAllowedResourceIds,\n getAllowedDeviceTypes,\n getAllowedFeatures,\n type PolicyLike,\n type PolicyPermissionLike,\n} from \"./policy-resolvers.js\";\nexport { SIS_DRIVERS, isSISDriver, type SISDriver } from \"./sisDrivers.js\";\nexport { SOS_AUDIENCES, type SOSAudience } from \"./sosAudiences.js\";\nexport {\n MESSAGE_ERROR_CATEGORIES,\n categoryForMessageErrorCode,\n isMessageErrorCategory,\n type MessageErrorCategory,\n} from \"./messageErrorCodes.js\";\nexport {\n DELIVERY_OUTCOMES,\n deliveryOutcomeForStatus,\n type DeliveryOutcome,\n} from \"./deliveryStatus.js\";\nexport type {\n EmergencyContactAudience,\n EmergencyContactPeople,\n EmergencyContactPerson,\n EmergencyContactRoleGroup,\n ExternalGroupCounts,\n} from \"./emergencyContacts.js\";\nexport {\n SIS_BUCKETS,\n type SISBucket,\n type SISHousehold,\n type SISHouseholdMember,\n type SISHouseholds,\n type SISHouseholdsQuery,\n type SISPage,\n type SISPeople,\n type SISPeopleQuery,\n type SISPeopleSort,\n type SISPerson,\n type SISSortDirection,\n type SISSyncResult,\n type SISSyncState,\n} from \"./sis.js\";\nexport { MAX_MESSAGE_ATTACHMENTS } from \"./messageAttachments.js\";\nexport {\n DEFAULT_MARKUP_TIERS,\n DEFAULT_DNE_AMOUNT,\n resolveMarkupTierTable,\n keyedMarkupPercent,\n DEFAULT_TAX_RATE,\n derivePrice,\n markupPercentFromPrice,\n signedMarkupPercent,\n billTotal,\n billTaxAmount,\n billGrandTotal,\n formatMoney,\n} from \"./money.js\";\nexport {\n effectiveTaxRate,\n taxableSubtotal,\n billTotals,\n resolveBillTaxExempt,\n settledBillTotal,\n billEffectiveDate,\n type BillTaxFields,\n type TaxableLine,\n type SettledBillTotalSource,\n type BillEffectiveDateSource,\n} from \"./bills.js\";\nexport {\n KFC_STATS_TIMEZONE,\n KFC_STATS_DEFAULT_WINDOW_DAYS,\n KFC_STATS_MAX_RANGE_DAYS,\n resolveKfcStatsWindowBounds,\n type KfcStatsWindowBounds,\n} from \"./kfcStatsWindow.js\";\nexport {\n serializeRichTextBody,\n isWellFormedRichText,\n type RichTextContent,\n type RichTextBlockNode,\n type RichTextInlineNode,\n type RichTextListItemNode,\n type RichTextMentionNode,\n} from \"./ticketRichText.js\";\n"],"mappings":""}
@@ -0,0 +1,108 @@
1
+ import type { SISDriver } from "./sisDrivers.js";
2
+ /** What DescribeSISSync reports for the request property's SIS System. */
3
+ export interface SISSyncState {
4
+ systemId: string;
5
+ driver: SISDriver;
6
+ /** Last successful roster sync, or null when the roster has never synced. */
7
+ syncedAt: string | null;
8
+ /** True while a sync for this system and property is in progress. */
9
+ running: boolean;
10
+ people: number;
11
+ households: number;
12
+ }
13
+ /** What SyncSISRoster returns once the roster has been written. */
14
+ export interface SISSyncResult {
15
+ systemId: string;
16
+ driver: SISDriver;
17
+ syncedAt: string;
18
+ people: number;
19
+ households: number;
20
+ }
21
+ /**
22
+ * Display grouping derived from a person's SIS roles, in priority order:
23
+ * a Student is a student even when also listed as someone's contact, a
24
+ * parent who also teaches is a parent, and only someone whose every role is
25
+ * Staff is staff.
26
+ */
27
+ export type SISBucket = "student" | "parentGuardian" | "otherContact" | "staff";
28
+ export declare const SIS_BUCKETS: readonly SISBucket[];
29
+ export interface SISPerson {
30
+ id: string;
31
+ systemId: string;
32
+ firstName: string;
33
+ lastName: string;
34
+ email: string | null;
35
+ phone: string | null;
36
+ roles: string[];
37
+ bucket: SISBucket;
38
+ /** The SIS's own label for the person's first non-Student role, or null. */
39
+ relationship: string | null;
40
+ }
41
+ export type SISPeopleSort = "name" | "bucket";
42
+ export type SISSortDirection = "asc" | "desc";
43
+ /** Query string ListSISPeople reads; every key is optional. */
44
+ export interface SISPeopleQuery {
45
+ page?: number;
46
+ limit?: number;
47
+ /** Case-insensitive substring of the full name, email or phone. */
48
+ search?: string;
49
+ /** Comma-separated buckets to keep; absent or empty keeps every bucket. */
50
+ bucket?: string;
51
+ sort?: SISPeopleSort;
52
+ direction?: SISSortDirection;
53
+ /** `none` narrows to people the SIS lists in no household. */
54
+ household?: "none";
55
+ }
56
+ /** Query string ListSISHouseholds reads; every key is optional. */
57
+ export interface SISHouseholdsQuery {
58
+ page?: number;
59
+ limit?: number;
60
+ /** Case-insensitive substring of the household name or any member's name, email or phone. */
61
+ search?: string;
62
+ /** Comma-separated buckets members must fall in; a household with none left drops out. */
63
+ bucket?: string;
64
+ }
65
+ export interface SISPage {
66
+ page: number;
67
+ pages: number;
68
+ /** Rows matching every filter, across all pages. */
69
+ total: number;
70
+ }
71
+ /**
72
+ * What ListSISPeople returns: one page of the roster, plus how fresh it is.
73
+ * `counts` is by bucket under the search alone, so a bucket filter reads the
74
+ * size of each choice before it is made.
75
+ */
76
+ export interface SISPeople extends SISPage {
77
+ systemId: string;
78
+ driver: SISDriver;
79
+ syncedAt: string | null;
80
+ running: boolean;
81
+ people: SISPerson[];
82
+ counts: Record<SISBucket, number>;
83
+ }
84
+ export interface SISHouseholdMember {
85
+ systemId: string;
86
+ /** The synced person's id, or null when the SIS listed a member it never returned as a person. */
87
+ personId: string | null;
88
+ name: string;
89
+ /** The relationship label the SIS recorded for this member of the household. */
90
+ relationship: string | null;
91
+ /** Derived from the synced person's roles; null when the member was not synced. */
92
+ bucket: SISBucket | null;
93
+ email: string | null;
94
+ phone: string | null;
95
+ }
96
+ export interface SISHousehold {
97
+ id: string;
98
+ systemId: string;
99
+ name: string;
100
+ members: SISHouseholdMember[];
101
+ }
102
+ /** What ListSISHouseholds returns: one page of households by name. */
103
+ export interface SISHouseholds extends SISPage {
104
+ systemId: string;
105
+ driver: SISDriver;
106
+ syncedAt: string | null;
107
+ households: SISHousehold[];
108
+ }
@@ -0,0 +1,11 @@
1
+ //#region .generated/lib/sis.ts
2
+ const SIS_BUCKETS = [
3
+ "staff",
4
+ "student",
5
+ "parentGuardian",
6
+ "otherContact"
7
+ ];
8
+ //#endregion
9
+ export { SIS_BUCKETS };
10
+
11
+ //# sourceMappingURL=sis.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sis.js","names":[],"sources":["../../.generated/lib/sis.ts"],"sourcesContent":["import type { SISDriver } from \"./sisDrivers.js\";\n\n/** What DescribeSISSync reports for the request property's SIS System. */\nexport interface SISSyncState {\n systemId: string;\n driver: SISDriver;\n /** Last successful roster sync, or null when the roster has never synced. */\n syncedAt: string | null;\n /** True while a sync for this system and property is in progress. */\n running: boolean;\n people: number;\n households: number;\n}\n\n/** What SyncSISRoster returns once the roster has been written. */\nexport interface SISSyncResult {\n systemId: string;\n driver: SISDriver;\n syncedAt: string;\n people: number;\n households: number;\n}\n\n/**\n * Display grouping derived from a person's SIS roles, in priority order:\n * a Student is a student even when also listed as someone's contact, a\n * parent who also teaches is a parent, and only someone whose every role is\n * Staff is staff.\n */\nexport type SISBucket = \"student\" | \"parentGuardian\" | \"otherContact\" | \"staff\";\n\nexport const SIS_BUCKETS: readonly SISBucket[] = [\n \"staff\",\n \"student\",\n \"parentGuardian\",\n \"otherContact\",\n];\n\nexport interface SISPerson {\n id: string;\n systemId: string;\n firstName: string;\n lastName: string;\n email: string | null;\n phone: string | null;\n roles: string[];\n bucket: SISBucket;\n /** The SIS's own label for the person's first non-Student role, or null. */\n relationship: string | null;\n}\n\nexport type SISPeopleSort = \"name\" | \"bucket\";\nexport type SISSortDirection = \"asc\" | \"desc\";\n\n/** Query string ListSISPeople reads; every key is optional. */\nexport interface SISPeopleQuery {\n page?: number;\n limit?: number;\n /** Case-insensitive substring of the full name, email or phone. */\n search?: string;\n /** Comma-separated buckets to keep; absent or empty keeps every bucket. */\n bucket?: string;\n sort?: SISPeopleSort;\n direction?: SISSortDirection;\n /** `none` narrows to people the SIS lists in no household. */\n household?: \"none\";\n}\n\n/** Query string ListSISHouseholds reads; every key is optional. */\nexport interface SISHouseholdsQuery {\n page?: number;\n limit?: number;\n /** Case-insensitive substring of the household name or any member's name, email or phone. */\n search?: string;\n /** Comma-separated buckets members must fall in; a household with none left drops out. */\n bucket?: string;\n}\n\nexport interface SISPage {\n page: number;\n pages: number;\n /** Rows matching every filter, across all pages. */\n total: number;\n}\n\n/**\n * What ListSISPeople returns: one page of the roster, plus how fresh it is.\n * `counts` is by bucket under the search alone, so a bucket filter reads the\n * size of each choice before it is made.\n */\nexport interface SISPeople extends SISPage {\n systemId: string;\n driver: SISDriver;\n syncedAt: string | null;\n running: boolean;\n people: SISPerson[];\n counts: Record<SISBucket, number>;\n}\n\nexport interface SISHouseholdMember {\n systemId: string;\n /** The synced person's id, or null when the SIS listed a member it never returned as a person. */\n personId: string | null;\n name: string;\n /** The relationship label the SIS recorded for this member of the household. */\n relationship: string | null;\n /** Derived from the synced person's roles; null when the member was not synced. */\n bucket: SISBucket | null;\n email: string | null;\n phone: string | null;\n}\n\nexport interface SISHousehold {\n id: string;\n systemId: string;\n name: string;\n members: SISHouseholdMember[];\n}\n\n/** What ListSISHouseholds returns: one page of households by name. */\nexport interface SISHouseholds extends SISPage {\n systemId: string;\n driver: SISDriver;\n syncedAt: string | null;\n households: SISHousehold[];\n}\n"],"mappings":";AA+BA,MAAa,cAAoC;CAC/C;CACA;CACA;CACA;AACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"entity.js","names":["#validate"],"sources":["../../.generated/models/entity.ts"],"sourcesContent":["import type { AnySchema, ValidateFunction } from \"ajv\";\nimport { ValidationError } from \"../errors/validationError\";\n\nexport class Entity {\n declare schema: AnySchema;\n declare validator: ValidateFunction;\n\n constructor(data: unknown) {\n if (!this.schema) {\n throw new Error(\"Schema is not defined\");\n }\n\n if (!this.validator) {\n throw new Error(\"Validator is not defined\");\n }\n\n this.#validate(data);\n }\n\n get schemaProperties(): string[] {\n const schema = this.validator.schema;\n if (typeof schema === \"object\" && schema !== null && \"properties\" in schema) {\n return Object.keys(schema.properties as Record<string, unknown>);\n }\n return [];\n }\n\n #validate(data: unknown) {\n const valid = this.validator(data);\n if (!valid) {\n throw new ValidationError(`Invalid ${this.constructor.name}`, {\n cause: this.validator.errors,\n });\n }\n }\n}\n"],"mappings":";;AAGA,IAAa,SAAb,MAAoB;CAIlB,YAAY,MAAe;EACzB,IAAI,CAAC,KAAK,QACR,MAAM,IAAI,MAAM,uBAAuB;EAGzC,IAAI,CAAC,KAAK,WACR,MAAM,IAAI,MAAM,0BAA0B;EAG5C,KAAKA,UAAU,IAAI;CACrB;CAEA,IAAI,mBAA6B;EAC/B,MAAM,SAAS,KAAK,UAAU;EAC9B,IAAI,OAAO,WAAW,YAAY,WAAW,QAAQ,gBAAgB,QACnE,OAAO,OAAO,KAAK,OAAO,UAAqC;EAEjE,OAAO,CAAC;CACV;CAEA,UAAU,MAAe;EAEvB,IAAI,CADU,KAAK,UAAU,IACpB,GACP,MAAM,IAAI,gBAAgB,WAAW,KAAK,YAAY,QAAQ,EAC5D,OAAO,KAAK,UAAU,OACxB,CAAC;CAEL;AACF"}
1
+ {"version":3,"file":"entity.js","names":[],"sources":["../../.generated/models/entity.ts"],"sourcesContent":["import type { AnySchema, ValidateFunction } from \"ajv\";\nimport { ValidationError } from \"../errors/validationError\";\n\nexport class Entity {\n declare schema: AnySchema;\n declare validator: ValidateFunction;\n\n constructor(data: unknown) {\n if (!this.schema) {\n throw new Error(\"Schema is not defined\");\n }\n\n if (!this.validator) {\n throw new Error(\"Validator is not defined\");\n }\n\n this.#validate(data);\n }\n\n get schemaProperties(): string[] {\n const schema = this.validator.schema;\n if (typeof schema === \"object\" && schema !== null && \"properties\" in schema) {\n return Object.keys(schema.properties as Record<string, unknown>);\n }\n return [];\n }\n\n #validate(data: unknown) {\n const valid = this.validator(data);\n if (!valid) {\n throw new ValidationError(`Invalid ${this.constructor.name}`, {\n cause: this.validator.errors,\n });\n }\n }\n}\n"],"mappings":";;AAGA,IAAa,SAAb,MAAoB;CAIlB,YAAY,MAAe;EACzB,IAAI,CAAC,KAAK,QACR,MAAM,IAAI,MAAM,uBAAuB;EAGzC,IAAI,CAAC,KAAK,WACR,MAAM,IAAI,MAAM,0BAA0B;EAG5C,KAAK,UAAU,IAAI;CACrB;CAEA,IAAI,mBAA6B;EAC/B,MAAM,SAAS,KAAK,UAAU;EAC9B,IAAI,OAAO,WAAW,YAAY,WAAW,QAAQ,gBAAgB,QACnE,OAAO,OAAO,KAAK,OAAO,UAAqC;EAEjE,OAAO,CAAC;CACV;CAEA,UAAU,MAAe;EAEvB,IAAI,CADU,KAAK,UAAU,IACpB,GACP,MAAM,IAAI,gBAAgB,WAAW,KAAK,YAAY,QAAQ,EAC5D,OAAO,KAAK,UAAU,OACxB,CAAC;CAEL;AACF"}
@@ -8,6 +8,7 @@ var Group = class extends Entity {
8
8
  this.id = data.id;
9
9
  if (data.systemId !== void 0) this.systemId = data.systemId;
10
10
  if (data.driver !== void 0) this.driver = data.driver;
11
+ if (data.propertyId !== void 0) this.propertyId = data.propertyId;
11
12
  this.type = data.type;
12
13
  this.discriminator = data.discriminator;
13
14
  if (data.name !== void 0) this.name = data.name;
@@ -1 +1 @@
1
- {"version":3,"file":"group.js","names":["validate"],"sources":["../../.generated/models/group.ts"],"sourcesContent":["/* This file is automatically generated. Do not modify it manually. */\n\nimport { Entity } from \"./entity.js\";\nimport { validateGroup as validate } from \"../validate.js\";\nimport { groupSchema, type GroupSchema } from \"../schemas/group.js\";\n\n/**\n * Data type for Group constructor - exported for backwards compatibility\n */\nexport type GroupData = GroupSchema;\n\n/**\n * A named collection of members.\n */\nexport interface Group extends GroupSchema {}\nexport class Group extends Entity {\n declare schema: typeof groupSchema;\n declare validator: typeof validate;\n\n constructor(data: GroupSchema) {\n super(data);\n this.id = data.id;\n if (data.systemId !== undefined) this.systemId = data.systemId;\n if (data.driver !== undefined) this.driver = data.driver;\n this.type = data.type;\n this.discriminator = data.discriminator;\n if (data.name !== undefined) this.name = data.name;\n if (data.members !== undefined) this.members = data.members;\n if (data.createdAt !== undefined) this.createdAt = data.createdAt;\n if (data.updatedAt !== undefined) this.updatedAt = data.updatedAt;\n if (data.deletedAt !== undefined) this.deletedAt = data.deletedAt;\n }\n\n\n\n\n\n\n\n\n}\n\nObject.defineProperty(Group.prototype, \"schema\", {\n value: groupSchema\n});\n\nObject.defineProperty(Group.prototype, \"validator\", {\n get: function() { return validate; }\n});\n"],"mappings":";;;;AAeA,IAAa,QAAb,cAA2B,OAAO;CAIhC,YAAY,MAAmB;EAC7B,MAAM,IAAI;EACV,KAAK,KAAK,KAAK;EACf,IAAI,KAAK,aAAa,KAAA,GAAW,KAAK,WAAW,KAAK;EACtD,IAAI,KAAK,WAAW,KAAA,GAAW,KAAK,SAAS,KAAK;EAClD,KAAK,OAAO,KAAK;EACjB,KAAK,gBAAgB,KAAK;EAC1B,IAAI,KAAK,SAAS,KAAA,GAAW,KAAK,OAAO,KAAK;EAC9C,IAAI,KAAK,YAAY,KAAA,GAAW,KAAK,UAAU,KAAK;EACpD,IAAI,KAAK,cAAc,KAAA,GAAW,KAAK,YAAY,KAAK;EACxD,IAAI,KAAK,cAAc,KAAA,GAAW,KAAK,YAAY,KAAK;EACxD,IAAI,KAAK,cAAc,KAAA,GAAW,KAAK,YAAY,KAAK;CAC1D;AASF;AAEA,OAAO,eAAe,MAAM,WAAW,UAAU,EAC/C,OAAO,YACT,CAAC;AAED,OAAO,eAAe,MAAM,WAAW,aAAa,EAClD,KAAK,WAAW;CAAE,OAAOA;AAAU,EACrC,CAAC"}
1
+ {"version":3,"file":"group.js","names":["validate"],"sources":["../../.generated/models/group.ts"],"sourcesContent":["/* This file is automatically generated. Do not modify it manually. */\n\nimport { Entity } from \"./entity.js\";\nimport { validateGroup as validate } from \"../validate.js\";\nimport { groupSchema, type GroupSchema } from \"../schemas/group.js\";\n\n/**\n * Data type for Group constructor - exported for backwards compatibility\n */\nexport type GroupData = GroupSchema;\n\n/**\n * A named collection of members.\n */\nexport interface Group extends GroupSchema {}\nexport class Group extends Entity {\n declare schema: typeof groupSchema;\n declare validator: typeof validate;\n\n constructor(data: GroupSchema) {\n super(data);\n this.id = data.id;\n if (data.systemId !== undefined) this.systemId = data.systemId;\n if (data.driver !== undefined) this.driver = data.driver;\n if (data.propertyId !== undefined) this.propertyId = data.propertyId;\n this.type = data.type;\n this.discriminator = data.discriminator;\n if (data.name !== undefined) this.name = data.name;\n if (data.members !== undefined) this.members = data.members;\n if (data.createdAt !== undefined) this.createdAt = data.createdAt;\n if (data.updatedAt !== undefined) this.updatedAt = data.updatedAt;\n if (data.deletedAt !== undefined) this.deletedAt = data.deletedAt;\n }\n\n\n\n\n\n\n\n\n}\n\nObject.defineProperty(Group.prototype, \"schema\", {\n value: groupSchema\n});\n\nObject.defineProperty(Group.prototype, \"validator\", {\n get: function() { return validate; }\n});\n"],"mappings":";;;;AAeA,IAAa,QAAb,cAA2B,OAAO;CAIhC,YAAY,MAAmB;EAC7B,MAAM,IAAI;EACV,KAAK,KAAK,KAAK;EACf,IAAI,KAAK,aAAa,KAAA,GAAW,KAAK,WAAW,KAAK;EACtD,IAAI,KAAK,WAAW,KAAA,GAAW,KAAK,SAAS,KAAK;EAClD,IAAI,KAAK,eAAe,KAAA,GAAW,KAAK,aAAa,KAAK;EAC1D,KAAK,OAAO,KAAK;EACjB,KAAK,gBAAgB,KAAK;EAC1B,IAAI,KAAK,SAAS,KAAA,GAAW,KAAK,OAAO,KAAK;EAC9C,IAAI,KAAK,YAAY,KAAA,GAAW,KAAK,UAAU,KAAK;EACpD,IAAI,KAAK,cAAc,KAAA,GAAW,KAAK,YAAY,KAAK;EACxD,IAAI,KAAK,cAAc,KAAA,GAAW,KAAK,YAAY,KAAK;EACxD,IAAI,KAAK,cAAc,KAAA,GAAW,KAAK,YAAY,KAAK;CAC1D;AASF;AAEA,OAAO,eAAe,MAAM,WAAW,UAAU,EAC/C,OAAO,YACT,CAAC;AAED,OAAO,eAAe,MAAM,WAAW,aAAa,EAClD,KAAK,WAAW;CAAE,OAAOA;AAAU,EACrC,CAAC"}
@@ -7,6 +7,7 @@ var System = class extends Entity {
7
7
  super(data);
8
8
  this.id = data.id;
9
9
  this.type = data.type;
10
+ if (data.discriminator !== void 0) this.discriminator = data.discriminator;
10
11
  if (data.name !== void 0) this.name = data.name;
11
12
  this.driver = data.driver;
12
13
  if (data.organizationId !== void 0) this.organizationId = data.organizationId;
@@ -16,7 +17,9 @@ var System = class extends Entity {
16
17
  if (data.logo !== void 0) this.logo = data.logo;
17
18
  if (data.config !== void 0) this.config = data.config;
18
19
  if (data.contactInfo !== void 0) this.contactInfo = data.contactInfo;
20
+ if (data.emergency !== void 0) this.emergency = data.emergency;
19
21
  if (data.health !== void 0) this.health = data.health;
22
+ if (data.syncedAt !== void 0) this.syncedAt = data.syncedAt;
20
23
  if (data.createdAt !== void 0) this.createdAt = data.createdAt;
21
24
  if (data.updatedAt !== void 0) this.updatedAt = data.updatedAt;
22
25
  if (data.deletedAt !== void 0) this.deletedAt = data.deletedAt;
@@ -1 +1 @@
1
- {"version":3,"file":"system.js","names":["validate"],"sources":["../../.generated/models/system.ts"],"sourcesContent":["/* This file is automatically generated. Do not modify it manually. */\n\nimport { Entity } from \"./entity.js\";\nimport { validateSystem as validate } from \"../validate.js\";\nimport { systemSchema, type SystemSchema } from \"../schemas/system.js\";\n\n/**\n * Data type for System constructor - exported for backwards compatibility\n */\nexport type SystemData = SystemSchema;\n\n/**\n * System\n */\nexport interface System extends SystemSchema {}\nexport class System extends Entity {\n declare schema: typeof systemSchema;\n declare validator: typeof validate;\n\n constructor(data: SystemSchema) {\n super(data);\n this.id = data.id;\n this.type = data.type;\n if (data.name !== undefined) this.name = data.name;\n this.driver = data.driver;\n if (data.organizationId !== undefined) this.organizationId = data.organizationId;\n if (data.propertyId !== undefined) this.propertyId = data.propertyId;\n this.entities = data.entities;\n if (data.driverApiVersion !== undefined) this.driverApiVersion = data.driverApiVersion;\n if (data.logo !== undefined) this.logo = data.logo;\n if (data.config !== undefined) this.config = data.config;\n if (data.contactInfo !== undefined) this.contactInfo = data.contactInfo;\n if (data.health !== undefined) this.health = data.health;\n if (data.createdAt !== undefined) this.createdAt = data.createdAt;\n if (data.updatedAt !== undefined) this.updatedAt = data.updatedAt;\n if (data.deletedAt !== undefined) this.deletedAt = data.deletedAt;\n }\n\n\n\n\n\n\n\n\n}\n\nObject.defineProperty(System.prototype, \"schema\", {\n value: systemSchema\n});\n\nObject.defineProperty(System.prototype, \"validator\", {\n get: function() { return validate; }\n});\n"],"mappings":";;;;AAeA,IAAa,SAAb,cAA4B,OAAO;CAIjC,YAAY,MAAoB;EAC9B,MAAM,IAAI;EACV,KAAK,KAAK,KAAK;EACf,KAAK,OAAO,KAAK;EACjB,IAAI,KAAK,SAAS,KAAA,GAAW,KAAK,OAAO,KAAK;EAC9C,KAAK,SAAS,KAAK;EACnB,IAAI,KAAK,mBAAmB,KAAA,GAAW,KAAK,iBAAiB,KAAK;EAClE,IAAI,KAAK,eAAe,KAAA,GAAW,KAAK,aAAa,KAAK;EAC1D,KAAK,WAAW,KAAK;EACrB,IAAI,KAAK,qBAAqB,KAAA,GAAW,KAAK,mBAAmB,KAAK;EACtE,IAAI,KAAK,SAAS,KAAA,GAAW,KAAK,OAAO,KAAK;EAC9C,IAAI,KAAK,WAAW,KAAA,GAAW,KAAK,SAAS,KAAK;EAClD,IAAI,KAAK,gBAAgB,KAAA,GAAW,KAAK,cAAc,KAAK;EAC5D,IAAI,KAAK,WAAW,KAAA,GAAW,KAAK,SAAS,KAAK;EAClD,IAAI,KAAK,cAAc,KAAA,GAAW,KAAK,YAAY,KAAK;EACxD,IAAI,KAAK,cAAc,KAAA,GAAW,KAAK,YAAY,KAAK;EACxD,IAAI,KAAK,cAAc,KAAA,GAAW,KAAK,YAAY,KAAK;CAC1D;AASF;AAEA,OAAO,eAAe,OAAO,WAAW,UAAU,EAChD,OAAO,aACT,CAAC;AAED,OAAO,eAAe,OAAO,WAAW,aAAa,EACnD,KAAK,WAAW;CAAE,OAAOA;AAAU,EACrC,CAAC"}
1
+ {"version":3,"file":"system.js","names":["validate"],"sources":["../../.generated/models/system.ts"],"sourcesContent":["/* This file is automatically generated. Do not modify it manually. */\n\nimport { Entity } from \"./entity.js\";\nimport { validateSystem as validate } from \"../validate.js\";\nimport { systemSchema, type SystemSchema } from \"../schemas/system.js\";\n\n/**\n * Data type for System constructor - exported for backwards compatibility\n */\nexport type SystemData = SystemSchema;\n\n/**\n * System\n */\nexport interface System extends SystemSchema {}\nexport class System extends Entity {\n declare schema: typeof systemSchema;\n declare validator: typeof validate;\n\n constructor(data: SystemSchema) {\n super(data);\n this.id = data.id;\n this.type = data.type;\n if (data.discriminator !== undefined) this.discriminator = data.discriminator;\n if (data.name !== undefined) this.name = data.name;\n this.driver = data.driver;\n if (data.organizationId !== undefined) this.organizationId = data.organizationId;\n if (data.propertyId !== undefined) this.propertyId = data.propertyId;\n this.entities = data.entities;\n if (data.driverApiVersion !== undefined) this.driverApiVersion = data.driverApiVersion;\n if (data.logo !== undefined) this.logo = data.logo;\n if (data.config !== undefined) this.config = data.config;\n if (data.contactInfo !== undefined) this.contactInfo = data.contactInfo;\n if (data.emergency !== undefined) this.emergency = data.emergency;\n if (data.health !== undefined) this.health = data.health;\n if (data.syncedAt !== undefined) this.syncedAt = data.syncedAt;\n if (data.createdAt !== undefined) this.createdAt = data.createdAt;\n if (data.updatedAt !== undefined) this.updatedAt = data.updatedAt;\n if (data.deletedAt !== undefined) this.deletedAt = data.deletedAt;\n }\n\n\n\n\n\n\n\n\n}\n\nObject.defineProperty(System.prototype, \"schema\", {\n value: systemSchema\n});\n\nObject.defineProperty(System.prototype, \"validator\", {\n get: function() { return validate; }\n});\n"],"mappings":";;;;AAeA,IAAa,SAAb,cAA4B,OAAO;CAIjC,YAAY,MAAoB;EAC9B,MAAM,IAAI;EACV,KAAK,KAAK,KAAK;EACf,KAAK,OAAO,KAAK;EACjB,IAAI,KAAK,kBAAkB,KAAA,GAAW,KAAK,gBAAgB,KAAK;EAChE,IAAI,KAAK,SAAS,KAAA,GAAW,KAAK,OAAO,KAAK;EAC9C,KAAK,SAAS,KAAK;EACnB,IAAI,KAAK,mBAAmB,KAAA,GAAW,KAAK,iBAAiB,KAAK;EAClE,IAAI,KAAK,eAAe,KAAA,GAAW,KAAK,aAAa,KAAK;EAC1D,KAAK,WAAW,KAAK;EACrB,IAAI,KAAK,qBAAqB,KAAA,GAAW,KAAK,mBAAmB,KAAK;EACtE,IAAI,KAAK,SAAS,KAAA,GAAW,KAAK,OAAO,KAAK;EAC9C,IAAI,KAAK,WAAW,KAAA,GAAW,KAAK,SAAS,KAAK;EAClD,IAAI,KAAK,gBAAgB,KAAA,GAAW,KAAK,cAAc,KAAK;EAC5D,IAAI,KAAK,cAAc,KAAA,GAAW,KAAK,YAAY,KAAK;EACxD,IAAI,KAAK,WAAW,KAAA,GAAW,KAAK,SAAS,KAAK;EAClD,IAAI,KAAK,aAAa,KAAA,GAAW,KAAK,WAAW,KAAK;EACtD,IAAI,KAAK,cAAc,KAAA,GAAW,KAAK,YAAY,KAAK;EACxD,IAAI,KAAK,cAAc,KAAA,GAAW,KAAK,YAAY,KAAK;EACxD,IAAI,KAAK,cAAc,KAAA,GAAW,KAAK,YAAY,KAAK;CAC1D;AASF;AAEA,OAAO,eAAe,OAAO,WAAW,UAAU,EAChD,OAAO,aACT,CAAC;AAED,OAAO,eAAe,OAAO,WAAW,aAAa,EACnD,KAAK,WAAW;CAAE,OAAOA;AAAU,EACrC,CAAC"}
@@ -28,7 +28,7 @@ var SystemUser = class extends Entity {
28
28
  if (data.updatedAt !== void 0) this.updatedAt = data.updatedAt;
29
29
  if (data.systemId !== void 0) this.systemId = data.systemId;
30
30
  if (data.propertyId !== void 0) this.propertyId = data.propertyId;
31
- if (data.syncedAt !== void 0) this.syncedAt = data.syncedAt;
31
+ if (data.consent !== void 0) this.consent = data.consent;
32
32
  }
33
33
  };
34
34
  Object.defineProperty(SystemUser.prototype, "schema", { value: systemUserSchema });
@@ -1 +1 @@
1
- {"version":3,"file":"systemUser.js","names":["validate"],"sources":["../../.generated/models/systemUser.ts"],"sourcesContent":["/* This file is automatically generated. Do not modify it manually. */\n\nimport { Entity } from \"./entity.js\";\nimport { validateSystemUser as validate } from \"../validate.js\";\nimport { systemUserSchema, type SystemUserSchema } from \"../schemas/systemUser.js\";\n\n/**\n * Data type for SystemUser constructor - exported for backwards compatibility\n */\nexport type SystemUserData = SystemUserSchema;\n\n/**\n * A system user is a user that originated from an external 3rd party system.\n */\nexport interface SystemUser extends SystemUserSchema {}\nexport class SystemUser extends Entity {\n declare schema: typeof systemUserSchema;\n declare validator: typeof validate;\n\n constructor(data: SystemUserSchema) {\n super(data);\n this.id = data.id;\n if (data.type !== undefined) this.type = data.type;\n if (data.driver !== undefined) this.driver = data.driver;\n this.firstName = data.firstName;\n this.lastName = data.lastName;\n if (data.phone !== undefined) this.phone = data.phone;\n if (data.email !== undefined) this.email = data.email;\n if (data.address !== undefined) this.address = data.address;\n if (data.photo !== undefined) this.photo = data.photo;\n if (data.jobTitle !== undefined) this.jobTitle = data.jobTitle;\n if (data.dob !== undefined) this.dob = data.dob;\n if (data.gender !== undefined) this.gender = data.gender;\n if (data.roles !== undefined) this.roles = data.roles;\n if (data.nationality !== undefined) this.nationality = data.nationality;\n if (data.notes !== undefined) this.notes = data.notes;\n if (data.files !== undefined) this.files = data.files;\n if (data.identifications !== undefined) this.identifications = data.identifications;\n if (data.payments !== undefined) this.payments = data.payments;\n if (data.revenue !== undefined) this.revenue = data.revenue;\n if (data.createdAt !== undefined) this.createdAt = data.createdAt;\n if (data.updatedAt !== undefined) this.updatedAt = data.updatedAt;\n if (data.systemId !== undefined) this.systemId = data.systemId;\n if (data.propertyId !== undefined) this.propertyId = data.propertyId;\n if (data.syncedAt !== undefined) this.syncedAt = data.syncedAt;\n }\n\n\n\n\n\n\n\n\n}\n\nObject.defineProperty(SystemUser.prototype, \"schema\", {\n value: systemUserSchema\n});\n\nObject.defineProperty(SystemUser.prototype, \"validator\", {\n get: function() { return validate; }\n});\n"],"mappings":";;;;AAeA,IAAa,aAAb,cAAgC,OAAO;CAIrC,YAAY,MAAwB;EAClC,MAAM,IAAI;EACV,KAAK,KAAK,KAAK;EACf,IAAI,KAAK,SAAS,KAAA,GAAW,KAAK,OAAO,KAAK;EAC9C,IAAI,KAAK,WAAW,KAAA,GAAW,KAAK,SAAS,KAAK;EAClD,KAAK,YAAY,KAAK;EACtB,KAAK,WAAW,KAAK;EACrB,IAAI,KAAK,UAAU,KAAA,GAAW,KAAK,QAAQ,KAAK;EAChD,IAAI,KAAK,UAAU,KAAA,GAAW,KAAK,QAAQ,KAAK;EAChD,IAAI,KAAK,YAAY,KAAA,GAAW,KAAK,UAAU,KAAK;EACpD,IAAI,KAAK,UAAU,KAAA,GAAW,KAAK,QAAQ,KAAK;EAChD,IAAI,KAAK,aAAa,KAAA,GAAW,KAAK,WAAW,KAAK;EACtD,IAAI,KAAK,QAAQ,KAAA,GAAW,KAAK,MAAM,KAAK;EAC5C,IAAI,KAAK,WAAW,KAAA,GAAW,KAAK,SAAS,KAAK;EAClD,IAAI,KAAK,UAAU,KAAA,GAAW,KAAK,QAAQ,KAAK;EAChD,IAAI,KAAK,gBAAgB,KAAA,GAAW,KAAK,cAAc,KAAK;EAC5D,IAAI,KAAK,UAAU,KAAA,GAAW,KAAK,QAAQ,KAAK;EAChD,IAAI,KAAK,UAAU,KAAA,GAAW,KAAK,QAAQ,KAAK;EAChD,IAAI,KAAK,oBAAoB,KAAA,GAAW,KAAK,kBAAkB,KAAK;EACpE,IAAI,KAAK,aAAa,KAAA,GAAW,KAAK,WAAW,KAAK;EACtD,IAAI,KAAK,YAAY,KAAA,GAAW,KAAK,UAAU,KAAK;EACpD,IAAI,KAAK,cAAc,KAAA,GAAW,KAAK,YAAY,KAAK;EACxD,IAAI,KAAK,cAAc,KAAA,GAAW,KAAK,YAAY,KAAK;EACxD,IAAI,KAAK,aAAa,KAAA,GAAW,KAAK,WAAW,KAAK;EACtD,IAAI,KAAK,eAAe,KAAA,GAAW,KAAK,aAAa,KAAK;EAC1D,IAAI,KAAK,aAAa,KAAA,GAAW,KAAK,WAAW,KAAK;CACxD;AASF;AAEA,OAAO,eAAe,WAAW,WAAW,UAAU,EACpD,OAAO,iBACT,CAAC;AAED,OAAO,eAAe,WAAW,WAAW,aAAa,EACvD,KAAK,WAAW;CAAE,OAAOA;AAAU,EACrC,CAAC"}
1
+ {"version":3,"file":"systemUser.js","names":["validate"],"sources":["../../.generated/models/systemUser.ts"],"sourcesContent":["/* This file is automatically generated. Do not modify it manually. */\n\nimport { Entity } from \"./entity.js\";\nimport { validateSystemUser as validate } from \"../validate.js\";\nimport { systemUserSchema, type SystemUserSchema } from \"../schemas/systemUser.js\";\n\n/**\n * Data type for SystemUser constructor - exported for backwards compatibility\n */\nexport type SystemUserData = SystemUserSchema;\n\n/**\n * A system user is a user that originated from an external 3rd party system.\n */\nexport interface SystemUser extends SystemUserSchema {}\nexport class SystemUser extends Entity {\n declare schema: typeof systemUserSchema;\n declare validator: typeof validate;\n\n constructor(data: SystemUserSchema) {\n super(data);\n this.id = data.id;\n if (data.type !== undefined) this.type = data.type;\n if (data.driver !== undefined) this.driver = data.driver;\n this.firstName = data.firstName;\n this.lastName = data.lastName;\n if (data.phone !== undefined) this.phone = data.phone;\n if (data.email !== undefined) this.email = data.email;\n if (data.address !== undefined) this.address = data.address;\n if (data.photo !== undefined) this.photo = data.photo;\n if (data.jobTitle !== undefined) this.jobTitle = data.jobTitle;\n if (data.dob !== undefined) this.dob = data.dob;\n if (data.gender !== undefined) this.gender = data.gender;\n if (data.roles !== undefined) this.roles = data.roles;\n if (data.nationality !== undefined) this.nationality = data.nationality;\n if (data.notes !== undefined) this.notes = data.notes;\n if (data.files !== undefined) this.files = data.files;\n if (data.identifications !== undefined) this.identifications = data.identifications;\n if (data.payments !== undefined) this.payments = data.payments;\n if (data.revenue !== undefined) this.revenue = data.revenue;\n if (data.createdAt !== undefined) this.createdAt = data.createdAt;\n if (data.updatedAt !== undefined) this.updatedAt = data.updatedAt;\n if (data.systemId !== undefined) this.systemId = data.systemId;\n if (data.propertyId !== undefined) this.propertyId = data.propertyId;\n if (data.consent !== undefined) this.consent = data.consent;\n }\n\n\n\n\n\n\n\n\n}\n\nObject.defineProperty(SystemUser.prototype, \"schema\", {\n value: systemUserSchema\n});\n\nObject.defineProperty(SystemUser.prototype, \"validator\", {\n get: function() { return validate; }\n});\n"],"mappings":";;;;AAeA,IAAa,aAAb,cAAgC,OAAO;CAIrC,YAAY,MAAwB;EAClC,MAAM,IAAI;EACV,KAAK,KAAK,KAAK;EACf,IAAI,KAAK,SAAS,KAAA,GAAW,KAAK,OAAO,KAAK;EAC9C,IAAI,KAAK,WAAW,KAAA,GAAW,KAAK,SAAS,KAAK;EAClD,KAAK,YAAY,KAAK;EACtB,KAAK,WAAW,KAAK;EACrB,IAAI,KAAK,UAAU,KAAA,GAAW,KAAK,QAAQ,KAAK;EAChD,IAAI,KAAK,UAAU,KAAA,GAAW,KAAK,QAAQ,KAAK;EAChD,IAAI,KAAK,YAAY,KAAA,GAAW,KAAK,UAAU,KAAK;EACpD,IAAI,KAAK,UAAU,KAAA,GAAW,KAAK,QAAQ,KAAK;EAChD,IAAI,KAAK,aAAa,KAAA,GAAW,KAAK,WAAW,KAAK;EACtD,IAAI,KAAK,QAAQ,KAAA,GAAW,KAAK,MAAM,KAAK;EAC5C,IAAI,KAAK,WAAW,KAAA,GAAW,KAAK,SAAS,KAAK;EAClD,IAAI,KAAK,UAAU,KAAA,GAAW,KAAK,QAAQ,KAAK;EAChD,IAAI,KAAK,gBAAgB,KAAA,GAAW,KAAK,cAAc,KAAK;EAC5D,IAAI,KAAK,UAAU,KAAA,GAAW,KAAK,QAAQ,KAAK;EAChD,IAAI,KAAK,UAAU,KAAA,GAAW,KAAK,QAAQ,KAAK;EAChD,IAAI,KAAK,oBAAoB,KAAA,GAAW,KAAK,kBAAkB,KAAK;EACpE,IAAI,KAAK,aAAa,KAAA,GAAW,KAAK,WAAW,KAAK;EACtD,IAAI,KAAK,YAAY,KAAA,GAAW,KAAK,UAAU,KAAK;EACpD,IAAI,KAAK,cAAc,KAAA,GAAW,KAAK,YAAY,KAAK;EACxD,IAAI,KAAK,cAAc,KAAA,GAAW,KAAK,YAAY,KAAK;EACxD,IAAI,KAAK,aAAa,KAAA,GAAW,KAAK,WAAW,KAAK;EACtD,IAAI,KAAK,eAAe,KAAA,GAAW,KAAK,aAAa,KAAK;EAC1D,IAAI,KAAK,YAAY,KAAA,GAAW,KAAK,UAAU,KAAK;CACtD;AASF;AAEA,OAAO,eAAe,WAAW,WAAW,UAAU,EACpD,OAAO,iBACT,CAAC;AAED,OAAO,eAAe,WAAW,WAAW,aAAa,EACvD,KAAK,WAAW;CAAE,OAAOA;AAAU,EACrC,CAAC"}
@@ -122,7 +122,22 @@ export declare const announcementSchema: {
122
122
  readonly recipients: {
123
123
  readonly type: "integer";
124
124
  readonly minimum: 0;
125
- readonly description: "Size of the roster the named groups resolved to.";
125
+ readonly description: "Roster contacts holding an address on at least one attempted channel. A contact with no address for any selected channel is not a recipient.";
126
+ };
127
+ readonly sent: {
128
+ readonly type: "integer";
129
+ readonly minimum: 0;
130
+ readonly description: "Recipients reached on at least one channel. Absent on sends recorded before it was stored.";
131
+ };
132
+ readonly failed: {
133
+ readonly type: "integer";
134
+ readonly minimum: 0;
135
+ readonly description: "Recipients reached on no channel, excluding those who opted out. Absent on sends recorded before it was stored.";
136
+ };
137
+ readonly optedOut: {
138
+ readonly type: "integer";
139
+ readonly minimum: 0;
140
+ readonly description: "Recipients skipped on every attempted channel because they opted out.";
126
141
  };
127
142
  readonly delivery: {
128
143
  readonly type: "object";
@@ -118,7 +118,22 @@ const announcementSchema = {
118
118
  recipients: {
119
119
  type: "integer",
120
120
  minimum: 0,
121
- description: "Size of the roster the named groups resolved to."
121
+ description: "Roster contacts holding an address on at least one attempted channel. A contact with no address for any selected channel is not a recipient."
122
+ },
123
+ sent: {
124
+ type: "integer",
125
+ minimum: 0,
126
+ description: "Recipients reached on at least one channel. Absent on sends recorded before it was stored."
127
+ },
128
+ failed: {
129
+ type: "integer",
130
+ minimum: 0,
131
+ description: "Recipients reached on no channel, excluding those who opted out. Absent on sends recorded before it was stored."
132
+ },
133
+ optedOut: {
134
+ type: "integer",
135
+ minimum: 0,
136
+ description: "Recipients skipped on every attempted channel because they opted out."
122
137
  },
123
138
  delivery: {
124
139
  type: "object",
@@ -1 +1 @@
1
- {"version":3,"file":"announcement.js","names":[],"sources":["../../.generated/schemas/announcement.ts"],"sourcesContent":["import defs, { ISODateString } from \"./definitions\";\nimport type { FromSchema } from \"json-schema-to-ts\";\n\nexport const announcementSchema = {\n $schema: \"http://json-schema.org/draft-07/schema\",\n $id: \"announcement.json\",\n title: \"Announcement\",\n description: \"Announcement message sent to users\",\n type: \"object\",\n required: [\"id\", \"type\"],\n properties: {\n id: { $ref: \"definitions.json#/definitions/id\" },\n propertyId: {\n type: \"string\",\n description:\n \"ID of the property this entity belongs to. Optional — used as a per-document filter inside the org-scoped database.\",\n },\n type: {\n type: \"string\",\n enum: [\"announcement\"],\n default: \"announcement\",\n },\n status: {\n type: \"string\",\n description:\n \"`sent` is a real broadcast; `preset` is a named, reusable configuration a sender loads into the composer. Absent on records written before presets existed — read as `sent`.\",\n enum: [\"sent\", \"preset\"],\n default: \"sent\",\n },\n name: {\n type: \"string\",\n description: \"Display name of a preset. Sent announcements have none.\",\n },\n presetId: {\n type: \"string\",\n description:\n \"The preset this sent announcement was loaded from, when it was.\",\n },\n audience: {\n $ref: \"definitions.json#/definitions/audience\",\n description:\n \"Who this announcement was directed at on the people axis. PA surfaces are the other axis and never reach the emergency-contact roster.\",\n },\n channels: {\n type: \"array\",\n description: \"Personal channels this announcement was sent over.\",\n items: {\n type: \"string\",\n enum: [\"sms\", \"email\"],\n },\n },\n subject: {\n type: \"string\",\n description: \"Email subject, and the title shown on a surface.\",\n },\n surfaces: {\n type: \"array\",\n description:\n \"Surface channels the announcement was broadcast to, as the sender selected them. `discriminator` is the mediaSource `Device.discriminator` targeted, open for future surface types; only `paSystem` ships today.\",\n items: {\n type: \"object\",\n required: [\"discriminator\", \"scope\"],\n properties: {\n discriminator: {\n type: \"string\",\n enum: [\"paSystem\"],\n },\n scope: {\n type: \"string\",\n enum: [\"all\", \"spaces\", \"devices\"],\n },\n spaceIds: {\n type: \"array\",\n items: { type: \"string\" },\n },\n deviceIds: {\n type: \"array\",\n items: { type: \"string\" },\n },\n outputs: {\n type: \"array\",\n description: \"PA output zones to page; all zones when omitted.\",\n items: { type: \"string\" },\n },\n playlistId: {\n type: \"string\",\n description:\n \"A PA playlist (driver recording) played in place of the spoken body; its zones are the playlist's own.\",\n },\n },\n additionalProperties: false,\n },\n },\n body: {\n type: \"string\",\n description:\n \"The spoken/written message. Optional only when every surface plays a preset and no channel is selected.\",\n },\n media: {\n $ref: \"mediaFile.json\",\n },\n sentBy: {\n type: \"string\",\n },\n result: {\n type: \"object\",\n additionalProperties: false,\n required: [\"recipientsResolved\", \"perChannel\", \"skipped\", \"surfaces\"],\n description:\n \"What the send actually achieved, written once at send time and never recomputed. Absent on presets and on sends recorded before this was stored. The `audience.delivery` counts are the same send viewed per audience; this is the per-channel and per-device detail behind them.\",\n properties: {\n recipientsResolved: {\n type: \"integer\",\n minimum: 0,\n description:\n \"How many internal Users the audience selector resolved to. Zero when no personal channel was selected, however wide the selector — an announcement with no channel reaches no User.\",\n },\n external: {\n type: \"object\",\n additionalProperties: false,\n required: [\"recipients\", \"delivery\"],\n description:\n \"The external SIS roster this send reached. Absent when no external group was named.\",\n properties: {\n recipients: {\n type: \"integer\",\n minimum: 0,\n description: \"Size of the roster the named groups resolved to.\",\n },\n delivery: {\n type: \"object\",\n additionalProperties: false,\n description:\n \"Per-channel counts, present only for the channels attempted.\",\n properties: {\n sms: { $ref: \"definitions.json#/definitions/deliveryCounts\" },\n email: { $ref: \"definitions.json#/definitions/deliveryCounts\" },\n },\n },\n },\n },\n perChannel: {\n type: \"object\",\n additionalProperties: false,\n required: [\"sms\", \"email\"],\n description:\n \"Messages handed to each personal channel; zero for a channel the send did not select.\",\n properties: {\n sms: { type: \"integer\" },\n email: { type: \"integer\" },\n },\n },\n skipped: {\n type: \"array\",\n description:\n \"Recipients a selected channel could not carry the announcement to. A missing contact detail is a per-channel skip, not a failed send, so one recipient may appear once per channel.\",\n items: {\n type: \"object\",\n required: [\"userId\", \"channel\", \"reason\"],\n additionalProperties: false,\n properties: {\n userId: { type: \"string\" },\n channel: { type: \"string\", enum: [\"sms\", \"email\"] },\n reason: { type: \"string\", enum: [\"no-phone\", \"no-email\"] },\n },\n },\n },\n surfaces: {\n type: \"array\",\n description:\n \"Per-device outcome of the surface page, one entry per device the selectors resolved to. Distinct from the top-level `surfaces`, which is the selector the sender expressed.\",\n items: {\n type: \"object\",\n required: [\"deviceId\", \"status\"],\n additionalProperties: false,\n properties: {\n deviceId: { type: \"string\" },\n status: {\n type: \"string\",\n enum: [\"sent\", \"failed\", \"skipped\"],\n },\n reason: {\n type: \"string\",\n description:\n '`unsupported` when the driver advertises no content command; absent otherwise.',\n },\n },\n },\n },\n },\n },\n tags: {\n type: \"array\",\n items: {\n type: \"string\",\n },\n },\n createdAt: {\n $ref: \"definitions.json#/definitions/date\",\n },\n updatedAt: {\n $ref: \"definitions.json#/definitions/date\",\n },\n deletedAt: {\n $ref: \"definitions.json#/definitions/date\",\n },\n },\n additionalProperties: false,\n} as const;\n\nexport type AnnouncementSchema = FromSchema<\n typeof announcementSchema,\n {\n references: [typeof defs];\n deserialize: [\n {\n pattern: {\n format: \"date-time\";\n };\n output: Date | ISODateString;\n },\n ];\n }\n>;\n"],"mappings":"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"}
1
+ {"version":3,"file":"announcement.js","names":[],"sources":["../../.generated/schemas/announcement.ts"],"sourcesContent":["import defs, { ISODateString } from \"./definitions\";\nimport type { FromSchema } from \"json-schema-to-ts\";\n\nexport const announcementSchema = {\n $schema: \"http://json-schema.org/draft-07/schema\",\n $id: \"announcement.json\",\n title: \"Announcement\",\n description: \"Announcement message sent to users\",\n type: \"object\",\n required: [\"id\", \"type\"],\n properties: {\n id: { $ref: \"definitions.json#/definitions/id\" },\n propertyId: {\n type: \"string\",\n description:\n \"ID of the property this entity belongs to. Optional — used as a per-document filter inside the org-scoped database.\",\n },\n type: {\n type: \"string\",\n enum: [\"announcement\"],\n default: \"announcement\",\n },\n status: {\n type: \"string\",\n description:\n \"`sent` is a real broadcast; `preset` is a named, reusable configuration a sender loads into the composer. Absent on records written before presets existed — read as `sent`.\",\n enum: [\"sent\", \"preset\"],\n default: \"sent\",\n },\n name: {\n type: \"string\",\n description: \"Display name of a preset. Sent announcements have none.\",\n },\n presetId: {\n type: \"string\",\n description:\n \"The preset this sent announcement was loaded from, when it was.\",\n },\n audience: {\n $ref: \"definitions.json#/definitions/audience\",\n description:\n \"Who this announcement was directed at on the people axis. PA surfaces are the other axis and never reach the emergency-contact roster.\",\n },\n channels: {\n type: \"array\",\n description: \"Personal channels this announcement was sent over.\",\n items: {\n type: \"string\",\n enum: [\"sms\", \"email\"],\n },\n },\n subject: {\n type: \"string\",\n description: \"Email subject, and the title shown on a surface.\",\n },\n surfaces: {\n type: \"array\",\n description:\n \"Surface channels the announcement was broadcast to, as the sender selected them. `discriminator` is the mediaSource `Device.discriminator` targeted, open for future surface types; only `paSystem` ships today.\",\n items: {\n type: \"object\",\n required: [\"discriminator\", \"scope\"],\n properties: {\n discriminator: {\n type: \"string\",\n enum: [\"paSystem\"],\n },\n scope: {\n type: \"string\",\n enum: [\"all\", \"spaces\", \"devices\"],\n },\n spaceIds: {\n type: \"array\",\n items: { type: \"string\" },\n },\n deviceIds: {\n type: \"array\",\n items: { type: \"string\" },\n },\n outputs: {\n type: \"array\",\n description: \"PA output zones to page; all zones when omitted.\",\n items: { type: \"string\" },\n },\n playlistId: {\n type: \"string\",\n description:\n \"A PA playlist (driver recording) played in place of the spoken body; its zones are the playlist's own.\",\n },\n },\n additionalProperties: false,\n },\n },\n body: {\n type: \"string\",\n description:\n \"The spoken/written message. Optional only when every surface plays a preset and no channel is selected.\",\n },\n media: {\n $ref: \"mediaFile.json\",\n },\n sentBy: {\n type: \"string\",\n },\n result: {\n type: \"object\",\n additionalProperties: false,\n required: [\"recipientsResolved\", \"perChannel\", \"skipped\", \"surfaces\"],\n description:\n \"What the send actually achieved, written once at send time and never recomputed. Absent on presets and on sends recorded before this was stored. The `audience.delivery` counts are the same send viewed per audience; this is the per-channel and per-device detail behind them.\",\n properties: {\n recipientsResolved: {\n type: \"integer\",\n minimum: 0,\n description:\n \"How many internal Users the audience selector resolved to. Zero when no personal channel was selected, however wide the selector — an announcement with no channel reaches no User.\",\n },\n external: {\n type: \"object\",\n additionalProperties: false,\n required: [\"recipients\", \"delivery\"],\n description:\n \"The external SIS roster this send reached. Absent when no external group was named.\",\n properties: {\n recipients: {\n type: \"integer\",\n minimum: 0,\n description:\n \"Roster contacts holding an address on at least one attempted channel. A contact with no address for any selected channel is not a recipient.\",\n },\n sent: {\n type: \"integer\",\n minimum: 0,\n description:\n \"Recipients reached on at least one channel. Absent on sends recorded before it was stored.\",\n },\n failed: {\n type: \"integer\",\n minimum: 0,\n description:\n \"Recipients reached on no channel, excluding those who opted out. Absent on sends recorded before it was stored.\",\n },\n optedOut: {\n type: \"integer\",\n minimum: 0,\n description:\n \"Recipients skipped on every attempted channel because they opted out.\",\n },\n delivery: {\n type: \"object\",\n additionalProperties: false,\n description:\n \"Per-channel counts, present only for the channels attempted.\",\n properties: {\n sms: { $ref: \"definitions.json#/definitions/deliveryCounts\" },\n email: { $ref: \"definitions.json#/definitions/deliveryCounts\" },\n },\n },\n },\n },\n perChannel: {\n type: \"object\",\n additionalProperties: false,\n required: [\"sms\", \"email\"],\n description:\n \"Messages handed to each personal channel; zero for a channel the send did not select.\",\n properties: {\n sms: { type: \"integer\" },\n email: { type: \"integer\" },\n },\n },\n skipped: {\n type: \"array\",\n description:\n \"Recipients a selected channel could not carry the announcement to. A missing contact detail is a per-channel skip, not a failed send, so one recipient may appear once per channel.\",\n items: {\n type: \"object\",\n required: [\"userId\", \"channel\", \"reason\"],\n additionalProperties: false,\n properties: {\n userId: { type: \"string\" },\n channel: { type: \"string\", enum: [\"sms\", \"email\"] },\n reason: { type: \"string\", enum: [\"no-phone\", \"no-email\"] },\n },\n },\n },\n surfaces: {\n type: \"array\",\n description:\n \"Per-device outcome of the surface page, one entry per device the selectors resolved to. Distinct from the top-level `surfaces`, which is the selector the sender expressed.\",\n items: {\n type: \"object\",\n required: [\"deviceId\", \"status\"],\n additionalProperties: false,\n properties: {\n deviceId: { type: \"string\" },\n status: {\n type: \"string\",\n enum: [\"sent\", \"failed\", \"skipped\"],\n },\n reason: {\n type: \"string\",\n description:\n '`unsupported` when the driver advertises no content command; absent otherwise.',\n },\n },\n },\n },\n },\n },\n tags: {\n type: \"array\",\n items: {\n type: \"string\",\n },\n },\n createdAt: {\n $ref: \"definitions.json#/definitions/date\",\n },\n updatedAt: {\n $ref: \"definitions.json#/definitions/date\",\n },\n deletedAt: {\n $ref: \"definitions.json#/definitions/date\",\n },\n },\n additionalProperties: false,\n} as const;\n\nexport type AnnouncementSchema = FromSchema<\n typeof announcementSchema,\n {\n references: [typeof defs];\n deserialize: [\n {\n pattern: {\n format: \"date-time\";\n };\n output: Date | ISODateString;\n },\n ];\n }\n>;\n"],"mappings":"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"}