@oneblink/sdk-core 10.0.0-beta.1 → 10.0.0-beta.3

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.
@@ -1,5 +1,5 @@
1
1
  import { ConditionTypes } from '@oneblink/types';
2
- import { AddOffsetToDate, FormElementsCtrl, ParseDate } from './types.js';
2
+ import { AddOffsetToDate, EndOfDay, FormElementsCtrl, ParseDayOnlyDate, StartOfDay } from './types.js';
3
3
  /**
4
4
  * Evaluate a `SUBMISSION_TIMESTAMP` conditional predicate against the form
5
5
  * submission timestamp.
@@ -8,13 +8,25 @@ import { AddOffsetToDate, FormElementsCtrl, ParseDate } from './types.js';
8
8
  * - `BEFORE` — submission timestamp is before (exclusive) the comparison date
9
9
  * - `BETWEEN` — submission timestamp is between `min` and `max` (inclusive)
10
10
  *
11
- * Date strings are parsed via `parseDate`. Day offsets are applied via
11
+ * When the comparison value is a day-only (`YYYY-MM-DD`) string, day
12
+ * boundaries are applied via the injected helpers:
13
+ *
14
+ * - `AFTER` — end of the comparison day
15
+ * - `BEFORE` — start of the comparison day
16
+ * - `BETWEEN` — start of `min` day through end of `max` day
17
+ *
18
+ * Full ISO datetime values compare at the exact instant.
19
+ *
20
+ * Day-only (`YYYY-MM-DD`) strings are parsed via `parseDayOnlyDate`. Other
21
+ * date strings use `new Date(value)`. Day offsets are applied via
12
22
  * `addDaysToDate(date, offset)`.
13
23
  */
