shutro-erp 0.2.1 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +17 -10
- package/dist/account_portal/.kosh/bindings.d.ts +22 -0
- package/dist/account_portal/.kosh/bindings.js +15 -0
- package/dist/account_portal/.kosh/schema.d.ts +1350 -0
- package/dist/account_portal/index.d.ts +3 -0
- package/dist/account_portal/index.js +73 -0
- package/dist/account_portal/module.d.ts +5983 -0
- package/dist/account_portal/module.js +18 -0
- package/dist/accounting/.kosh/bindings.js +1 -1
- package/dist/accounting/.kosh/schema.d.ts +142 -9
- package/dist/accounting/chart.d.ts +40 -8
- package/dist/accounting/chart.js +124 -30
- package/dist/accounting/closing.d.ts +6 -1
- package/dist/accounting/closing.js +5 -1
- package/dist/accounting/demo.js +6 -5
- package/dist/accounting/index.d.ts +3 -3
- package/dist/accounting/index.js +200 -23
- package/dist/accounting/module.d.ts +3326 -1086
- package/dist/accounting/module.js +408 -66
- package/dist/accounting/payments.d.ts +25 -0
- package/dist/accounting/payments.js +96 -4
- package/dist/accounting/web/RegisterPayment.d.ts +3 -2
- package/dist/accounting/web/RegisterPayment.js +39 -6
- package/dist/accounting/web/SettingsPage.js +5 -1
- package/dist/accounting/web/messages.js +10 -0
- package/dist/cli/init.js +172 -48
- package/dist/cli/launch.d.ts +16 -0
- package/dist/cli/launch.js +138 -0
- package/dist/cli/prompt.d.ts +35 -0
- package/dist/cli/prompt.js +46 -0
- package/dist/cli/templates.d.ts +11 -3
- package/dist/cli/templates.js +32 -7
- package/dist/cli/tui.d.ts +7 -0
- package/dist/cli/tui.js +254 -0
- package/dist/cli/ui.d.ts +25 -5
- package/dist/cli/ui.js +49 -9
- package/dist/contacts/.kosh/bindings.js +1 -1
- package/dist/contacts/.kosh/schema.d.ts +3 -1
- package/dist/contacts/index.js +24 -1
- package/dist/contacts/module.d.ts +42 -0
- package/dist/contacts/module.js +3 -1
- package/dist/import/convert.d.ts +55 -0
- package/dist/import/convert.js +224 -0
- package/dist/import/csv.d.ts +28 -0
- package/dist/import/csv.js +115 -0
- package/dist/import/index.d.ts +33 -0
- package/dist/import/index.js +60 -0
- package/dist/import/mapping.d.ts +15 -0
- package/dist/import/mapping.js +33 -0
- package/dist/import/match.d.ts +24 -0
- package/dist/import/match.js +60 -0
- package/dist/import/models.d.ts +2 -0
- package/dist/import/models.js +102 -0
- package/dist/import/routes.d.ts +13 -0
- package/dist/import/routes.js +392 -0
- package/dist/import/run.d.ts +131 -0
- package/dist/import/run.js +568 -0
- package/dist/import/service.d.ts +153 -0
- package/dist/import/service.js +367 -0
- package/dist/import/web/ImportButton.d.ts +7 -0
- package/dist/import/web/ImportButton.js +31 -0
- package/dist/import/web/ImportWizard.d.ts +75 -0
- package/dist/import/web/ImportWizard.js +217 -0
- package/dist/import/web/index.d.ts +13 -0
- package/dist/import/web/index.js +18 -0
- package/dist/import/web/messages.d.ts +2 -0
- package/dist/import/web/messages.js +139 -0
- package/dist/import/worker.d.ts +3 -0
- package/dist/import/worker.js +52 -0
- package/dist/import/xlsx.d.ts +20 -0
- package/dist/import/xlsx.js +192 -0
- package/dist/l10n_bd/.kosh/bindings.d.ts +22 -0
- package/dist/l10n_bd/.kosh/bindings.js +15 -0
- package/dist/l10n_bd/.kosh/schema.d.ts +1281 -0
- package/dist/l10n_bd/documents.d.ts +8 -0
- package/dist/l10n_bd/documents.js +183 -0
- package/dist/l10n_bd/index.d.ts +8 -0
- package/dist/l10n_bd/index.js +156 -0
- package/dist/l10n_bd/module.d.ts +5705 -0
- package/dist/l10n_bd/module.js +163 -0
- package/dist/l10n_bd/mushak.d.ts +67 -0
- package/dist/l10n_bd/mushak.js +139 -0
- package/dist/l10n_bd/routes.d.ts +3 -0
- package/dist/l10n_bd/routes.js +205 -0
- package/dist/l10n_bd/web/MushakPage.d.ts +7 -0
- package/dist/l10n_bd/web/MushakPage.js +53 -0
- package/dist/l10n_bd/web/index.d.ts +13 -0
- package/dist/l10n_bd/web/index.js +18 -0
- package/dist/l10n_bd/web/messages.d.ts +2 -0
- package/dist/l10n_bd/web/messages.js +101 -0
- package/dist/l10n_in/.kosh/bindings.d.ts +22 -0
- package/dist/l10n_in/.kosh/bindings.js +15 -0
- package/dist/l10n_in/.kosh/schema.d.ts +1343 -0
- package/dist/l10n_in/documents.d.ts +8 -0
- package/dist/l10n_in/documents.js +114 -0
- package/dist/l10n_in/einvoice.d.ts +253 -0
- package/dist/l10n_in/einvoice.js +485 -0
- package/dist/l10n_in/gstr.d.ts +109 -0
- package/dist/l10n_in/gstr.js +430 -0
- package/dist/l10n_in/index.d.ts +20 -0
- package/dist/l10n_in/index.js +232 -0
- package/dist/l10n_in/module.d.ts +7823 -0
- package/dist/l10n_in/module.js +427 -0
- package/dist/l10n_in/routes-einvoice.d.ts +15 -0
- package/dist/l10n_in/routes-einvoice.js +124 -0
- package/dist/l10n_in/routes.d.ts +17 -0
- package/dist/l10n_in/routes.js +282 -0
- package/dist/l10n_in/web/EInvoicePanel.d.ts +8 -0
- package/dist/l10n_in/web/EInvoicePanel.js +63 -0
- package/dist/l10n_in/web/GstPage.d.ts +7 -0
- package/dist/l10n_in/web/GstPage.js +57 -0
- package/dist/l10n_in/web/GstSettings.d.ts +10 -0
- package/dist/l10n_in/web/GstSettings.js +36 -0
- package/dist/l10n_in/web/index.d.ts +15 -0
- package/dist/l10n_in/web/index.js +22 -0
- package/dist/l10n_in/web/messages.d.ts +2 -0
- package/dist/l10n_in/web/messages.js +166 -0
- package/dist/modules-sdk/demo.d.ts +2 -0
- package/dist/modules-sdk/demo.js +7 -3
- package/dist/modules-sdk/index.d.ts +2 -2
- package/dist/modules-sdk/index.js +1 -1
- package/dist/modules-sdk/manifest.d.ts +132 -0
- package/dist/modules-sdk/manifest.js +22 -0
- package/dist/notify/inbox.js +21 -0
- package/dist/notify/messages.js +4 -0
- package/dist/notify/models.d.ts +1 -1
- package/dist/notify/models.js +2 -0
- package/dist/notify/web/messages.js +4 -0
- package/dist/portal/.kosh/bindings.d.ts +22 -0
- package/dist/portal/.kosh/bindings.js +15 -0
- package/dist/portal/.kosh/schema.d.ts +346 -0
- package/dist/portal/announce.d.ts +16 -0
- package/dist/portal/announce.js +117 -0
- package/dist/portal/documents.d.ts +17 -0
- package/dist/portal/documents.js +61 -0
- package/dist/portal/index.d.ts +20 -0
- package/dist/portal/index.js +65 -0
- package/dist/portal/module.d.ts +1405 -0
- package/dist/portal/module.js +84 -0
- package/dist/portal/routes-documents.d.ts +2 -0
- package/dist/portal/routes-documents.js +391 -0
- package/dist/portal/routes.d.ts +13 -0
- package/dist/portal/routes.js +313 -0
- package/dist/portal/rules.d.ts +11 -0
- package/dist/portal/rules.js +25 -0
- package/dist/portal/web/PortalAccess.d.ts +8 -0
- package/dist/portal/web/PortalAccess.js +66 -0
- package/dist/portal/web/index.d.ts +12 -0
- package/dist/portal/web/index.js +17 -0
- package/dist/portal/web/messages.d.ts +2 -0
- package/dist/portal/web/messages.js +33 -0
- package/dist/product/.kosh/bindings.js +1 -1
- package/dist/product/.kosh/schema.d.ts +12 -3
- package/dist/product/demo.js +6 -5
- package/dist/product/index.d.ts +1 -0
- package/dist/product/index.js +17 -4
- package/dist/product/module.d.ts +346 -14
- package/dist/product/module.js +48 -18
- package/dist/product/taxes.d.ts +59 -0
- package/dist/product/taxes.js +61 -0
- package/dist/project/.kosh/bindings.js +1 -1
- package/dist/project/.kosh/schema.d.ts +3 -1
- package/dist/project/module.d.ts +20 -0
- package/dist/project_portal/.kosh/bindings.d.ts +22 -0
- package/dist/project_portal/.kosh/bindings.js +15 -0
- package/dist/project_portal/.kosh/schema.d.ts +671 -0
- package/dist/project_portal/index.d.ts +9 -0
- package/dist/project_portal/index.js +42 -0
- package/dist/project_portal/module.d.ts +2142 -0
- package/dist/project_portal/module.js +22 -0
- package/dist/purchase/.kosh/bindings.js +1 -1
- package/dist/purchase/.kosh/schema.d.ts +15 -4
- package/dist/purchase/demo.js +3 -3
- package/dist/purchase/index.js +1 -1
- package/dist/purchase/module.d.ts +232 -8
- package/dist/purchase/module.js +51 -9
- package/dist/purchase_account/.kosh/bindings.js +1 -1
- package/dist/purchase_account/.kosh/schema.d.ts +144 -10
- package/dist/purchase_account/module.d.ts +2008 -641
- package/dist/purchase_account/module.js +2 -2
- package/dist/purchase_portal/.kosh/bindings.d.ts +22 -0
- package/dist/purchase_portal/.kosh/bindings.js +15 -0
- package/dist/purchase_portal/.kosh/schema.d.ts +822 -0
- package/dist/purchase_portal/index.d.ts +9 -0
- package/dist/purchase_portal/index.js +53 -0
- package/dist/purchase_portal/module.d.ts +2758 -0
- package/dist/purchase_portal/module.js +18 -0
- package/dist/reporting/documents.js +20 -3
- package/dist/reporting/index.d.ts +1 -0
- package/dist/reporting/index.js +1 -0
- package/dist/reporting/routes-documents.js +9 -2
- package/dist/reporting/words.d.ts +11 -0
- package/dist/reporting/words.js +229 -0
- package/dist/sale_account/.kosh/bindings.js +1 -1
- package/dist/sale_account/.kosh/schema.d.ts +144 -10
- package/dist/sale_account/module.d.ts +2008 -641
- package/dist/sale_account/module.js +3 -3
- package/dist/sale_portal/.kosh/bindings.d.ts +22 -0
- package/dist/sale_portal/.kosh/bindings.js +15 -0
- package/dist/sale_portal/.kosh/schema.d.ts +736 -0
- package/dist/sale_portal/index.d.ts +9 -0
- package/dist/sale_portal/index.js +71 -0
- package/dist/sale_portal/module.d.ts +2718 -0
- package/dist/sale_portal/module.js +19 -0
- package/dist/sale_project/.kosh/bindings.js +1 -1
- package/dist/sale_project/.kosh/schema.d.ts +15 -4
- package/dist/sale_project/module.d.ts +390 -10
- package/dist/sales/.kosh/bindings.js +1 -1
- package/dist/sales/.kosh/schema.d.ts +15 -4
- package/dist/sales/demo.js +3 -3
- package/dist/sales/index.js +67 -1
- package/dist/sales/module.d.ts +232 -8
- package/dist/sales/module.js +51 -12
- package/dist/server/auth/base.js +2 -0
- package/dist/server/auth/service.d.ts +2 -0
- package/dist/server/auth/service.js +7 -1
- package/dist/server/index.d.ts +1 -1
- package/dist/server/index.js +1 -1
- package/dist/server/server.js +26 -1
- package/dist/ui/api.d.ts +2 -0
- package/dist/ui/app.js +1 -1
- package/dist/ui/context.d.ts +3 -1
- package/dist/ui/context.js +2 -2
- package/dist/ui/index.d.ts +1 -1
- package/dist/ui/index.js +1 -1
- package/dist/ui/lib/format.d.ts +2 -0
- package/dist/ui/lib/format.js +3 -1
- package/dist/ui/views/FormView.js +19 -6
- package/package.json +50 -2
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A minimal XLSX reader without dependencies (RFC 0014 §5.1), the counterpart of `shutro-erp/reporting`'s writer: the zip
|
|
3
|
+
* is read with `node:zlib`, sheets with a small tag scanner. Cells come back typed: text (shared and inline
|
|
4
|
+
* strings), numbers, booleans, and dates for numbers whose format is a date format. A formula is never evaluated:
|
|
5
|
+
* its cached value is read. Errors (`#N/A`) read as text.
|
|
6
|
+
*/
|
|
7
|
+
import { inflateRawSync } from 'node:zlib';
|
|
8
|
+
export class XlsxError extends Error {
|
|
9
|
+
name = 'XlsxError';
|
|
10
|
+
}
|
|
11
|
+
/** The entries of a zip archive by name (stored or deflated; no ZIP64, no encryption). */
|
|
12
|
+
export function unzip(bytes) {
|
|
13
|
+
const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
|
|
14
|
+
let end = -1;
|
|
15
|
+
for (let i = bytes.length - 22; i >= Math.max(0, bytes.length - 22 - 65_535); i--)
|
|
16
|
+
if (view.getUint32(i, true) === 0x06054b50) {
|
|
17
|
+
end = i;
|
|
18
|
+
break;
|
|
19
|
+
}
|
|
20
|
+
if (end < 0)
|
|
21
|
+
throw new XlsxError('The file is not an XLSX workbook (no zip directory).');
|
|
22
|
+
const count = view.getUint16(end + 10, true);
|
|
23
|
+
let at = view.getUint32(end + 16, true);
|
|
24
|
+
const out = new Map();
|
|
25
|
+
const decoder = new TextDecoder();
|
|
26
|
+
for (let n = 0; n < count; n++) {
|
|
27
|
+
if (view.getUint32(at, true) !== 0x02014b50)
|
|
28
|
+
throw new XlsxError('The zip directory is damaged.');
|
|
29
|
+
const method = view.getUint16(at + 10, true);
|
|
30
|
+
const size = view.getUint32(at + 20, true);
|
|
31
|
+
const nameLength = view.getUint16(at + 28, true);
|
|
32
|
+
const extraLength = view.getUint16(at + 30, true);
|
|
33
|
+
const commentLength = view.getUint16(at + 32, true);
|
|
34
|
+
const local = view.getUint32(at + 42, true);
|
|
35
|
+
const name = decoder.decode(bytes.subarray(at + 46, at + 46 + nameLength));
|
|
36
|
+
at += 46 + nameLength + extraLength + commentLength;
|
|
37
|
+
if (view.getUint32(local, true) !== 0x04034b50)
|
|
38
|
+
throw new XlsxError('A zip entry is damaged.');
|
|
39
|
+
const start = local + 30 + view.getUint16(local + 26, true) + view.getUint16(local + 28, true);
|
|
40
|
+
const data = bytes.subarray(start, start + size);
|
|
41
|
+
if (method === 0)
|
|
42
|
+
out.set(name, data);
|
|
43
|
+
else if (method === 8)
|
|
44
|
+
out.set(name, new Uint8Array(inflateRawSync(data)));
|
|
45
|
+
else
|
|
46
|
+
throw new XlsxError(`Zip compression method ${method} is not supported.`);
|
|
47
|
+
}
|
|
48
|
+
return out;
|
|
49
|
+
}
|
|
50
|
+
const ENTITIES = { amp: '&', lt: '<', gt: '>', quot: '"', apos: "'" };
|
|
51
|
+
/** XML text with its entities resolved. */
|
|
52
|
+
export function unescapeXml(text) {
|
|
53
|
+
return text.replace(/&(#x[0-9a-fA-F]+|#[0-9]+|[a-z]+);/g, (all, ref) => {
|
|
54
|
+
if (ref.startsWith('#x'))
|
|
55
|
+
return String.fromCodePoint(Number.parseInt(ref.slice(2), 16));
|
|
56
|
+
if (ref.startsWith('#'))
|
|
57
|
+
return String.fromCodePoint(Number.parseInt(ref.slice(1), 10));
|
|
58
|
+
return ENTITIES[ref] ?? all;
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
/** The value of attribute `name` in the attributes text of a tag. */
|
|
62
|
+
function attr(attrs, name) {
|
|
63
|
+
const m = new RegExp(`(?:^|\\s)${name}="([^"]*)"`).exec(attrs);
|
|
64
|
+
return m === null ? undefined : unescapeXml(m[1]);
|
|
65
|
+
}
|
|
66
|
+
/** The text of the `<t>` elements in `xml` (a shared string or an inline string, rich runs joined). */
|
|
67
|
+
function texts(xml) {
|
|
68
|
+
let out = '';
|
|
69
|
+
const visible = xml.replace(/<rPh[\s\S]*?<\/rPh>/g, ''); // phonetic guides are not the text
|
|
70
|
+
for (const m of visible.matchAll(/<t(?:\s[^>]*)?>([\s\S]*?)<\/t>/g))
|
|
71
|
+
out += unescapeXml(m[1]);
|
|
72
|
+
return out;
|
|
73
|
+
}
|
|
74
|
+
/** Built-in number formats that are dates or times. */
|
|
75
|
+
const DATE_FORMATS = new Set([14, 15, 16, 17, 18, 19, 20, 21, 22, 45, 46, 47]);
|
|
76
|
+
/** Whether a custom number format code shows a date or time (letters outside quotes and brackets). */
|
|
77
|
+
export function isDateFormat(code) {
|
|
78
|
+
const bare = code.replace(/"[^"]*"|\[[^\]]*\]|\\./g, '');
|
|
79
|
+
return /[dmyhs]/i.test(bare) && !/^[#0.,%\s]*$/.test(bare);
|
|
80
|
+
}
|
|
81
|
+
/** For each cell style index: whether it formats a date. */
|
|
82
|
+
function dateStyles(xml) {
|
|
83
|
+
if (xml === undefined)
|
|
84
|
+
return [];
|
|
85
|
+
const custom = new Map();
|
|
86
|
+
for (const m of xml.matchAll(/<numFmt\s([^>]*?)\/?>/g)) {
|
|
87
|
+
const id = Number(attr(m[1], 'numFmtId'));
|
|
88
|
+
custom.set(id, attr(m[1], 'formatCode') ?? '');
|
|
89
|
+
}
|
|
90
|
+
const xfs = /<cellXfs[^>]*>([\s\S]*?)<\/cellXfs>/.exec(xml)?.[1] ?? '';
|
|
91
|
+
return [...xfs.matchAll(/<xf\s([^>]*?)\/?>/g)].map((m) => {
|
|
92
|
+
const id = Number(attr(m[1], 'numFmtId') ?? 0);
|
|
93
|
+
const code = custom.get(id);
|
|
94
|
+
return code === undefined ? DATE_FORMATS.has(id) : isDateFormat(code);
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
/** An Excel serial date (days since 1899-12-30) as a UTC date, to the second. */
|
|
98
|
+
export function fromSerial(serial) {
|
|
99
|
+
return new Date(Math.round((serial - 25_569) * 86_400) * 1000);
|
|
100
|
+
}
|
|
101
|
+
/** Column index of a cell reference (`C7` → 2). */
|
|
102
|
+
function columnOf(ref) {
|
|
103
|
+
let n = 0;
|
|
104
|
+
for (const ch of ref) {
|
|
105
|
+
const code = ch.charCodeAt(0);
|
|
106
|
+
if (code < 65 || code > 90)
|
|
107
|
+
break;
|
|
108
|
+
n = n * 26 + (code - 64);
|
|
109
|
+
}
|
|
110
|
+
return n - 1;
|
|
111
|
+
}
|
|
112
|
+
function readSheet(xml, shared, dates) {
|
|
113
|
+
const rows = [];
|
|
114
|
+
const data = /<sheetData[^>]*>([\s\S]*?)<\/sheetData>|<sheetData[^>]*\/>/.exec(xml)?.[1] ?? '';
|
|
115
|
+
for (const rowMatch of data.matchAll(/<row(\s[^>]*?)?(?:\/>|>([\s\S]*?)<\/row>)/g)) {
|
|
116
|
+
const index = Number(attr(rowMatch[1] ?? '', 'r') ?? rows.length + 1) - 1;
|
|
117
|
+
const row = [];
|
|
118
|
+
for (const cell of (rowMatch[2] ?? '').matchAll(/<c(\s[^>]*?)?(?:\/>|>([\s\S]*?)<\/c>)/g)) {
|
|
119
|
+
const attrs = cell[1] ?? '';
|
|
120
|
+
const body = cell[2] ?? '';
|
|
121
|
+
const ref = attr(attrs, 'r');
|
|
122
|
+
const col = ref === undefined ? row.length : columnOf(ref);
|
|
123
|
+
const type = attr(attrs, 't') ?? 'n';
|
|
124
|
+
const raw = /<v>([\s\S]*?)<\/v>/.exec(body)?.[1];
|
|
125
|
+
let value = null;
|
|
126
|
+
if (type === 'inlineStr')
|
|
127
|
+
value = texts(/<is>([\s\S]*?)<\/is>/.exec(body)?.[1] ?? '');
|
|
128
|
+
else if (raw === undefined)
|
|
129
|
+
value = null;
|
|
130
|
+
else if (type === 's')
|
|
131
|
+
value = shared[Number(raw)] ?? '';
|
|
132
|
+
else if (type === 'b')
|
|
133
|
+
value = raw === '1';
|
|
134
|
+
else if (type === 'str' || type === 'e')
|
|
135
|
+
value = unescapeXml(raw);
|
|
136
|
+
else {
|
|
137
|
+
const n = Number(raw);
|
|
138
|
+
value = dates[Number(attr(attrs, 's') ?? 0)] === true ? fromSerial(n) : n;
|
|
139
|
+
}
|
|
140
|
+
while (row.length < col)
|
|
141
|
+
row.push(null);
|
|
142
|
+
row[col] = value;
|
|
143
|
+
}
|
|
144
|
+
while (rows.length < index)
|
|
145
|
+
rows.push([]);
|
|
146
|
+
rows[index] = row;
|
|
147
|
+
}
|
|
148
|
+
while (rows.length > 0 && rows.at(-1).every((c) => c === null || c === ''))
|
|
149
|
+
rows.pop();
|
|
150
|
+
return rows;
|
|
151
|
+
}
|
|
152
|
+
/** The sheet names of a workbook, in order. */
|
|
153
|
+
export function xlsxSheetNames(bytes) {
|
|
154
|
+
return sheetsOf(unzip(bytes)).map((s) => s.name);
|
|
155
|
+
}
|
|
156
|
+
function sheetsOf(files) {
|
|
157
|
+
const text = (path) => {
|
|
158
|
+
const b = files.get(path);
|
|
159
|
+
return b === undefined ? undefined : new TextDecoder().decode(b);
|
|
160
|
+
};
|
|
161
|
+
const workbook = text('xl/workbook.xml');
|
|
162
|
+
if (workbook === undefined)
|
|
163
|
+
throw new XlsxError('The file is not an XLSX workbook (no workbook).');
|
|
164
|
+
const targets = new Map();
|
|
165
|
+
for (const m of (text('xl/_rels/workbook.xml.rels') ?? '').matchAll(/<Relationship\s([^>]*?)\/?>/g)) {
|
|
166
|
+
const target = attr(m[1], 'Target') ?? '';
|
|
167
|
+
targets.set(attr(m[1], 'Id') ?? '', target.startsWith('/') ? target.slice(1) : `xl/${target}`);
|
|
168
|
+
}
|
|
169
|
+
return [...workbook.matchAll(/<sheet\s([^>]*?)\/?>/g)].map((m, i) => ({
|
|
170
|
+
name: attr(m[1], 'name') ?? `Sheet${i + 1}`,
|
|
171
|
+
path: targets.get(attr(m[1], 'r:id') ?? '') ?? `xl/worksheets/sheet${i + 1}.xml`,
|
|
172
|
+
}));
|
|
173
|
+
}
|
|
174
|
+
/** Reads one sheet of a workbook: by name, else the first. @throws {XlsxError} */
|
|
175
|
+
export function readXlsx(bytes, sheet) {
|
|
176
|
+
const files = unzip(bytes);
|
|
177
|
+
const text = (path) => {
|
|
178
|
+
const b = files.get(path);
|
|
179
|
+
return b === undefined ? undefined : new TextDecoder().decode(b);
|
|
180
|
+
};
|
|
181
|
+
const sheets = sheetsOf(files);
|
|
182
|
+
const chosen = sheet === undefined ? sheets[0] : sheets.find((s) => s.name === sheet);
|
|
183
|
+
if (chosen === undefined)
|
|
184
|
+
throw new XlsxError(sheet === undefined ? 'The workbook has no sheet.' : `The workbook has no sheet '${sheet}'.`);
|
|
185
|
+
const xml = text(chosen.path);
|
|
186
|
+
if (xml === undefined)
|
|
187
|
+
throw new XlsxError(`The sheet '${chosen.name}' is missing.`);
|
|
188
|
+
const shared = [
|
|
189
|
+
...(text('xl/sharedStrings.xml') ?? '').matchAll(/<si>([\s\S]*?)<\/si>|<si\/>/g),
|
|
190
|
+
].map((m) => texts(m[1] ?? ''));
|
|
191
|
+
return { name: chosen.name, rows: readSheet(xml, shared, dateStyles(text('xl/styles.xml'))) };
|
|
192
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export { defineModel, defineModule, extendModel, f, replace } from '../../server/orm.js';
|
|
2
|
+
import { type DefinitionHelpers } from '../../server/orm.js';
|
|
3
|
+
import type { DefaultLoaded, Env as CoreEnv, RecordSet as CoreRecordSet, Shutro as CoreShutro } from '../../server/orm.js';
|
|
4
|
+
import type { SchemaView } from './schema.js';
|
|
5
|
+
export type { SchemaView };
|
|
6
|
+
/** Every model visible in this view. */
|
|
7
|
+
export type ModelName = keyof SchemaView & string;
|
|
8
|
+
/** `Env` typed to this view. */
|
|
9
|
+
export type Env = CoreEnv<SchemaView>;
|
|
10
|
+
/** `Shutro` typed to this view. */
|
|
11
|
+
export type Shutro = CoreShutro<SchemaView>;
|
|
12
|
+
/** A recordset of `M`, with the default loaded shape unless `L` is given. */
|
|
13
|
+
export type Records<M extends ModelName, L = DefaultLoaded<SchemaView, M>> = CoreRecordSet<SchemaView, M, L>;
|
|
14
|
+
export declare const compute: DefinitionHelpers<SchemaView>['compute'];
|
|
15
|
+
export declare const check: DefinitionHelpers<SchemaView>['check'];
|
|
16
|
+
export declare const onchange: DefinitionHelpers<SchemaView>['onchange'];
|
|
17
|
+
export declare const records: DefinitionHelpers<SchemaView>['records'];
|
|
18
|
+
export declare const method: DefinitionHelpers<SchemaView>['method'];
|
|
19
|
+
/** Module data (RFC 0017): records, overrides of dependencies' records, and references, typed like creates. */
|
|
20
|
+
export declare const record: DefinitionHelpers<SchemaView>['record'];
|
|
21
|
+
export declare const override: DefinitionHelpers<SchemaView>['override'];
|
|
22
|
+
export declare const ref: DefinitionHelpers<SchemaView>['ref'];
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
// GENERATED by `pnpm generate:models` (Shutro’s generator). Do not edit. definitions-hash: 3a5b3163d9a0a2af
|
|
2
|
+
// Bindings of module `l10n_bd`: import the definition API from here to get types scoped to what it can see.
|
|
3
|
+
export { defineModel, defineModule, extendModel, f, replace } from '../../server/orm.js';
|
|
4
|
+
import { definitions } from '../../server/orm.js';
|
|
5
|
+
/** Definition callbacks typed against this module's view: no casts in computes, checks, onchange, methods. */
|
|
6
|
+
const helpers = definitions();
|
|
7
|
+
export const compute = helpers.compute;
|
|
8
|
+
export const check = helpers.check;
|
|
9
|
+
export const onchange = helpers.onchange;
|
|
10
|
+
export const records = helpers.records;
|
|
11
|
+
export const method = helpers.method;
|
|
12
|
+
/** Module data (RFC 0017): records, overrides of dependencies' records, and references, typed like creates. */
|
|
13
|
+
export const record = helpers.record;
|
|
14
|
+
export const override = helpers.override;
|
|
15
|
+
export const ref = helpers.ref;
|