@zeniai/client-epic-state 5.1.99 → 5.2.0-beta0AK

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 (38) hide show
  1. package/lib/commonStateTypes/accountView/nestedAccountID.d.ts +0 -3
  2. package/lib/commonStateTypes/accountView/nestedAccountID.js +1 -4
  3. package/lib/commonStateTypes/coaBalance/coaBalance.d.ts +0 -5
  4. package/lib/commonStateTypes/timePeriod.d.ts +0 -2
  5. package/lib/commonStateTypes/timePeriod.js +1 -6
  6. package/lib/entity/invoicing/invoicingCustomer/invoicingCustomerPayload.d.ts +16 -0
  7. package/lib/entity/invoicing/invoicingCustomer/invoicingCustomerPayload.js +20 -0
  8. package/lib/entity/invoicing/invoicingCustomer/invoicingCustomerSelector.d.ts +8 -1
  9. package/lib/entity/invoicing/invoicingCustomer/invoicingCustomerSelector.js +48 -0
  10. package/lib/entity/invoicing/invoicingCustomer/invoicingCustomerState.d.ts +24 -0
  11. package/lib/entity/invoicing/invoicingSubscription/invoicingSubscriptionPayload.d.ts +1 -0
  12. package/lib/entity/invoicing/invoicingSubscription/invoicingSubscriptionPayload.js +1 -0
  13. package/lib/entity/invoicing/invoicingSubscription/invoicingSubscriptionState.d.ts +1 -0
  14. package/lib/entity/toastNotification/epic/pushToastNotificationEpic.d.ts +0 -1
  15. package/lib/entity/toastNotification/epic/pushToastNotificationEpic.js +0 -1
  16. package/lib/entity/transaction/toSupportedTransaction.d.ts +1 -1
  17. package/lib/entity/transaction/toSupportedTransaction.js +0 -1
  18. package/lib/esm/commonStateTypes/accountView/nestedAccountID.js +0 -3
  19. package/lib/esm/commonStateTypes/timePeriod.js +0 -4
  20. package/lib/esm/entity/invoicing/invoicingCustomer/invoicingCustomerPayload.js +20 -0
  21. package/lib/esm/entity/invoicing/invoicingCustomer/invoicingCustomerSelector.js +47 -0
  22. package/lib/esm/entity/invoicing/invoicingSubscription/invoicingSubscriptionPayload.js +1 -0
  23. package/lib/esm/entity/toastNotification/epic/pushToastNotificationEpic.js +0 -1
  24. package/lib/esm/entity/transaction/toSupportedTransaction.js +1 -1
  25. package/lib/esm/index.js +3 -3
  26. package/lib/esm/view/invoicing/createInvoice/createInvoiceSelector.js +1 -0
  27. package/lib/esm/view/invoicing/invoicingCustomerDetailView/invoicingCustomerDetailViewSelector.js +4 -2
  28. package/lib/esm/view/profitAndLossProjectView/profitAndLossProjectViewReducer.js +2 -1
  29. package/lib/index.d.ts +5 -5
  30. package/lib/view/invoicing/createInvoice/createInvoiceSelector.d.ts +4 -1
  31. package/lib/view/invoicing/createInvoice/createInvoiceSelector.js +1 -0
  32. package/lib/view/invoicing/invoicingCustomerDetailView/invoicingCustomerDetailViewSelector.d.ts +2 -1
  33. package/lib/view/invoicing/invoicingCustomerDetailView/invoicingCustomerDetailViewSelector.js +3 -1
  34. package/lib/view/profitAndLossProjectView/profitAndLossProjectViewReducer.js +2 -1
  35. package/package.json +4 -10
  36. package/lib/commonStateTypes/selectorTypes/pickAndMergeForecastSection.d.ts +0 -0
  37. package/lib/commonStateTypes/selectorTypes/pickAndMergeForecastSection.js +0 -1
  38. package/lib/esm/commonStateTypes/selectorTypes/pickAndMergeForecastSection.js +0 -1