14
- export default function evaluateConditionalSubmissionTimestampPredicate({ predicate, formElementsCtrl, submissionTimestamp, parseDate, addDaysToDate, }: {
24
+ export default function evaluateConditionalSubmissionTimestampPredicate({ predicate, formElementsCtrl, submissionTimestamp, parseDayOnlyDate, addDaysToDate, startOfDay, endOfDay, }: {
15
25
  predicate: ConditionTypes.ConditionalPredicateSubmissionTimestamp;
16
26
  formElementsCtrl: FormElementsCtrl;
17
27
  submissionTimestamp: string;
18
- parseDate: ParseDate;
28
+ parseDayOnlyDate: ParseDayOnlyDate;
19
29
  addDaysToDate: AddOffsetToDate;
30
+ startOfDay: StartOfDay;
31
+ endOfDay: EndOfDay;
20
32
  }): boolean;
@@ -1,27 +1,37 @@
1
1
  import { getElementAndValue } from './evaluateFormElementConditionalPredicate.js';
2
- function resolveDateValue(dateValue, formElementsCtrl, parseDate, addDaysToDate) {
2
+ const DATE_ONLY_PATTERN = /^\d{4}-\d{2}-\d{2}$/;
3
+ function resolveDateValue(dateValue, formElementsCtrl, parseDayOnlyDate, addDaysToDate, startOfDay, endOfDay, dayBoundary) {
3
4
  let dateString;
4
5
  if (dateValue.compareWith === 'ELEMENT') {
5
- const elementAndValue = getElementAndValue(formElementsCtrl, dateValue.formElementId);
6
+ const elementAndValue = getElementAndValue(formElementsCtrl, dateValue.elementId);
6
7
  if (typeof elementAndValue.value === 'string' && elementAndValue.value) {
7
8
  dateString = elementAndValue.value;
8
9
  }
9
- if (!dateString) {
10
+ else {
10
11
  return undefined;
11
12
  }
12
13
  }
13
14
  else {
14
15
  dateString = dateValue.value;
15
16
  }
16
- const date = parseDate(dateString);
17
+ const isDayOnly = DATE_ONLY_PATTERN.test(dateString);
18
+ const date = isDayOnly ? parseDayOnlyDate(dateString) : new Date(dateString);
17
19
  if (Number.isNaN(date.getTime())) {
18
20
  return undefined;
19
21
  }
20
- if (typeof dateValue.daysOffset !== 'number' ||
21
- Number.isNaN(dateValue.daysOffset)) {
22
- return date;
22
+ const dateWithOffset = typeof dateValue.daysOffset !== 'number' ||
23
+ Number.isNaN(dateValue.daysOffset)
24
+ ? date
25
+ : addDaysToDate(date, dateValue.daysOffset);
26
+ if (isDayOnly) {
27
+ if (dayBoundary === 'start') {
28
+ return startOfDay(dateWithOffset);
29
+ }
30
+ else {
31
+ return endOfDay(dateWithOffset);
32
+ }
23
33
  }
24
- return addDaysToDate(date, dateValue.daysOffset);
34
+ return dateWithOffset;
25
35
  }
26
36
  /**
27
37
  * Evaluate a `SUBMISSION_TIMESTAMP` conditional predicate against the form
@@ -31,10 +41,20 @@ function resolveDateValue(dateValue, formElementsCtrl, parseDate, addDaysToDate)
31
41
  * - `BEFORE` — submission timestamp is before (exclusive) the comparison date
32
42
  * - `BETWEEN` — submission timestamp is between `min` and `max` (inclusive)
33
43
  *
34
- * Date strings are parsed via `parseDate`. Day offsets are applied via
44
+ * When the comparison value is a day-only (`YYYY-MM-DD`) string, day
45
+ * boundaries are applied via the injected helpers:
46
+ *
47
+ * - `AFTER` — end of the comparison day
48
+ * - `BEFORE` — start of the comparison day
49
+ * - `BETWEEN` — start of `min` day through end of `max` day
50
+ *
51
+ * Full ISO datetime values compare at the exact instant.
52
+ *
53
+ * Day-only (`YYYY-MM-DD`) strings are parsed via `parseDayOnlyDate`. Other
54
+ * date strings use `new Date(value)`. Day offsets are applied via
35
55
  * `addDaysToDate(date, offset)`.
36
56
  */
37
- export default function evaluateConditionalSubmissionTimestampPredicate({ predicate, formElementsCtrl, submissionTimestamp, parseDate, addDaysToDate, }) {
57
+ export default function evaluateConditionalSubmissionTimestampPredicate({ predicate, formElementsCtrl, submissionTimestamp, parseDayOnlyDate, addDaysToDate, startOfDay, endOfDay, }) {
38
58
  const submissionDate = new Date(submissionTimestamp);
39
59
  if (Number.isNaN(submissionDate.getTime())) {
40
60
  return false;
@@ -42,15 +62,16 @@ export default function evaluateConditionalSubmissionTimestampPredicate({ predic
42
62
  const submissionTime = submissionDate.getTime();
43
63
  switch (predicate.operator) {
44
64
  case 'BETWEEN': {
45
- const min = resolveDateValue(predicate.min, formElementsCtrl, parseDate, addDaysToDate);
46
- const max = resolveDateValue(predicate.max, formElementsCtrl, parseDate, addDaysToDate);
65
+ const min = resolveDateValue(predicate.min, formElementsCtrl, parseDayOnlyDate, addDaysToDate, startOfDay, endOfDay, 'start');
66
+ const max = resolveDateValue(predicate.max, formElementsCtrl, parseDayOnlyDate, addDaysToDate, startOfDay, endOfDay, 'end');
47
67
  if (!min || !max) {
48
68
  return false;
49
69
  }
50
70
  return submissionTime >= min.getTime() && submissionTime <= max.getTime();
51
71
  }
52
72
  default: {
53
- const compareDate = resolveDateValue(predicate, formElementsCtrl, parseDate, addDaysToDate);
73
+ const dayBoundary = predicate.operator === 'AFTER' ? 'end' : 'start';
74
+ const compareDate = resolveDateValue(predicate, formElementsCtrl, parseDayOnlyDate, addDaysToDate, startOfDay, endOfDay, dayBoundary);
54
75
  if (!compareDate) {
55
76
  return false;
56
77
  }
@@ -1 +1 @@
1
- {"version":3,"file":"evaluateConditionalSubmissionTimestampPredicate.js","sourceRoot":"","sources":["../../src/conditionalLogicService/evaluateConditionalSubmissionTimestampPredicate.ts"],"names":[],"mappings":"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","sourcesContent":["import { ConditionTypes } from '@oneblink/types'\nimport { AddOffsetToDate, FormElementsCtrl, ParseDate } from './types.js'\nimport { getElementAndValue } from './evaluateFormElementConditionalPredicate.js'\n\nfunction resolveDateValue(\n dateValue: ConditionTypes.ConditionalPredicateDateValue,\n formElementsCtrl: FormElementsCtrl,\n parseDate: ParseDate,\n addDaysToDate: AddOffsetToDate,\n): Date | undefined {\n let dateString: string | undefined\n\n if (dateValue.compareWith === 'ELEMENT') {\n const elementAndValue = getElementAndValue(\n formElementsCtrl,\n dateValue.formElementId,\n )\n if (typeof elementAndValue.value === 'string' && elementAndValue.value) {\n dateString = elementAndValue.value\n }\n if (!dateString) {\n return undefined\n }\n } else {\n dateString = dateValue.value\n }\n\n const date = parseDate(dateString)\n if (Number.isNaN(date.getTime())) {\n return undefined\n }\n\n if (\n typeof dateValue.daysOffset !== 'number' ||\n Number.isNaN(dateValue.daysOffset)\n ) {\n return date\n }\n\n return addDaysToDate(date, dateValue.daysOffset)\n}\n\n/**\n * Evaluate a `SUBMISSION_TIMESTAMP` conditional predicate against the form\n * submission timestamp.\n *\n * - `AFTER` — submission timestamp is after (exclusive) the comparison date\n * - `BEFORE` — submission timestamp is before (exclusive) the comparison date\n * - `BETWEEN` — submission timestamp is between `min` and `max` (inclusive)\n *\n * Date strings are parsed via `parseDate`. Day offsets are applied via\n * `addDaysToDate(date, offset)`.\n */\nexport default function evaluateConditionalSubmissionTimestampPredicate({\n predicate,\n formElementsCtrl,\n submissionTimestamp,\n parseDate,\n addDaysToDate,\n}: {\n predicate: ConditionTypes.ConditionalPredicateSubmissionTimestamp\n formElementsCtrl: FormElementsCtrl\n submissionTimestamp: string\n parseDate: ParseDate\n addDaysToDate: AddOffsetToDate\n}): boolean {\n const submissionDate = new Date(submissionTimestamp)\n if (Number.isNaN(submissionDate.getTime())) {\n return false\n }\n\n const submissionTime = submissionDate.getTime()\n\n switch (predicate.operator) {\n case 'BETWEEN': {\n const min = resolveDateValue(\n predicate.min,\n formElementsCtrl,\n parseDate,\n addDaysToDate,\n )\n const max = resolveDateValue(\n predicate.max,\n formElementsCtrl,\n parseDate,\n addDaysToDate,\n )\n if (!min || !max) {\n return false\n }\n return submissionTime >= min.getTime() && submissionTime <= max.getTime()\n }\n default: {\n const compareDate = resolveDateValue(\n predicate,\n formElementsCtrl,\n parseDate,\n addDaysToDate,\n )\n if (!compareDate) {\n return false\n }\n\n switch (predicate.operator) {\n case 'AFTER':\n return submissionTime > compareDate.getTime()\n case 'BEFORE':\n return submissionTime < compareDate.getTime()\n default: {\n const n: never = predicate\n console.warn('Unhandled predicate operator', n)\n return false\n }\n }\n }\n }\n}\n"]}
1
+ {"version":3,"file":"evaluateConditionalSubmissionTimestampPredicate.js","sourceRoot":"","sources":["../../src/conditionalLogicService/evaluateConditionalSubmissionTimestampPredicate.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,kBAAkB,EAAE,MAAM,8CAA8C,CAAA;AAEjF,MAAM,iBAAiB,GAAG,qBAAqB,CAAA;AAI/C,SAAS,gBAAgB,CACvB,SAAuD,EACvD,gBAAkC,EAClC,gBAAkC,EAClC,aAA8B,EAC9B,UAAsB,EACtB,QAAkB,EAClB,WAAwB;IAExB,IAAI,UAA8B,CAAA;IAElC,IAAI,SAAS,CAAC,WAAW,KAAK,SAAS,EAAE,CAAC;QACxC,MAAM,eAAe,GAAG,kBAAkB,CACxC,gBAAgB,EAChB,SAAS,CAAC,SAAS,CACpB,CAAA;QACD,IAAI,OAAO,eAAe,CAAC,KAAK,KAAK,QAAQ,IAAI,eAAe,CAAC,KAAK,EAAE,CAAC;YACvE,UAAU,GAAG,eAAe,CAAC,KAAK,CAAA;QACpC,CAAC;aAAM,CAAC;YACN,OAAO,SAAS,CAAA;QAClB,CAAC;IACH,CAAC;SAAM,CAAC;QACN,UAAU,GAAG,SAAS,CAAC,KAAK,CAAA;IAC9B,CAAC;IAED,MAAM,SAAS,GAAG,iBAAiB,CAAC,IAAI,CAAC,UAAU,CAAC,CAAA;IACpD,MAAM,IAAI,GAAG,SAAS,CAAC,CAAC,CAAC,gBAAgB,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,CAAA;IAC5E,IAAI,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC;QACjC,OAAO,SAAS,CAAA;IAClB,CAAC;IAED,MAAM,cAAc,GAClB,OAAO,SAAS,CAAC,UAAU,KAAK,QAAQ;QACxC,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,UAAU,CAAC;QAChC,CAAC,CAAC,IAAI;QACN,CAAC,CAAC,aAAa,CAAC,IAAI,EAAE,SAAS,CAAC,UAAU,CAAC,CAAA;IAE/C,IAAI,SAAS,EAAE,CAAC;QACd,IAAI,WAAW,KAAK,OAAO,EAAE,CAAC;YAC5B,OAAO,UAAU,CAAC,cAAc,CAAC,CAAA;QACnC,CAAC;aAAM,CAAC;YACN,OAAO,QAAQ,CAAC,cAAc,CAAC,CAAA;QACjC,CAAC;IACH,CAAC;IAED,OAAO,cAAc,CAAA;AACvB,CAAC;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,CAAC,OAAO,UAAU,+CAA+C,CAAC,EACtE,SAAS,EACT,gBAAgB,EAChB,mBAAmB,EACnB,gBAAgB,EAChB,aAAa,EACb,UAAU,EACV,QAAQ,GAST;IACC,MAAM,cAAc,GAAG,IAAI,IAAI,CAAC,mBAAmB,CAAC,CAAA;IACpD,IAAI,MAAM,CAAC,KAAK,CAAC,cAAc,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC;QAC3C,OAAO,KAAK,CAAA;IACd,CAAC;IAED,MAAM,cAAc,GAAG,cAAc,CAAC,OAAO,EAAE,CAAA;IAE/C,QAAQ,SAAS,CAAC,QAAQ,EAAE,CAAC;QAC3B,KAAK,SAAS,CAAC,CAAC,CAAC;YACf,MAAM,GAAG,GAAG,gBAAgB,CAC1B,SAAS,CAAC,GAAG,EACb,gBAAgB,EAChB,gBAAgB,EAChB,aAAa,EACb,UAAU,EACV,QAAQ,EACR,OAAO,CACR,CAAA;YACD,MAAM,GAAG,GAAG,gBAAgB,CAC1B,SAAS,CAAC,GAAG,EACb,gBAAgB,EAChB,gBAAgB,EAChB,aAAa,EACb,UAAU,EACV,QAAQ,EACR,KAAK,CACN,CAAA;YACD,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;gBACjB,OAAO,KAAK,CAAA;YACd,CAAC;YACD,OAAO,cAAc,IAAI,GAAG,CAAC,OAAO,EAAE,IAAI,cAAc,IAAI,GAAG,CAAC,OAAO,EAAE,CAAA;QAC3E,CAAC;QACD,OAAO,CAAC,CAAC,CAAC;YACR,MAAM,WAAW,GACf,SAAS,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAA;YAClD,MAAM,WAAW,GAAG,gBAAgB,CAClC,SAAS,EACT,gBAAgB,EAChB,gBAAgB,EAChB,aAAa,EACb,UAAU,EACV,QAAQ,EACR,WAAW,CACZ,CAAA;YACD,IAAI,CAAC,WAAW,EAAE,CAAC;gBACjB,OAAO,KAAK,CAAA;YACd,CAAC;YAED,QAAQ,SAAS,CAAC,QAAQ,EAAE,CAAC;gBAC3B,KAAK,OAAO;oBACV,OAAO,cAAc,GAAG,WAAW,CAAC,OAAO,EAAE,CAAA;gBAC/C,KAAK,QAAQ;oBACX,OAAO,cAAc,GAAG,WAAW,CAAC,OAAO,EAAE,CAAA;gBAC/C,OAAO,CAAC,CAAC,CAAC;oBACR,MAAM,CAAC,GAAU,SAAS,CAAA;oBAC1B,OAAO,CAAC,IAAI,CAAC,8BAA8B,EAAE,CAAC,CAAC,CAAA;oBAC/C,OAAO,KAAK,CAAA;gBACd,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;AACH,CAAC","sourcesContent":["import { ConditionTypes } from '@oneblink/types'\nimport {\n AddOffsetToDate,\n EndOfDay,\n FormElementsCtrl,\n ParseDayOnlyDate,\n StartOfDay,\n} from './types.js'\nimport { getElementAndValue } from './evaluateFormElementConditionalPredicate.js'\n\nconst DATE_ONLY_PATTERN = /^\\d{4}-\\d{2}-\\d{2}$/\n\ntype DayBoundary = 'start' | 'end'\n\nfunction resolveDateValue(\n dateValue: ConditionTypes.ConditionalPredicateDateValue,\n formElementsCtrl: FormElementsCtrl,\n parseDayOnlyDate: ParseDayOnlyDate,\n addDaysToDate: AddOffsetToDate,\n startOfDay: StartOfDay,\n endOfDay: EndOfDay,\n dayBoundary: DayBoundary,\n): Date | undefined {\n let dateString: string | undefined\n\n if (dateValue.compareWith === 'ELEMENT') {\n const elementAndValue = getElementAndValue(\n formElementsCtrl,\n dateValue.elementId,\n )\n if (typeof elementAndValue.value === 'string' && elementAndValue.value) {\n dateString = elementAndValue.value\n } else {\n return undefined\n }\n } else {\n dateString = dateValue.value\n }\n\n const isDayOnly = DATE_ONLY_PATTERN.test(dateString)\n const date = isDayOnly ? parseDayOnlyDate(dateString) : new Date(dateString)\n if (Number.isNaN(date.getTime())) {\n return undefined\n }\n\n const dateWithOffset =\n typeof dateValue.daysOffset !== 'number' ||\n Number.isNaN(dateValue.daysOffset)\n ? date\n : addDaysToDate(date, dateValue.daysOffset)\n\n if (isDayOnly) {\n if (dayBoundary === 'start') {\n return startOfDay(dateWithOffset)\n } else {\n return endOfDay(dateWithOffset)\n }\n }\n\n return dateWithOffset\n}\n\n/**\n * Evaluate a `SUBMISSION_TIMESTAMP` conditional predicate against the form\n * submission timestamp.\n *\n * - `AFTER` — submission timestamp is after (exclusive) the comparison date\n * - `BEFORE` — submission timestamp is before (exclusive) the comparison date\n * - `BETWEEN` — submission timestamp is between `min` and `max` (inclusive)\n *\n * When the comparison value is a day-only (`YYYY-MM-DD`) string, day\n * boundaries are applied via the injected helpers:\n *\n * - `AFTER` — end of the comparison day\n * - `BEFORE` — start of the comparison day\n * - `BETWEEN` — start of `min` day through end of `max` day\n *\n * Full ISO datetime values compare at the exact instant.\n *\n * Day-only (`YYYY-MM-DD`) strings are parsed via `parseDayOnlyDate`. Other\n * date strings use `new Date(value)`. Day offsets are applied via\n * `addDaysToDate(date, offset)`.\n */\nexport default function evaluateConditionalSubmissionTimestampPredicate({\n predicate,\n formElementsCtrl,\n submissionTimestamp,\n parseDayOnlyDate,\n addDaysToDate,\n startOfDay,\n endOfDay,\n}: {\n predicate: ConditionTypes.ConditionalPredicateSubmissionTimestamp\n formElementsCtrl: FormElementsCtrl\n submissionTimestamp: string\n parseDayOnlyDate: ParseDayOnlyDate\n addDaysToDate: AddOffsetToDate\n startOfDay: StartOfDay\n endOfDay: EndOfDay\n}): boolean {\n const submissionDate = new Date(submissionTimestamp)\n if (Number.isNaN(submissionDate.getTime())) {\n return false\n }\n\n const submissionTime = submissionDate.getTime()\n\n switch (predicate.operator) {\n case 'BETWEEN': {\n const min = resolveDateValue(\n predicate.min,\n formElementsCtrl,\n parseDayOnlyDate,\n addDaysToDate,\n startOfDay,\n endOfDay,\n 'start',\n )\n const max = resolveDateValue(\n predicate.max,\n formElementsCtrl,\n parseDayOnlyDate,\n addDaysToDate,\n startOfDay,\n endOfDay,\n 'end',\n )\n if (!min || !max) {\n return false\n }\n return submissionTime >= min.getTime() && submissionTime <= max.getTime()\n }\n default: {\n const dayBoundary: DayBoundary =\n predicate.operator === 'AFTER' ? 'end' : 'start'\n const compareDate = resolveDateValue(\n predicate,\n formElementsCtrl,\n parseDayOnlyDate,\n addDaysToDate,\n startOfDay,\n endOfDay,\n dayBoundary,\n )\n if (!compareDate) {\n return false\n }\n\n switch (predicate.operator) {\n case 'AFTER':\n return submissionTime > compareDate.getTime()\n case 'BEFORE':\n return submissionTime < compareDate.getTime()\n default: {\n const n: never = predicate\n console.warn('Unhandled predicate operator', n)\n return false\n }\n }\n }\n }\n}\n"]}
@@ -1,14 +1,26 @@
1
1
  import { FormTypes, SubmissionTypes } from '@oneblink/types';
2
2
  /**
3
- * Parse a date/datetime string into a `Date`. Callers supply timezone-aware
4
- * parsing (e.g. treating `YYYY-MM-DD` as the start of day in an organisation
5
- * timezone).
3
+ * Parse a day-only (`YYYY-MM-DD`) string into a `Date`. Callers supply
4
+ * timezone-aware parsing (e.g. start of day in an organisation timezone).
5
+ * sdk-core only invokes this for values that match `YYYY-MM-DD`.
6
6
  */
7
- export type ParseDate = (value: string) => Date;
7
+ export type ParseDayOnlyDate = (value: string) => Date;
8
8
  /**
9
9
  * Add an offset to a date. Callers supply timezone-aware calendar arithmetic.
10
10
  */
11
11
  export type AddOffsetToDate = (date: Date, offset: number) => Date;
12
+ /**
13
+ * Move a date to the start of its calendar day. Callers supply timezone-aware
14
+ * behaviour (e.g. organisation timezone on the server, local timezone in the
15
+ * browser).
16
+ */
17
+ export type StartOfDay = (date: Date) => Date;
18
+ /**
19
+ * Move a date to the end of its calendar day (last millisecond). Callers supply
20
+ * timezone-aware behaviour (e.g. organisation timezone on the server, local
21
+ * timezone in the browser).
22
+ */
23
+ export type EndOfDay = (date: Date) => Date;
12
24
  export type FormElementsCtrl = {
13
25
  model: SubmissionTypes.S3SubmissionData['submission'] | undefined;
14
26
  flattenedElements: FormTypes.FormElement[];
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/conditionalLogicService/types.ts"],"names":[],"mappings":"","sourcesContent":["import { FormTypes, SubmissionTypes } from '@oneblink/types'\n\n/**\n * Parse a date/datetime string into a `Date`. Callers supply timezone-aware\n * parsing (e.g. treating `YYYY-MM-DD` as the start of day in an organisation\n * timezone).\n */\nexport type ParseDate = (value: string) => Date\n\n/**\n * Add an offset to a date. Callers supply timezone-aware calendar arithmetic.\n */\nexport type AddOffsetToDate = (date: Date, offset: number) => Date\n\nexport type FormElementsCtrl = {\n model: SubmissionTypes.S3SubmissionData['submission'] | undefined\n flattenedElements: FormTypes.FormElement[]\n parentFormElementsCtrl?: FormElementsCtrl\n}\n"]}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/conditionalLogicService/types.ts"],"names":[],"mappings":"","sourcesContent":["import { FormTypes, SubmissionTypes } from '@oneblink/types'\n\n/**\n * Parse a day-only (`YYYY-MM-DD`) string into a `Date`. Callers supply\n * timezone-aware parsing (e.g. start of day in an organisation timezone).\n * sdk-core only invokes this for values that match `YYYY-MM-DD`.\n */\nexport type ParseDayOnlyDate = (value: string) => Date\n\n/**\n * Add an offset to a date. Callers supply timezone-aware calendar arithmetic.\n */\nexport type AddOffsetToDate = (date: Date, offset: number) => Date\n\n/**\n * Move a date to the start of its calendar day. Callers supply timezone-aware\n * behaviour (e.g. organisation timezone on the server, local timezone in the\n * browser).\n */\nexport type StartOfDay = (date: Date) => Date\n\n/**\n * Move a date to the end of its calendar day (last millisecond). Callers supply\n * timezone-aware behaviour (e.g. organisation timezone on the server, local\n * timezone in the browser).\n */\nexport type EndOfDay = (date: Date) => Date\n\nexport type FormElementsCtrl = {\n model: SubmissionTypes.S3SubmissionData['submission'] | undefined\n flattenedElements: FormTypes.FormElement[]\n parentFormElementsCtrl?: FormElementsCtrl\n}\n"]}
@@ -1,7 +1,7 @@
1
1
  import { ConditionTypes, FormTypes, SubmissionTypes } from '@oneblink/types';
2
- import { AddOffsetToDate, ParseDate } from './conditionalLogicService/types.js';
2
+ import { AddOffsetToDate, EndOfDay, ParseDayOnlyDate, StartOfDay } from './conditionalLogicService/types.js';
3
3
  export * from './conditionalLogicService/generateFormElementsConditionallyShown.js';
4
- export type { AddOffsetToDate, ParseDate } from './conditionalLogicService/types.js';
4
+ export type { AddOffsetToDate, EndOfDay, ParseDayOnlyDate, StartOfDay, } from './conditionalLogicService/types.js';
5
5
  /**
6
6
  * Given a set of form elements and submission data, evaluate if predicates are
7
7
  * met or not.
@@ -58,11 +58,19 @@ export type { AddOffsetToDate, ParseDate } from './conditionalLogicService/types
58
58
  * },
59
59
  * ],
60
60
  * submissionTimestamp: new Date().toISOString(),
61
- * parseDate: (value) => new Date(value),
61
+ * parseDayOnlyDate: (value) => new Date(`${value}T00:00:00.000Z`),
62
62
  * addDaysToDate: (date, days) => {
63
63
  * date.setUTCDate(date.getUTCDate() + days)
64
64
  * return date
65
65
  * },
66
+ * startOfDay: (date) => {
67
+ * date.setUTCHours(0, 0, 0, 0)
68
+ * return date
69
+ * },
70
+ * endOfDay: (date) => {
71
+ * date.setUTCHours(23, 59, 59, 999)
72
+ * return date
73
+ * },
66
74
  * },
67
75
  * )
68
76
  * ```
@@ -70,7 +78,7 @@ export type { AddOffsetToDate, ParseDate } from './conditionalLogicService/types
70
78
  * @param options
71
79
  * @returns
72
80
  */
73
- export declare function evaluateConditionalPredicates({ isConditional, requiresAllConditionalPredicates, conditionalPredicates, formElements, submission, submissionTimestamp, parseDate, addDaysToDate, }: {
81
+ export declare function evaluateConditionalPredicates({ isConditional, requiresAllConditionalPredicates, conditionalPredicates, formElements, submission, submissionTimestamp, parseDayOnlyDate, addDaysToDate, startOfDay, endOfDay, }: {
74
82
  isConditional: boolean;
75
83
  requiresAllConditionalPredicates: boolean;
76
84
  conditionalPredicates: ConditionTypes.ConditionalPredicate[];
@@ -78,8 +86,12 @@ export declare function evaluateConditionalPredicates({ isConditional, requiresA
78
86
  submission: SubmissionTypes.S3SubmissionData['submission'];
79
87
  /** ISO timestamp the form was submitted. When evaluating during submission, pass `new Date().toISOString()`. */
80
88
  submissionTimestamp: string;
81
- /** Parse date/datetime strings when evaluating date based predicates */
82
- parseDate: ParseDate;
89
+ /** Parse `YYYY-MM-DD` strings when evaluating date based predicates */
90
+ parseDayOnlyDate: ParseDayOnlyDate;
83
91
  /** Add days to a date when evaluating date based predicates */
84
92
  addDaysToDate: AddOffsetToDate;
93
+ /** Start of calendar day when evaluating date (not datetime) based predicates */
94
+ startOfDay: StartOfDay;
95
+ /** End of calendar day when evaluating date (not datetime) based predicates */
96
+ endOfDay: EndOfDay;
85
97
  }): boolean;
@@ -58,11 +58,19 @@ export * from './conditionalLogicService/generateFormElementsConditionallyShown.
58
58
  * },
59
59
  * ],
60
60
  * submissionTimestamp: new Date().toISOString(),
61
- * parseDate: (value) => new Date(value),
61
+ * parseDayOnlyDate: (value) => new Date(`${value}T00:00:00.000Z`),
62
62
  * addDaysToDate: (date, days) => {
63
63
  * date.setUTCDate(date.getUTCDate() + days)
64
64
  * return date
65
65
  * },
66
+ * startOfDay: (date) => {
67
+ * date.setUTCHours(0, 0, 0, 0)
68
+ * return date
69
+ * },
70
+ * endOfDay: (date) => {
71
+ * date.setUTCHours(23, 59, 59, 999)
72
+ * return date
73
+ * },
66
74
  * },
67
75
  * )
68
76
  * ```
@@ -70,7 +78,7 @@ export * from './conditionalLogicService/generateFormElementsConditionallyShown.
70
78
  * @param options
71
79
  * @returns
72
80
  */
73
- export function evaluateConditionalPredicates({ isConditional, requiresAllConditionalPredicates, conditionalPredicates, formElements, submission, submissionTimestamp, parseDate, addDaysToDate, }) {
81
+ export function evaluateConditionalPredicates({ isConditional, requiresAllConditionalPredicates, conditionalPredicates, formElements, submission, submissionTimestamp, parseDayOnlyDate, addDaysToDate, startOfDay, endOfDay, }) {
74
82
  if (!isConditional || !conditionalPredicates.length) {
75
83
  return true;
76
84
  }
@@ -84,8 +92,10 @@ export function evaluateConditionalPredicates({ isConditional, requiresAllCondit
84
92
  predicate,
85
93
  formElementsCtrl,
86
94
  submissionTimestamp,
87
- parseDate,
95
+ parseDayOnlyDate,
88
96
  addDaysToDate,
97
+ startOfDay,
98
+ endOfDay,
89
99
  });
90
100
  }
91
101
  return !!evaluateFormElementConditionalPredicate({
@@ -1 +1 @@
1
- {"version":3,"file":"conditionalLogicService.js","sourceRoot":"","sources":["../src/conditionalLogicService.ts"],"names":[],"mappings":"AAAA,OAAO,uCAAuC,MAAM,sEAAsE,CAAA;AAC1H,OAAO,+CAA+C,MAAM,8EAA8E,CAAA;AAC1I,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAA;AAI9D,cAAc,qEAAqE,CAAA;AAGnF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmEG;AACH,MAAM,UAAU,6BAA6B,CAAC,EAC5C,aAAa,EACb,gCAAgC,EAChC,qBAAqB,EACrB,YAAY,EACZ,UAAU,EACV,mBAAmB,EACnB,SAAS,EACT,aAAa,GAad;IACC,IAAI,CAAC,aAAa,IAAI,CAAC,qBAAqB,CAAC,MAAM,EAAE,CAAC;QACpD,OAAO,IAAI,CAAA;IACb,CAAC;IACD,MAAM,gBAAgB,GAAG;QACvB,iBAAiB,EAAE,mBAAmB,CAAC,YAAY,CAAC;QACpD,KAAK,EAAE,UAAU;KAClB,CAAA;IAED,MAAM,WAAW,GAAG,CAAC,SAA8C,EAAE,EAAE;QACrE,IAAI,SAAS,CAAC,IAAI,KAAK,sBAAsB,EAAE,CAAC;YAC9C,OAAO,+CAA+C,CAAC;gBACrD,SAAS;gBACT,gBAAgB;gBAChB,mBAAmB;gBACnB,SAAS;gBACT,aAAa;aACd,CAAC,CAAA;QACJ,CAAC;QAED,OAAO,CAAC,CAAC,uCAAuC,CAAC;YAC/C,SAAS;YACT,gBAAgB;SACjB,CAAC,CAAA;IACJ,CAAC,CAAA;IACD,IAAI,gCAAgC,EAAE,CAAC;QACrC,OAAO,qBAAqB,CAAC,KAAK,CAAC,WAAW,CAAC,CAAA;IACjD,CAAC;SAAM,CAAC;QACN,OAAO,qBAAqB,CAAC,IAAI,CAAC,WAAW,CAAC,CAAA;IAChD,CAAC;AACH,CAAC","sourcesContent":["import evaluateFormElementConditionalPredicate from './conditionalLogicService/evaluateFormElementConditionalPredicate.js'\nimport evaluateConditionalSubmissionTimestampPredicate from './conditionalLogicService/evaluateConditionalSubmissionTimestampPredicate.js'\nimport { flattenFormElements } from './formElementsService.js'\nimport { ConditionTypes, FormTypes, SubmissionTypes } from '@oneblink/types'\nimport { AddOffsetToDate, ParseDate } from './conditionalLogicService/types.js'\n\nexport * from './conditionalLogicService/generateFormElementsConditionallyShown.js'\nexport type { AddOffsetToDate, ParseDate } from './conditionalLogicService/types.js'\n\n/**\n * Given a set of form elements and submission data, evaluate if predicates are\n * met or not.\n *\n * #### Example\n *\n * ```js\n * const evaluation = conditionalLogicService.evaluateConditionalPredicates(\n * {\n * isConditional: true,\n * requiresAllConditionalPredicates: false,\n * conditionalPredicates: [\n * {\n * type: 'OPTIONS',\n * elementId: '3534abe4-b0b5-4ffa-a216-49c223ab6f95',\n * optionIds: ['9ce633dd-22d6-4e0e-a9e0-1aa62d435e72'],\n * },\n * ],\n * submission: {\n * checkboxes: ['a'],\n * },\n * formElements: [\n * {\n * name: 'checkboxes',\n * label: 'Checkboxes',\n * type: 'checkboxes',\n * required: false,\n * id: '3534abe4-b0b5-4ffa-a216-49c223ab6f95',\n * options: [\n * {\n * id: '9ce633dd-22d6-4e0e-a9e0-1aa62d435e72',\n * label: 'First',\n * value: 'a',\n * },\n * {\n * id: '5850b32c-3833-4498-a072-47fcc8122242',\n * label: 'Second',\n * value: 'b',\n * },\n * {\n * id: 'ab363e9f-a63f-4923-ba0d-47892fc26a93',\n * label: 'Third',\n * value: 'c',\n * },\n * ],\n * readOnly: false,\n * buttons: false,\n * optionsType: 'CUSTOM',\n * conditionallyShowOptions: false,\n * isDataLookup: false,\n * isElementLookup: false,\n * conditionallyShow: false,\n * requiresAllConditionallyShowPredicates: false,\n * },\n * ],\n * submissionTimestamp: new Date().toISOString(),\n * parseDate: (value) => new Date(value),\n * addDaysToDate: (date, days) => {\n * date.setUTCDate(date.getUTCDate() + days)\n * return date\n * },\n * },\n * )\n * ```\n *\n * @param options\n * @returns\n */\nexport function evaluateConditionalPredicates({\n isConditional,\n requiresAllConditionalPredicates,\n conditionalPredicates,\n formElements,\n submission,\n submissionTimestamp,\n parseDate,\n addDaysToDate,\n}: {\n isConditional: boolean\n requiresAllConditionalPredicates: boolean\n conditionalPredicates: ConditionTypes.ConditionalPredicate[]\n formElements: FormTypes.FormElement[]\n submission: SubmissionTypes.S3SubmissionData['submission']\n /** ISO timestamp the form was submitted. When evaluating during submission, pass `new Date().toISOString()`. */\n submissionTimestamp: string\n /** Parse date/datetime strings when evaluating date based predicates */\n parseDate: ParseDate\n /** Add days to a date when evaluating date based predicates */\n addDaysToDate: AddOffsetToDate\n}): boolean {\n if (!isConditional || !conditionalPredicates.length) {\n return true\n }\n const formElementsCtrl = {\n flattenedElements: flattenFormElements(formElements),\n model: submission,\n }\n\n const predicateFn = (predicate: ConditionTypes.ConditionalPredicate) => {\n if (predicate.type === 'SUBMISSION_TIMESTAMP') {\n return evaluateConditionalSubmissionTimestampPredicate({\n predicate,\n formElementsCtrl,\n submissionTimestamp,\n parseDate,\n addDaysToDate,\n })\n }\n\n return !!evaluateFormElementConditionalPredicate({\n predicate,\n formElementsCtrl,\n })\n }\n if (requiresAllConditionalPredicates) {\n return conditionalPredicates.every(predicateFn)\n } else {\n return conditionalPredicates.some(predicateFn)\n }\n}\n"]}
1
+ {"version":3,"file":"conditionalLogicService.js","sourceRoot":"","sources":["../src/conditionalLogicService.ts"],"names":[],"mappings":"AAAA,OAAO,uCAAuC,MAAM,sEAAsE,CAAA;AAC1H,OAAO,+CAA+C,MAAM,8EAA8E,CAAA;AAC1I,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAA;AAS9D,cAAc,qEAAqE,CAAA;AAQnF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2EG;AACH,MAAM,UAAU,6BAA6B,CAAC,EAC5C,aAAa,EACb,gCAAgC,EAChC,qBAAqB,EACrB,YAAY,EACZ,UAAU,EACV,mBAAmB,EACnB,gBAAgB,EAChB,aAAa,EACb,UAAU,EACV,QAAQ,GAiBT;IACC,IAAI,CAAC,aAAa,IAAI,CAAC,qBAAqB,CAAC,MAAM,EAAE,CAAC;QACpD,OAAO,IAAI,CAAA;IACb,CAAC;IACD,MAAM,gBAAgB,GAAG;QACvB,iBAAiB,EAAE,mBAAmB,CAAC,YAAY,CAAC;QACpD,KAAK,EAAE,UAAU;KAClB,CAAA;IAED,MAAM,WAAW,GAAG,CAAC,SAA8C,EAAE,EAAE;QACrE,IAAI,SAAS,CAAC,IAAI,KAAK,sBAAsB,EAAE,CAAC;YAC9C,OAAO,+CAA+C,CAAC;gBACrD,SAAS;gBACT,gBAAgB;gBAChB,mBAAmB;gBACnB,gBAAgB;gBAChB,aAAa;gBACb,UAAU;gBACV,QAAQ;aACT,CAAC,CAAA;QACJ,CAAC;QAED,OAAO,CAAC,CAAC,uCAAuC,CAAC;YAC/C,SAAS;YACT,gBAAgB;SACjB,CAAC,CAAA;IACJ,CAAC,CAAA;IACD,IAAI,gCAAgC,EAAE,CAAC;QACrC,OAAO,qBAAqB,CAAC,KAAK,CAAC,WAAW,CAAC,CAAA;IACjD,CAAC;SAAM,CAAC;QACN,OAAO,qBAAqB,CAAC,IAAI,CAAC,WAAW,CAAC,CAAA;IAChD,CAAC;AACH,CAAC","sourcesContent":["import evaluateFormElementConditionalPredicate from './conditionalLogicService/evaluateFormElementConditionalPredicate.js'\nimport evaluateConditionalSubmissionTimestampPredicate from './conditionalLogicService/evaluateConditionalSubmissionTimestampPredicate.js'\nimport { flattenFormElements } from './formElementsService.js'\nimport { ConditionTypes, FormTypes, SubmissionTypes } from '@oneblink/types'\nimport {\n AddOffsetToDate,\n EndOfDay,\n ParseDayOnlyDate,\n StartOfDay,\n} from './conditionalLogicService/types.js'\n\nexport * from './conditionalLogicService/generateFormElementsConditionallyShown.js'\nexport type {\n AddOffsetToDate,\n EndOfDay,\n ParseDayOnlyDate,\n StartOfDay,\n} from './conditionalLogicService/types.js'\n\n/**\n * Given a set of form elements and submission data, evaluate if predicates are\n * met or not.\n *\n * #### Example\n *\n * ```js\n * const evaluation = conditionalLogicService.evaluateConditionalPredicates(\n * {\n * isConditional: true,\n * requiresAllConditionalPredicates: false,\n * conditionalPredicates: [\n * {\n * type: 'OPTIONS',\n * elementId: '3534abe4-b0b5-4ffa-a216-49c223ab6f95',\n * optionIds: ['9ce633dd-22d6-4e0e-a9e0-1aa62d435e72'],\n * },\n * ],\n * submission: {\n * checkboxes: ['a'],\n * },\n * formElements: [\n * {\n * name: 'checkboxes',\n * label: 'Checkboxes',\n * type: 'checkboxes',\n * required: false,\n * id: '3534abe4-b0b5-4ffa-a216-49c223ab6f95',\n * options: [\n * {\n * id: '9ce633dd-22d6-4e0e-a9e0-1aa62d435e72',\n * label: 'First',\n * value: 'a',\n * },\n * {\n * id: '5850b32c-3833-4498-a072-47fcc8122242',\n * label: 'Second',\n * value: 'b',\n * },\n * {\n * id: 'ab363e9f-a63f-4923-ba0d-47892fc26a93',\n * label: 'Third',\n * value: 'c',\n * },\n * ],\n * readOnly: false,\n * buttons: false,\n * optionsType: 'CUSTOM',\n * conditionallyShowOptions: false,\n * isDataLookup: false,\n * isElementLookup: false,\n * conditionallyShow: false,\n * requiresAllConditionallyShowPredicates: false,\n * },\n * ],\n * submissionTimestamp: new Date().toISOString(),\n * parseDayOnlyDate: (value) => new Date(`${value}T00:00:00.000Z`),\n * addDaysToDate: (date, days) => {\n * date.setUTCDate(date.getUTCDate() + days)\n * return date\n * },\n * startOfDay: (date) => {\n * date.setUTCHours(0, 0, 0, 0)\n * return date\n * },\n * endOfDay: (date) => {\n * date.setUTCHours(23, 59, 59, 999)\n * return date\n * },\n * },\n * )\n * ```\n *\n * @param options\n * @returns\n */\nexport function evaluateConditionalPredicates({\n isConditional,\n requiresAllConditionalPredicates,\n conditionalPredicates,\n formElements,\n submission,\n submissionTimestamp,\n parseDayOnlyDate,\n addDaysToDate,\n startOfDay,\n endOfDay,\n}: {\n isConditional: boolean\n requiresAllConditionalPredicates: boolean\n conditionalPredicates: ConditionTypes.ConditionalPredicate[]\n formElements: FormTypes.FormElement[]\n submission: SubmissionTypes.S3SubmissionData['submission']\n /** ISO timestamp the form was submitted. When evaluating during submission, pass `new Date().toISOString()`. */\n submissionTimestamp: string\n /** Parse `YYYY-MM-DD` strings when evaluating date based predicates */\n parseDayOnlyDate: ParseDayOnlyDate\n /** Add days to a date when evaluating date based predicates */\n addDaysToDate: AddOffsetToDate\n /** Start of calendar day when evaluating date (not datetime) based predicates */\n startOfDay: StartOfDay\n /** End of calendar day when evaluating date (not datetime) based predicates */\n endOfDay: EndOfDay\n}): boolean {\n if (!isConditional || !conditionalPredicates.length) {\n return true\n }\n const formElementsCtrl = {\n flattenedElements: flattenFormElements(formElements),\n model: submission,\n }\n\n const predicateFn = (predicate: ConditionTypes.ConditionalPredicate) => {\n if (predicate.type === 'SUBMISSION_TIMESTAMP') {\n return evaluateConditionalSubmissionTimestampPredicate({\n predicate,\n formElementsCtrl,\n submissionTimestamp,\n parseDayOnlyDate,\n addDaysToDate,\n startOfDay,\n endOfDay,\n })\n }\n\n return !!evaluateFormElementConditionalPredicate({\n predicate,\n formElementsCtrl,\n })\n }\n if (requiresAllConditionalPredicates) {\n return conditionalPredicates.every(predicateFn)\n } else {\n return conditionalPredicates.some(predicateFn)\n }\n}\n"]}
@@ -1,6 +1,6 @@
1
1
  import { FormTypes, SubmissionEventTypes, SubmissionTypes } from '@oneblink/types';
2
2
  import { ReplaceInjectablesFormatters } from './submissionService.js';
3
- import { AddOffsetToDate, ParseDate } from './conditionalLogicService/types.js';
3
+ import { AddOffsetToDate, EndOfDay, ParseDayOnlyDate, StartOfDay } from './conditionalLogicService/types.js';
4
4
  /**
5
5
  * Examine a submission and its form definition to validate whether a payment
6
6
  * workflow event needs to run.
@@ -12,26 +12,38 @@ import { AddOffsetToDate, ParseDate } from './conditionalLogicService/types.js';
12
12
  * definition: form,
13
13
  * submission,
14
14
  * submissionTimestamp,
15
- * parseDate: (value) => new Date(value),
15
+ * parseDayOnlyDate: (value) => new Date(`${value}T00:00:00.000Z`),
16
16
  * addDaysToDate: (date, days) => {
17
17
  * date.setUTCDate(date.getUTCDate() + days)
18
18
  * return date
19
19
  * },
20
+ * startOfDay: (date) => {
21
+ * date.setUTCHours(0, 0, 0, 0)
22
+ * return date
23
+ * },
24
+ * endOfDay: (date) => {
25
+ * date.setUTCHours(23, 59, 59, 999)
26
+ * return date
27
+ * },
20
28
  * })
21
29
  * ```
22
30
  *
23
31
  * @param options
24
32
  * @returns
25
33
  */
26
- export declare function checkForPaymentEvent({ definition, submission, submissionTimestamp, parseDate, addDaysToDate, }: {
34
+ export declare function checkForPaymentEvent({ definition, submission, submissionTimestamp, parseDayOnlyDate, addDaysToDate, startOfDay, endOfDay, }: {
27
35
  definition: FormTypes.Form;
28
36
  submission: SubmissionTypes.S3SubmissionData['submission'];
29
37
  /** ISO timestamp the form was submitted. When evaluating during submission, pass `new Date().toISOString()`. */
30
38
  submissionTimestamp: string;
31
- /** Parse date/datetime strings when evaluating date based predicates */
32
- parseDate: ParseDate;
39
+ /** Parse `YYYY-MM-DD` strings when evaluating date based predicates */
40
+ parseDayOnlyDate: ParseDayOnlyDate;
33
41
  /** Add days to a date when evaluating date based predicates */
34
42
  addDaysToDate: AddOffsetToDate;
43
+ /** Start of calendar day when evaluating date (not datetime) based predicates */
44
+ startOfDay: StartOfDay;
45
+ /** End of calendar day when evaluating date (not datetime) based predicates */
46
+ endOfDay: EndOfDay;
35
47
  }): {
36
48
  paymentSubmissionEvent: SubmissionEventTypes.FormPaymentEvent;
37
49
  amount: number;
@@ -11,18 +11,26 @@ import { getRootElementValueById, } from './submissionService.js';
11
11
  * definition: form,
12
12
  * submission,
13
13
  * submissionTimestamp,
14
- * parseDate: (value) => new Date(value),
14
+ * parseDayOnlyDate: (value) => new Date(`${value}T00:00:00.000Z`),
15
15
  * addDaysToDate: (date, days) => {
16
16
  * date.setUTCDate(date.getUTCDate() + days)
17
17
  * return date
18
18
  * },
19
+ * startOfDay: (date) => {
20
+ * date.setUTCHours(0, 0, 0, 0)
21
+ * return date
22
+ * },
23
+ * endOfDay: (date) => {
24
+ * date.setUTCHours(23, 59, 59, 999)
25
+ * return date
26
+ * },
19
27
  * })
20
28
  * ```
21
29
  *
22
30
  * @param options
23
31
  * @returns
24
32
  */
25
- export function checkForPaymentEvent({ definition, submission, submissionTimestamp, parseDate, addDaysToDate, }) {
33
+ export function checkForPaymentEvent({ definition, submission, submissionTimestamp, parseDayOnlyDate, addDaysToDate, startOfDay, endOfDay, }) {
26
34
  const paymentSubmissionEvents = definition.paymentEvents || [];
27
35
  const paymentSubmissionEvent = paymentSubmissionEvents.find((paymentSubmissionEvent) => {
28
36
  return (paymentSubmissionEvent &&
@@ -33,8 +41,10 @@ export function checkForPaymentEvent({ definition, submission, submissionTimesta
33
41
  submission: submission,
34
42
  formElements: definition.elements,
35
43
  submissionTimestamp,
36
- parseDate,
44
+ parseDayOnlyDate,
37
45
  addDaysToDate,
46
+ startOfDay,
47
+ endOfDay,
38
48
  }));
39
49
  });
40
50
  if (!paymentSubmissionEvent) {
@@ -1 +1 @@
1
- {"version":3,"file":"paymentService.js","sourceRoot":"","sources":["../src/paymentService.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n FormTypes,\n SubmissionEventTypes,\n SubmissionTypes,\n} from '@oneblink/types'\nimport { conditionalLogicService, formElementsService } from './index.js'\nimport {\n getRootElementValueById,\n ReplaceInjectablesFormatters,\n} from './submissionService.js'\nimport { AddOffsetToDate, ParseDate } from './conditionalLogicService/types.js'\n\n/**\n * Examine a submission and its form definition to validate whether a payment\n * workflow event needs to run.\n *\n * #### Example\n *\n * ```js\n * const result = paymentService.checkForPaymentEvent({\n * definition: form,\n * submission,\n * submissionTimestamp,\n * parseDate: (value) => new Date(value),\n * addDaysToDate: (date, days) => {\n * date.setUTCDate(date.getUTCDate() + days)\n * return date\n * },\n * })\n * ```\n *\n * @param options\n * @returns\n */\nexport function checkForPaymentEvent({\n definition,\n submission,\n submissionTimestamp,\n parseDate,\n addDaysToDate,\n}: {\n definition: FormTypes.Form\n submission: SubmissionTypes.S3SubmissionData['submission']\n /** ISO timestamp the form was submitted. When evaluating during submission, pass `new Date().toISOString()`. */\n submissionTimestamp: string\n /** Parse date/datetime strings when evaluating date based predicates */\n parseDate: ParseDate\n /** Add days to a date when evaluating date based predicates */\n addDaysToDate: AddOffsetToDate\n}):\n | {\n paymentSubmissionEvent: SubmissionEventTypes.FormPaymentEvent\n amount: number\n }\n | undefined {\n const paymentSubmissionEvents = definition.paymentEvents || []\n const paymentSubmissionEvent = paymentSubmissionEvents.find(\n (paymentSubmissionEvent) => {\n return (\n paymentSubmissionEvent &&\n conditionalLogicService.evaluateConditionalPredicates({\n isConditional: !!paymentSubmissionEvent.conditionallyExecute,\n requiresAllConditionalPredicates:\n !!paymentSubmissionEvent.requiresAllConditionallyExecutePredicates,\n conditionalPredicates:\n paymentSubmissionEvent.conditionallyExecutePredicates || [],\n submission: submission,\n formElements: definition.elements,\n submissionTimestamp,\n parseDate,\n addDaysToDate,\n })\n )\n },\n )\n\n if (!paymentSubmissionEvent) {\n return\n }\n console.log(\n 'Checking if submission with payment submission event needs processing',\n )\n\n const amountElement = formElementsService.findFormElement(\n definition.elements,\n (element) => element.id === paymentSubmissionEvent.configuration.elementId,\n )\n if (!amountElement || amountElement.type === 'page') {\n console.log(\n 'Form has a payment submission event but the amount element does not exist, throwing error',\n )\n throw new Error(\n 'We could not find the configuration required to make a payment. Please contact your administrator to ensure your application configuration has been completed successfully.',\n )\n }\n\n console.log('Found form element for payment submission event', amountElement)\n\n const amount = getRootElementValueById(\n amountElement.id,\n definition.elements,\n submission,\n )\n\n if (!amount) {\n console.log(\n 'Form has a payment submission event but the amount has been entered as 0 or not at all, finishing as normal submission',\n )\n return\n }\n\n if (typeof amount !== 'number') {\n console.log(\n 'Form has a payment submission event but the amount is not a number, throwing error',\n )\n throw new Error(\n 'The configuration required to make a payment is incorrect. Please contact your administrator to ensure your application configuration has been completed successfully.',\n )\n }\n\n const result = {\n paymentSubmissionEvent,\n amount,\n }\n\n return result\n}\n\ntype PaymentDisplayDetail = {\n label: string\n value: string\n /** A unique key across payment providers to identify the detail */\n key: SubmissionEventTypes.PaymentDisplayDetailKey\n}\n\n/**\n * Retrieve an array of detail items from a form submission payment.\n *\n * #### Example\n *\n * ```js\n * const detailItems =\n * paymentService.getDisplayDetailsFromFormSubmissionPayment(\n * formSubmissionPayment,\n * {\n * formatCurrency,\n * formatDateTime,\n * formatDate,\n * },\n * )\n * ```\n *\n * @param formSubmissionPayment\n * @param options\n * @returns\n */\nexport const getDisplayDetailsFromFormSubmissionPayment = (\n /** The form submission payment to get the details from */\n formSubmissionPayment: SubmissionTypes.FormSubmissionPayment,\n {\n formatCurrency,\n formatDateTime,\n formatDate,\n }: Pick<\n ReplaceInjectablesFormatters,\n 'formatCurrency' | 'formatDate' | 'formatDateTime'\n >,\n):\n | {\n amount: {\n value: number\n formatted: string\n }\n paymentDisplayDetails: PaymentDisplayDetail[]\n }\n | undefined => {\n switch (formSubmissionPayment.type) {\n case 'NSW_GOV_PAY': {\n const { paymentTransaction } = formSubmissionPayment\n if (!paymentTransaction || !paymentTransaction.agencyCompletionPayment) {\n return\n }\n\n const amount = {\n value: paymentTransaction.agencyCompletionPayment.amount,\n formatted: formatCurrency(\n paymentTransaction.agencyCompletionPayment.amount,\n ),\n }\n return {\n amount,\n paymentDisplayDetails: [\n {\n key: 'NSW_GOV_PAY_COMPLETION_REFERENCE',\n label: 'Completion Reference',\n value:\n paymentTransaction.agencyCompletionPayment\n .paymentCompletionReference,\n },\n {\n key: 'NSW_GOV_PAY_PAYMENT_REFERENCE',\n label: 'Payment Reference',\n value: paymentTransaction.agencyCompletionPayment.paymentReference,\n },\n {\n key: 'NSW_GOV_PAY_BANK_REFERENCE',\n label: 'Bank Reference',\n value: paymentTransaction.agencyCompletionPayment.bankReference,\n },\n {\n key: 'NSW_GOV_PAY_PAYMENT_METHOD',\n label: 'Payment Method',\n value: paymentTransaction.agencyCompletionPayment.paymentMethod,\n },\n ...(paymentTransaction.agencyCompletionPayment.paymentMethod ===\n 'BPAY' &&\n paymentTransaction.agencyCompletionPayment.bPay?.billerCode\n ? [\n {\n key: 'NSW_GOV_PAY_BPAY_BILLER_CODE' as const,\n label: 'BPay Biller Code',\n value:\n paymentTransaction.agencyCompletionPayment.bPay.billerCode,\n },\n ]\n : []),\n ...(paymentTransaction.agencyCompletionPayment.paymentMethod ===\n 'CARD'\n ? [\n {\n key: 'NSW_GOV_PAY_CREDIT_CARD_NUMBER' as const,\n label: 'Card Number',\n value: `xxxx xxxx xxxx ${paymentTransaction.agencyCompletionPayment.card?.last4Digits}`,\n },\n ]\n : []),\n {\n key: 'NSW_GOV_PAY_AMOUNT',\n label: 'Amount',\n value: amount.formatted,\n },\n {\n key: 'NSW_GOV_PAY_SURCHARGE_AMOUNT',\n label: 'Surcharge Amount',\n value: formatCurrency(\n paymentTransaction.agencyCompletionPayment.surcharge,\n ),\n },\n {\n key: 'NSW_GOV_PAY_SURCHARGE_GST',\n label: 'Surcharge GST',\n value: formatCurrency(\n paymentTransaction.agencyCompletionPayment.surchargeGst,\n ),\n },\n {\n key: 'NSW_GOV_PAY_CREATED_DATE_TIME',\n label: 'Created Date Time',\n value: formatDateTime(formSubmissionPayment.createdAt),\n },\n ],\n }\n }\n case 'BPOINT': {\n const { paymentTransaction } = formSubmissionPayment\n if (!paymentTransaction) {\n return\n }\n const amountValue = paymentTransaction.Amount / 100\n const amount = {\n value: amountValue,\n formatted: formatCurrency(amountValue),\n }\n return {\n amount,\n paymentDisplayDetails: [\n {\n key: 'BPOINT_RECEIPT_NUMBER',\n label: 'Receipt Number',\n value: paymentTransaction.ReceiptNumber,\n },\n {\n key: 'BPOINT_CRN1',\n label: 'CRN 1',\n value: paymentTransaction.Crn1,\n },\n {\n key: 'BPOINT_CRN2',\n label: 'CRN 2',\n value: paymentTransaction.Crn2,\n },\n {\n key: 'BPOINT_CRN3',\n label: 'CRN 3',\n value: paymentTransaction.Crn3,\n },\n {\n key: 'BPOINT_BILLER_CODE',\n label: 'Biller Code',\n value: paymentTransaction.BillerCode,\n },\n {\n key: 'BPOINT_CREDIT_CARD_MASK',\n label: 'Card Number',\n value: paymentTransaction.CardDetails.MaskedCardNumber,\n },\n {\n key: 'BPOINT_AMOUNT',\n label: 'Amount',\n value: amount.formatted,\n },\n {\n key: 'BPOINT_SURCHARGE_AMOUNT',\n label: 'Surcharge Amount',\n value: formatCurrency(paymentTransaction.AmountSurcharge / 100),\n },\n {\n key: 'BPOINT_PROCESSED_DATE_TIME',\n label: 'Processed Date Time',\n value: formatDateTime(paymentTransaction.ProcessedDateTime),\n },\n ],\n }\n }\n case 'CP_PAY': {\n const { paymentTransaction } = formSubmissionPayment\n if (!paymentTransaction) {\n return\n }\n\n const determineDetails = () => {\n switch (paymentTransaction.cpPayVersion) {\n case 'v2': {\n return {\n transactionId: paymentTransaction.result.id,\n orderNumber:\n paymentTransaction.result.externalReferenceId ?? undefined,\n paymentType: paymentTransaction.result.paymentType,\n creditCardMask: paymentTransaction.result.lastFour\n ? `xxxx xxxx xxxx ${paymentTransaction.result.lastFour}`\n : undefined,\n amount:\n paymentTransaction.result.amount !== undefined\n ? {\n value: paymentTransaction.result.amount,\n formatted: formatCurrency(\n paymentTransaction.result.amount,\n ),\n }\n : {\n value: NaN,\n formatted: 'Unknown',\n },\n createdDateTime: paymentTransaction.result.createdOnUtc,\n }\n }\n default: {\n return {\n transactionId: paymentTransaction.transactionId,\n orderNumber: paymentTransaction.orderNumber ?? undefined,\n paymentType:\n paymentTransaction.paymentTypeId === 1\n ? 'Credit/Debit Card'\n : paymentTransaction.paymentTypeId === 2\n ? 'ACH'\n : undefined,\n creditCardMask: paymentTransaction.lastFour\n ? `xxxx xxxx xxxx ${paymentTransaction.lastFour}`\n : undefined,\n amount: {\n value: paymentTransaction.amount,\n formatted: formatCurrency(paymentTransaction.amount),\n },\n createdDateTime: paymentTransaction.createdAt,\n }\n }\n }\n }\n\n const {\n transactionId,\n orderNumber,\n paymentType,\n creditCardMask,\n amount,\n createdDateTime,\n } = determineDetails()\n const paymentDisplayDetails: PaymentDisplayDetail[] = []\n if (transactionId) {\n paymentDisplayDetails.push({\n key: 'CP_PAY_TRANSACTION_ID',\n label: 'Transaction Id',\n value: transactionId,\n })\n }\n if (orderNumber) {\n paymentDisplayDetails.push({\n key: 'CP_PAY_ORDER_NUMBER',\n label: 'Order Number',\n value: orderNumber,\n })\n }\n if (paymentType) {\n paymentDisplayDetails.push({\n key: 'CP_PAY_PAYMENT_TYPE',\n label: 'Payment Type',\n value: paymentType,\n })\n }\n if (creditCardMask) {\n paymentDisplayDetails.push({\n key: 'CP_PAY_CREDIT_CARD_MASK',\n label: 'Card Number',\n value: creditCardMask,\n })\n }\n paymentDisplayDetails.push({\n key: 'CP_PAY_AMOUNT',\n label: 'Amount',\n value: amount.formatted,\n })\n if (createdDateTime) {\n paymentDisplayDetails.push({\n key: 'CP_PAY_CREATED_DATE_TIME',\n label: 'Created At',\n value: formatDateTime(createdDateTime),\n })\n }\n\n return {\n amount,\n paymentDisplayDetails,\n }\n }\n case 'WESTPAC_QUICK_STREAM': {\n const { paymentTransaction } = formSubmissionPayment\n if (!paymentTransaction) {\n return\n }\n\n const amount = {\n value: paymentTransaction.totalAmount.amount,\n formatted: formatCurrency(\n parseFloat(paymentTransaction.totalAmount.amount.toString()),\n ),\n }\n\n return {\n amount,\n paymentDisplayDetails: [\n {\n key: 'WESTPAC_QUICK_STREAM_RECEIPT_NUMBER',\n label: 'Receipt Number',\n value: paymentTransaction.receiptNumber,\n },\n {\n key: 'WESTPAC_QUICK_STREAM_PAYMENT_REFERENCE_NUMBER',\n label: 'Payment Reference',\n value: paymentTransaction.paymentReferenceNumber,\n },\n {\n key: 'WESTPAC_QUICK_STREAM_CUSTOMER_REFERENCE_NUMBER',\n label: 'Customer Reference Number',\n value: paymentTransaction.customerReferenceNumber,\n },\n {\n key: 'WESTPAC_QUICK_STREAM_AMOUNT',\n label: 'Amount',\n value: amount.formatted,\n },\n ...(paymentTransaction.surchargeAmount.amount\n ? [\n {\n key: 'WESTPAC_QUICK_STREAM_SURCHARGE_AMOUNT' as const,\n label: 'Surcharge Amount',\n value: formatCurrency(\n parseFloat(\n paymentTransaction.surchargeAmount.amount.toString(),\n ),\n ),\n },\n ]\n : []),\n {\n key: 'WESTPAC_QUICK_STREAM_SETTLEMENT_DATE',\n label: 'Settlement Date',\n value: formatDate(paymentTransaction.settlementDate),\n },\n ],\n }\n }\n }\n}\n"]}
1
+ {"version":3,"file":"paymentService.js","sourceRoot":"","sources":["../src/paymentService.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n FormTypes,\n SubmissionEventTypes,\n SubmissionTypes,\n} from '@oneblink/types'\nimport { conditionalLogicService, formElementsService } from './index.js'\nimport {\n getRootElementValueById,\n ReplaceInjectablesFormatters,\n} from './submissionService.js'\nimport {\n AddOffsetToDate,\n EndOfDay,\n ParseDayOnlyDate,\n StartOfDay,\n} from './conditionalLogicService/types.js'\n\n/**\n * Examine a submission and its form definition to validate whether a payment\n * workflow event needs to run.\n *\n * #### Example\n *\n * ```js\n * const result = paymentService.checkForPaymentEvent({\n * definition: form,\n * submission,\n * submissionTimestamp,\n * parseDayOnlyDate: (value) => new Date(`${value}T00:00:00.000Z`),\n * addDaysToDate: (date, days) => {\n * date.setUTCDate(date.getUTCDate() + days)\n * return date\n * },\n * startOfDay: (date) => {\n * date.setUTCHours(0, 0, 0, 0)\n * return date\n * },\n * endOfDay: (date) => {\n * date.setUTCHours(23, 59, 59, 999)\n * return date\n * },\n * })\n * ```\n *\n * @param options\n * @returns\n */\nexport function checkForPaymentEvent({\n definition,\n submission,\n submissionTimestamp,\n parseDayOnlyDate,\n addDaysToDate,\n startOfDay,\n endOfDay,\n}: {\n definition: FormTypes.Form\n submission: SubmissionTypes.S3SubmissionData['submission']\n /** ISO timestamp the form was submitted. When evaluating during submission, pass `new Date().toISOString()`. */\n submissionTimestamp: string\n /** Parse `YYYY-MM-DD` strings when evaluating date based predicates */\n parseDayOnlyDate: ParseDayOnlyDate\n /** Add days to a date when evaluating date based predicates */\n addDaysToDate: AddOffsetToDate\n /** Start of calendar day when evaluating date (not datetime) based predicates */\n startOfDay: StartOfDay\n /** End of calendar day when evaluating date (not datetime) based predicates */\n endOfDay: EndOfDay\n}):\n | {\n paymentSubmissionEvent: SubmissionEventTypes.FormPaymentEvent\n amount: number\n }\n | undefined {\n const paymentSubmissionEvents = definition.paymentEvents || []\n const paymentSubmissionEvent = paymentSubmissionEvents.find(\n (paymentSubmissionEvent) => {\n return (\n paymentSubmissionEvent &&\n conditionalLogicService.evaluateConditionalPredicates({\n isConditional: !!paymentSubmissionEvent.conditionallyExecute,\n requiresAllConditionalPredicates:\n !!paymentSubmissionEvent.requiresAllConditionallyExecutePredicates,\n conditionalPredicates:\n paymentSubmissionEvent.conditionallyExecutePredicates || [],\n submission: submission,\n formElements: definition.elements,\n submissionTimestamp,\n parseDayOnlyDate,\n addDaysToDate,\n startOfDay,\n endOfDay,\n })\n )\n },\n )\n\n if (!paymentSubmissionEvent) {\n return\n }\n console.log(\n 'Checking if submission with payment submission event needs processing',\n )\n\n const amountElement = formElementsService.findFormElement(\n definition.elements,\n (element) => element.id === paymentSubmissionEvent.configuration.elementId,\n )\n if (!amountElement || amountElement.type === 'page') {\n console.log(\n 'Form has a payment submission event but the amount element does not exist, throwing error',\n )\n throw new Error(\n 'We could not find the configuration required to make a payment. Please contact your administrator to ensure your application configuration has been completed successfully.',\n )\n }\n\n console.log('Found form element for payment submission event', amountElement)\n\n const amount = getRootElementValueById(\n amountElement.id,\n definition.elements,\n submission,\n )\n\n if (!amount) {\n console.log(\n 'Form has a payment submission event but the amount has been entered as 0 or not at all, finishing as normal submission',\n )\n return\n }\n\n if (typeof amount !== 'number') {\n console.log(\n 'Form has a payment submission event but the amount is not a number, throwing error',\n )\n throw new Error(\n 'The configuration required to make a payment is incorrect. Please contact your administrator to ensure your application configuration has been completed successfully.',\n )\n }\n\n const result = {\n paymentSubmissionEvent,\n amount,\n }\n\n return result\n}\n\ntype PaymentDisplayDetail = {\n label: string\n value: string\n /** A unique key across payment providers to identify the detail */\n key: SubmissionEventTypes.PaymentDisplayDetailKey\n}\n\n/**\n * Retrieve an array of detail items from a form submission payment.\n *\n * #### Example\n *\n * ```js\n * const detailItems =\n * paymentService.getDisplayDetailsFromFormSubmissionPayment(\n * formSubmissionPayment,\n * {\n * formatCurrency,\n * formatDateTime,\n * formatDate,\n * },\n * )\n * ```\n *\n * @param formSubmissionPayment\n * @param options\n * @returns\n */\nexport const getDisplayDetailsFromFormSubmissionPayment = (\n /** The form submission payment to get the details from */\n formSubmissionPayment: SubmissionTypes.FormSubmissionPayment,\n {\n formatCurrency,\n formatDateTime,\n formatDate,\n }: Pick<\n ReplaceInjectablesFormatters,\n 'formatCurrency' | 'formatDate' | 'formatDateTime'\n >,\n):\n | {\n amount: {\n value: number\n formatted: string\n }\n paymentDisplayDetails: PaymentDisplayDetail[]\n }\n | undefined => {\n switch (formSubmissionPayment.type) {\n case 'NSW_GOV_PAY': {\n const { paymentTransaction } = formSubmissionPayment\n if (!paymentTransaction || !paymentTransaction.agencyCompletionPayment) {\n return\n }\n\n const amount = {\n value: paymentTransaction.agencyCompletionPayment.amount,\n formatted: formatCurrency(\n paymentTransaction.agencyCompletionPayment.amount,\n ),\n }\n return {\n amount,\n paymentDisplayDetails: [\n {\n key: 'NSW_GOV_PAY_COMPLETION_REFERENCE',\n label: 'Completion Reference',\n value:\n paymentTransaction.agencyCompletionPayment\n .paymentCompletionReference,\n },\n {\n key: 'NSW_GOV_PAY_PAYMENT_REFERENCE',\n label: 'Payment Reference',\n value: paymentTransaction.agencyCompletionPayment.paymentReference,\n },\n {\n key: 'NSW_GOV_PAY_BANK_REFERENCE',\n label: 'Bank Reference',\n value: paymentTransaction.agencyCompletionPayment.bankReference,\n },\n {\n key: 'NSW_GOV_PAY_PAYMENT_METHOD',\n label: 'Payment Method',\n value: paymentTransaction.agencyCompletionPayment.paymentMethod,\n },\n ...(paymentTransaction.agencyCompletionPayment.paymentMethod ===\n 'BPAY' &&\n paymentTransaction.agencyCompletionPayment.bPay?.billerCode\n ? [\n {\n key: 'NSW_GOV_PAY_BPAY_BILLER_CODE' as const,\n label: 'BPay Biller Code',\n value:\n paymentTransaction.agencyCompletionPayment.bPay.billerCode,\n },\n ]\n : []),\n ...(paymentTransaction.agencyCompletionPayment.paymentMethod ===\n 'CARD'\n ? [\n {\n key: 'NSW_GOV_PAY_CREDIT_CARD_NUMBER' as const,\n label: 'Card Number',\n value: `xxxx xxxx xxxx ${paymentTransaction.agencyCompletionPayment.card?.last4Digits}`,\n },\n ]\n : []),\n {\n key: 'NSW_GOV_PAY_AMOUNT',\n label: 'Amount',\n value: amount.formatted,\n },\n {\n key: 'NSW_GOV_PAY_SURCHARGE_AMOUNT',\n label: 'Surcharge Amount',\n value: formatCurrency(\n paymentTransaction.agencyCompletionPayment.surcharge,\n ),\n },\n {\n key: 'NSW_GOV_PAY_SURCHARGE_GST',\n label: 'Surcharge GST',\n value: formatCurrency(\n paymentTransaction.agencyCompletionPayment.surchargeGst,\n ),\n },\n {\n key: 'NSW_GOV_PAY_CREATED_DATE_TIME',\n label: 'Created Date Time',\n value: formatDateTime(formSubmissionPayment.createdAt),\n },\n ],\n }\n }\n case 'BPOINT': {\n const { paymentTransaction } = formSubmissionPayment\n if (!paymentTransaction) {\n return\n }\n const amountValue = paymentTransaction.Amount / 100\n const amount = {\n value: amountValue,\n formatted: formatCurrency(amountValue),\n }\n return {\n amount,\n paymentDisplayDetails: [\n {\n key: 'BPOINT_RECEIPT_NUMBER',\n label: 'Receipt Number',\n value: paymentTransaction.ReceiptNumber,\n },\n {\n key: 'BPOINT_CRN1',\n label: 'CRN 1',\n value: paymentTransaction.Crn1,\n },\n {\n key: 'BPOINT_CRN2',\n label: 'CRN 2',\n value: paymentTransaction.Crn2,\n },\n {\n key: 'BPOINT_CRN3',\n label: 'CRN 3',\n value: paymentTransaction.Crn3,\n },\n {\n key: 'BPOINT_BILLER_CODE',\n label: 'Biller Code',\n value: paymentTransaction.BillerCode,\n },\n {\n key: 'BPOINT_CREDIT_CARD_MASK',\n label: 'Card Number',\n value: paymentTransaction.CardDetails.MaskedCardNumber,\n },\n {\n key: 'BPOINT_AMOUNT',\n label: 'Amount',\n value: amount.formatted,\n },\n {\n key: 'BPOINT_SURCHARGE_AMOUNT',\n label: 'Surcharge Amount',\n value: formatCurrency(paymentTransaction.AmountSurcharge / 100),\n },\n {\n key: 'BPOINT_PROCESSED_DATE_TIME',\n label: 'Processed Date Time',\n value: formatDateTime(paymentTransaction.ProcessedDateTime),\n },\n ],\n }\n }\n case 'CP_PAY': {\n const { paymentTransaction } = formSubmissionPayment\n if (!paymentTransaction) {\n return\n }\n\n const determineDetails = () => {\n switch (paymentTransaction.cpPayVersion) {\n case 'v2': {\n return {\n transactionId: paymentTransaction.result.id,\n orderNumber:\n paymentTransaction.result.externalReferenceId ?? undefined,\n paymentType: paymentTransaction.result.paymentType,\n creditCardMask: paymentTransaction.result.lastFour\n ? `xxxx xxxx xxxx ${paymentTransaction.result.lastFour}`\n : undefined,\n amount:\n paymentTransaction.result.amount !== undefined\n ? {\n value: paymentTransaction.result.amount,\n formatted: formatCurrency(\n paymentTransaction.result.amount,\n ),\n }\n : {\n value: NaN,\n formatted: 'Unknown',\n },\n createdDateTime: paymentTransaction.result.createdOnUtc,\n }\n }\n default: {\n return {\n transactionId: paymentTransaction.transactionId,\n orderNumber: paymentTransaction.orderNumber ?? undefined,\n paymentType:\n paymentTransaction.paymentTypeId === 1\n ? 'Credit/Debit Card'\n : paymentTransaction.paymentTypeId === 2\n ? 'ACH'\n : undefined,\n creditCardMask: paymentTransaction.lastFour\n ? `xxxx xxxx xxxx ${paymentTransaction.lastFour}`\n : undefined,\n amount: {\n value: paymentTransaction.amount,\n formatted: formatCurrency(paymentTransaction.amount),\n },\n createdDateTime: paymentTransaction.createdAt,\n }\n }\n }\n }\n\n const {\n transactionId,\n orderNumber,\n paymentType,\n creditCardMask,\n amount,\n createdDateTime,\n } = determineDetails()\n const paymentDisplayDetails: PaymentDisplayDetail[] = []\n if (transactionId) {\n paymentDisplayDetails.push({\n key: 'CP_PAY_TRANSACTION_ID',\n label: 'Transaction Id',\n value: transactionId,\n })\n }\n if (orderNumber) {\n paymentDisplayDetails.push({\n key: 'CP_PAY_ORDER_NUMBER',\n label: 'Order Number',\n value: orderNumber,\n })\n }\n if (paymentType) {\n paymentDisplayDetails.push({\n key: 'CP_PAY_PAYMENT_TYPE',\n label: 'Payment Type',\n value: paymentType,\n })\n }\n if (creditCardMask) {\n paymentDisplayDetails.push({\n key: 'CP_PAY_CREDIT_CARD_MASK',\n label: 'Card Number',\n value: creditCardMask,\n })\n }\n paymentDisplayDetails.push({\n key: 'CP_PAY_AMOUNT',\n label: 'Amount',\n value: amount.formatted,\n })\n if (createdDateTime) {\n paymentDisplayDetails.push({\n key: 'CP_PAY_CREATED_DATE_TIME',\n label: 'Created At',\n value: formatDateTime(createdDateTime),\n })\n }\n\n return {\n amount,\n paymentDisplayDetails,\n }\n }\n case 'WESTPAC_QUICK_STREAM': {\n const { paymentTransaction } = formSubmissionPayment\n if (!paymentTransaction) {\n return\n }\n\n const amount = {\n value: paymentTransaction.totalAmount.amount,\n formatted: formatCurrency(\n parseFloat(paymentTransaction.totalAmount.amount.toString()),\n ),\n }\n\n return {\n amount,\n paymentDisplayDetails: [\n {\n key: 'WESTPAC_QUICK_STREAM_RECEIPT_NUMBER',\n label: 'Receipt Number',\n value: paymentTransaction.receiptNumber,\n },\n {\n key: 'WESTPAC_QUICK_STREAM_PAYMENT_REFERENCE_NUMBER',\n label: 'Payment Reference',\n value: paymentTransaction.paymentReferenceNumber,\n },\n {\n key: 'WESTPAC_QUICK_STREAM_CUSTOMER_REFERENCE_NUMBER',\n label: 'Customer Reference Number',\n value: paymentTransaction.customerReferenceNumber,\n },\n {\n key: 'WESTPAC_QUICK_STREAM_AMOUNT',\n label: 'Amount',\n value: amount.formatted,\n },\n ...(paymentTransaction.surchargeAmount.amount\n ? [\n {\n key: 'WESTPAC_QUICK_STREAM_SURCHARGE_AMOUNT' as const,\n label: 'Surcharge Amount',\n value: formatCurrency(\n parseFloat(\n paymentTransaction.surchargeAmount.amount.toString(),\n ),\n ),\n },\n ]\n : []),\n {\n key: 'WESTPAC_QUICK_STREAM_SETTLEMENT_DATE',\n label: 'Settlement Date',\n value: formatDate(paymentTransaction.settlementDate),\n },\n ],\n }\n }\n }\n}\n"]}
@@ -1,5 +1,5 @@
1
1
  import { FormTypes, SubmissionEventTypes, SubmissionTypes } from '@oneblink/types';
2
- import { AddOffsetToDate, ParseDate } from './conditionalLogicService/types.js';
2
+ import { AddOffsetToDate, EndOfDay, ParseDayOnlyDate, StartOfDay } from './conditionalLogicService/types.js';
3
3
  /**
4
4
  * Examine a submission and its form definition to validate whether a scheduling
5
5
  * workflow event needs to run.
@@ -11,24 +11,36 @@ import { AddOffsetToDate, ParseDate } from './conditionalLogicService/types.js';
11
11
  * definition: form,
12
12
  * submission,
13
13
  * submissionTimestamp,
14
- * parseDate: (value) => new Date(value),
14
+ * parseDayOnlyDate: (value) => new Date(`${value}T00:00:00.000Z`),
15
15
  * addDaysToDate: (date, days) => {
16
16
  * date.setUTCDate(date.getUTCDate() + days)
17
17
  * return date
18
18
  * },
19
+ * startOfDay: (date) => {
20
+ * date.setUTCHours(0, 0, 0, 0)
21
+ * return date
22
+ * },
23
+ * endOfDay: (date) => {
24
+ * date.setUTCHours(23, 59, 59, 999)
25
+ * return date
26
+ * },
19
27
  * })
20
28
  * ```
21
29
  *
22
30
  * @param options
23
31
  * @returns
24
32
  */
25
- export declare function checkForSchedulingEvent({ definition, submission, submissionTimestamp, parseDate, addDaysToDate, }: {
33
+ export declare function checkForSchedulingEvent({ definition, submission, submissionTimestamp, parseDayOnlyDate, addDaysToDate, startOfDay, endOfDay, }: {
26
34
  definition: FormTypes.Form;
27
35
  submission: SubmissionTypes.S3SubmissionData['submission'];
28
36
  /** ISO timestamp the form was submitted. When evaluating during submission, pass `new Date().toISOString()`. */
29
37
  submissionTimestamp: string;
30
- /** Parse date/datetime strings when evaluating date based predicates */
31
- parseDate: ParseDate;
38
+ /** Parse `YYYY-MM-DD` strings when evaluating date based predicates */
39
+ parseDayOnlyDate: ParseDayOnlyDate;
32
40
  /** Add days to a date when evaluating date based predicates */
33
41
  addDaysToDate: AddOffsetToDate;
42
+ /** Start of calendar day when evaluating date (not datetime) based predicates */
43
+ startOfDay: StartOfDay;
44
+ /** End of calendar day when evaluating date (not datetime) based predicates */
45
+ endOfDay: EndOfDay;
34
46
  }): SubmissionEventTypes.FormSchedulingEvent | undefined;
@@ -10,18 +10,26 @@ import { conditionalLogicService } from './index.js';
10
10
  * definition: form,
11
11
  * submission,
12
12
  * submissionTimestamp,
13
- * parseDate: (value) => new Date(value),
13
+ * parseDayOnlyDate: (value) => new Date(`${value}T00:00:00.000Z`),
14
14
  * addDaysToDate: (date, days) => {
15
15
  * date.setUTCDate(date.getUTCDate() + days)
16
16
  * return date
17
17
  * },
18
+ * startOfDay: (date) => {
19
+ * date.setUTCHours(0, 0, 0, 0)
20
+ * return date
21
+ * },
22
+ * endOfDay: (date) => {
23
+ * date.setUTCHours(23, 59, 59, 999)
24
+ * return date
25
+ * },
18
26
  * })
19
27
  * ```
20
28
  *
21
29
  * @param options
22
30
  * @returns
23
31
  */
24
- export function checkForSchedulingEvent({ definition, submission, submissionTimestamp, parseDate, addDaysToDate, }) {
32
+ export function checkForSchedulingEvent({ definition, submission, submissionTimestamp, parseDayOnlyDate, addDaysToDate, startOfDay, endOfDay, }) {
25
33
  const schedulingSubmissionEvents = definition.schedulingEvents || [];
26
34
  return schedulingSubmissionEvents.find((schedulingSubmissionEvent) => conditionalLogicService.evaluateConditionalPredicates({
27
35
  isConditional: !!schedulingSubmissionEvent.conditionallyExecute,
@@ -30,8 +38,10 @@ export function checkForSchedulingEvent({ definition, submission, submissionTime
30
38
  submission: submission,
31
39
  formElements: definition.elements,
32
40
  submissionTimestamp,
33
- parseDate,
41
+ parseDayOnlyDate,
34
42
  addDaysToDate,
43
+ startOfDay,
44
+ endOfDay,
35
45
  }));
36
46
  }
37
47
  //# sourceMappingURL=schedulingService.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"schedulingService.js","sourceRoot":"","sources":["../src/schedulingService.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAA;AAGpD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,UAAU,uBAAuB,CAAC,EACtC,UAAU,EACV,UAAU,EACV,mBAAmB,EACnB,SAAS,EACT,aAAa,GAUd;IACC,MAAM,0BAA0B,GAAG,UAAU,CAAC,gBAAgB,IAAI,EAAE,CAAA;IACpE,OAAO,0BAA0B,CAAC,IAAI,CAAC,CAAC,yBAAyB,EAAE,EAAE,CACnE,uBAAuB,CAAC,6BAA6B,CAAC;QACpD,aAAa,EAAE,CAAC,CAAC,yBAAyB,CAAC,oBAAoB;QAC/D,gCAAgC,EAC9B,CAAC,CAAC,yBAAyB,CAAC,yCAAyC;QACvE,qBAAqB,EACnB,yBAAyB,CAAC,8BAA8B,IAAI,EAAE;QAChE,UAAU,EAAE,UAAU;QACtB,YAAY,EAAE,UAAU,CAAC,QAAQ;QACjC,mBAAmB;QACnB,SAAS;QACT,aAAa;KACd,CAAC,CACH,CAAA;AACH,CAAC","sourcesContent":["import {\n FormTypes,\n SubmissionEventTypes,\n SubmissionTypes,\n} from '@oneblink/types'\nimport { conditionalLogicService } from './index.js'\nimport { AddOffsetToDate, ParseDate } from './conditionalLogicService/types.js'\n\n/**\n * Examine a submission and its form definition to validate whether a scheduling\n * workflow event needs to run.\n *\n * #### Example\n *\n * ```js\n * const result = schedulingService.checkForSchedulingEvent({\n * definition: form,\n * submission,\n * submissionTimestamp,\n * parseDate: (value) => new Date(value),\n * addDaysToDate: (date, days) => {\n * date.setUTCDate(date.getUTCDate() + days)\n * return date\n * },\n * })\n * ```\n *\n * @param options\n * @returns\n */\nexport function checkForSchedulingEvent({\n definition,\n submission,\n submissionTimestamp,\n parseDate,\n addDaysToDate,\n}: {\n definition: FormTypes.Form\n submission: SubmissionTypes.S3SubmissionData['submission']\n /** ISO timestamp the form was submitted. When evaluating during submission, pass `new Date().toISOString()`. */\n submissionTimestamp: string\n /** Parse date/datetime strings when evaluating date based predicates */\n parseDate: ParseDate\n /** Add days to a date when evaluating date based predicates */\n addDaysToDate: AddOffsetToDate\n}): SubmissionEventTypes.FormSchedulingEvent | undefined {\n const schedulingSubmissionEvents = definition.schedulingEvents || []\n return schedulingSubmissionEvents.find((schedulingSubmissionEvent) =>\n conditionalLogicService.evaluateConditionalPredicates({\n isConditional: !!schedulingSubmissionEvent.conditionallyExecute,\n requiresAllConditionalPredicates:\n !!schedulingSubmissionEvent.requiresAllConditionallyExecutePredicates,\n conditionalPredicates:\n schedulingSubmissionEvent.conditionallyExecutePredicates || [],\n submission: submission,\n formElements: definition.elements,\n submissionTimestamp,\n parseDate,\n addDaysToDate,\n }),\n )\n}\n"]}
1
+ {"version":3,"file":"schedulingService.js","sourceRoot":"","sources":["../src/schedulingService.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAA;AAQpD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,MAAM,UAAU,uBAAuB,CAAC,EACtC,UAAU,EACV,UAAU,EACV,mBAAmB,EACnB,gBAAgB,EAChB,aAAa,EACb,UAAU,EACV,QAAQ,GAcT;IACC,MAAM,0BAA0B,GAAG,UAAU,CAAC,gBAAgB,IAAI,EAAE,CAAA;IACpE,OAAO,0BAA0B,CAAC,IAAI,CAAC,CAAC,yBAAyB,EAAE,EAAE,CACnE,uBAAuB,CAAC,6BAA6B,CAAC;QACpD,aAAa,EAAE,CAAC,CAAC,yBAAyB,CAAC,oBAAoB;QAC/D,gCAAgC,EAC9B,CAAC,CAAC,yBAAyB,CAAC,yCAAyC;QACvE,qBAAqB,EACnB,yBAAyB,CAAC,8BAA8B,IAAI,EAAE;QAChE,UAAU,EAAE,UAAU;QACtB,YAAY,EAAE,UAAU,CAAC,QAAQ;QACjC,mBAAmB;QACnB,gBAAgB;QAChB,aAAa;QACb,UAAU;QACV,QAAQ;KACT,CAAC,CACH,CAAA;AACH,CAAC","sourcesContent":["import {\n FormTypes,\n SubmissionEventTypes,\n SubmissionTypes,\n} from '@oneblink/types'\nimport { conditionalLogicService } from './index.js'\nimport {\n AddOffsetToDate,\n EndOfDay,\n ParseDayOnlyDate,\n StartOfDay,\n} from './conditionalLogicService/types.js'\n\n/**\n * Examine a submission and its form definition to validate whether a scheduling\n * workflow event needs to run.\n *\n * #### Example\n *\n * ```js\n * const result = schedulingService.checkForSchedulingEvent({\n * definition: form,\n * submission,\n * submissionTimestamp,\n * parseDayOnlyDate: (value) => new Date(`${value}T00:00:00.000Z`),\n * addDaysToDate: (date, days) => {\n * date.setUTCDate(date.getUTCDate() + days)\n * return date\n * },\n * startOfDay: (date) => {\n * date.setUTCHours(0, 0, 0, 0)\n * return date\n * },\n * endOfDay: (date) => {\n * date.setUTCHours(23, 59, 59, 999)\n * return date\n * },\n * })\n * ```\n *\n * @param options\n * @returns\n */\nexport function checkForSchedulingEvent({\n definition,\n submission,\n submissionTimestamp,\n parseDayOnlyDate,\n addDaysToDate,\n startOfDay,\n endOfDay,\n}: {\n definition: FormTypes.Form\n submission: SubmissionTypes.S3SubmissionData['submission']\n /** ISO timestamp the form was submitted. When evaluating during submission, pass `new Date().toISOString()`. */\n submissionTimestamp: string\n /** Parse `YYYY-MM-DD` strings when evaluating date based predicates */\n parseDayOnlyDate: ParseDayOnlyDate\n /** Add days to a date when evaluating date based predicates */\n addDaysToDate: AddOffsetToDate\n /** Start of calendar day when evaluating date (not datetime) based predicates */\n startOfDay: StartOfDay\n /** End of calendar day when evaluating date (not datetime) based predicates */\n endOfDay: EndOfDay\n}): SubmissionEventTypes.FormSchedulingEvent | undefined {\n const schedulingSubmissionEvents = definition.schedulingEvents || []\n return schedulingSubmissionEvents.find((schedulingSubmissionEvent) =>\n conditionalLogicService.evaluateConditionalPredicates({\n isConditional: !!schedulingSubmissionEvent.conditionallyExecute,\n requiresAllConditionalPredicates:\n !!schedulingSubmissionEvent.requiresAllConditionallyExecutePredicates,\n conditionalPredicates:\n schedulingSubmissionEvent.conditionallyExecutePredicates || [],\n submission: submission,\n formElements: definition.elements,\n submissionTimestamp,\n parseDayOnlyDate,\n addDaysToDate,\n startOfDay,\n endOfDay,\n }),\n )\n}\n"]}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@oneblink/sdk-core",
3
3
  "description": "OneBlink SDK for JavaScript (works in Browsers and NodeJS)",
4
- "version": "10.0.0-beta.1",
4
+ "version": "10.0.0-beta.3",
5
5
  "author": "OneBlink <developers@oneblink.io> (https://oneblink.io)",
6
6
  "bugs": {
7
7
  "url": "https://github.com/oneblink/sdk-core-js/issues"