@kaspernj/api-maker 1.0.2171 → 1.0.2173

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 (37) hide show
  1. package/build/commands-pool.d.ts +139 -0
  2. package/build/commands-pool.d.ts.map +1 -1
  3. package/build/commands-pool.js +88 -19
  4. package/build/config.d.ts +21 -0
  5. package/build/config.d.ts.map +1 -1
  6. package/build/config.js +24 -1
  7. package/build/session-expired-error.d.ts +14 -0
  8. package/build/session-expired-error.d.ts.map +1 -0
  9. package/build/session-expired-error.js +19 -0
  10. package/build/session-status-updater.d.ts +16 -0
  11. package/build/session-status-updater.d.ts.map +1 -1
  12. package/build/session-status-updater.js +34 -1
  13. package/build/table/export/cell-value.d.ts +3 -0
  14. package/build/table/export/cell-value.d.ts.map +1 -0
  15. package/build/table/export/cell-value.js +47 -0
  16. package/build/table/export/file-sinks/web-file-sink.d.ts +53 -0
  17. package/build/table/export/file-sinks/web-file-sink.d.ts.map +1 -0
  18. package/build/table/export/file-sinks/web-file-sink.js +75 -0
  19. package/build/table/export/format-writers/csv-writer.d.ts +30 -0
  20. package/build/table/export/format-writers/csv-writer.d.ts.map +1 -0
  21. package/build/table/export/format-writers/csv-writer.js +47 -0
  22. package/build/table/export/format-writers/html-writer.d.ts +20 -0
  23. package/build/table/export/format-writers/html-writer.d.ts.map +1 -0
  24. package/build/table/export/format-writers/html-writer.js +30 -0
  25. package/build/table/export/format-writers/xlsx-writer.d.ts +23 -0
  26. package/build/table/export/format-writers/xlsx-writer.d.ts.map +1 -0
  27. package/build/table/export/format-writers/xlsx-writer.js +41 -0
  28. package/build/table/export/open-export-file-sink.d.ts +19 -0
  29. package/build/table/export/open-export-file-sink.d.ts.map +1 -0
  30. package/build/table/export/open-export-file-sink.js +26 -0
  31. package/build/table/export/table-exporter.d.ts +80 -0
  32. package/build/table/export/table-exporter.d.ts.map +1 -0
  33. package/build/table/export/table-exporter.js +141 -0
  34. package/build/table/settings/download-action.d.ts +8 -1
  35. package/build/table/settings/download-action.d.ts.map +1 -1
  36. package/build/table/settings/download-action.js +51 -24
  37. package/package.json +4 -3