@@ -32,9 +32,6 @@ type AccountIDPlus4SubAccount = [
32
32
  * and so on..
33
33
  */
34
34
  export type NestedAccountID = AccountIDPlus0SubAccount | AccountIDPlus1SubAccount | AccountIDPlus2SubAccount | AccountIDPlus3SubAccount | AccountIDPlus4SubAccount;
35
- export declare const MAX_SUB_ACCOUNTS_SUPPORTED = 4;
36
- export declare const MAX_SUB_CLASSES_SUPPORTED = 4;
37
- export declare const MAX_SUB_CUSTOMERS_SUPPORTED = 4;
38
35
  export declare function getNestedAccountIDStr(nestedAccountId: NestedAccountID): `${string}-${string}-${string}-${string}-${string}`;
39
36
  export declare const isEqualNestedAccountId: (nestedAccountIdA: NestedAccountID, nestedAccountIdB: NestedAccountID) => boolean;
40
37
  export interface AccountsViewParentID {
@@ -1,10 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.isEqualNestedAccountId = exports.MAX_SUB_CUSTOMERS_SUPPORTED = exports.MAX_SUB_CLASSES_SUPPORTED = exports.MAX_SUB_ACCOUNTS_SUPPORTED = void 0;
3
+ exports.isEqualNestedAccountId = void 0;
4
4
  exports.getNestedAccountIDStr = getNestedAccountIDStr;
5
- exports.MAX_SUB_ACCOUNTS_SUPPORTED = 4;
6
- exports.MAX_SUB_CLASSES_SUPPORTED = 4;
7
- exports.MAX_SUB_CUSTOMERS_SUPPORTED = 4;
8
5
  function getNestedAccountIDStr(nestedAccountId) {
9
6
  const [accountId, parentAccountId, greatParentAccountId, greatGreatParentAccountId, greatGreatGreatParentAccountId,] = nestedAccountId;
10
7
  return `${accountId}-${parentAccountId ?? ''}-${greatParentAccountId ?? ''}-${greatGreatParentAccountId ?? ''}-${greatGreatGreatParentAccountId ?? ''}`;
@@ -45,11 +45,6 @@ export interface COABalanceGrouped extends COABalanceGroupedByPeriod {
45
45
  years?: COABalance;
46
46
  };
47
47
  }
48
- export interface COABalanceWithAveragesGrouped extends COABalanceGrouped {
49
- averages?: {
50
- months?: COABalance;
51
- };
52
- }
53
48
  export interface COABalanceGroupedWithIDs extends COABalanceGrouped {
54
49
  accountGroupIDs: string[];
55
50
  accountIDs: string[];
@@ -26,9 +26,7 @@ export interface MonthYearPeriod {
26
26
  year: number;
27
27
  }
28
28
  export type MonthYearPeriodId = `${Month}_${number}`;
29
- export type MonthYearPeriodQuery = `${Month}-${number}`;
30
29
  export declare const toMonthYearPeriod: (periodPayload: string) => MonthYearPeriod;
31
- export declare const toMonthYearPeriodQuery: (selectedPeriod: MonthYearPeriod) => MonthYearPeriodQuery;
32
30
  export declare const toMonthYearPeriodId: (selectedPeriod: MonthYearPeriod) => MonthYearPeriodId;
33
31
  /**
34
32
  * Convert to start: string; end: string in the format yyyy-mm-dd
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.toString = exports.toMonthYearPeriodId = exports.toMonthYearPeriodQuery = exports.toMonthYearPeriod = exports.toQuarterStrict = exports.toQuarter = exports.getMonthFromMonthName = exports.toMonthStrict = exports.toMonth = exports.LAST_SCHEDULE_DAY_OF_MONTH = exports.MAX_SCHEDULE_DAY_OF_MONTH = exports.MIN_SCHEDULE_DAY_OF_MONTH = exports.toScheduleDaysOfMonth = exports.SCHEDULE_DAYS_OF_MONTH = void 0;
3
+ exports.toString = exports.toMonthYearPeriodId = exports.toMonthYearPeriod = exports.toQuarterStrict = exports.toQuarter = exports.getMonthFromMonthName = exports.toMonthStrict = exports.toMonth = exports.LAST_SCHEDULE_DAY_OF_MONTH = exports.MAX_SCHEDULE_DAY_OF_MONTH = exports.MIN_SCHEDULE_DAY_OF_MONTH = exports.toScheduleDaysOfMonth = exports.SCHEDULE_DAYS_OF_MONTH = void 0;
4
4
  exports.convertToPeriod = convertToPeriod;
5
5
  exports.toAbsoluteDay = toAbsoluteDay;
6
6
  const zeniDayJS_1 = require("../zeniDayJS");
@@ -47,11 +47,6 @@ const toMonthYearPeriod = (periodPayload) => {
47
47
  };
48
48
  };
49
49
  exports.toMonthYearPeriod = toMonthYearPeriod;
50
- const toMonthYearPeriodQuery = (selectedPeriod) => {
51
- const { month, year } = selectedPeriod;
52
- return `${month}-${year}`;
53
- };
54
- exports.toMonthYearPeriodQuery = toMonthYearPeriodQuery;
55
50
  const toMonthYearPeriodId = (selectedPeriod) => {
56
51
  const { month, year } = selectedPeriod;
57
52
  return `${month}_${year}`;
@@ -2,6 +2,19 @@ import { AddressPayload } from '../../address/addressPayload';
2
2
  import { InvoicingListCounts } from '../invoicingCommonPayload';
3
3
  import { InvoicingSubscriptionPayload } from '../invoicingSubscription/invoicingSubscriptionPayload';
4
4
  import { InvoicingCustomer } from './invoicingCustomerState';
5
+ /**
6
+ * A single entry of the customer `payment_methods` array. Its field names
7
+ * differ from the customer-level scalars (`last4` vs `payment_method_last4`),
8
+ * so they are mapped independently.
9
+ */
10
+ export interface InvoicingCustomerPaymentMethodPayload {
11
+ payment_method_id: string;
12
+ exp_month?: number;
13
+ exp_year?: number;
14
+ is_default?: boolean;
15
+ last4?: string;
16
+ payment_method_type?: string;
17
+ }
5
18
  export interface InvoicingCustomerPayload {
6
19
  id: string;
7
20
  arr?: number;
@@ -28,8 +41,11 @@ export interface InvoicingCustomerPayload {
28
41
  net_term_days?: number;
29
42
  notes?: string;
30
43
  payment_method?: string;
44
+ payment_method_exp_month?: number;
45
+ payment_method_exp_year?: number;
31
46
  payment_method_last4?: string;
32
47
  payment_method_type?: 'ach' | 'card' | 'none';
48
+ payment_methods?: InvoicingCustomerPaymentMethodPayload[];
33
49
  phone?: string;
34
50
  plan?: string;
35
51
  plan_name?: string;
@@ -15,6 +15,19 @@ const extractInvoicingCustomerAddresses = (payloads) => payloads
15
15
  .map((payload) => payload.billing_address)
16
16
  .filter((address) => address != null);
17
17
  exports.extractInvoicingCustomerAddresses = extractInvoicingCustomerAddresses;
18
+ const toInvoicingPaymentMethodType = (rawType) => rawType === 'ach' ||
19
+ rawType === 'us_bank_account' ||
20
+ rawType === 'bank_account'
21
+ ? 'ach'
22
+ : 'card';
23
+ const mapInvoicingCustomerPaymentMethodPayloadToState = (payload) => ({
24
+ id: payload.payment_method_id,
25
+ isDefault: payload.is_default === true,
26
+ type: toInvoicingPaymentMethodType(payload.payment_method_type),
27
+ expMonth: payload.exp_month,
28
+ expYear: payload.exp_year,
29
+ last4: payload.last4,
30
+ });
18
31
  const mapInvoicingCustomerPayloadToState = (payload) => {
19
32
  const currencyCode = payload.preferred_currency_code ?? currencyHelper_1.defaultCustomerCurrency.currencyCode;
20
33
  const currencySymbol = payload.preferred_currency_symbol ?? currencyHelper_1.defaultCustomerCurrency.currencySymbol;
@@ -51,8 +64,15 @@ const mapInvoicingCustomerPayloadToState = (payload) => {
51
64
  netTermDays: payload.net_term_days,
52
65
  notes: payload.notes,
53
66
  paymentMethod: payload.payment_method,
67
+ paymentMethodExpMonth: payload.payment_method_exp_month,
68
+ paymentMethodExpYear: payload.payment_method_exp_year,
54
69
  paymentMethodLast4: payload.payment_method_last4,
55
70
  paymentMethodType: payload.payment_method_type,
71
+ paymentMethods: payload.payment_methods
72
+ ?.filter((method) => method != null &&
73
+ method.payment_method_id != null &&
74
+ method.payment_method_id !== '')
75
+ .map(mapInvoicingCustomerPaymentMethodPayloadToState),
56
76
  phone: payload.phone,
57
77
  plan: payload.plan,
58
78
  planName: payload.plan_name,
@@ -1,4 +1,11 @@
1
1
  import { ID } from '../../../commonStateTypes/common';
2
- import { InvoicingCustomer, InvoicingCustomerState } from './invoicingCustomerState';
2
+ import { InvoicingCustomer, InvoicingCustomerPaymentMethod, InvoicingCustomerState } from './invoicingCustomerState';
3
3
  export declare function getInvoicingCustomersByIds(invoicingCustomerState: InvoicingCustomerState, ids: ID[]): InvoicingCustomer[];
4
4
  export declare function getInvoicingCustomerById(invoicingCustomerState: InvoicingCustomerState, id: ID): InvoicingCustomer | undefined;
5
+ /**
6
+ * Every payment method to show for a customer, with exactly one flagged as the
7
+ * default. `paymentMethods` wins when the backend returns it; otherwise the
8
+ * scalar default-method fields are synthesized into a single method so older
9
+ * responses keep rendering one row.
10
+ */
11
+ export declare function invoicingCustomerPaymentMethods(customer: InvoicingCustomer | undefined): InvoicingCustomerPaymentMethod[];
@@ -5,6 +5,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.getInvoicingCustomersByIds = getInvoicingCustomersByIds;
7
7
  exports.getInvoicingCustomerById = getInvoicingCustomerById;
8
+ exports.invoicingCustomerPaymentMethods = invoicingCustomerPaymentMethods;
8
9
  const get_1 = __importDefault(require("lodash/get"));
9
10
  function getInvoicingCustomersByIds(invoicingCustomerState, ids) {
10
11
  const invoicingCustomers = ids
@@ -15,3 +16,50 @@ function getInvoicingCustomersByIds(invoicingCustomerState, ids) {
15
16
  function getInvoicingCustomerById(invoicingCustomerState, id) {
16
17
  return (0, get_1.default)(invoicingCustomerState.customerByID, id);
17
18
  }
19
+ function scalarPaymentMethod(customer) {
20
+ const { paymentMethodType } = customer;
21
+ if (paymentMethodType == null || paymentMethodType === 'none') {
22
+ return [];
23
+ }
24
+ return [
25
+ {
26
+ // Legacy responses carry no per-method id, so the customer id stands in
27
+ // as a stable display-only key. Nothing reads it as a payment method id.
28
+ id: customer.defaultPaymentMethodID ?? customer.id,
29
+ isDefault: true,
30
+ type: paymentMethodType,
31
+ brand: customer.paymentMethod,
32
+ expMonth: customer.paymentMethodExpMonth,
33
+ expYear: customer.paymentMethodExpYear,
34
+ last4: customer.paymentMethodLast4,
35
+ },
36
+ ];
37
+ }
38
+ function defaultPaymentMethodIndex(paymentMethods, defaultPaymentMethodID) {
39
+ const flaggedIndex = paymentMethods.findIndex((paymentMethod) => paymentMethod.isDefault);
40
+ if (flaggedIndex >= 0) {
41
+ return flaggedIndex;
42
+ }
43
+ const matchedIndex = paymentMethods.findIndex((paymentMethod) => paymentMethod.id === defaultPaymentMethodID);
44
+ return matchedIndex >= 0 ? matchedIndex : 0;
45
+ }
46
+ /**
47
+ * Every payment method to show for a customer, with exactly one flagged as the
48
+ * default. `paymentMethods` wins when the backend returns it; otherwise the
49
+ * scalar default-method fields are synthesized into a single method so older
50
+ * responses keep rendering one row.
51
+ */
52
+ function invoicingCustomerPaymentMethods(customer) {
53
+ if (customer == null) {
54
+ return [];
55
+ }
56
+ const paymentMethods = customer.paymentMethods ?? scalarPaymentMethod(customer);
57
+ if (paymentMethods.length === 0) {
58
+ return [];
59
+ }
60
+ const defaultIndex = defaultPaymentMethodIndex(paymentMethods, customer.defaultPaymentMethodID);
61
+ return paymentMethods.map((paymentMethod, index) => ({
62
+ ...paymentMethod,
63
+ isDefault: index === defaultIndex,
64
+ }));
65
+ }
@@ -2,6 +2,22 @@ import { Amount } from '../../../commonStateTypes/amount';
2
2
  import { ID } from '../../../commonStateTypes/common';
3
3
  import { ZeniDate } from '../../../zeniDayJS';
4
4
  import { InvoicingSubscription } from '../invoicingSubscription/invoicingSubscriptionState';
5
+ export type InvoicingPaymentMethodType = 'ach' | 'card';
6
+ /**
7
+ * One stored payment method for a customer. `isDefault` is only trustworthy
8
+ * after `invoicingCustomerPaymentMethods` has normalized a list — that is
9
+ * what guarantees a single default across the returned methods.
10
+ */
11
+ export interface InvoicingCustomerPaymentMethod {
12
+ id: ID;
13
+ isDefault: boolean;
14
+ type: InvoicingPaymentMethodType;
15
+ /** Card network label; only known for the legacy scalar default method. */
16
+ brand?: string;
17
+ expMonth?: number;
18
+ expYear?: number;
19
+ last4?: string;
20
+ }
5
21
  export interface InvoicingCustomer {
6
22
  id: ID;
7
23
  arr?: Amount;
@@ -27,7 +43,15 @@ export interface InvoicingCustomer {
27
43
  netTermDays?: number;
28
44
  notes?: string;
29
45
  paymentMethod?: string;
46
+ paymentMethodExpMonth?: number;
47
+ paymentMethodExpYear?: number;
30
48
  paymentMethodLast4?: string;
49
+ /**
50
+ * Every payment method on file. Absent (not empty) on responses from a
51
+ * backend that only returns the scalar default-method fields, which is how
52
+ * `invoicingCustomerPaymentMethods` decides whether to synthesize a row.
53
+ */
54
+ paymentMethods?: InvoicingCustomerPaymentMethod[];
31
55
  paymentMethodType?: 'ach' | 'card' | 'none';
32
56
  phone?: string;
33
57
  plan?: string;
@@ -68,6 +68,7 @@ export interface InvoicingSubscriptionPayload {
68
68
  shipping_address?: AddressPayload | null;
69
69
  started_at?: string;
70
70
  subscription_items?: InvoicingSubscriptionItemPayload[];
71
+ subscription_number?: string;
71
72
  total_dues?: number;
72
73
  trial_end?: string;
73
74
  trial_start?: string;
@@ -107,6 +107,7 @@ const mapInvoicingSubscriptionPayloadToState = (payload) => {
107
107
  : undefined,
108
108
  startedAt: payload.started_at != null ? (0, zeniDayJS_1.date)(payload.started_at) : undefined,
109
109
  subscriptionItems: payload.subscription_items?.map((item) => (0, exports.mapInvoicingSubscriptionItemPayloadToState)(item, currencyCode, currencySymbol)),
110
+ subscriptionNumber: payload.subscription_number,
110
111
  totalDues: payload.total_dues != null
111
112
  ? (0, amount_1.toAmount)(payload.total_dues, currencyCode, currencySymbol)
112
113
  : undefined,
@@ -67,6 +67,7 @@ export interface InvoicingSubscription {
67
67
  shippingAddressId?: ID;
68
68
  startedAt?: ZeniDate;
69
69
  subscriptionItems?: InvoicingSubscriptionItem[];
70
+ subscriptionNumber?: string;
70
71
  totalDues?: Amount;
71
72
  trialEnd?: ZeniDate;
72
73
  trialStart?: ZeniDate;
@@ -16,4 +16,3 @@ export declare const pushToastNotificationEpic: (actions$: ActionsObservable<Act
16
16
  };
17
17
  type: "snackbar/openSnackbar";
18
18
  }>;
19
- export default pushToastNotificationEpic;
@@ -39,4 +39,3 @@ const pushToastNotificationEpic = (actions$, state$) => actions$.pipe((0, operat
39
39
  return (0, rxjs_1.from)([]);
40
40
  }));
41
41
  exports.pushToastNotificationEpic = pushToastNotificationEpic;
42
- exports.default = exports.pushToastNotificationEpic;
@@ -1,3 +1,3 @@
1
1
  import { SupportedTransaction, SupportedTransactionPayload } from './transactionState';
2
- export declare function toSupportedTransaction(payload: SupportedTransactionPayload): SupportedTransaction;
2
+ declare function toSupportedTransaction(payload: SupportedTransactionPayload): SupportedTransaction;
3
3
  export default toSupportedTransaction;
@@ -1,6 +1,5 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.toSupportedTransaction = toSupportedTransaction;
4
3
  const customerTransactionPayload_1 = require("./payloadTypes/customerTransactionPayload");
5
4
  const otherTransactionPayload_1 = require("./payloadTypes/otherTransactionPayload");
6
5
  const transactionPayload_1 = require("./payloadTypes/transactionPayload");
@@ -1,6 +1,3 @@
1
- export const MAX_SUB_ACCOUNTS_SUPPORTED = 4;
2
- export const MAX_SUB_CLASSES_SUPPORTED = 4;
3
- export const MAX_SUB_CUSTOMERS_SUPPORTED = 4;
4
1
  export function getNestedAccountIDStr(nestedAccountId) {
5
2
  const [accountId, parentAccountId, greatParentAccountId, greatGreatParentAccountId, greatGreatGreatParentAccountId,] = nestedAccountId;
6
3
  return `${accountId}-${parentAccountId ?? ''}-${greatParentAccountId ?? ''}-${greatGreatParentAccountId ?? ''}-${greatGreatGreatParentAccountId ?? ''}`;
@@ -35,10 +35,6 @@ export const toMonthYearPeriod = (periodPayload) => {
35
35
  year: Number(periodPayload.split('-')[1]),
36
36
  };
37
37
  };
38
- export const toMonthYearPeriodQuery = (selectedPeriod) => {
39
- const { month, year } = selectedPeriod;
40
- return `${month}-${year}`;
41
- };
42
38
  export const toMonthYearPeriodId = (selectedPeriod) => {
43
39
  const { month, year } = selectedPeriod;
44
40
  return `${month}_${year}`;
@@ -11,6 +11,19 @@ import { mapInvoicingSubscriptionPayloadToState, } from '../invoicingSubscriptio
11
11
  export const extractInvoicingCustomerAddresses = (payloads) => payloads
12
12
  .map((payload) => payload.billing_address)
13
13
  .filter((address) => address != null);
14
+ const toInvoicingPaymentMethodType = (rawType) => rawType === 'ach' ||
15
+ rawType === 'us_bank_account' ||
16
+ rawType === 'bank_account'
17
+ ? 'ach'
18
+ : 'card';
19
+ const mapInvoicingCustomerPaymentMethodPayloadToState = (payload) => ({
20
+ id: payload.payment_method_id,
21
+ isDefault: payload.is_default === true,
22
+ type: toInvoicingPaymentMethodType(payload.payment_method_type),
23
+ expMonth: payload.exp_month,
24
+ expYear: payload.exp_year,
25
+ last4: payload.last4,
26
+ });
14
27
  export const mapInvoicingCustomerPayloadToState = (payload) => {
15
28
  const currencyCode = payload.preferred_currency_code ?? defaultCustomerCurrency.currencyCode;
16
29
  const currencySymbol = payload.preferred_currency_symbol ?? defaultCustomerCurrency.currencySymbol;
@@ -47,8 +60,15 @@ export const mapInvoicingCustomerPayloadToState = (payload) => {
47
60
  netTermDays: payload.net_term_days,
48
61
  notes: payload.notes,
49
62
  paymentMethod: payload.payment_method,
63
+ paymentMethodExpMonth: payload.payment_method_exp_month,
64
+ paymentMethodExpYear: payload.payment_method_exp_year,
50
65
  paymentMethodLast4: payload.payment_method_last4,
51
66
  paymentMethodType: payload.payment_method_type,
67
+ paymentMethods: payload.payment_methods
68
+ ?.filter((method) => method != null &&
69
+ method.payment_method_id != null &&
70
+ method.payment_method_id !== '')
71
+ .map(mapInvoicingCustomerPaymentMethodPayloadToState),
52
72
  phone: payload.phone,
53
73
  plan: payload.plan,
54
74
  planName: payload.plan_name,
@@ -8,3 +8,50 @@ export function getInvoicingCustomersByIds(invoicingCustomerState, ids) {
8
8
  export function getInvoicingCustomerById(invoicingCustomerState, id) {
9
9
  return recordGet(invoicingCustomerState.customerByID, id);
10
10
  }
11
+ function scalarPaymentMethod(customer) {
12
+ const { paymentMethodType } = customer;
13
+ if (paymentMethodType == null || paymentMethodType === 'none') {
14
+ return [];
15
+ }
16
+ return [
17
+ {
18
+ // Legacy responses carry no per-method id, so the customer id stands in
19
+ // as a stable display-only key. Nothing reads it as a payment method id.
20
+ id: customer.defaultPaymentMethodID ?? customer.id,
21
+ isDefault: true,
22
+ type: paymentMethodType,
23
+ brand: customer.paymentMethod,
24
+ expMonth: customer.paymentMethodExpMonth,
25
+ expYear: customer.paymentMethodExpYear,
26
+ last4: customer.paymentMethodLast4,
27
+ },
28
+ ];
29
+ }
30
+ function defaultPaymentMethodIndex(paymentMethods, defaultPaymentMethodID) {
31
+ const flaggedIndex = paymentMethods.findIndex((paymentMethod) => paymentMethod.isDefault);
32
+ if (flaggedIndex >= 0) {
33
+ return flaggedIndex;
34
+ }
35
+ const matchedIndex = paymentMethods.findIndex((paymentMethod) => paymentMethod.id === defaultPaymentMethodID);
36
+ return matchedIndex >= 0 ? matchedIndex : 0;
37
+ }
38
+ /**
39
+ * Every payment method to show for a customer, with exactly one flagged as the
40
+ * default. `paymentMethods` wins when the backend returns it; otherwise the
41
+ * scalar default-method fields are synthesized into a single method so older
42
+ * responses keep rendering one row.
43
+ */
44
+ export function invoicingCustomerPaymentMethods(customer) {
45
+ if (customer == null) {
46
+ return [];
47
+ }
48
+ const paymentMethods = customer.paymentMethods ?? scalarPaymentMethod(customer);
49
+ if (paymentMethods.length === 0) {
50
+ return [];
51
+ }
52
+ const defaultIndex = defaultPaymentMethodIndex(paymentMethods, customer.defaultPaymentMethodID);
53
+ return paymentMethods.map((paymentMethod, index) => ({
54
+ ...paymentMethod,
55
+ isDefault: index === defaultIndex,
56
+ }));
57
+ }
@@ -100,6 +100,7 @@ export const mapInvoicingSubscriptionPayloadToState = (payload) => {
100
100
  : undefined,
101
101
  startedAt: payload.started_at != null ? date(payload.started_at) : undefined,
102
102
  subscriptionItems: payload.subscription_items?.map((item) => mapInvoicingSubscriptionItemPayloadToState(item, currencyCode, currencySymbol)),
103
+ subscriptionNumber: payload.subscription_number,
103
104
  totalDues: payload.total_dues != null
104
105
  ? toAmount(payload.total_dues, currencyCode, currencySymbol)
105
106
  : undefined,
@@ -35,4 +35,3 @@ export const pushToastNotificationEpic = (actions$, state$) => actions$.pipe(fil
35
35
  }
36
36
  return from([]);
37
37
  }));
38
- export default pushToastNotificationEpic;
@@ -2,7 +2,7 @@ import { isCustomerTransactionPayload, toCustomerTransaction, } from './payloadT
2
2
  import { isTransferTransactionPayload, toTransferTransaction, } from './payloadTypes/otherTransactionPayload';
3
3
  import { toTransaction } from './payloadTypes/transactionPayload';
4
4
  import { isVendorTransactionPayload, isVendorTransactionWithCustomerPayload, toVendorTransaction, toVendorTransactionWithCustomer, } from './payloadTypes/vendorTransactionPayload';
5
- export function toSupportedTransaction(payload) {
5
+ function toSupportedTransaction(payload) {
6
6
  if (isCustomerTransactionPayload(payload)) {
7
7
  return toCustomerTransaction(payload);
8
8
  }
package/lib/esm/index.js CHANGED
@@ -729,7 +729,7 @@ export { mapAuditLogEntry } from './view/invoicing/auditView/auditViewPayload';
729
729
  export { clearAllInvoices, removeInvoice, updateInvoices, } from './entity/invoicing/invoice/invoiceReducer';
730
730
  export { getInvoiceById, getInvoicesByIds, } from './entity/invoicing/invoice/invoiceSelector';
731
731
  export { clearInvoiceList, fetchInvoiceCounts, fetchInvoiceKPIs, fetchInvoiceList, fetchInvoiceListPage, setInvoiceActiveTab, updateInvoiceListFilters, } from './view/invoicing/invoiceList/invoiceListReducer';
732
- export { ALL_INVOICING_INVOICE_TAB_IDS, } from './view/invoicing/invoiceList/invoiceListState';
732
+ export { ALL_INVOICING_INVOICE_TAB_IDS } from './view/invoicing/invoiceList/invoiceListState';
733
733
  export { getInvoiceListView } from './view/invoicing/invoiceList/invoiceListSelector';
734
734
  export { clearAllInvoiceDetail, fetchInvoiceDetail, } from './view/invoicing/invoiceDetail/invoiceDetailReducer';
735
735
  export { getInvoiceDetail } from './view/invoicing/invoiceDetail/invoiceDetailSelector';
@@ -738,14 +738,14 @@ export { blankInvoicingCreateInvoiceLineItem, createInvoiceFormLocalDataToReques
738
738
  export { resetRecordPayment, initializeRecordPaymentDraft, submitRecordPayment, updateRecordPaymentFormDraft, } from './view/invoicing/recordPayment/recordPaymentReducer';
739
739
  export { initializeIssueCreditNoteDraft, issueCreditNoteFailure, issueCreditNoteSuccess, resetIssueCreditNote, submitIssueCreditNote, updateIssueCreditNoteFormDraft, } from './view/invoicing/issueCreditNote/issueCreditNoteReducer';
740
740
  export { computeIssueCreditNoteTotal, initializeIssueCreditNoteDraftFromInvoice, localDataToIssueCreditNotePayload, } from './view/invoicing/issueCreditNote/issueCreditNotePayload';
741
- export { initialIssueCreditNoteFormLocalData, } from './view/invoicing/issueCreditNote/issueCreditNoteFormConfig';
741
+ export { initialIssueCreditNoteFormLocalData } from './view/invoicing/issueCreditNote/issueCreditNoteFormConfig';
742
742
  export { getIssueCreditNoteView } from './view/invoicing/issueCreditNote/issueCreditNoteSelector';
743
743
  export { createCreditNoteFailure, createCreditNoteSuccess, resetCreateCreditNote, submitCreateCreditNote, updateCreateCreditNoteFormDraft, } from './view/invoicing/createCreditNote/createCreditNoteReducer';
744
744
  export { localDataToCreateCreditNotePayload } from './view/invoicing/createCreditNote/createCreditNotePayload';
745
745
  export { initialCreateCreditNoteFormLocalData } from './view/invoicing/createCreditNote/createCreditNoteFormConfig';
746
746
  export { getCreateCreditNoteFormView, getCreateCreditNoteView, } from './view/invoicing/createCreditNote/createCreditNoteSelector';
747
747
  export { initializeRecordPaymentDraftFromInvoice, localDataToInvoiceRecordPaymentBody, localDataToRecordPaymentPayload, } from './view/invoicing/recordPayment/recordPaymentPayload';
748
- export { initialRecordPaymentFormLocalData, } from './view/invoicing/recordPayment/recordPaymentFormConfig';
748
+ export { initialRecordPaymentFormLocalData } from './view/invoicing/recordPayment/recordPaymentFormConfig';
749
749
  export { clearInvoicingOverview, fetchInvoicingOverview, } from './view/invoicing/invoicingOverview/invoicingOverviewReducer';
750
750
  export { buildPeriodOptions, getInvoicingOverview, } from './view/invoicing/invoicingOverview/invoicingOverviewSelector';
751
751
  export { clearInvoicingAuditView, fetchInvoicingAuditLog, } from './view/invoicing/auditView/auditViewReducer';
@@ -45,6 +45,7 @@ export const getCreateInvoiceFormView = (state) => {
45
45
  .filter((subFamily) => (subFamily.name ?? '') !== '')
46
46
  .map((subFamily) => ({
47
47
  planName: plan.name ?? '',
48
+ price: subFamily.price?.amount,
48
49
  subFamilyName: subFamily.name ?? '',
49
50
  }))),
50
51
  products: getInvoicingCatalogPrices(catalogListView.products),
@@ -1,6 +1,6 @@
1
1
  import recordGet from 'lodash/get';
2
2
  import { getInvoicesByIds } from '../../../entity/invoicing/invoice/invoiceSelector';
3
- import { getInvoicingCustomerById } from '../../../entity/invoicing/invoicingCustomer/invoicingCustomerSelector';
3
+ import { getInvoicingCustomerById, invoicingCustomerPaymentMethods, } from '../../../entity/invoicing/invoicingCustomer/invoicingCustomerSelector';
4
4
  import { getInvoicingPaymentLinkSendState, getInvoicingPaymentMethodSaveState, getInvoicingPlaidLinkToken, getInvoicingSentPaymentLinkEmail, getInvoicingSentPaymentLinkMagicUrl, getInvoicingSetupIntent, getInvoicingSetupIntentFetchState, } from '../customerPaymentMethod/customerPaymentMethodSelector';
5
5
  import { isStripeConnectedFromSettings } from '../settingsView/invoicingSettingsHelpers';
6
6
  import { getInvoicingSettings } from '../settingsView/settingsViewSelector';
@@ -8,9 +8,11 @@ export const getInvoicingCustomerDetail = (state, invoicingCustomerID) => {
8
8
  const { invoicingCustomerState, invoicingCustomerDetailViewState } = state;
9
9
  const invoicingCustomerDetail = recordGet(invoicingCustomerDetailViewState.detailById, invoicingCustomerID, undefined);
10
10
  const settings = getInvoicingSettings(state);
11
+ const invoicingCustomer = getInvoicingCustomerById(invoicingCustomerState, invoicingCustomerID);
11
12
  return {
12
- invoicingCustomer: getInvoicingCustomerById(invoicingCustomerState, invoicingCustomerID),
13
+ invoicingCustomer,
13
14
  invoices: getInvoicesByIds(state.invoicingInvoiceState, state.invoicingInvoiceListState.invoiceByTab[state.invoicingInvoiceListState.activeTab]?.invoiceIds ?? []),
15
+ paymentMethods: invoicingCustomerPaymentMethods(invoicingCustomer),
14
16
  setupIntent: getInvoicingSetupIntent(state),
15
17
  setupIntentFetchState: getInvoicingSetupIntentFetchState(state),
16
18
  plaidLinkToken: getInvoicingPlaidLinkToken(state),
@@ -22,7 +22,8 @@ export const initialState = {
22
22
  reportId: 'profit_and_loss_by_projects',
23
23
  reportTitle: 'profit_and_loss_by_projects',
24
24
  uiState: {
25
- accountViewMode: 'project',
25
+ // Starts on the accounts view like every other report slice.
26
+ accountViewMode: 'account_group',
26
27
  nodeCollapseState: {},
27
28
  projectsToFilterOut: [],
28
29
  scrollPosition: undefined,
package/lib/index.d.ts CHANGED
@@ -1019,8 +1019,8 @@ export type { InvoicingCouponApplyOn, InvoicingCouponCode, InvoicingCouponDurati
1019
1019
  export type { InvoicingCoupon } from './entity/invoicing/coupon/couponState';
1020
1020
  export type { InvoicingCreditNote, InvoicingCreditNoteAllocation, InvoicingCreditNoteLineItem, } from './entity/invoicing/creditNote/creditNoteState';
1021
1021
  export type { InvoicingCreditNoteStatus, InvoicingCreditNoteType, } from './entity/invoicing/creditNote/creditNotePayload';
1022
- export type { InvoicingCustomer } from './entity/invoicing/invoicingCustomer/invoicingCustomerState';
1023
- export type { InvoicingCustomerCounts, InvoicingCustomerPayload, } from './entity/invoicing/invoicingCustomer/invoicingCustomerPayload';
1022
+ export type { InvoicingCustomer, InvoicingCustomerPaymentMethod, InvoicingPaymentMethodType, } from './entity/invoicing/invoicingCustomer/invoicingCustomerState';
1023
+ export type { InvoicingCustomerCounts, InvoicingCustomerPayload, InvoicingCustomerPaymentMethodPayload, } from './entity/invoicing/invoicingCustomer/invoicingCustomerPayload';
1024
1024
  export type { InvoicingDunningCase } from './entity/invoicing/dunningCase/dunningCaseState';
1025
1025
  export type { InvoicingDunningStatus } from './entity/invoicing/dunningCase/dunningCasePayload';
1026
1026
  export type { InvoicingInvoicePayload, InvoicingInvoiceDiscountPayload, InvoicingInvoiceStatus, } from './entity/invoicing/invoice/invoicePayload';
@@ -1041,7 +1041,7 @@ export type { StripeConnectCredentials } from './view/invoicing/settingsView/set
1041
1041
  export { clearAllInvoices, removeInvoice, updateInvoices, } from './entity/invoicing/invoice/invoiceReducer';
1042
1042
  export { getInvoiceById, getInvoicesByIds, } from './entity/invoicing/invoice/invoiceSelector';
1043
1043
  export { clearInvoiceList, fetchInvoiceCounts, fetchInvoiceKPIs, fetchInvoiceList, fetchInvoiceListPage, setInvoiceActiveTab, updateInvoiceListFilters, } from './view/invoicing/invoiceList/invoiceListReducer';
1044
- export { ALL_INVOICING_INVOICE_TAB_IDS, } from './view/invoicing/invoiceList/invoiceListState';
1044
+ export { ALL_INVOICING_INVOICE_TAB_IDS } from './view/invoicing/invoiceList/invoiceListState';
1045
1045
  export type { InvoiceListFilters, InvoiceListState, InvoicingInvoiceTabId, } from './view/invoicing/invoiceList/invoiceListState';
1046
1046
  export { getInvoiceListView } from './view/invoicing/invoiceList/invoiceListSelector';
1047
1047
  export type { InvoiceListView } from './view/invoicing/invoiceList/invoiceListSelector';
@@ -1057,7 +1057,7 @@ export { initializeIssueCreditNoteDraft, issueCreditNoteFailure, issueCreditNote
1057
1057
  export type { IssueCreditNoteRequest, IssueCreditNoteResponse, CreateCreditNoteRequest, CreateCreditNoteResponse, } from './view/invoicing/issueCreditNote/issueCreditNotePayload';
1058
1058
  export { computeIssueCreditNoteTotal, initializeIssueCreditNoteDraftFromInvoice, localDataToIssueCreditNotePayload, } from './view/invoicing/issueCreditNote/issueCreditNotePayload';
1059
1059
  export type { IssueCreditNoteFormLocalData, IssueCreditNoteLineItemDraft, } from './view/invoicing/issueCreditNote/issueCreditNoteState';
1060
- export { initialIssueCreditNoteFormLocalData, } from './view/invoicing/issueCreditNote/issueCreditNoteFormConfig';
1060
+ export { initialIssueCreditNoteFormLocalData } from './view/invoicing/issueCreditNote/issueCreditNoteFormConfig';
1061
1061
  export { getIssueCreditNoteView } from './view/invoicing/issueCreditNote/issueCreditNoteSelector';
1062
1062
  export type { IssueCreditNoteView } from './view/invoicing/issueCreditNote/issueCreditNoteSelector';
1063
1063
  export { createCreditNoteFailure, createCreditNoteSuccess, resetCreateCreditNote, submitCreateCreditNote, updateCreateCreditNoteFormDraft, } from './view/invoicing/createCreditNote/createCreditNoteReducer';
@@ -1069,7 +1069,7 @@ export type { CreateCreditNoteFormView, InvoicingCreateCreditNoteView, } from '.
1069
1069
  export type { InvoiceRecordPaymentRequest, RecordPaymentLinkedInvoice, RecordPaymentRequest, } from './view/invoicing/recordPayment/recordPaymentPayload';
1070
1070
  export { initializeRecordPaymentDraftFromInvoice, localDataToInvoiceRecordPaymentBody, localDataToRecordPaymentPayload, } from './view/invoicing/recordPayment/recordPaymentPayload';
1071
1071
  export type { RecordPaymentFormLocalData } from './view/invoicing/recordPayment/recordPaymentState';
1072
- export { initialRecordPaymentFormLocalData, } from './view/invoicing/recordPayment/recordPaymentFormConfig';
1072
+ export { initialRecordPaymentFormLocalData } from './view/invoicing/recordPayment/recordPaymentFormConfig';
1073
1073
  export { clearInvoicingOverview, fetchInvoicingOverview, } from './view/invoicing/invoicingOverview/invoicingOverviewReducer';
1074
1074
  export type { InvoicingOverviewData, InvoicingOverviewPeriod, } from './view/invoicing/invoicingOverview/invoicingOverviewState';
1075
1075
  export { buildPeriodOptions, getInvoicingOverview, } from './view/invoicing/invoicingOverview/invoicingOverviewSelector';
@@ -8,11 +8,14 @@ import { InvoicingCreateInvoiceFormLocalData } from './createInvoiceState';
8
8
  /**
9
9
  * One catalog plan price, split into its two naming parts so consumers can
10
10
  * compose the label themselves (the plan family name and the sub-family/price
11
- * name are separate columns in the catalog).
11
+ * name are separate columns in the catalog). `price` is the sub-family's
12
+ * catalog price in whole USD (never minor units), absent when the catalog
13
+ * carries no price for it.
12
14
  */
13
15
  export interface InvoicingPlanNameOption {
14
16
  planName: string;
15
17
  subFamilyName: string;
18
+ price?: number;
16
19
  }
17
20
  /** One customer row of the create-invoice customer picker. */
18
21
  export interface InvoicingCreateInvoiceCustomerOption {
@@ -48,6 +48,7 @@ const getCreateInvoiceFormView = (state) => {
48
48
  .filter((subFamily) => (subFamily.name ?? '') !== '')
49
49
  .map((subFamily) => ({
50
50
  planName: plan.name ?? '',
51
+ price: subFamily.price?.amount,
51
52
  subFamilyName: subFamily.name ?? '',
52
53
  }))),
53
54
  products: (0, invoicingCatalogListViewSelector_1.getInvoicingCatalogPrices)(catalogListView.products),
@@ -1,7 +1,7 @@
1
1
  import { FetchStateAndError, ID } from '../../../commonStateTypes/common';
2
2
  import { SelectorView } from '../../../commonStateTypes/viewAndReport/viewAndReport';
3
3
  import { InvoicingInvoice } from '../../../entity/invoicing/invoice/invoiceState';
4
- import { InvoicingCustomer } from '../../../entity/invoicing/invoicingCustomer/invoicingCustomerState';
4
+ import { InvoicingCustomer, InvoicingCustomerPaymentMethod } from '../../../entity/invoicing/invoicingCustomer/invoicingCustomerState';
5
5
  import { RootState } from '../../../reducer';
6
6
  import { InvoicingSetupIntent } from '../customerPaymentMethod/customerPaymentMethodState';
7
7
  /**
@@ -14,6 +14,7 @@ import { InvoicingSetupIntent } from '../customerPaymentMethod/customerPaymentMe
14
14
  */
15
15
  export interface InvoicingCustomerDetailView extends SelectorView {
16
16
  invoices: InvoicingInvoice[];
17
+ paymentMethods: InvoicingCustomerPaymentMethod[];
17
18
  paymentMethodSaveState: FetchStateAndError;
18
19
  sendLinkState: FetchStateAndError;
19
20
  setupIntentFetchState: FetchStateAndError;
@@ -14,9 +14,11 @@ const getInvoicingCustomerDetail = (state, invoicingCustomerID) => {
14
14
  const { invoicingCustomerState, invoicingCustomerDetailViewState } = state;
15
15
  const invoicingCustomerDetail = (0, get_1.default)(invoicingCustomerDetailViewState.detailById, invoicingCustomerID, undefined);
16
16
  const settings = (0, settingsViewSelector_1.getInvoicingSettings)(state);
17
+ const invoicingCustomer = (0, invoicingCustomerSelector_1.getInvoicingCustomerById)(invoicingCustomerState, invoicingCustomerID);
17
18
  return {
18
- invoicingCustomer: (0, invoicingCustomerSelector_1.getInvoicingCustomerById)(invoicingCustomerState, invoicingCustomerID),
19
+ invoicingCustomer,
19
20
  invoices: (0, invoiceSelector_1.getInvoicesByIds)(state.invoicingInvoiceState, state.invoicingInvoiceListState.invoiceByTab[state.invoicingInvoiceListState.activeTab]?.invoiceIds ?? []),
21
+ paymentMethods: (0, invoicingCustomerSelector_1.invoicingCustomerPaymentMethods)(invoicingCustomer),
20
22
  setupIntent: (0, customerPaymentMethodSelector_1.getInvoicingSetupIntent)(state),
21
23
  setupIntentFetchState: (0, customerPaymentMethodSelector_1.getInvoicingSetupIntentFetchState)(state),
22
24
  plaidLinkToken: (0, customerPaymentMethodSelector_1.getInvoicingPlaidLinkToken)(state),
@@ -26,7 +26,8 @@ exports.initialState = {
26
26
  reportId: 'profit_and_loss_by_projects',
27
27
  reportTitle: 'profit_and_loss_by_projects',
28
28
  uiState: {
29
- accountViewMode: 'project',
29
+ // Starts on the accounts view like every other report slice.
30
+ accountViewMode: 'account_group',
30
31
  nodeCollapseState: {},
31
32
  projectsToFilterOut: [],
32
33
  scrollPosition: undefined,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zeniai/client-epic-state",
3
- "version": "5.1.99",
3
+ "version": "5.2.0-beta0AK",
4
4
  "description": "Shared module between Web & Mobile containing required abstractions for state management, async network communication. ",
5
5
  "main": "lib/index.js",
6
6
  "module": "lib/esm/index.js",
@@ -54,7 +54,6 @@
54
54
  },
55
55
  "homepage": "https://github.com/zeni-ai/client-epic-state#readme",
56
56
  "devDependencies": {
57
- "@eslint/eslintrc": "^3.3.1",
58
57
  "@eslint/js": "^9.24.0",
59
58
  "@liveblocks/client": "^2.23.0",
60
59
  "@trivago/prettier-plugin-sort-imports": "^5.2.2",
@@ -64,21 +63,17 @@
64
63
  "@types/url-parse": "^1.4.11",
65
64
  "@typescript-eslint/eslint-plugin": "^8.56.0",
66
65
  "@typescript-eslint/parser": "^8.56.0",
67
- "c8": "^10.1.3",
68
66
  "concurrently": "^9.1.2",
69
67
  "eslint": "^9.24.0",
70
68
  "eslint-config-prettier": "^10.0.2",
71
69
  "eslint-plugin-perfectionist": "^4.15.0",
72
- "eslint-plugin-prettier": "^5.2.3",
73
70
  "eslint-plugin-unused-imports": "^4.1.4",
74
71
  "globals": "^16.0.0",
72
+ "knip": "^6.21.0",
75
73
  "madge": "^8.0.0",
76
74
  "prettier": "^3.5.3",
77
- "prettier-plugin-import-sort": "^0.0.7",
78
75
  "rimraf": "^6.0.1",
79
76
  "semver": "^7.7.1",
80
- "ts-prune": "^0.10.3",
81
- "ts-unused-exports": "^11.0.1",
82
77
  "typescript": "^5.7.3",
83
78
  "vite": "^7.3.5",
84
79
  "vitest": "^4.1.8"
@@ -118,8 +113,6 @@
118
113
  "lint:fix-modified-files": "chmod +x ./scripts/lint-modified-files.sh && LINT_FIX=true ./scripts/lint-modified-files.sh",
119
114
  "tsc-modified-files": "chmod +x ./scripts/tsc-modified-files.sh && ./scripts/tsc-modified-files.sh",
120
115
  "typecheck": "tsc --noEmit",
121
- "find-dead-code": "bash ./scripts/run-find-dead-code.sh",
122
- "find-unused-exports": "ts-unused-exports ./tsconfig.json",
123
116
  "circular-dependency": "madge --circular --extensions ts ./src",
124
117
  "build": "chmod +x ./scripts/run_build.sh && ./scripts/run_build.sh && rimraf \"lib/**/__mocks__\" \"lib/**/__testHelpers__\"",
125
118
  "only-build": "eslint . --ext .js,.jsx,.ts,.tsx && time tsc && tsc -p tsconfig.esm.json && rimraf \"lib/**/__mocks__\" \"lib/**/__testHelpers__\"",
@@ -140,6 +133,7 @@
140
133
  "build-beta-and-copy": "chmod +x ./scripts/build_and_copy.sh && ./scripts/build_and_copy.sh",
141
134
  "pr-approvals-update": "chmod +x ./scripts/pr_approvals.sh && ./scripts/pr_approvals.sh",
142
135
  "raise-pr-automation": "chmod +x ./scripts/raise_pr_automation.sh && ./scripts/raise_pr_automation.sh",
143
- "test:file": "scripts/test-file.sh"
136
+ "test:file": "bash ./scripts/test-file.sh",
137
+ "find-unused-code": "knip"
144
138
  }
145
139
  }