@mulmoclaude/accounting-plugin 1.2.0 → 1.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/vue.cjs CHANGED
@@ -1,5 +1,5 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_shared = require("./shared-C9K9ZkfK.cjs");
2
+ const require_shared = require("./shared-KHOWwwiZ.cjs");
3
3
  let vue = require("vue");
4
4
  let _mulmoclaude_core_plugin_vue_i18n = require("@mulmoclaude/core/plugin-vue/i18n");
5
5
  //#region src/vue/hostContext.ts
@@ -1845,7 +1845,7 @@ var NewBookForm_default = /* @__PURE__ */ (0, vue.defineComponent)({
1845
1845
  function regionFromLocaleTag(tag) {
1846
1846
  try {
1847
1847
  const { region } = new Intl.Locale(tag).maximize();
1848
- if (region && require_shared.SUPPORTED_COUNTRY_CODES.includes(region)) return region;
1848
+ if (require_shared.isSupportedCountryCode(region)) return region;
1849
1849
  } catch {}
1850
1850
  return "";
1851
1851
  }
@@ -2016,7 +2016,8 @@ var BookSwitcher_default = /* @__PURE__ */ (0, vue.defineComponent)({
2016
2016
  return `${book.name} (${suffix})`;
2017
2017
  }
2018
2018
  function onSelect(event) {
2019
- const target = event.target;
2019
+ const { target } = event;
2020
+ if (!(target instanceof HTMLSelectElement)) return;
2020
2021
  const bookId = target.value;
2021
2022
  if (bookId === NEW_BOOK_SENTINEL) {
2022
2023
  target.value = props.modelValue;
@@ -2140,7 +2141,10 @@ var DateRangePicker_default = /* @__PURE__ */ (0, vue.defineComponent)({
2140
2141
  if (rangesEqual(value, UNBOUNDED_RANGE)) return "all";
2141
2142
  return "";
2142
2143
  });
2143
- function onShortcutChange(raw) {
2144
+ function onShortcutChange(event) {
2145
+ const { target } = event;
2146
+ if (!(target instanceof HTMLSelectElement)) return;
2147
+ const raw = target.value;
2144
2148
  const today = /* @__PURE__ */ new Date();
2145
2149
  if (raw === "currentQuarter") emit("update:modelValue", require_shared.currentQuarterRange(props.fiscalYearEnd, today));
2146
2150
  else if (raw === "previousQuarter") emit("update:modelValue", require_shared.previousQuarterRange(props.fiscalYearEnd, today));
@@ -2151,16 +2155,20 @@ var DateRangePicker_default = /* @__PURE__ */ (0, vue.defineComponent)({
2151
2155
  if (lifetime) emit("update:modelValue", lifetime);
2152
2156
  } else if (raw === "all") emit("update:modelValue", UNBOUNDED_RANGE);
2153
2157
  }
2154
- function onFromChange(value) {
2158
+ function onFromChange(event) {
2159
+ const { target } = event;
2160
+ if (!(target instanceof HTMLInputElement)) return;
2155
2161
  emit("update:modelValue", {
2156
- from: value,
2162
+ from: target.value,
2157
2163
  to: props.modelValue.to
2158
2164
  });
2159
2165
  }
2160
- function onToChange(value) {
2166
+ function onToChange(event) {
2167
+ const { target } = event;
2168
+ if (!(target instanceof HTMLInputElement)) return;
2161
2169
  emit("update:modelValue", {
2162
2170
  from: props.modelValue.from,
2163
- to: value
2171
+ to: target.value
2164
2172
  });
2165
2173
  }
2166
2174
  return (_ctx, _cache) => {
@@ -2169,9 +2177,9 @@ var DateRangePicker_default = /* @__PURE__ */ (0, vue.defineComponent)({
2169
2177
  value: selectedShortcut.value,
2170
2178
  class: "h-8 px-2 rounded border border-gray-300 text-sm bg-white",
2171
2179
  "data-testid": "accounting-daterange-shortcut",
2172
- onChange: _cache[0] || (_cache[0] = ($event) => onShortcutChange($event.target.value))
2180
+ onChange: onShortcutChange
2173
2181
  }, [
2174
- _cache[3] || (_cache[3] = (0, vue.createElementVNode)("option", {
2182
+ _cache[0] || (_cache[0] = (0, vue.createElementVNode)("option", {
2175
2183
  value: "",
2176
2184
  hidden: ""
2177
2185
  }, null, -1)),
@@ -2187,14 +2195,14 @@ var DateRangePicker_default = /* @__PURE__ */ (0, vue.defineComponent)({
2187
2195
  type: "date",
2188
2196
  class: "h-8 px-2 rounded border border-gray-300 text-sm",
2189
2197
  "data-testid": "accounting-daterange-from",
2190
- onInput: _cache[1] || (_cache[1] = ($event) => onFromChange($event.target.value))
2198
+ onInput: onFromChange
2191
2199
  }, null, 40, _hoisted_11$9)]),
2192
2200
  (0, vue.createElementVNode)("label", _hoisted_12$9, [(0, vue.createTextVNode)((0, vue.toDisplayString)((0, vue.unref)(t)("pluginAccounting.dateRange.toLabel")) + " ", 1), (0, vue.createElementVNode)("input", {
2193
2201
  value: __props.modelValue.to,
2194
2202
  type: "date",
2195
2203
  class: "h-8 px-2 rounded border border-gray-300 text-sm",
2196
2204
  "data-testid": "accounting-daterange-to",
2197
- onInput: _cache[2] || (_cache[2] = ($event) => onToChange($event.target.value))
2205
+ onInput: onToChange
2198
2206
  }, null, 40, _hoisted_13$9)])
2199
2207
  ]);
2200
2208
  };
@@ -2228,8 +2236,7 @@ function isValidAccountCode(code) {
2228
2236
  function typeForCode(code) {
2229
2237
  if (!isValidAccountCode(code)) return null;
2230
2238
  const leading = Number.parseInt(code[0], 10);
2231
- for (const [type, prefix] of Object.entries(ACCOUNT_TYPE_PREFIX)) if (prefix === leading) return type;
2232
- return null;
2239
+ return require_shared.ACCOUNT_TYPES.find((type) => ACCOUNT_TYPE_PREFIX[type] === leading) ?? null;
2233
2240
  }
2234
2241
  function codeMatchesType(code, type) {
2235
2242
  return typeForCode(code) === type;
@@ -2641,7 +2648,7 @@ var AccountsModal_default = /* @__PURE__ */ (0, vue.defineComponent)({
2641
2648
  }
2642
2649
  function bindNewEditor(node, sectionType) {
2643
2650
  if (sectionType !== draft.value.type) return;
2644
- newEditorWrapper.value = node ?? null;
2651
+ newEditorWrapper.value = node instanceof HTMLDivElement ? node : null;
2645
2652
  }
2646
2653
  function onEdit(account) {
2647
2654
  addingNew.value = false;
@@ -3779,12 +3786,13 @@ var OpeningBalancesForm_default = /*#__PURE__*/ _plugin_vue_export_helper_defaul
3779
3786
  for (const account of bsAccounts.value) {
3780
3787
  const row = rows.value[account.code];
3781
3788
  if (!row) continue;
3782
- const debitOk = isPositiveAmount(row.debit);
3783
- const creditOk = isPositiveAmount(row.credit);
3789
+ const { debit, credit } = row;
3790
+ const debitOk = isPositiveAmount(debit);
3791
+ const creditOk = isPositiveAmount(credit);
3784
3792
  if (!debitOk && !creditOk) continue;
3785
3793
  const line = { accountCode: account.code };
3786
- if (debitOk) line.debit = row.debit;
3787
- if (creditOk) line.credit = row.credit;
3794
+ if (debitOk) line.debit = debit;
3795
+ if (creditOk) line.credit = credit;
3788
3796
  out.push(line);
3789
3797
  }
3790
3798
  return out;
@@ -3934,7 +3942,7 @@ var OpeningBalancesForm_default = /*#__PURE__*/ _plugin_vue_export_helper_defaul
3934
3942
  }, null, 8, ["book-id", "accounts"])) : (0, vue.createCommentVNode)("", true)], 64);
3935
3943
  };
3936
3944
  }
3937
- }), [["__scopeId", "data-v-530643ac"]]);
3945
+ }), [["__scopeId", "data-v-60e71a73"]]);
3938
3946
  //#endregion
3939
3947
  //#region src/vue/components/AccountsList.vue?vue&type=script&setup=true&lang.ts
3940
3948
  var _hoisted_1$6 = {
@@ -4317,7 +4325,10 @@ var BalanceSheet_default = /* @__PURE__ */ (0, vue.defineComponent)({
4317
4325
  if (value === require_shared.decemberOfPreviousYearString(now)) return "lastYear";
4318
4326
  return "";
4319
4327
  });
4320
- function onShortcutChange(raw) {
4328
+ function onShortcutChange(event) {
4329
+ const { target } = event;
4330
+ if (!(target instanceof HTMLSelectElement)) return;
4331
+ const raw = target.value;
4321
4332
  const now = /* @__PURE__ */ new Date();
4322
4333
  if (raw === "thisMonth") period.value = require_shared.localMonthString(now);
4323
4334
  else if (raw === "lastMonth") period.value = require_shared.previousMonthString(now);
@@ -4355,9 +4366,9 @@ var BalanceSheet_default = /* @__PURE__ */ (0, vue.defineComponent)({
4355
4366
  value: selectedShortcut.value,
4356
4367
  class: "h-8 px-2 rounded border border-gray-300 text-sm bg-white",
4357
4368
  "data-testid": "accounting-bs-shortcut",
4358
- onChange: _cache[0] || (_cache[0] = ($event) => onShortcutChange($event.target.value))
4369
+ onChange: onShortcutChange
4359
4370
  }, [
4360
- _cache[2] || (_cache[2] = (0, vue.createElementVNode)("option", {
4371
+ _cache[1] || (_cache[1] = (0, vue.createElementVNode)("option", {
4361
4372
  value: "",
4362
4373
  hidden: ""
4363
4374
  }, null, -1)),
@@ -4367,7 +4378,7 @@ var BalanceSheet_default = /* @__PURE__ */ (0, vue.defineComponent)({
4367
4378
  (0, vue.createElementVNode)("option", _hoisted_8$3, (0, vue.toDisplayString)((0, vue.unref)(t)("pluginAccounting.balanceSheet.lastYear")), 1)
4368
4379
  ], 40, _hoisted_4$3)]),
4369
4380
  (0, vue.createElementVNode)("label", _hoisted_9$3, [(0, vue.createTextVNode)((0, vue.toDisplayString)((0, vue.unref)(t)("pluginAccounting.balanceSheet.asOfLabel")) + " ", 1), (0, vue.withDirectives)((0, vue.createElementVNode)("input", {
4370
- "onUpdate:modelValue": _cache[1] || (_cache[1] = ($event) => period.value = $event),
4381
+ "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => period.value = $event),
4371
4382
  type: "month",
4372
4383
  class: "h-8 px-2 rounded border border-gray-300 text-sm",
4373
4384
  "data-testid": "accounting-bs-period"
@@ -4375,7 +4386,7 @@ var BalanceSheet_default = /* @__PURE__ */ (0, vue.defineComponent)({
4375
4386
  (0, vue.createElementVNode)("button", {
4376
4387
  class: "h-8 px-2.5 rounded border border-gray-300 text-sm text-gray-600 hover:bg-gray-50",
4377
4388
  onClick: refresh
4378
- }, [..._cache[3] || (_cache[3] = [(0, vue.createElementVNode)("span", { class: "material-icons text-base align-middle" }, "refresh", -1)])])
4389
+ }, [..._cache[2] || (_cache[2] = [(0, vue.createElementVNode)("span", { class: "material-icons text-base align-middle" }, "refresh", -1)])])
4379
4390
  ]), loading.value ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("p", _hoisted_10$3, (0, vue.toDisplayString)((0, vue.unref)(t)("pluginAccounting.common.loading")), 1)) : error.value ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("p", _hoisted_11$3, (0, vue.toDisplayString)((0, vue.unref)(t)("pluginAccounting.common.error", { error: error.value })), 1)) : balanceSheet.value ? ((0, vue.openBlock)(), (0, vue.createElementBlock)(vue.Fragment, { key: 2 }, [(0, vue.createElementVNode)("div", _hoisted_12$3, [((0, vue.openBlock)(true), (0, vue.createElementBlock)(vue.Fragment, null, (0, vue.renderList)(balanceSheet.value.sections, (section) => {
4380
4391
  return (0, vue.openBlock)(), (0, vue.createElementBlock)("section", {
4381
4392
  key: section.type,
@@ -4828,6 +4839,19 @@ var BookSettings_default = /* @__PURE__ */ (0, vue.defineComponent)({
4828
4839
  });
4829
4840
  //#endregion
4830
4841
  //#region src/vue/useAccountingChannel.ts
4842
+ var BOOK_EVENT_KIND_VALUES = Object.values(require_shared.BOOK_EVENT_KINDS);
4843
+ /** The host hands subscribers an `unknown`, so rebuild the payload from
4844
+ * the fields we can prove rather than trusting the publisher's type. */
4845
+ function toBookChannelPayload(data) {
4846
+ if (typeof data !== "object" || data === null || !("kind" in data)) return null;
4847
+ const kind = BOOK_EVENT_KIND_VALUES.find((candidate) => candidate === data.kind);
4848
+ if (kind === void 0) return null;
4849
+ const period = "period" in data && typeof data.period === "string" ? data.period : void 0;
4850
+ return period === void 0 ? { kind } : {
4851
+ kind,
4852
+ period
4853
+ };
4854
+ }
4831
4855
  function useAccountingChannel(bookId, onPayload) {
4832
4856
  const version = (0, vue.ref)(0);
4833
4857
  let unsubscribe = null;
@@ -4837,9 +4861,9 @@ function useAccountingChannel(bookId, onPayload) {
4837
4861
  version.value = 0;
4838
4862
  if (!nextBookId) return;
4839
4863
  unsubscribe = hostSubscribe(require_shared.bookChannel(nextBookId), (data) => {
4840
- const event = data;
4841
4864
  version.value += 1;
4842
- onPayload?.(event);
4865
+ const event = toBookChannelPayload(data);
4866
+ if (event) onPayload?.(event);
4843
4867
  });
4844
4868
  }
4845
4869
  (0, vue.watch)(bookId, bind, { immediate: true });
@@ -4955,7 +4979,7 @@ var View_default = /* @__PURE__ */ (0, vue.defineComponent)({
4955
4979
  }
4956
4980
  ];
4957
4981
  function isTabKey(value) {
4958
- return typeof value === "string" && TAB_KEYS.includes(value);
4982
+ return TAB_KEYS.some((key) => key === value);
4959
4983
  }
4960
4984
  const initialPayload = (0, vue.computed)(() => props.selectedResult?.data ?? props.selectedResult?.jsonData ?? {});
4961
4985
  const currentTab = (0, vue.ref)((0, vue.computed)(() => isTabKey(initialPayload.value.initialTab) ? initialPayload.value.initialTab : "journal").value);
@@ -5260,6 +5284,73 @@ var View_default = /* @__PURE__ */ (0, vue.defineComponent)({
5260
5284
  }
5261
5285
  });
5262
5286
  //#endregion
5287
+ //#region src/vue/previewSummary.ts
5288
+ var optionalString = (value) => typeof value === "string" ? value : void 0;
5289
+ var optionalNumber = (value) => typeof value === "number" ? value : void 0;
5290
+ function summariseError(json, translate) {
5291
+ const error = optionalString(json.error);
5292
+ if (error === void 0) return null;
5293
+ return translate("pluginAccounting.previewError", { error });
5294
+ }
5295
+ function summariseEntry(json, translate) {
5296
+ const [first] = require_shared.isUnknownArray(json.entries) ? json.entries : [];
5297
+ const entry = require_shared.isRecord(first) ? first : void 0;
5298
+ const entryId = optionalString(entry?.id);
5299
+ const date = optionalString(entry?.date);
5300
+ if (!entryId || !date) return null;
5301
+ return translate("pluginAccounting.preview.entry", { date });
5302
+ }
5303
+ function summarisePl(json, translate) {
5304
+ const { profitLoss } = json;
5305
+ if (!require_shared.isRecord(profitLoss)) return null;
5306
+ const netIncome = optionalNumber(profitLoss.netIncome);
5307
+ if (netIncome === void 0) return null;
5308
+ return translate("pluginAccounting.preview.pl", {
5309
+ from: optionalString(profitLoss.from) ?? "?",
5310
+ to: optionalString(profitLoss.to) ?? "?",
5311
+ net: require_shared.formatAmountNumeric(netIncome)
5312
+ });
5313
+ }
5314
+ function summariseBs(json, translate) {
5315
+ const { balanceSheet } = json;
5316
+ if (!require_shared.isRecord(balanceSheet)) return null;
5317
+ const date = optionalString(balanceSheet.asOf);
5318
+ const sections = require_shared.isUnknownArray(balanceSheet.sections) ? balanceSheet.sections : void 0;
5319
+ if (!date || !sections) return null;
5320
+ const assets = sections.find((section) => require_shared.isRecord(section) && section.type === "asset");
5321
+ return translate("pluginAccounting.preview.bs", {
5322
+ date,
5323
+ assets: require_shared.isRecord(assets) ? require_shared.formatAmountNumeric(optionalNumber(assets.total) ?? 0) : "?"
5324
+ });
5325
+ }
5326
+ function summariseBook(json, translate) {
5327
+ const { book } = json;
5328
+ if (!require_shared.isRecord(book)) return null;
5329
+ const bookId = optionalString(book.id);
5330
+ const name = optionalString(book.name);
5331
+ if (!bookId || !name) return null;
5332
+ return translate("pluginAccounting.preview.bookCreated", {
5333
+ name,
5334
+ id: bookId
5335
+ });
5336
+ }
5337
+ function summariseFallback(json, translate) {
5338
+ const bookId = optionalString(json.bookId);
5339
+ if (bookId !== void 0) return translate("pluginAccounting.previewSummary", { bookId });
5340
+ return translate("pluginAccounting.previewGeneric");
5341
+ }
5342
+ /** Merge the two props a host might carry the payload on. `isRecord` rejects
5343
+ * arrays, which the old `typeof value === "object"` check spread into the
5344
+ * payload. */
5345
+ var asPayload = (value) => require_shared.isRecord(value) ? value : {};
5346
+ function summarisePreview(data, jsonData, translate) {
5347
+ const json = {
5348
+ ...asPayload(data),
5349
+ ...asPayload(jsonData)
5350
+ };
5351
+ return summariseError(json, translate) ?? summariseEntry(json, translate) ?? summarisePl(json, translate) ?? summariseBs(json, translate) ?? summariseBook(json, translate) ?? summariseFallback(json, translate);
5352
+ }
5353
+ //#endregion
5263
5354
  //#region src/vue/Preview.vue?vue&type=script&setup=true&lang.ts
5264
5355
  var _hoisted_1 = {
5265
5356
  class: "text-sm text-gray-700",
@@ -5276,59 +5367,7 @@ var Preview_default = /* @__PURE__ */ (0, vue.defineComponent)({
5276
5367
  setup(__props) {
5277
5368
  const { t } = useAccountingI18n();
5278
5369
  const props = __props;
5279
- function summariseError(json) {
5280
- const { error } = json;
5281
- if (typeof error !== "string") return null;
5282
- return t("pluginAccounting.previewError", { error });
5283
- }
5284
- function summariseEntry(json) {
5285
- const { entries } = json;
5286
- if (!Array.isArray(entries) || entries.length === 0) return null;
5287
- const [first] = entries;
5288
- if (!first?.id || !first?.date) return null;
5289
- return t("pluginAccounting.preview.entry", { date: first.date });
5290
- }
5291
- function summarisePl(json) {
5292
- const { profitLoss } = json;
5293
- if (!profitLoss || typeof profitLoss.netIncome !== "number") return null;
5294
- return t("pluginAccounting.preview.pl", {
5295
- from: profitLoss.from ?? "?",
5296
- to: profitLoss.to ?? "?",
5297
- net: require_shared.formatAmountNumeric(profitLoss.netIncome)
5298
- });
5299
- }
5300
- function summariseBs(json) {
5301
- const { balanceSheet } = json;
5302
- if (!balanceSheet?.asOf || !balanceSheet.sections) return null;
5303
- const assets = balanceSheet.sections.find((section) => section.type === "asset");
5304
- return t("pluginAccounting.preview.bs", {
5305
- date: balanceSheet.asOf,
5306
- assets: assets ? require_shared.formatAmountNumeric(assets.total ?? 0) : "?"
5307
- });
5308
- }
5309
- function summariseBook(json) {
5310
- const { book } = json;
5311
- if (!book?.id || !book?.name) return null;
5312
- return t("pluginAccounting.preview.bookCreated", {
5313
- name: book.name,
5314
- id: book.id
5315
- });
5316
- }
5317
- function summariseFallback(json) {
5318
- const { bookId } = json;
5319
- if (typeof bookId === "string") return t("pluginAccounting.previewSummary", { bookId });
5320
- return t("pluginAccounting.previewGeneric");
5321
- }
5322
- function asObject(value) {
5323
- return value && typeof value === "object" ? value : {};
5324
- }
5325
- const summary = (0, vue.computed)(() => {
5326
- const json = {
5327
- ...asObject(props.data),
5328
- ...asObject(props.jsonData)
5329
- };
5330
- return summariseError(json) ?? summariseEntry(json) ?? summarisePl(json) ?? summariseBs(json) ?? summariseBook(json) ?? summariseFallback(json);
5331
- });
5370
+ const summary = (0, vue.computed)(() => summarisePreview(props.data, props.jsonData, t));
5332
5371
  return (_ctx, _cache) => {
5333
5372
  return (0, vue.openBlock)(), (0, vue.createElementBlock)("div", _hoisted_1, [_cache[0] || (_cache[0] = (0, vue.createElementVNode)("span", { class: "material-icons text-base align-middle mr-1" }, "account_balance", -1)), (0, vue.createElementVNode)("span", null, (0, vue.toDisplayString)(summary.value), 1)]);
5334
5373
  };