@@ -0,0 +1,19 @@
1
+ /** @typedef {import("./file-sinks/web-file-sink.js").ExportFileSink} ExportFileSink */
2
+ /**
3
+ * Opens a file sink for an export, abstracting over platforms. A host-configured opener (e.g. an
4
+ * expo-file-system/expo-sharing implementation on React Native) takes precedence; otherwise the built-in web
5
+ * sink is used. On native without a configured opener this throws with guidance.
6
+ *
7
+ * @param {object} args
8
+ * @param {string} args.fileName
9
+ * @param {string} args.mimeType
10
+ * @param {string} args.format
11
+ * @returns {Promise<ExportFileSink>}
12
+ */
13
+ export default function openExportFileSink(args: {
14
+ fileName: string;
15
+ mimeType: string;
16
+ format: string;
17
+ }): Promise<ExportFileSink>;
18
+ export type ExportFileSink = import("./file-sinks/web-file-sink.js").ExportFileSink;
19
+ //# sourceMappingURL=open-export-file-sink.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"open-export-file-sink.d.ts","sourceRoot":"/src/","sources":["table/export/open-export-file-sink.js"],"names":[],"mappings":"AAKA,uFAAuF;AAEvF;;;;;;;;;;GAUG;AACH,iDALG;IAAqB,QAAQ,EAArB,MAAM;IACO,QAAQ,EAArB,MAAM;IACO,MAAM,EAAnB,MAAM;CACd,GAAU,OAAO,CAAC,cAAc,CAAC,CAYnC;6BAvBa,OAAO,+BAA+B,EAAE,cAAc"}
@@ -0,0 +1,26 @@
1
+ // @ts-check
2
+ import { Platform } from "react-native";
3
+ import apiMakerConfig from "../../config.js";
4
+ import openWebFileSink from "./file-sinks/web-file-sink.js";
5
+ /** @typedef {import("./file-sinks/web-file-sink.js").ExportFileSink} ExportFileSink */
6
+ /**
7
+ * Opens a file sink for an export, abstracting over platforms. A host-configured opener (e.g. an
8
+ * expo-file-system/expo-sharing implementation on React Native) takes precedence; otherwise the built-in web
9
+ * sink is used. On native without a configured opener this throws with guidance.
10
+ *
11
+ * @param {object} args
12
+ * @param {string} args.fileName
13
+ * @param {string} args.mimeType
14
+ * @param {string} args.format
15
+ * @returns {Promise<ExportFileSink>}
16
+ */
17
+ export default async function openExportFileSink(args) {
18
+ const configuredOpener = apiMakerConfig.getExportFileSinkOpener();
19
+ if (configuredOpener)
20
+ return await configuredOpener(args);
21
+ if (Platform.OS === "web")
22
+ return await openWebFileSink(args);
23
+ throw new Error("No export file sink configured for this platform. On React Native/Expo, call " +
24
+ "apiMakerConfig.setExportFileSinkOpener(...) (e.g. using expo-file-system + expo-sharing).");
25
+ }
26
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3Blbi1leHBvcnQtZmlsZS1zaW5rLmpzIiwic291cmNlUm9vdCI6Ii9zcmMvIiwic291cmNlcyI6WyJ0YWJsZS9leHBvcnQvb3Blbi1leHBvcnQtZmlsZS1zaW5rLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLFlBQVk7QUFDWixPQUFPLEVBQUMsUUFBUSxFQUFDLE1BQU0sY0FBYyxDQUFBO0FBQ3JDLE9BQU8sY0FBYyxNQUFNLGlCQUFpQixDQUFBO0FBQzVDLE9BQU8sZUFBZSxNQUFNLCtCQUErQixDQUFBO0FBRTNELHVGQUF1RjtBQUV2Rjs7Ozs7Ozs7OztHQVVHO0FBQ0gsTUFBTSxDQUFDLE9BQU8sQ0FBQyxLQUFLLFVBQVUsa0JBQWtCLENBQUMsSUFBSTtJQUNuRCxNQUFNLGdCQUFnQixHQUFHLGNBQWMsQ0FBQyx1QkFBdUIsRUFBRSxDQUFBO0lBRWpFLElBQUksZ0JBQWdCO1FBQUUsT0FBTyxNQUFNLGdCQUFnQixDQUFDLElBQUksQ0FBQyxDQUFBO0lBQ3pELElBQUksUUFBUSxDQUFDLEVBQUUsS0FBSyxLQUFLO1FBQUUsT0FBTyxNQUFNLGVBQWUsQ0FBQyxJQUFJLENBQUMsQ0FBQTtJQUU3RCxNQUFNLElBQUksS0FBSyxDQUNiLCtFQUErRTtRQUMvRSwyRkFBMkYsQ0FDNUYsQ0FBQTtBQUNILENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBAdHMtY2hlY2tcbmltcG9ydCB7UGxhdGZvcm19IGZyb20gXCJyZWFjdC1uYXRpdmVcIlxuaW1wb3J0IGFwaU1ha2VyQ29uZmlnIGZyb20gXCIuLi8uLi9jb25maWcuanNcIlxuaW1wb3J0IG9wZW5XZWJGaWxlU2luayBmcm9tIFwiLi9maWxlLXNpbmtzL3dlYi1maWxlLXNpbmsuanNcIlxuXG4vKiogQHR5cGVkZWYge2ltcG9ydChcIi4vZmlsZS1zaW5rcy93ZWItZmlsZS1zaW5rLmpzXCIpLkV4cG9ydEZpbGVTaW5rfSBFeHBvcnRGaWxlU2luayAqL1xuXG4vKipcbiAqIE9wZW5zIGEgZmlsZSBzaW5rIGZvciBhbiBleHBvcnQsIGFic3RyYWN0aW5nIG92ZXIgcGxhdGZvcm1zLiBBIGhvc3QtY29uZmlndXJlZCBvcGVuZXIgKGUuZy4gYW5cbiAqIGV4cG8tZmlsZS1zeXN0ZW0vZXhwby1zaGFyaW5nIGltcGxlbWVudGF0aW9uIG9uIFJlYWN0IE5hdGl2ZSkgdGFrZXMgcHJlY2VkZW5jZTsgb3RoZXJ3aXNlIHRoZSBidWlsdC1pbiB3ZWJcbiAqIHNpbmsgaXMgdXNlZC4gT24gbmF0aXZlIHdpdGhvdXQgYSBjb25maWd1cmVkIG9wZW5lciB0aGlzIHRocm93cyB3aXRoIGd1aWRhbmNlLlxuICpcbiAqIEBwYXJhbSB7b2JqZWN0fSBhcmdzXG4gKiBAcGFyYW0ge3N0cmluZ30gYXJncy5maWxlTmFtZVxuICogQHBhcmFtIHtzdHJpbmd9IGFyZ3MubWltZVR5cGVcbiAqIEBwYXJhbSB7c3RyaW5nfSBhcmdzLmZvcm1hdFxuICogQHJldHVybnMge1Byb21pc2U8RXhwb3J0RmlsZVNpbms+fVxuICovXG5leHBvcnQgZGVmYXVsdCBhc3luYyBmdW5jdGlvbiBvcGVuRXhwb3J0RmlsZVNpbmsoYXJncykge1xuICBjb25zdCBjb25maWd1cmVkT3BlbmVyID0gYXBpTWFrZXJDb25maWcuZ2V0RXhwb3J0RmlsZVNpbmtPcGVuZXIoKVxuXG4gIGlmIChjb25maWd1cmVkT3BlbmVyKSByZXR1cm4gYXdhaXQgY29uZmlndXJlZE9wZW5lcihhcmdzKVxuICBpZiAoUGxhdGZvcm0uT1MgPT09IFwid2ViXCIpIHJldHVybiBhd2FpdCBvcGVuV2ViRmlsZVNpbmsoYXJncylcblxuICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgXCJObyBleHBvcnQgZmlsZSBzaW5rIGNvbmZpZ3VyZWQgZm9yIHRoaXMgcGxhdGZvcm0uIE9uIFJlYWN0IE5hdGl2ZS9FeHBvLCBjYWxsIFwiICtcbiAgICBcImFwaU1ha2VyQ29uZmlnLnNldEV4cG9ydEZpbGVTaW5rT3BlbmVyKC4uLikgKGUuZy4gdXNpbmcgZXhwby1maWxlLXN5c3RlbSArIGV4cG8tc2hhcmluZykuXCJcbiAgKVxufVxuIl19
@@ -0,0 +1,80 @@
1
+ /** Thrown when the user cancels an in-progress export. */
2
+ export class ApiMakerTableExportAbortedError extends Error {
3
+ }
4
+ /**
5
+ * Streams a table's whole result set to a file, fetching it page-by-page and writing each page straight to a
6
+ * file sink, so only one page (plus the format writer's own buffering) is ever held in memory.
7
+ *
8
+ * @typedef {object} ExporterArgs
9
+ * @property {number} [batchSize]
10
+ * @property {"csv" | "html" | "xlsx"} format
11
+ * @property {(format: string, value: Date) => string} l
12
+ * @property {(progress: {page: number, totalPages: number, written: number}) => void} [onProgress]
13
+ * @property {object} table
14
+ */
15
+ export default class ApiMakerTableExporter {
16
+ /** @param {ExporterArgs} args */
17
+ constructor({ batchSize, format, l, onProgress, table }: ExporterArgs);
18
+ batchSize: number;
19
+ format: "html" | "csv" | "xlsx";
20
+ l: (format: string, value: Date) => string;
21
+ onProgress: (progress: {
22
+ page: number;
23
+ totalPages: number;
24
+ written: number;
25
+ }) => void;
26
+ table: any;
27
+ aborted: boolean;
28
+ abort(): void;
29
+ /** @returns {Promise<{written: number}>} */
30
+ run(): Promise<{
31
+ written: number;
32
+ }>;
33
+ /** @returns {Array<{column: object, tableSettingColumn: object}>} */
34
+ visibleColumns(): Array<{
35
+ column: object;
36
+ tableSettingColumn: object;
37
+ }>;
38
+ /**
39
+ * @param {{column: object}} preparedColumn
40
+ * @param {object} model
41
+ * @returns {unknown}
42
+ */
43
+ cellValue(preparedColumn: {
44
+ column: object;
45
+ }, model: object): unknown;
46
+ /** @returns {string} */
47
+ modelName(): string;
48
+ baseQuery(): any;
49
+ /**
50
+ * @param {{write: (chunk: string | Uint8Array) => Promise<void>}} sink
51
+ * @param {string | Uint8Array | null | undefined} chunk
52
+ * @returns {Promise<void>}
53
+ */
54
+ writeChunk(sink: {
55
+ write: (chunk: string | Uint8Array) => Promise<void>;
56
+ }, chunk: string | Uint8Array | null | undefined): Promise<void>;
57
+ /**
58
+ * @param {{abort: () => Promise<void>}} sink
59
+ * @returns {Promise<void>}
60
+ */
61
+ abortSink(sink: {
62
+ abort: () => Promise<void>;
63
+ }): Promise<void>;
64
+ }
65
+ /**
66
+ * Streams a table's whole result set to a file, fetching it page-by-page and writing each page straight to a
67
+ * file sink, so only one page (plus the format writer's own buffering) is ever held in memory.
68
+ */
69
+ export type ExporterArgs = {
70
+ batchSize?: number;
71
+ format: "csv" | "html" | "xlsx";
72
+ l: (format: string, value: Date) => string;
73
+ onProgress?: (progress: {
74
+ page: number;
75
+ totalPages: number;
76
+ written: number;
77
+ }) => void;
78
+ table: object;
79
+ };
80
+ //# sourceMappingURL=table-exporter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"table-exporter.d.ts","sourceRoot":"/src/","sources":["table/export/table-exporter.js"],"names":[],"mappings":"AAkBA,0DAA0D;AAC1D;CAA6D;AAE7D;;;;;;;;;;GAUG;AACH;IACE,iCAAiC;IACjC,yDADY,YAAY,EAQvB;IANC,kBAA0B;IAC1B,gCAAoB;IACpB,YATmB,MAAM,SAAS,IAAI,KAAK,MAAM,CASvC;IACV,uBATqB;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAC,KAAK,IAAI,CASrD;IAC5B,WAAkB;IAClB,iBAAoB;IAGtB,cAEC;IAED,4CAA4C;IAC5C,OADc,OAAO,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAC,CAAC,CA4DvC;IAED,qEAAqE;IACrE,kBADc,KAAK,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,kBAAkB,EAAE,MAAM,CAAA;KAAC,CAAC,CAKhE;IAED;;;;OAIG;IACH,0BAJW;QAAC,MAAM,EAAE,MAAM,CAAA;KAAC,SAChB,MAAM,GACJ,OAAO,CAInB;IAED,wBAAwB;IACxB,aADc,MAAM,CAGnB;IAED,iBAEC;IAED;;;;OAIG;IACH,iBAJW;QAAC,KAAK,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,UAAU,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;KAAC,SACtD,MAAM,GAAG,UAAU,GAAG,IAAI,GAAG,SAAS,GACpC,OAAO,CAAC,IAAI,CAAC,CAOzB;IAED;;;OAGG;IACH,gBAHW;QAAC,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;KAAC,GAC1B,OAAO,CAAC,IAAI,CAAC,CAQzB;CACF;;;;;;gBAnIa,MAAM;YACN,KAAK,GAAG,MAAM,GAAG,MAAM;OACvB,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,KAAK,MAAM;iBACvC,CAAC,QAAQ,EAAE;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAC,KAAK,IAAI;WACvE,MAAM"}
@@ -0,0 +1,141 @@
1
+ // @ts-check
2
+ // The export is intentionally sequential: each page is fetched and written before the next so only one page
3
+ // is ever in memory. That requires awaiting inside the paging loop.
4
+ /* eslint-disable no-await-in-loop, sort-imports */
5
+ import { digg } from "diggerize";
6
+ import columnVisible from "../column-visible.js";
7
+ import ColumnContent from "../column-content";
8
+ import CsvWriter from "./format-writers/csv-writer.js";
9
+ import HtmlWriter from "./format-writers/html-writer.js";
10
+ import openExportFileSink from "./open-export-file-sink.js";
11
+ import XlsxWriter from "./format-writers/xlsx-writer.js";
12
+ const FORMATS = {
13
+ csv: { extension: "csv", mimeType: "text/csv;charset=utf-8", Writer: CsvWriter },
14
+ html: { extension: "html", mimeType: "text/html;charset=utf-8", Writer: HtmlWriter },
15
+ xlsx: { extension: "xlsx", mimeType: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", Writer: XlsxWriter }
16
+ };
17
+ /** Thrown when the user cancels an in-progress export. */
18
+ export class ApiMakerTableExportAbortedError extends Error {
19
+ }
20
+ /**
21
+ * Streams a table's whole result set to a file, fetching it page-by-page and writing each page straight to a
22
+ * file sink, so only one page (plus the format writer's own buffering) is ever held in memory.
23
+ *
24
+ * @typedef {object} ExporterArgs
25
+ * @property {number} [batchSize]
26
+ * @property {"csv" | "html" | "xlsx"} format
27
+ * @property {(format: string, value: Date) => string} l
28
+ * @property {(progress: {page: number, totalPages: number, written: number}) => void} [onProgress]
29
+ * @property {object} table
30
+ */
31
+ export default class ApiMakerTableExporter {
32
+ /** @param {ExporterArgs} args */
33
+ constructor({ batchSize = 1000, format, l, onProgress, table }) {
34
+ this.batchSize = batchSize;
35
+ this.format = format;
36
+ this.l = l;
37
+ this.onProgress = onProgress;
38
+ this.table = table;
39
+ this.aborted = false;
40
+ }
41
+ abort() {
42
+ this.aborted = true;
43
+ }
44
+ /** @returns {Promise<{written: number}>} */
45
+ async run() {
46
+ const formatConfig = FORMATS[this.format];
47
+ if (!formatConfig)
48
+ throw new Error(`Unknown export format: ${this.format}`);
49
+ const writer = new formatConfig.Writer();
50
+ const columns = this.visibleColumns();
51
+ const labels = columns.map((preparedColumn) => this.table.headerLabelForColumn(preparedColumn.column));
52
+ const fileName = `${this.modelName()}.${formatConfig.extension}`;
53
+ const sink = await openExportFileSink({ fileName, format: this.format, mimeType: formatConfig.mimeType });
54
+ let written = 0;
55
+ try {
56
+ await this.writeChunk(sink, writer.header(labels));
57
+ let page = 1;
58
+ let totalPages = 1;
59
+ do {
60
+ const result = await this.baseQuery()
61
+ .clone()
62
+ .page(page)
63
+ .per(this.batchSize)
64
+ .result();
65
+ if (page === 1)
66
+ totalPages = result.totalPages();
67
+ let buffer = "";
68
+ for (const model of result.models()) {
69
+ if (this.aborted)
70
+ throw new ApiMakerTableExportAbortedError("Export aborted");
71
+ const values = columns.map((preparedColumn) => this.cellValue(preparedColumn, model));
72
+ const chunk = writer.row(values);
73
+ if (typeof chunk === "string") {
74
+ buffer += chunk;
75
+ }
76
+ else if (chunk !== null && chunk !== undefined) {
77
+ await this.writeChunk(sink, chunk);
78
+ }
79
+ written += 1;
80
+ }
81
+ if (buffer.length > 0)
82
+ await sink.write(buffer);
83
+ if (this.onProgress)
84
+ this.onProgress({ page, totalPages, written });
85
+ page += 1;
86
+ } while (page <= totalPages);
87
+ await this.writeChunk(sink, await writer.footer());
88
+ await sink.close();
89
+ return { written };
90
+ }
91
+ catch (error) {
92
+ await this.abortSink(sink);
93
+ throw error;
94
+ }
95
+ }
96
+ /** @returns {Array<{column: object, tableSettingColumn: object}>} */
97
+ visibleColumns() {
98
+ const preparedColumns = this.table.s.preparedColumns || [];
99
+ return preparedColumns.filter(({ column, tableSettingColumn }) => columnVisible(column, tableSettingColumn));
100
+ }
101
+ /**
102
+ * @param {{column: object}} preparedColumn
103
+ * @param {object} model
104
+ * @returns {unknown}
105
+ */
106
+ cellValue(preparedColumn, model) {
107
+ return new ColumnContent({ column: preparedColumn.column, l: this.l, mode: "html", model, table: this.table }).content();
108
+ }
109
+ /** @returns {string} */
110
+ modelName() {
111
+ return this.table.p.modelClass.modelName().human({ count: 2 });
112
+ }
113
+ baseQuery() {
114
+ return digg(this.table.tt.collection, "query");
115
+ }
116
+ /**
117
+ * @param {{write: (chunk: string | Uint8Array) => Promise<void>}} sink
118
+ * @param {string | Uint8Array | null | undefined} chunk
119
+ * @returns {Promise<void>}
120
+ */
121
+ async writeChunk(sink, chunk) {
122
+ if (chunk === null || chunk === undefined)
123
+ return;
124
+ if (typeof chunk === "string" && chunk.length === 0)
125
+ return;
126
+ await sink.write(chunk);
127
+ }
128
+ /**
129
+ * @param {{abort: () => Promise<void>}} sink
130
+ * @returns {Promise<void>}
131
+ */
132
+ async abortSink(sink) {
133
+ try {
134
+ await sink.abort();
135
+ }
136
+ catch {
137
+ // Ignore secondary errors while cleaning up after a failed/aborted export.
138
+ }
139
+ }
140
+ }
141
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGFibGUtZXhwb3J0ZXIuanMiLCJzb3VyY2VSb290IjoiL3NyYy8iLCJzb3VyY2VzIjpbInRhYmxlL2V4cG9ydC90YWJsZS1leHBvcnRlci5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxZQUFZO0FBQ1osNEdBQTRHO0FBQzVHLG9FQUFvRTtBQUNwRSxtREFBbUQ7QUFDbkQsT0FBTyxFQUFDLElBQUksRUFBQyxNQUFNLFdBQVcsQ0FBQTtBQUM5QixPQUFPLGFBQWEsTUFBTSxzQkFBc0IsQ0FBQTtBQUNoRCxPQUFPLGFBQWEsTUFBTSxtQkFBbUIsQ0FBQTtBQUM3QyxPQUFPLFNBQVMsTUFBTSxnQ0FBZ0MsQ0FBQTtBQUN0RCxPQUFPLFVBQVUsTUFBTSxpQ0FBaUMsQ0FBQTtBQUN4RCxPQUFPLGtCQUFrQixNQUFNLDRCQUE0QixDQUFBO0FBQzNELE9BQU8sVUFBVSxNQUFNLGlDQUFpQyxDQUFBO0FBRXhELE1BQU0sT0FBTyxHQUFHO0lBQ2QsR0FBRyxFQUFFLEVBQUMsU0FBUyxFQUFFLEtBQUssRUFBRSxRQUFRLEVBQUUsd0JBQXdCLEVBQUUsTUFBTSxFQUFFLFNBQVMsRUFBQztJQUM5RSxJQUFJLEVBQUUsRUFBQyxTQUFTLEVBQUUsTUFBTSxFQUFFLFFBQVEsRUFBRSx5QkFBeUIsRUFBRSxNQUFNLEVBQUUsVUFBVSxFQUFDO0lBQ2xGLElBQUksRUFBRSxFQUFDLFNBQVMsRUFBRSxNQUFNLEVBQUUsUUFBUSxFQUFFLG1FQUFtRSxFQUFFLE1BQU0sRUFBRSxVQUFVLEVBQUM7Q0FDN0gsQ0FBQTtBQUVELDBEQUEwRDtBQUMxRCxNQUFNLE9BQU8sK0JBQWdDLFNBQVEsS0FBSztDQUFHO0FBRTdEOzs7Ozs7Ozs7O0dBVUc7QUFDSCxNQUFNLENBQUMsT0FBTyxPQUFPLHFCQUFxQjtJQUN4QyxpQ0FBaUM7SUFDakMsWUFBWSxFQUFDLFNBQVMsR0FBRyxJQUFJLEVBQUUsTUFBTSxFQUFFLENBQUMsRUFBRSxVQUFVLEVBQUUsS0FBSyxFQUFDO1FBQzFELElBQUks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RUFBRSxJQUFJLENBQUMsQ0FBQyxFQUFFLElBQUksRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxJQUFJLENBQUMsS0FBSyxFQUFDLENBQUMsQ0FBQyxPQUFPLEVBQUUsQ0FBQTtJQUN4SCxDQUFDO0lBRUQsd0JBQXdCO0lBQ3hCLFNBQVM7UUFDUCxPQUFPLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxTQUFTLEVBQUUsQ0FBQyxLQUFLLENBQUMsRUFBQyxLQUFLLEVBQUUsQ0FBQyxFQUFDLENBQUMsQ0FBQTtJQUM5RCxDQUFDO0lBRUQsU0FBUztRQUNQLE9BQU8sSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLFVBQVUsRUFBRSxPQUFPLENBQUMsQ0FBQTtJQUNoRCxDQUFDO0lBRUQ7Ozs7T0FJRztJQUNILEtBQUssQ0FBQyxVQUFVLENBQUMsSUFBSSxFQUFFLEtBQUs7UUFDMUIsSUFBSSxLQUFLLEtBQUssSUFBSSxJQUFJLEtBQUssS0FBSyxTQUFTO1lBQUUsT0FBTTtRQUNqRCxJQUFJLE9BQU8sS0FBSyxLQUFLLFFBQVEsSUFBSSxLQUFLLENBQUMsTUFBTSxLQUFLLENBQUM7WUFBRSxPQUFNO1FBRTNELE1BQU0sSUFBSSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQTtJQUN6QixDQUFDO0lBRUQ7OztPQUdHO0lBQ0gsS0FBSyxDQUFDLFNBQVMsQ0FBQyxJQUFJO1FBQ2xCLElBQUksQ0FBQztZQUNILE1BQU0sSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFBO1FBQ3BCLENBQUM7UUFBQyxNQUFNLENBQUM7WUFDUCwyRUFBMkU7UUFDN0UsQ0FBQztJQUNILENBQUM7Q0FDRiIsInNvdXJjZXNDb250ZW50IjpbIi8vIEB0cy1jaGVja1xuLy8gVGhlIGV4cG9ydCBpcyBpbnRlbnRpb25hbGx5IHNlcXVlbnRpYWw6IGVhY2ggcGFnZSBpcyBmZXRjaGVkIGFuZCB3cml0dGVuIGJlZm9yZSB0aGUgbmV4dCBzbyBvbmx5IG9uZSBwYWdlXG4vLyBpcyBldmVyIGluIG1lbW9yeS4gVGhhdCByZXF1aXJlcyBhd2FpdGluZyBpbnNpZGUgdGhlIHBhZ2luZyBsb29wLlxuLyogZXNsaW50LWRpc2FibGUgbm8tYXdhaXQtaW4tbG9vcCwgc29ydC1pbXBvcnRzICovXG5pbXBvcnQge2RpZ2d9IGZyb20gXCJkaWdnZXJpemVcIlxuaW1wb3J0IGNvbHVtblZpc2libGUgZnJvbSBcIi4uL2NvbHVtbi12aXNpYmxlLmpzXCJcbmltcG9ydCBDb2x1bW5Db250ZW50IGZyb20gXCIuLi9jb2x1bW4tY29udGVudFwiXG5pbXBvcnQgQ3N2V3JpdGVyIGZyb20gXCIuL2Zvcm1hdC13cml0ZXJzL2Nzdi13cml0ZXIuanNcIlxuaW1wb3J0IEh0bWxXcml0ZXIgZnJvbSBcIi4vZm9ybWF0LXdyaXRlcnMvaHRtbC13cml0ZXIuanNcIlxuaW1wb3J0IG9wZW5FeHBvcnRGaWxlU2luayBmcm9tIFwiLi9vcGVuLWV4cG9ydC1maWxlLXNpbmsuanNcIlxuaW1wb3J0IFhsc3hXcml0ZXIgZnJvbSBcIi4vZm9ybWF0LXdyaXRlcnMveGxzeC13cml0ZXIuanNcIlxuXG5jb25zdCBGT1JNQVRTID0ge1xuICBjc3Y6IHtleHRlbnNpb246IFwiY3N2XCIsIG1pbWVUeXBlOiBcInRleHQvY3N2O2NoYXJzZXQ9dXRmLThcIiwgV3JpdGVyOiBDc3ZXcml0ZXJ9LFxuICBodG1sOiB7ZXh0ZW5zaW9uOiBcImh0bWxcIiwgbWltZVR5cGU6IFwidGV4dC9odG1sO2NoYXJzZXQ9dXRmLThcIiwgV3JpdGVyOiBIdG1sV3JpdGVyfSxcbiAgeGxzeDoge2V4dGVuc2lvbjogXCJ4bHN4XCIsIG1pbWVUeXBlOiBcImFwcGxpY2F0aW9uL3ZuZC5vcGVueG1sZm9ybWF0cy1vZmZpY2Vkb2N1bWVudC5zcHJlYWRzaGVldG1sLnNoZWV0XCIsIFdyaXRlcjogWGxzeFdyaXRlcn1cbn1cblxuLyoqIFRocm93biB3aGVuIHRoZSB1c2VyIGNhbmNlbHMgYW4gaW4tcHJvZ3Jlc3MgZXhwb3J0LiAqL1xuZXhwb3J0IGNsYXNzIEFwaU1ha2VyVGFibGVFeHBvcnRBYm9ydGVkRXJyb3IgZXh0ZW5kcyBFcnJvciB7fVxuXG4vKipcbiAqIFN0cmVhbXMgYSB0YWJsZSdzIHdob2xlIHJlc3VsdCBzZXQgdG8gYSBmaWxlLCBmZXRjaGluZyBpdCBwYWdlLWJ5LXBhZ2UgYW5kIHdyaXRpbmcgZWFjaCBwYWdlIHN0cmFpZ2h0IHRvIGFcbiAqIGZpbGUgc2luaywgc28gb25seSBvbmUgcGFnZSAocGx1cyB0aGUgZm9ybWF0IHdyaXRlcidzIG93biBidWZmZXJpbmcpIGlzIGV2ZXIgaGVsZCBpbiBtZW1vcnkuXG4gKlxuICogQHR5cGVkZWYge29iamVjdH0gRXhwb3J0ZXJBcmdzXG4gKiBAcHJvcGVydHkge251bWJlcn0gW2JhdGNoU2l6ZV1cbiAqIEBwcm9wZXJ0eSB7XCJjc3ZcIiB8IFwiaHRtbFwiIHwgXCJ4bHN4XCJ9IGZvcm1hdFxuICogQHByb3BlcnR5IHsoZm9ybWF0OiBzdHJpbmcsIHZhbHVlOiBEYXRlKSA9PiBzdHJpbmd9IGxcbiAqIEBwcm9wZXJ0eSB7KHByb2dyZXNzOiB7cGFnZTogbnVtYmVyLCB0b3RhbFBhZ2VzOiBudW1iZXIsIHdyaXR0ZW46IG51bWJlcn0pID0+IHZvaWR9IFtvblByb2dyZXNzXVxuICogQHByb3BlcnR5IHtvYmplY3R9IHRhYmxlXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIEFwaU1ha2VyVGFibGVFeHBvcnRlciB7XG4gIC8qKiBAcGFyYW0ge0V4cG9ydGVyQXJnc30gYXJncyAqL1xuICBjb25zdHJ1Y3Rvcih7YmF0Y2hTaXplID0gMTAwMCwgZm9ybWF0LCBsLCBvblByb2dyZXNzLCB0YWJsZX0pIHtcbiAgICB0aGlzLmJhdGNoU2l6ZSA9IGJhdGNoU2l6ZVxuICAgIHRoaXMuZm9ybWF0ID0gZm9ybWF0XG4gICAgdGhpcy5sID0gbFxuICAgIHRoaXMub25Qcm9ncmVzcyA9IG9uUHJvZ3Jlc3NcbiAgICB0aGlzLnRhYmxlID0gdGFibGVcbiAgICB0aGlzLmFib3J0ZWQgPSBmYWxzZVxuICB9XG5cbiAgYWJvcnQoKSB7XG4gICAgdGhpcy5hYm9ydGVkID0gdHJ1ZVxuICB9XG5cbiAgLyoqIEByZXR1cm5zIHtQcm9taXNlPHt3cml0dGVuOiBudW1iZXJ9Pn0gKi9cbiAgYXN5bmMgcnVuKCkge1xuICAgIGNvbnN0IGZvcm1hdENvbmZpZyA9IEZPUk1BVFNbdGhpcy5mb3JtYXRdXG5cbiAgICBpZiAoIWZvcm1hdENvbmZpZykgdGhyb3cgbmV3IEVycm9yKGBVbmtub3duIGV4cG9ydCBmb3JtYXQ6ICR7dGhpcy5mb3JtYXR9YClcblxuICAgIGNvbnN0IHdyaXRlciA9IG5ldyBmb3JtYXRDb25maWcuV3JpdGVyKClcbiAgICBjb25zdCBjb2x1bW5zID0gdGhpcy52aXNpYmxlQ29sdW1ucygpXG4gICAgY29uc3QgbGFiZWxzID0gY29sdW1ucy5tYXAoKHByZXBhcmVkQ29sdW1uKSA9PiB0aGlzLnRhYmxlLmhlYWRlckxhYmVsRm9yQ29sdW1uKHByZXBhcmVkQ29sdW1uLmNvbHVtbikpXG4gICAgY29uc3QgZmlsZU5hbWUgPSBgJHt0aGlzLm1vZGVsTmFtZSgpfS4ke2Zvcm1hdENvbmZpZy5leHRlbnNpb259YFxuICAgIGNvbnN0IHNpbmsgPSBhd2FpdCBvcGVuRXhwb3J0RmlsZVNpbmsoe2ZpbGVOYW1lLCBmb3JtYXQ6IHRoaXMuZm9ybWF0LCBtaW1lVHlwZTogZm9ybWF0Q29uZmlnLm1pbWVUeXBlfSlcbiAgICBsZXQgd3JpdHRlbiA9IDBcblxuICAgIHRyeSB7XG4gICAgICBhd2FpdCB0aGlzLndyaXRlQ2h1bmsoc2luaywgd3JpdGVyLmhlYWRlcihsYWJlbHMpKVxuXG4gICAgICBsZXQgcGFnZSA9IDFcbiAgICAgIGxldCB0b3RhbFBhZ2VzID0gMVxuXG4gICAgICBkbyB7XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHRoaXMuYmFzZVF1ZXJ5KClcbiAgICAgICAgICAuY2xvbmUoKVxuICAgICAgICAgIC5wYWdlKHBhZ2UpXG4gICAgICAgICAgLnBlcih0aGlzLmJhdGNoU2l6ZSlcbiAgICAgICAgICAucmVzdWx0KClcblxuICAgICAgICBpZiAocGFnZSA9PT0gMSkgdG90YWxQYWdlcyA9IHJlc3VsdC50b3RhbFBhZ2VzKClcblxuICAgICAgICBsZXQgYnVmZmVyID0gXCJcIlxuXG4gICAgICAgIGZvciAoY29uc3QgbW9kZWwgb2YgcmVzdWx0Lm1vZGVscygpKSB7XG4gICAgICAgICAgaWYgKHRoaXMuYWJvcnRlZCkgdGhyb3cgbmV3IEFwaU1ha2VyVGFibGVFeHBvcnRBYm9ydGVkRXJyb3IoXCJFeHBvcnQgYWJvcnRlZFwiKVxuXG4gICAgICAgICAgY29uc3QgdmFsdWVzID0gY29sdW1ucy5tYXAoKHByZXBhcmVkQ29sdW1uKSA9PiB0aGlzLmNlbGxWYWx1ZShwcmVwYXJlZENvbHVtbiwgbW9kZWwpKVxuICAgICAgICAgIGNvbnN0IGNodW5rID0gd3JpdGVyLnJvdyh2YWx1ZXMpXG5cbiAgICAgICAgICBpZiAodHlwZW9mIGNodW5rID09PSBcInN0cmluZ1wiKSB7XG4gICAgICAgICAgICBidWZmZXIgKz0gY2h1bmtcbiAgICAgICAgICB9IGVsc2UgaWYgKGNodW5rICE9PSBudWxsICYmIGNodW5rICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIGF3YWl0IHRoaXMud3JpdGVDaHVuayhzaW5rLCBjaHVuaylcbiAgICAgICAgICB9XG5cbiAgICAgICAgICB3cml0dGVuICs9IDFcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChidWZmZXIubGVuZ3RoID4gMCkgYXdhaXQgc2luay53cml0ZShidWZmZXIpXG4gICAgICAgIGlmICh0aGlzLm9uUHJvZ3Jlc3MpIHRoaXMub25Qcm9ncmVzcyh7cGFnZSwgdG90YWxQYWdlcywgd3JpdHRlbn0pXG5cbiAgICAgICAgcGFnZSArPSAxXG4gICAgICB9IHdoaWxlIChwYWdlIDw9IHRvdGFsUGFnZXMpXG5cbiAgICAgIGF3YWl0IHRoaXMud3JpdGVDaHVuayhzaW5rLCBhd2FpdCB3cml0ZXIuZm9vdGVyKCkpXG4gICAgICBhd2FpdCBzaW5rLmNsb3NlKClcblxuICAgICAgcmV0dXJuIHt3cml0dGVufVxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBhd2FpdCB0aGlzLmFib3J0U2luayhzaW5rKVxuXG4gICAgICB0aHJvdyBlcnJvclxuICAgIH1cbiAgfVxuXG4gIC8qKiBAcmV0dXJucyB7QXJyYXk8e2NvbHVtbjogb2JqZWN0LCB0YWJsZVNldHRpbmdDb2x1bW46IG9iamVjdH0+fSAqL1xuICB2aXNpYmxlQ29sdW1ucygpIHtcbiAgICBjb25zdCBwcmVwYXJlZENvbHVtbnMgPSB0aGlzLnRhYmxlLnMucHJlcGFyZWRDb2x1bW5zIHx8IFtdXG5cbiAgICByZXR1cm4gcHJlcGFyZWRDb2x1bW5zLmZpbHRlcigoe2NvbHVtbiwgdGFibGVTZXR0aW5nQ29sdW1ufSkgPT4gY29sdW1uVmlzaWJsZShjb2x1bW4sIHRhYmxlU2V0dGluZ0NvbHVtbikpXG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHt7Y29sdW1uOiBvYmplY3R9fSBwcmVwYXJlZENvbHVtblxuICAgKiBAcGFyYW0ge29iamVjdH0gbW9kZWxcbiAgICogQHJldHVybnMge3Vua25vd259XG4gICAqL1xuICBjZWxsVmFsdWUocHJlcGFyZWRDb2x1bW4sIG1vZGVsKSB7XG4gICAgcmV0dXJuIG5ldyBDb2x1bW5Db250ZW50KHtjb2x1bW46IHByZXBhcmVkQ29sdW1uLmNvbHVtbiwgbDogdGhpcy5sLCBtb2RlOiBcImh0bWxcIiwgbW9kZWwsIHRhYmxlOiB0aGlzLnRhYmxlfSkuY29udGVudCgpXG4gIH1cblxuICAvKiogQHJldHVybnMge3N0cmluZ30gKi9cbiAgbW9kZWxOYW1lKCkge1xuICAgIHJldHVybiB0aGlzLnRhYmxlLnAubW9kZWxDbGFzcy5tb2RlbE5hbWUoKS5odW1hbih7Y291bnQ6IDJ9KVxuICB9XG5cbiAgYmFzZVF1ZXJ5KCkge1xuICAgIHJldHVybiBkaWdnKHRoaXMudGFibGUudHQuY29sbGVjdGlvbiwgXCJxdWVyeVwiKVxuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7e3dyaXRlOiAoY2h1bms6IHN0cmluZyB8IFVpbnQ4QXJyYXkpID0+IFByb21pc2U8dm9pZD59fSBzaW5rXG4gICAqIEBwYXJhbSB7c3RyaW5nIHwgVWludDhBcnJheSB8IG51bGwgfCB1bmRlZmluZWR9IGNodW5rXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fVxuICAgKi9cbiAgYXN5bmMgd3JpdGVDaHVuayhzaW5rLCBjaHVuaykge1xuICAgIGlmIChjaHVuayA9PT0gbnVsbCB8fCBjaHVuayA9PT0gdW5kZWZpbmVkKSByZXR1cm5cbiAgICBpZiAodHlwZW9mIGNodW5rID09PSBcInN0cmluZ1wiICYmIGNodW5rLmxlbmd0aCA9PT0gMCkgcmV0dXJuXG5cbiAgICBhd2FpdCBzaW5rLndyaXRlKGNodW5rKVxuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7e2Fib3J0OiAoKSA9PiBQcm9taXNlPHZvaWQ+fX0gc2lua1xuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn1cbiAgICovXG4gIGFzeW5jIGFib3J0U2luayhzaW5rKSB7XG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IHNpbmsuYWJvcnQoKVxuICAgIH0gY2F0Y2gge1xuICAgICAgLy8gSWdub3JlIHNlY29uZGFyeSBlcnJvcnMgd2hpbGUgY2xlYW5pbmcgdXAgYWZ0ZXIgYSBmYWlsZWQvYWJvcnRlZCBleHBvcnQuXG4gICAgfVxuICB9XG59XG4iXX0=
@@ -1,9 +1,16 @@
1
1
  declare const _default: React.NamedExoticComponent<Record<string, any>>;
2
2
  export default _default;
3
+ /**
4
+ * Streams the whole table result set to a file (CSV / HTML / Excel) instead of building one big string in
5
+ * memory. Excel is only offered when the host app has registered an xlsx serializer via
6
+ * apiMakerConfig.setExportXlsxSerializer.
7
+ */
3
8
  export type Props = {
4
9
  l: Function;
5
10
  table: object;
6
11
  };
7
- export type State = Record<string, never>;
12
+ export type State = {
13
+ exporting: boolean;
14
+ };
8
15
  import React from "react";
9
16
  //# sourceMappingURL=download-action.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"download-action.d.ts","sourceRoot":"/src/","sources":["table/settings/download-action.jsx"],"names":[],"mappings":";;;;WAmBc,MAAM;;oBAEN,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC;kBAXjB,OAAO"}
1
+ {"version":3,"file":"download-action.d.ts","sourceRoot":"/src/","sources":["table/settings/download-action.jsx"],"names":[],"mappings":";;;;;;;;;WAsBc,MAAM;;oBAEN;IAAC,SAAS,EAAE,OAAO,CAAA;CAAC;kBAbhB,OAAO"}
@@ -1,46 +1,73 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  // @ts-check
3
- /* eslint-disable implicit-arrow-linebreak, react/jsx-no-literals, sort-imports */
4
- import ColumnContent from "../column-content";
5
- import columnIdentifier from "../column-identifier.js";
6
- import columnVisible from "../column-visible.js";
7
- import { saveAs } from "file-saver";
3
+ /* eslint-disable sort-imports */
4
+ import { ShapeComponent, shapeComponent } from "set-state-compare/build/shape-component.js";
5
+ import { FlashNotifications } from "flash-notifications";
6
+ import { Pressable, View } from "react-native";
7
+ import apiMakerConfig from "../../config.js";
8
+ import ApiMakerTableExporter, { ApiMakerTableExportAbortedError } from "../export/table-exporter";
8
9
  import Icon from "../../utils/icon";
9
10
  import memo from "set-state-compare/build/memo.js";
10
11
  import PropTypes from "prop-types";
11
12
  import propTypesExact from "prop-types-exact";
12
13
  import React from "react";
13
- import { renderToString } from "react-dom/server"; // eslint-disable-line import/no-unresolved
14
- import { ShapeComponent, shapeComponent } from "set-state-compare/build/shape-component.js";
15
- import { Pressable } from "react-native";
16
14
  import Text from "../../utils/text";
15
+ import useI18n from "i18n-on-steroids/build/src/use-i18n.js";
17
16
  /**
17
+ * Streams the whole table result set to a file (CSV / HTML / Excel) instead of building one big string in
18
+ * memory. Excel is only offered when the host app has registered an xlsx serializer via
19
+ * apiMakerConfig.setExportXlsxSerializer.
20
+ *
18
21
  * @typedef {object} Props
19
22
  * @property {Function} l
20
23
  * @property {object} table
21
24
  */
22
- /** @typedef {Record<string, never>} State */
25
+ /** @typedef {{exporting: boolean}} State */
23
26
  export default memo(shapeComponent(/** @augments {ShapeComponent<Props, State>} */ class ApiMakerTableSettingsDownloadAction extends ShapeComponent {
24
27
  static propTypes = propTypesExact({
25
28
  l: PropTypes.func.isRequired,
26
29
  table: PropTypes.object.isRequired
27
30
  });
31
+ state = {
32
+ exporting: false
33
+ };
34
+ setup() {
35
+ const { t } = useI18n({ namespace: "js.api_maker.table.download_action" });
36
+ this.t = t;
37
+ }
28
38
  render() {
29
- return (_jsxs(Pressable, { dataSet: this.cache("pressableDataSet", { component: "api-maker/table/settings/download-action" }), onPress: this.tt.onDownloadPress, style: this.cache("pressableStyle", { flexDirection: "row", alignItems: "center" }), children: [_jsx(Icon, { name: "download", size: 20 }), _jsx(Text, { style: this.cache("textStyle", { marginLeft: 5 }), children: "Download" })] }));
39
+ const excelAvailable = Boolean(apiMakerConfig.getExportXlsxSerializer());
40
+ return (_jsxs(View, { dataSet: this.cache("rootViewDataSet", { component: "api-maker/table/settings/download-action" }), children: [_jsx(Text, { style: this.cache("labelStyle", { fontWeight: "bold", marginBottom: 4 }), children: this.t(".download", { defaultValue: "Download" }) }), this.formatButton({ format: "csv", label: "CSV", onPress: this.tt.onDownloadCsv }), this.formatButton({ format: "html", label: "HTML", onPress: this.tt.onDownloadHtml }), excelAvailable && this.formatButton({ format: "xlsx", label: "Excel", onPress: this.tt.onDownloadXlsx })] }));
41
+ }
42
+ /**
43
+ * @param {{format: "csv" | "html" | "xlsx", label: string, onPress: () => void}} args
44
+ * @returns {import("react").ReactNode}
45
+ */
46
+ formatButton({ format, label, onPress }) {
47
+ return (_jsxs(Pressable, { dataSet: this.cache(`download${format}DataSet`, { component: `api-maker/table/settings/download-action/${format}` }), disabled: this.s.exporting, onPress: onPress, style: this.cache("formatButtonStyle", { flexDirection: "row", alignItems: "center", paddingVertical: 3 }), testID: `download-action-${format}`, children: [_jsx(Icon, { name: "download", size: 18 }), _jsx(Text, { style: this.cache("formatLabelStyle", { marginLeft: 5 }), children: label })] }));
30
48
  }
31
- onDownloadPress = () => {
32
- const { l, table } = this.p;
33
- const { modelClass } = table.p;
34
- const { collection } = table.tt;
35
- const { models } = collection;
36
- const { preparedColumns } = table.s;
37
- const tableElement = (_jsxs("table", { children: [_jsx("thead", { children: _jsx("tr", { children: preparedColumns?.map(({ column, tableSettingColumn }) => columnVisible(column, tableSettingColumn) &&
38
- _jsx("th", { children: table.headerLabelForColumn(column) }, columnIdentifier(column))) }) }), _jsx("tbody", { children: models.map((model) => _jsx("tr", { children: preparedColumns?.map(({ column, tableSettingColumn }) => columnVisible(column, tableSettingColumn) &&
39
- _jsx("td", { children: new ColumnContent({ column, l, mode: "html", model, table }).content() }, columnIdentifier(column))) }, model.id())) })] }));
40
- const tableHTML = renderToString(tableElement);
41
- const blob = new Blob([tableHTML], { type: "text/html;charset=utf-8" });
42
- const fileName = `${modelClass.modelName().human({ count: 2 })}.html`;
43
- saveAs(blob, fileName);
49
+ onDownloadCsv = () => this.startExport("csv");
50
+ onDownloadHtml = () => this.startExport("html");
51
+ onDownloadXlsx = () => this.startExport("xlsx");
52
+ /** @param {"csv" | "html" | "xlsx"} format */
53
+ startExport = async (format) => {
54
+ if (this.s.exporting)
55
+ return;
56
+ this.s.exporting = true;
57
+ const exporter = new ApiMakerTableExporter({ format, l: this.p.l, table: this.p.table });
58
+ try {
59
+ await exporter.run();
60
+ }
61
+ catch (error) {
62
+ if (error instanceof ApiMakerTableExportAbortedError)
63
+ return;
64
+ if (error && /** @type {Error} */ (error).name === "AbortError")
65
+ return;
66
+ FlashNotifications.errorResponse(error);
67
+ }
68
+ finally {
69
+ this.s.exporting = false;
70
+ }
44
71
  };
45
72
  }));
46
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZG93bmxvYWQtYWN0aW9uLmpzIiwic291cmNlUm9vdCI6Ii9zcmMvIiwic291cmNlcyI6WyJ0YWJsZS9zZXR0aW5ncy9kb3dubG9hZC1hY3Rpb24uanN4Il0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSxZQUFZO0FBQ1osa0ZBQWtGO0FBQ2xGLE9BQU8sYUFBYSxNQUFNLG1CQUFtQixDQUFBO0FBQzdDLE9BQU8sZ0JBQWdCLE1BQU0seUJBQXlCLENBQUE7QUFDdEQsT0FBTyxhQUFhLE1BQU0sc0JBQXNCLENBQUE7QUFDaEQsT0FBTyxFQUFDLE1BQU0sRUFBQyxNQUFNLFlBQVksQ0FBQTtBQUNqQyxPQUFPLElBQUksTUFBTSxrQkFBa0IsQ0FBQTtBQUNuQyxPQUFPLElBQUksTUFBTSxpQ0FBaUMsQ0FBQTtBQUNsRCxPQUFPLFNBQVMsTUFBTSxZQUFZLENBQUE7QUFDbEMsT0FBTyxjQUFjLE1BQU0sa0JBQWtCLENBQUE7QUFDN0MsT0FBTyxLQUFLLE1BQU0sT0FBTyxDQUFBO0FBQ3pCLE9BQU8sRUFBQyxjQUFjLEVBQUMsTUFBTSxrQkFBa0IsQ0FBQSxDQUFDLDJDQUEyQztBQUMzRixPQUFPLEVBQUMsY0FBYyxFQUFFLGNBQWMsRUFBQyxNQUFNLDRDQUE0QyxDQUFBO0FBQ3pGLE9BQU8sRUFBQyxTQUFTLEVBQUMsTUFBTSxjQUFjLENBQUE7QUFDdEMsT0FBTyxJQUFJLE1BQU0sa0JBQWtCLENBQUE7QUFFbkM7Ozs7R0FJRztBQUNILDZDQUE2QztBQUM3QyxlQUFlLElBQUksQ0FBQyxjQUFjLENBQUMsK0NBQStDLENBQUMsTUFBTSxtQ0FBb0MsU0FBUSxjQUFjO0lBQ2pKLE1BQU0sQ0FBQyxTQUFTLEdBQUcsY0FBYyxDQUFDO1FBQ2hDLENBQUMsRUFBRSxTQUFTLENBQUMsSUFBSSxDQUFDLFVBQVU7UUFDNUIsS0FBSyxFQUFFLFNBQVMsQ0FBQyxNQUFNLENBQUMsVUFBVTtLQUNuQyxDQUFDLENBQUE7SUFFRixNQUFNO1FBQ0osT0FBTyxDQUNMLE1BQUMsU0FBUyxJQUNSLE9BQU8sRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLGtCQUFrQixFQUFFLEVBQUMsU0FBUyxFQUFFLDBDQUEwQyxFQUFDLENBQUMsRUFDaEcsT0FBTyxFQUFFLElBQUksQ0FBQyxFQUFFLENBQUMsZUFBZSxFQUNoQyxLQUFLLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxnQkFBZ0IsRUFBRSxFQUFDLGFBQWEsRUFBRSxLQUFLLEVBQUUsVUFBVSxFQUFFLFFBQVEsRUFBQyxDQUFDLGFBRWpGLEtBQUMsSUFBSSxJQUFDLElBQUksRUFBQyxVQUFVLEVBQUMsSUFBSSxFQUFFLEVBQUUsR0FBSSxFQUNsQyxLQUFDLElBQUksSUFBQyxLQUFLLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxXQUFXLEVBQUUsRUFBQyxVQUFVLEVBQUUsQ0FBQyxFQUFDLENBQUMseUJBRTlDLElBQ0csQ0FDYixDQUFBO0lBQ0gsQ0FBQztJQUVELGVBQWUsR0FBRyxHQUFHLEVBQUU7UUFDckIsTUFBTSxFQUFDLENBQUMsRUFBRSxLQUFLLEVBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFBO1FBQ3pCLE1BQU0sRUFBQyxVQUFVLEVBQUMsR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFBO1FBQzVCLE1BQU0sRUFBQyxVQUFVLEVBQUMsR0FBRyxLQUFLLENBQUMsRUFBRSxDQUFBO1FBQzdCLE1BQU0sRUFBQyxNQUFNLEVBQUMsR0FBRyxVQUFVLENBQUE7UUFDM0IsTUFBTSxFQUFDLGVBQWUsRUFBQyxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUE7UUFDakMsTUFBTSxZQUFZLEdBQUcsQ0FDbkIsNEJBQ0UsMEJBQ0UsdUJBQ0csZUFBZSxFQUFFLEdBQUcsQ0FBQyxDQUFDLEVBQUMsTUFBTSxFQUFFLGtCQUFrQixFQUFDLEVBQUUsRUFBRSxDQUFDLGFBQWEsQ0FBQyxNQUFNLEVBQUUsa0JBQWtCLENBQUM7NEJBQy9GLHVCQUNHLEtBQUssQ0FBQyxvQkFBb0IsQ0FBQyxNQUFNLENBQUMsSUFENUIsZ0JBQWdCLENBQUMsTUFBTSxDQUFDLENBRTVCLENBQ04sR0FDRSxHQUNDLEVBQ1IsMEJBQ0csTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQ3BCLHVCQUNHLGVBQWUsRUFBRSxHQUFHLENBQUMsQ0FBQyxFQUFDLE1BQU0sRUFBRSxrQkFBa0IsRUFBQyxFQUFFLEVBQUUsQ0FBQyxhQUFhLENBQUMsTUFBTSxFQUFFLGtCQUFrQixDQUFDOzRCQUMvRix1QkFDRyxJQUFJLGFBQWEsQ0FBQyxFQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsSUFBSSxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFDLENBQUMsQ0FBQyxPQUFPLEVBQUUsSUFEOUQsZ0JBQWdCLENBQUMsTUFBTSxDQUFDLENBRTVCLENBQ04sSUFMTSxLQUFLLENBQUMsRUFBRSxFQUFFLENBTWQsQ0FDTixHQUNLLElBQ0YsQ0FDVCxDQUFBO1FBQ0QsTUFBTSxTQUFTLEdBQUcsY0FBYyxDQUFDLFlBQVksQ0FBQyxDQUFBO1FBQzlDLE1BQU0sSUFBSSxHQUFHLElBQUksSUFBSSxDQUFDLENBQUMsU0FBUyxDQUFDLEVBQUUsRUFBQyxJQUFJLEVBQUUseUJBQXlCLEVBQUMsQ0FBQyxDQUFBO1FBQ3JFLE1BQU0sUUFBUSxHQUFHLEdBQUcsVUFBVSxDQUFDLFNBQVMsRUFBRSxDQUFDLEtBQUssQ0FBQyxFQUFDLEtBQUssRUFBRSxDQUFDLEVBQUMsQ0FBQyxPQUFPLENBQUE7UUFFbkUsTUFBTSxDQUFDLElBQUksRUFBRSxRQUFRLENBQUMsQ0FBQTtJQUN4QixDQUFDLENBQUE7Q0FDRixDQUFDLENBQUMsQ0FBQSIsInNvdXJjZXNDb250ZW50IjpbIi8vIEB0cy1jaGVja1xuLyogZXNsaW50LWRpc2FibGUgaW1wbGljaXQtYXJyb3ctbGluZWJyZWFrLCByZWFjdC9qc3gtbm8tbGl0ZXJhbHMsIHNvcnQtaW1wb3J0cyAqL1xuaW1wb3J0IENvbHVtbkNvbnRlbnQgZnJvbSBcIi4uL2NvbHVtbi1jb250ZW50XCJcbmltcG9ydCBjb2x1bW5JZGVudGlmaWVyIGZyb20gXCIuLi9jb2x1bW4taWRlbnRpZmllci5qc1wiXG5pbXBvcnQgY29sdW1uVmlzaWJsZSBmcm9tIFwiLi4vY29sdW1uLXZpc2libGUuanNcIlxuaW1wb3J0IHtzYXZlQXN9IGZyb20gXCJmaWxlLXNhdmVyXCJcbmltcG9ydCBJY29uIGZyb20gXCIuLi8uLi91dGlscy9pY29uXCJcbmltcG9ydCBtZW1vIGZyb20gXCJzZXQtc3RhdGUtY29tcGFyZS9idWlsZC9tZW1vLmpzXCJcbmltcG9ydCBQcm9wVHlwZXMgZnJvbSBcInByb3AtdHlwZXNcIlxuaW1wb3J0IHByb3BUeXBlc0V4YWN0IGZyb20gXCJwcm9wLXR5cGVzLWV4YWN0XCJcbmltcG9ydCBSZWFjdCBmcm9tIFwicmVhY3RcIlxuaW1wb3J0IHtyZW5kZXJUb1N0cmluZ30gZnJvbSBcInJlYWN0LWRvbS9zZXJ2ZXJcIiAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIGltcG9ydC9uby11bnJlc29sdmVkXG5pbXBvcnQge1NoYXBlQ29tcG9uZW50LCBzaGFwZUNvbXBvbmVudH0gZnJvbSBcInNldC1zdGF0ZS1jb21wYXJlL2J1aWxkL3NoYXBlLWNvbXBvbmVudC5qc1wiXG5pbXBvcnQge1ByZXNzYWJsZX0gZnJvbSBcInJlYWN0LW5hdGl2ZVwiXG5pbXBvcnQgVGV4dCBmcm9tIFwiLi4vLi4vdXRpbHMvdGV4dFwiXG5cbi8qKlxuICogQHR5cGVkZWYge29iamVjdH0gUHJvcHNcbiAqIEBwcm9wZXJ0eSB7RnVuY3Rpb259IGxcbiAqIEBwcm9wZXJ0eSB7b2JqZWN0fSB0YWJsZVxuICovXG4vKiogQHR5cGVkZWYge1JlY29yZDxzdHJpbmcsIG5ldmVyPn0gU3RhdGUgKi9cbmV4cG9ydCBkZWZhdWx0IG1lbW8oc2hhcGVDb21wb25lbnQoLyoqIEBhdWdtZW50cyB7U2hhcGVDb21wb25lbnQ8UHJvcHMsIFN0YXRlPn0gKi8gY2xhc3MgQXBpTWFrZXJUYWJsZVNldHRpbmdzRG93bmxvYWRBY3Rpb24gZXh0ZW5kcyBTaGFwZUNvbXBvbmVudCB7XG4gIHN0YXRpYyBwcm9wVHlwZXMgPSBwcm9wVHlwZXNFeGFjdCh7XG4gICAgbDogUHJvcFR5cGVzLmZ1bmMuaXNSZXF1aXJlZCxcbiAgICB0YWJsZTogUHJvcFR5cGVzLm9iamVjdC5pc1JlcXVpcmVkXG4gIH0pXG5cbiAgcmVuZGVyKCkge1xuICAgIHJldHVybiAoXG4gICAgICA8UHJlc3NhYmxlXG4gICAgICAgIGRhdGFTZXQ9e3RoaXMuY2FjaGUoXCJwcmVzc2FibGVEYXRhU2V0XCIsIHtjb21wb25lbnQ6IFwiYXBpLW1ha2VyL3RhYmxlL3NldHRpbmdzL2Rvd25sb2FkLWFjdGlvblwifSl9XG4gICAgICAgIG9uUHJlc3M9e3RoaXMudHQub25Eb3dubG9hZFByZXNzfVxuICAgICAgICBzdHlsZT17dGhpcy5jYWNoZShcInByZXNzYWJsZVN0eWxlXCIsIHtmbGV4RGlyZWN0aW9uOiBcInJvd1wiLCBhbGlnbkl0ZW1zOiBcImNlbnRlclwifSl9XG4gICAgICA+XG4gICAgICAgIDxJY29uIG5hbWU9XCJkb3dubG9hZFwiIHNpemU9ezIwfSAvPlxuICAgICAgICA8VGV4dCBzdHlsZT17dGhpcy5jYWNoZShcInRleHRTdHlsZVwiLCB7bWFyZ2luTGVmdDogNX0pfT5cbiAgICAgICAgICBEb3dubG9hZFxuICAgICAgICA8L1RleHQ+XG4gICAgICA8L1ByZXNzYWJsZT5cbiAgICApXG4gIH1cblxuICBvbkRvd25sb2FkUHJlc3MgPSAoKSA9PiB7XG4gICAgY29uc3Qge2wsIHRhYmxlfSA9IHRoaXMucFxuICAgIGNvbnN0IHttb2RlbENsYXNzfSA9IHRhYmxlLnBcbiAgICBjb25zdCB7Y29sbGVjdGlvbn0gPSB0YWJsZS50dFxuICAgIGNvbnN0IHttb2RlbHN9ID0gY29sbGVjdGlvblxuICAgIGNvbnN0IHtwcmVwYXJlZENvbHVtbnN9ID0gdGFibGUuc1xuICAgIGNvbnN0IHRhYmxlRWxlbWVudCA9IChcbiAgICAgIDx0YWJsZT5cbiAgICAgICAgPHRoZWFkPlxuICAgICAgICAgIDx0cj5cbiAgICAgICAgICAgIHtwcmVwYXJlZENvbHVtbnM/Lm1hcCgoe2NvbHVtbiwgdGFibGVTZXR0aW5nQ29sdW1ufSkgPT4gY29sdW1uVmlzaWJsZShjb2x1bW4sIHRhYmxlU2V0dGluZ0NvbHVtbikgJiZcbiAgICAgICAgICAgICAgPHRoIGtleT17Y29sdW1uSWRlbnRpZmllcihjb2x1bW4pfT5cbiAgICAgICAgICAgICAgICB7dGFibGUuaGVhZGVyTGFiZWxGb3JDb2x1bW4oY29sdW1uKX1cbiAgICAgICAgICAgICAgPC90aD5cbiAgICAgICAgICAgICl9XG4gICAgICAgICAgPC90cj5cbiAgICAgICAgPC90aGVhZD5cbiAgICAgICAgPHRib2R5PlxuICAgICAgICAgIHttb2RlbHMubWFwKChtb2RlbCkgPT5cbiAgICAgICAgICAgIDx0ciBrZXk9e21vZGVsLmlkKCl9PlxuICAgICAgICAgICAgICB7cHJlcGFyZWRDb2x1bW5zPy5tYXAoKHtjb2x1bW4sIHRhYmxlU2V0dGluZ0NvbHVtbn0pID0+IGNvbHVtblZpc2libGUoY29sdW1uLCB0YWJsZVNldHRpbmdDb2x1bW4pICYmXG4gICAgICAgICAgICAgICAgPHRkIGtleT17Y29sdW1uSWRlbnRpZmllcihjb2x1bW4pfT5cbiAgICAgICAgICAgICAgICAgIHtuZXcgQ29sdW1uQ29udGVudCh7Y29sdW1uLCBsLCBtb2RlOiBcImh0bWxcIiwgbW9kZWwsIHRhYmxlfSkuY29udGVudCgpfVxuICAgICAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICAgICl9XG4gICAgICAgICAgICA8L3RyPlxuICAgICAgICAgICl9XG4gICAgICAgIDwvdGJvZHk+XG4gICAgICA8L3RhYmxlPlxuICAgIClcbiAgICBjb25zdCB0YWJsZUhUTUwgPSByZW5kZXJUb1N0cmluZyh0YWJsZUVsZW1lbnQpXG4gICAgY29uc3QgYmxvYiA9IG5ldyBCbG9iKFt0YWJsZUhUTUxdLCB7dHlwZTogXCJ0ZXh0L2h0bWw7Y2hhcnNldD11dGYtOFwifSlcbiAgICBjb25zdCBmaWxlTmFtZSA9IGAke21vZGVsQ2xhc3MubW9kZWxOYW1lKCkuaHVtYW4oe2NvdW50OiAyfSl9Lmh0bWxgXG5cbiAgICBzYXZlQXMoYmxvYiwgZmlsZU5hbWUpXG4gIH1cbn0pKVxuIl19
73
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZG93bmxvYWQtYWN0aW9uLmpzIiwic291cmNlUm9vdCI6Ii9zcmMvIiwic291cmNlcyI6WyJ0YWJsZS9zZXR0aW5ncy9kb3dubG9hZC1hY3Rpb24uanN4Il0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSxZQUFZO0FBQ1osaUNBQWlDO0FBQ2pDLE9BQU8sRUFBQyxjQUFjLEVBQUUsY0FBYyxFQUFDLE1BQU0sNENBQTRDLENBQUE7QUFDekYsT0FBTyxFQUFDLGtCQUFrQixFQUFDLE1BQU0scUJBQXFCLENBQUE7QUFDdEQsT0FBTyxFQUFDLFNBQVMsRUFBRSxJQUFJLEVBQUMsTUFBTSxjQUFjLENBQUE7QUFDNUMsT0FBTyxjQUFjLE1BQU0saUJBQWlCLENBQUE7QUFDNUMsT0FBTyxxQkFBcUIsRUFBRSxFQUFDLCtCQUErQixFQUFDLE1BQU0sMEJBQTBCLENBQUE7QUFDL0YsT0FBTyxJQUFJLE1BQU0sa0JBQWtCLENBQUE7QUFDbkMsT0FBTyxJQUFJLE1BQU0saUNBQWlDLENBQUE7QUFDbEQsT0FBTyxTQUFTLE1BQU0sWUFBWSxDQUFBO0FBQ2xDLE9BQU8sY0FBYyxNQUFNLGtCQUFrQixDQUFBO0FBQzdDLE9BQU8sS0FBSyxNQUFNLE9BQU8sQ0FBQTtBQUN6QixPQUFPLElBQUksTUFBTSxrQkFBa0IsQ0FBQTtBQUNuQyxPQUFPLE9BQU8sTUFBTSx3Q0FBd0MsQ0FBQTtBQUU1RDs7Ozs7Ozs7R0FRRztBQUNILDRDQUE0QztBQUM1QyxlQUFlLElBQUksQ0FBQyxjQUFjLENBQUMsK0NBQStDLENBQUMsTUFBTSxtQ0FBb0MsU0FBUSxjQUFjO0lBQ2pKLE1BQU0sQ0FBQyxTQUFTLEdBQUcsY0FBYyxDQUFDO1FBQ2hDLENBQUMsRUFBRSxTQUFTLENBQUMsSUFBSSxDQUFDLFVBQVU7UUFDNUIsS0FBSyxFQUFFLFNBQVMsQ0FBQyxNQUFNLENBQUMsVUFBVTtLQUNuQyxDQUFDLENBQUE7SUFFRixLQUFLLEdBQUc7UUFDTixTQUFTLEVBQUUsS0FBSztLQUNqQixDQUFBO0lBRUQsS0FBSztRQUNILE1BQU0sRUFBQyxDQUFDLEVBQUMsR0FBRyxPQUFPLENBQUMsRUFBQyxTQUFTLEVBQUUsb0NBQW9DLEVBQUMsQ0FBQyxDQUFBO1FBRXRFLElBQUksQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFBO0lBQ1osQ0FBQztJQUVELE1BQU07UUFDSixNQUFNLGNBQWMsR0FBRyxPQUFPLENBQUMsY0FBYyxDQUFDLHVCQUF1QixFQUFFLENBQUMsQ0FBQTtRQUV4RSxPQUFPLENBQ0wsTUFBQyxJQUFJLElBQUMsT0FBTyxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsaUJBQWlCLEVBQUUsRUFBQyxTQUFTLEVBQUUsMENBQTBDLEVBQUMsQ0FBQyxhQUNuRyxLQUFDLElBQUksSUFBQyxLQUFLLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxZQUFZLEVBQUUsRUFBQyxVQUFVLEVBQUUsTUFBTSxFQUFFLFlBQVksRUFBRSxDQUFDLEVBQUMsQ0FBQyxZQUN6RSxJQUFJLENBQUMsQ0FBQyxDQUFDLFdBQVcsRUFBRSxFQUFDLFlBQVksRUFBRSxVQUFVLEVBQUMsQ0FBQyxHQUMzQyxFQUNOLElBQUksQ0FBQyxZQUFZLENBQUMsRUFBQyxNQUFNLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsT0FBTyxFQUFFLElBQUksQ0FBQyxFQUFFLENBQUMsYUFBYSxFQUFDLENBQUMsRUFDaEYsSUFBSSxDQUFDLFlBQVksQ0FBQyxFQUFDLE1BQU0sRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxPQUFPLEVBQUUsSUFBSSxDQUFDLEVBQUUsQ0FBQyxjQUFjLEVBQUMsQ0FBQyxFQUNuRixjQUFjLElBQUksSUFBSSxDQUFDLFlBQVksQ0FBQyxFQUFDLE1BQU0sRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFFLE9BQU8sRUFBRSxPQUFPLEVBQUUsSUFBSSxDQUFDLEVBQUUsQ0FBQyxjQUFjLEVBQUMsQ0FBQyxJQUNsRyxDQUNSLENBQUE7SUFDSCxDQUFDO0lBRUQ7OztPQUdHO0lBQ0gsWUFBWSxDQUFDLEVBQUMsTUFBTSxFQUFFLEtBQUssRUFBRSxPQUFPLEVBQUM7UUFDbkMsT0FBTyxDQUNMLE1BQUMsU0FBUyxJQUNSLE9BQU8sRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLFdBQVcsTUFBTSxTQUFTLEVBQUUsRUFBQyxTQUFTLEVBQUUsNENBQTRDLE1BQU0sRUFBRSxFQUFDLENBQUMsRUFDbEgsUUFBUSxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUMsU0FBUyxFQUMxQixPQUFPLEVBQUUsT0FBTyxFQUNoQixLQUFLLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxtQkFBbUIsRUFBRSxFQUFDLGFBQWEsRUFBRSxLQUFLLEVBQUUsVUFBVSxFQUFFLFFBQVEsRUFBRSxlQUFlLEVBQUUsQ0FBQyxFQUFDLENBQUMsRUFDeEcsTUFBTSxFQUFFLG1CQUFtQixNQUFNLEVBQUUsYUFFbkMsS0FBQyxJQUFJLElBQUMsSUFBSSxFQUFDLFVBQVUsRUFBQyxJQUFJLEVBQUUsRUFBRSxHQUFJLEVBQ2xDLEtBQUMsSUFBSSxJQUFDLEtBQUssRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLGtCQUFrQixFQUFFLEVBQUMsVUFBVSxFQUFFLENBQUMsRUFBQyxDQUFDLFlBQ3pELEtBQUssR0FDRCxJQUNHLENBQ2IsQ0FBQTtJQUNILENBQUM7SUFFRCxhQUFhLEdBQUcsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxLQUFLLENBQUMsQ0FBQTtJQUM3QyxjQUFjLEdBQUcsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxNQUFNLENBQUMsQ0FBQTtJQUMvQyxjQUFjLEdBQUcsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxNQUFNLENBQUMsQ0FBQTtJQUUvQyw4Q0FBOEM7SUFDOUMsV0FBVyxHQUFHLEtBQUssRUFBRSxNQUFNLEVBQUUsRUFBRTtRQUM3QixJQUFJLElBQUksQ0FBQyxDQUFDLENBQUMsU0FBUztZQUFFLE9BQU07UUFFNUIsSUFBSSxDQUFDLENBQUMsQ0FBQyxTQUFTLEdBQUcsSUFBSSxDQUFBO1FBRXZCLE1BQU0sUUFBUSxHQUFHLElBQUkscUJBQXFCLENBQUMsRUFBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLEtBQUssRUFBRSxJQUFJLENBQUMsQ0FBQyxDQUFDLEtBQUssRUFBQyxDQUFDLENBQUE7UUFFdEYsSUFBSSxDQUFDO1lBQ0gsTUFBTSxRQUFRLENBQUMsR0FBRyxFQUFFLENBQUE7UUFDdEIsQ0FBQztRQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7WUFDZixJQUFJLEtBQUssWUFBWSwrQkFBK0I7Z0JBQUUsT0FBTTtZQUM1RCxJQUFJLEtBQUssSUFBSSxvQkFBb0IsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLElBQUksS0FBSyxZQUFZO2dCQUFFLE9BQU07WUFFdkUsa0JBQWtCLENBQUMsYUFBYSxDQUFDLEtBQUssQ0FBQyxDQUFBO1FBQ3pDLENBQUM7Z0JBQVMsQ0FBQztZQUNULElBQUksQ0FBQyxDQUFDLENBQUMsU0FBUyxHQUFHLEtBQUssQ0FBQTtRQUMxQixDQUFDO0lBQ0gsQ0FBQyxDQUFBO0NBQ0YsQ0FBQyxDQUFDLENBQUEiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBAdHMtY2hlY2tcbi8qIGVzbGludC1kaXNhYmxlIHNvcnQtaW1wb3J0cyAqL1xuaW1wb3J0IHtTaGFwZUNvbXBvbmVudCwgc2hhcGVDb21wb25lbnR9IGZyb20gXCJzZXQtc3RhdGUtY29tcGFyZS9idWlsZC9zaGFwZS1jb21wb25lbnQuanNcIlxuaW1wb3J0IHtGbGFzaE5vdGlmaWNhdGlvbnN9IGZyb20gXCJmbGFzaC1ub3RpZmljYXRpb25zXCJcbmltcG9ydCB7UHJlc3NhYmxlLCBWaWV3fSBmcm9tIFwicmVhY3QtbmF0aXZlXCJcbmltcG9ydCBhcGlNYWtlckNvbmZpZyBmcm9tIFwiLi4vLi4vY29uZmlnLmpzXCJcbmltcG9ydCBBcGlNYWtlclRhYmxlRXhwb3J0ZXIsIHtBcGlNYWtlclRhYmxlRXhwb3J0QWJvcnRlZEVycm9yfSBmcm9tIFwiLi4vZXhwb3J0L3RhYmxlLWV4cG9ydGVyXCJcbmltcG9ydCBJY29uIGZyb20gXCIuLi8uLi91dGlscy9pY29uXCJcbmltcG9ydCBtZW1vIGZyb20gXCJzZXQtc3RhdGUtY29tcGFyZS9idWlsZC9tZW1vLmpzXCJcbmltcG9ydCBQcm9wVHlwZXMgZnJvbSBcInByb3AtdHlwZXNcIlxuaW1wb3J0IHByb3BUeXBlc0V4YWN0IGZyb20gXCJwcm9wLXR5cGVzLWV4YWN0XCJcbmltcG9ydCBSZWFjdCBmcm9tIFwicmVhY3RcIlxuaW1wb3J0IFRleHQgZnJvbSBcIi4uLy4uL3V0aWxzL3RleHRcIlxuaW1wb3J0IHVzZUkxOG4gZnJvbSBcImkxOG4tb24tc3Rlcm9pZHMvYnVpbGQvc3JjL3VzZS1pMThuLmpzXCJcblxuLyoqXG4gKiBTdHJlYW1zIHRoZSB3aG9sZSB0YWJsZSByZXN1bHQgc2V0IHRvIGEgZmlsZSAoQ1NWIC8gSFRNTCAvIEV4Y2VsKSBpbnN0ZWFkIG9mIGJ1aWxkaW5nIG9uZSBiaWcgc3RyaW5nIGluXG4gKiBtZW1vcnkuIEV4Y2VsIGlzIG9ubHkgb2ZmZXJlZCB3aGVuIHRoZSBob3N0IGFwcCBoYXMgcmVnaXN0ZXJlZCBhbiB4bHN4IHNlcmlhbGl6ZXIgdmlhXG4gKiBhcGlNYWtlckNvbmZpZy5zZXRFeHBvcnRYbHN4U2VyaWFsaXplci5cbiAqXG4gKiBAdHlwZWRlZiB7b2JqZWN0fSBQcm9wc1xuICogQHByb3BlcnR5IHtGdW5jdGlvbn0gbFxuICogQHByb3BlcnR5IHtvYmplY3R9IHRhYmxlXG4gKi9cbi8qKiBAdHlwZWRlZiB7e2V4cG9ydGluZzogYm9vbGVhbn19IFN0YXRlICovXG5leHBvcnQgZGVmYXVsdCBtZW1vKHNoYXBlQ29tcG9uZW50KC8qKiBAYXVnbWVudHMge1NoYXBlQ29tcG9uZW50PFByb3BzLCBTdGF0ZT59ICovIGNsYXNzIEFwaU1ha2VyVGFibGVTZXR0aW5nc0Rvd25sb2FkQWN0aW9uIGV4dGVuZHMgU2hhcGVDb21wb25lbnQge1xuICBzdGF0aWMgcHJvcFR5cGVzID0gcHJvcFR5cGVzRXhhY3Qoe1xuICAgIGw6IFByb3BUeXBlcy5mdW5jLmlzUmVxdWlyZWQsXG4gICAgdGFibGU6IFByb3BUeXBlcy5vYmplY3QuaXNSZXF1aXJlZFxuICB9KVxuXG4gIHN0YXRlID0ge1xuICAgIGV4cG9ydGluZzogZmFsc2VcbiAgfVxuXG4gIHNldHVwKCkge1xuICAgIGNvbnN0IHt0fSA9IHVzZUkxOG4oe25hbWVzcGFjZTogXCJqcy5hcGlfbWFrZXIudGFibGUuZG93bmxvYWRfYWN0aW9uXCJ9KVxuXG4gICAgdGhpcy50ID0gdFxuICB9XG5cbiAgcmVuZGVyKCkge1xuICAgIGNvbnN0IGV4Y2VsQXZhaWxhYmxlID0gQm9vbGVhbihhcGlNYWtlckNvbmZpZy5nZXRFeHBvcnRYbHN4U2VyaWFsaXplcigpKVxuXG4gICAgcmV0dXJuIChcbiAgICAgIDxWaWV3IGRhdGFTZXQ9e3RoaXMuY2FjaGUoXCJyb290Vmlld0RhdGFTZXRcIiwge2NvbXBvbmVudDogXCJhcGktbWFrZXIvdGFibGUvc2V0dGluZ3MvZG93bmxvYWQtYWN0aW9uXCJ9KX0+XG4gICAgICAgIDxUZXh0IHN0eWxlPXt0aGlzLmNhY2hlKFwibGFiZWxTdHlsZVwiLCB7Zm9udFdlaWdodDogXCJib2xkXCIsIG1hcmdpbkJvdHRvbTogNH0pfT5cbiAgICAgICAgICB7dGhpcy50KFwiLmRvd25sb2FkXCIsIHtkZWZhdWx0VmFsdWU6IFwiRG93bmxvYWRcIn0pfVxuICAgICAgICA8L1RleHQ+XG4gICAgICAgIHt0aGlzLmZvcm1hdEJ1dHRvbih7Zm9ybWF0OiBcImNzdlwiLCBsYWJlbDogXCJDU1ZcIiwgb25QcmVzczogdGhpcy50dC5vbkRvd25sb2FkQ3N2fSl9XG4gICAgICAgIHt0aGlzLmZvcm1hdEJ1dHRvbih7Zm9ybWF0OiBcImh0bWxcIiwgbGFiZWw6IFwiSFRNTFwiLCBvblByZXNzOiB0aGlzLnR0Lm9uRG93bmxvYWRIdG1sfSl9XG4gICAgICAgIHtleGNlbEF2YWlsYWJsZSAmJiB0aGlzLmZvcm1hdEJ1dHRvbih7Zm9ybWF0OiBcInhsc3hcIiwgbGFiZWw6IFwiRXhjZWxcIiwgb25QcmVzczogdGhpcy50dC5vbkRvd25sb2FkWGxzeH0pfVxuICAgICAgPC9WaWV3PlxuICAgIClcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge3tmb3JtYXQ6IFwiY3N2XCIgfCBcImh0bWxcIiB8IFwieGxzeFwiLCBsYWJlbDogc3RyaW5nLCBvblByZXNzOiAoKSA9PiB2b2lkfX0gYXJnc1xuICAgKiBAcmV0dXJucyB7aW1wb3J0KFwicmVhY3RcIikuUmVhY3ROb2RlfVxuICAgKi9cbiAgZm9ybWF0QnV0dG9uKHtmb3JtYXQsIGxhYmVsLCBvblByZXNzfSkge1xuICAgIHJldHVybiAoXG4gICAgICA8UHJlc3NhYmxlXG4gICAgICAgIGRhdGFTZXQ9e3RoaXMuY2FjaGUoYGRvd25sb2FkJHtmb3JtYXR9RGF0YVNldGAsIHtjb21wb25lbnQ6IGBhcGktbWFrZXIvdGFibGUvc2V0dGluZ3MvZG93bmxvYWQtYWN0aW9uLyR7Zm9ybWF0fWB9KX1cbiAgICAgICAgZGlzYWJsZWQ9e3RoaXMucy5leHBvcnRpbmd9XG4gICAgICAgIG9uUHJlc3M9e29uUHJlc3N9XG4gICAgICAgIHN0eWxlPXt0aGlzLmNhY2hlKFwiZm9ybWF0QnV0dG9uU3R5bGVcIiwge2ZsZXhEaXJlY3Rpb246IFwicm93XCIsIGFsaWduSXRlbXM6IFwiY2VudGVyXCIsIHBhZGRpbmdWZXJ0aWNhbDogM30pfVxuICAgICAgICB0ZXN0SUQ9e2Bkb3dubG9hZC1hY3Rpb24tJHtmb3JtYXR9YH1cbiAgICAgID5cbiAgICAgICAgPEljb24gbmFtZT1cImRvd25sb2FkXCIgc2l6ZT17MTh9IC8+XG4gICAgICAgIDxUZXh0IHN0eWxlPXt0aGlzLmNhY2hlKFwiZm9ybWF0TGFiZWxTdHlsZVwiLCB7bWFyZ2luTGVmdDogNX0pfT5cbiAgICAgICAgICB7bGFiZWx9XG4gICAgICAgIDwvVGV4dD5cbiAgICAgIDwvUHJlc3NhYmxlPlxuICAgIClcbiAgfVxuXG4gIG9uRG93bmxvYWRDc3YgPSAoKSA9PiB0aGlzLnN0YXJ0RXhwb3J0KFwiY3N2XCIpXG4gIG9uRG93bmxvYWRIdG1sID0gKCkgPT4gdGhpcy5zdGFydEV4cG9ydChcImh0bWxcIilcbiAgb25Eb3dubG9hZFhsc3ggPSAoKSA9PiB0aGlzLnN0YXJ0RXhwb3J0KFwieGxzeFwiKVxuXG4gIC8qKiBAcGFyYW0ge1wiY3N2XCIgfCBcImh0bWxcIiB8IFwieGxzeFwifSBmb3JtYXQgKi9cbiAgc3RhcnRFeHBvcnQgPSBhc3luYyAoZm9ybWF0KSA9PiB7XG4gICAgaWYgKHRoaXMucy5leHBvcnRpbmcpIHJldHVyblxuXG4gICAgdGhpcy5zLmV4cG9ydGluZyA9IHRydWVcblxuICAgIGNvbnN0IGV4cG9ydGVyID0gbmV3IEFwaU1ha2VyVGFibGVFeHBvcnRlcih7Zm9ybWF0LCBsOiB0aGlzLnAubCwgdGFibGU6IHRoaXMucC50YWJsZX0pXG5cbiAgICB0cnkge1xuICAgICAgYXdhaXQgZXhwb3J0ZXIucnVuKClcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgaWYgKGVycm9yIGluc3RhbmNlb2YgQXBpTWFrZXJUYWJsZUV4cG9ydEFib3J0ZWRFcnJvcikgcmV0dXJuXG4gICAgICBpZiAoZXJyb3IgJiYgLyoqIEB0eXBlIHtFcnJvcn0gKi8gKGVycm9yKS5uYW1lID09PSBcIkFib3J0RXJyb3JcIikgcmV0dXJuXG5cbiAgICAgIEZsYXNoTm90aWZpY2F0aW9ucy5lcnJvclJlc3BvbnNlKGVycm9yKVxuICAgIH0gZmluYWxseSB7XG4gICAgICB0aGlzLnMuZXhwb3J0aW5nID0gZmFsc2VcbiAgICB9XG4gIH1cbn0pKVxuIl19
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@kaspernj/api-maker",
3
3
  "type": "module",
4
- "version": "1.0.2171",
4
+ "version": "1.0.2173",
5
5
  "description": "My new module",
6
6
  "files": [
7
7
  "build/**"
@@ -11,7 +11,7 @@
11
11
  "scripts": {
12
12
  "build": "rm -rf build && tsc",
13
13
  "clean": "expo-module clean",
14
- "lint": "expo-module lint -- --max-warnings 0",
14
+ "lint": "npm run eslint && npm run lint:eslint && npm run typecheck",
15
15
  "test": "NODE_OPTIONS=--experimental-vm-modules expo-module test",
16
16
  "prepare": "npm run clean && npm run build",
17
17
  "prepublishOnly": "expo-module prepublishOnly && npm run build",
@@ -22,7 +22,8 @@
22
22
  "release:patch-master": "node scripts/release-patch.js --require-master",
23
23
  "typecheck": "tsc --noEmit",
24
24
  "typecheck:file": "sh -c 'file=\"${npm_config_file:-${FILE:-}}\"; if [ -z \"$file\" ] && [ \"${0#--file=}\" != \"$0\" ]; then file=\"${0#--file=}\"; fi; if [ -z \"$file\" ] && [ \"${1#--file=}\" != \"$1\" ]; then file=\"${1#--file=}\"; fi; file=\"${file#npm-api-maker/}\"; file=\"${file#./}\"; if [ -z \"$file\" ]; then echo \"Missing --file=src/path/to/file.js\"; exit 2; fi; tmp=$(mktemp); tsc --noEmit -p tsconfig.json --pretty false >\"$tmp\" 2>&1; if rg --fixed-strings \"$file\" \"$tmp\" >/dev/null; then rg --fixed-strings \"$file\" \"$tmp\"; rm -f \"$tmp\"; exit 1; else rm -f \"$tmp\"; exit 0; fi'",
25
- "watch": "tsc -w"
25
+ "watch": "tsc -w",
26
+ "eslint": "expo-module lint -- --max-warnings 0"
26
27
  },
27
28
  "keywords": [
28
29
  "react-native",