@navette-js/panels 1.0.0-beta.3 → 1.0.0-beta.5

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 (41) hide show
  1. package/THIRD-PARTY-NOTICES.md +2 -1
  2. package/dist/navette/navette/calendar.css +5 -5
  3. package/dist/navette/navette/motion.css +21 -21
  4. package/dist/navette/navette/motion.js +6 -6
  5. package/dist/navette/navette/security-keys.css +11 -0
  6. package/dist/navette/navette/security-keys.js +72 -0
  7. package/lib/auth.d.ts +17 -0
  8. package/lib/auth.js +70 -0
  9. package/lib/error-pages.d.ts +9 -0
  10. package/lib/error-pages.js +173 -0
  11. package/lib/import-export.d.ts +185 -0
  12. package/lib/import-export.js +543 -0
  13. package/lib/index.d.ts +629 -79
  14. package/lib/index.js +1945 -333
  15. package/lib/multi-factor.d.ts +348 -0
  16. package/lib/multi-factor.js +928 -0
  17. package/lib/notifications.d.ts +20 -2
  18. package/lib/notifications.js +34 -4
  19. package/lib/qr-code.d.ts +16 -0
  20. package/lib/qr-code.js +255 -0
  21. package/lib/session-store.d.ts +21 -0
  22. package/lib/session-store.js +35 -0
  23. package/lib/throttle.d.ts +10 -0
  24. package/lib/throttle.js +25 -0
  25. package/lib/topbar.d.ts +3 -1
  26. package/lib/topbar.js +18 -1
  27. package/lib/totp.d.ts +38 -0
  28. package/lib/totp.js +104 -0
  29. package/lib/webauthn.d.ts +155 -0
  30. package/lib/webauthn.js +287 -0
  31. package/lib/xlsx.d.ts +7 -0
  32. package/lib/xlsx.js +171 -0
  33. package/package.json +9 -9
  34. package/views/components/tenant-menu.ejs +3 -3
  35. package/views/components/user-menu.ejs +3 -2
  36. package/views/errors/page.ejs +87 -0
  37. package/views/layout/base.ejs +9 -1
  38. package/views/livewire/sidebar.ejs +35 -20
  39. package/views/livewire/topbar.ejs +1 -1
  40. package/views/pages/page.ejs +53 -35
  41. package/views/pages/simple.ejs +4 -0
@@ -0,0 +1,185 @@
1
+ import { Action } from '@navette-js/actions';
2
+ type StoredFile = {
3
+ owner: string;
4
+ name: string;
5
+ type: string;
6
+ content: Buffer;
7
+ expires: number;
8
+ };
9
+ /**
10
+ * Files offered for download to one user (exports, failed import rows), kept in memory for a limited time. They are lost
11
+ * when the process restarts and are not shared between processes.
12
+ */
13
+ export declare class DownloadStore {
14
+ private files;
15
+ private readonly ttl;
16
+ private readonly maxFiles;
17
+ constructor(options?: {
18
+ ttl?: number;
19
+ maxFiles?: number;
20
+ });
21
+ /** Stores a file for a user and returns its token (part of the download URL). */
22
+ put(owner: string | number, name: string, type: string, content: string | Buffer): string;
23
+ /** The file of a token, only for the user who created it. */
24
+ get(token: string, owner: string | number): StoredFile | null;
25
+ }
26
+ /**
27
+ * A CSV cell. Text starting with `=`, `+`, `-`, `@`, a tab or a carriage return is prefixed with `'`, so that spreadsheet
28
+ * software does not run it as a formula (CSV injection).
29
+ */
30
+ export declare function csvCell(value: unknown): string;
31
+ export declare const csvLine: (cells: unknown[]) => string;
32
+ /** Parses CSV text (quoted cells, doubled quotes, line breaks inside quotes). */
33
+ export declare function parseCsv(text: string, maxRows?: number): string[][];
34
+ /** Column of an export: its header and the value written for each record. */
35
+ export declare class ExportColumn {
36
+ readonly name: string;
37
+ private _label;
38
+ private _state;
39
+ private _format;
40
+ private _enabledByDefault;
41
+ constructor(name: string);
42
+ static make(name: string): ExportColumn;
43
+ label(label: string | null): this;
44
+ getLabel(): string;
45
+ /** Value from the record, instead of the attribute with the column's name (dots read relationships: `author.name`). */
46
+ state(resolver: ((record: any) => unknown) | null): this;
47
+ formatStateUsing(format: ((state: unknown, record: any) => unknown) | null): this;
48
+ /** `false`: unchecked in the export modal. */
49
+ enabledByDefault(condition?: boolean): this;
50
+ isEnabledByDefault(): boolean;
51
+ getValue(record: any): unknown;
52
+ }
53
+ /** Describes an export: its columns, and optionally the query and the notification. */
54
+ export declare abstract class Exporter {
55
+ static getColumns(): ExportColumn[];
56
+ /** Changes the query of the exported records (e.g. eager loading). */
57
+ static modifyQuery(_query: any): void;
58
+ /** Body of the "Export completed" notification. */
59
+ static getCompletedNotificationBody(count: number): string;
60
+ /** File name, without extension. */
61
+ static getFileName(_count: number): string;
62
+ }
63
+ export type ExportActionInstance = Action & {
64
+ exporter(exporter: typeof Exporter): ExportActionInstance;
65
+ /** Refuses exports of more rows (10,000 by default, 100,000 at most). */
66
+ maxRows(count: number): ExportActionInstance;
67
+ /** `false`: no column selection, every column is exported (the modal only confirms). */
68
+ columnMapping(condition: boolean): ExportActionInstance;
69
+ /** Files offered for download: `['csv', 'xlsx']` (both by default). */
70
+ formats(formats: ('csv' | 'xlsx')[]): ExportActionInstance;
71
+ /** Builds the files after the response, in the background; the download links arrive in the bell. */
72
+ queued(condition?: boolean): ExportActionInstance;
73
+ };
74
+ /** Exports the records of the table (with its filters, search and sort) to a CSV file. */
75
+ export declare class ExportAction {
76
+ static make(name?: string): ExportActionInstance;
77
+ }
78
+ /** Exports the selected records to a CSV file. */
79
+ export declare class ExportBulkAction {
80
+ static make(name?: string): ExportActionInstance;
81
+ }
82
+ type ImportRule = string | ((value: unknown, row: Record<string, unknown>) => string | null);
83
+ /** Column of an import: the file column it is read from, its validation and how the value is cast. */
84
+ export declare class ImportColumn {
85
+ readonly name: string;
86
+ private _label;
87
+ private _guesses;
88
+ private _required;
89
+ private _rules;
90
+ private _cast;
91
+ private _example;
92
+ private _fill;
93
+ constructor(name: string);
94
+ static make(name: string): ImportColumn;
95
+ label(label: string | null): this;
96
+ getLabel(): string;
97
+ /** Other file headers that map to this column (compared case-insensitively). */
98
+ guess(headers: string[]): this;
99
+ /** The file must contain this column. */
100
+ requiredMapping(condition?: boolean): this;
101
+ isMappingRequired(): boolean;
102
+ /** `required`, `email`, `numeric`, `integer`, `boolean`, `min:n`, `max:n`, `in:a,b`, or a function returning an error message. */
103
+ rules(rules: ImportRule[]): this;
104
+ /** Converts the text of the cell before it is saved. */
105
+ castStateUsing(cast: ((value: string | null) => unknown) | null): this;
106
+ numeric(): this;
107
+ boolean(): this;
108
+ /** Value written in the example file. */
109
+ example(value: string | null): this;
110
+ getExample(): string;
111
+ /** Writes the value into the record yourself, instead of the attribute with the column's name. */
112
+ fillRecordUsing(fill: ((record: Record<string, unknown>, value: unknown) => void) | null): this;
113
+ matches(header: string): boolean;
114
+ validate(value: string | null, row: Record<string, unknown>): string | null;
115
+ cast(value: string | null): unknown;
116
+ fill(record: Record<string, unknown>, value: unknown): void;
117
+ }
118
+ /** Describes an import: its columns, how a row finds or creates its record, and hooks. */
119
+ export declare abstract class Importer {
120
+ static getColumns(): ImportColumn[];
121
+ /**
122
+ * Existing record a row updates, or `null` to create one (the default). For example, find a product by its SKU with the
123
+ * data adapter. Only return records the user may change.
124
+ */
125
+ static resolveRecord(_data: Record<string, unknown>, _ctx: {
126
+ livewire: any;
127
+ }): Promise<any | null>;
128
+ /** Runs before a record is saved; `data` may be changed. */
129
+ static beforeSave(_data: Record<string, unknown>, _record: any | null): Promise<void>;
130
+ static afterSave(_record: any): Promise<void>;
131
+ static getCompletedNotificationBody(imported: number, failed: number): string;
132
+ }
133
+ export type ImportActionInstance = Action & {
134
+ importer(importer: typeof Importer): ImportActionInstance;
135
+ /** Refuses files with more rows (1,000 by default, 10,000 at most; 100,000 for a queued import). */
136
+ maxRows(count: number): ImportActionInstance;
137
+ /** Largest accepted file, in kilobytes (5,120 by default). */
138
+ maxFileSize(kilobytes: number): ImportActionInstance;
139
+ /** `false`: no column selection after the upload; file headers are matched to the columns automatically. */
140
+ columnMapping(condition: boolean): ImportActionInstance;
141
+ /** Runs after the response, in the background: the user is told it started, then notified in the bell when it ends. */
142
+ queued(condition?: boolean): ImportActionInstance;
143
+ };
144
+ /** Rows of an uploaded CSV or XLSX file (detected from its content, never its name), up to `limit` rows. */
145
+ export declare function readSpreadsheet(path: string, limit: number): string[][];
146
+ export type BackgroundTask = () => Promise<void>;
147
+ /**
148
+ * Runs queued imports and exports. By default, one at a time in this process, after the response. Plug your own queue (BullMQ,
149
+ * a worker…) with a function receiving each task.
150
+ */
151
+ export declare const useBackgroundRunner: (runner: (task: BackgroundTask) => void) => void;
152
+ export declare const runInBackground: (task: BackgroundTask) => void;
153
+ /** Where runs of imports and exports are recorded (see `knexImportExportHistory()`). */
154
+ export interface ImportExportHistory {
155
+ startImport(data: {
156
+ userId: string | number;
157
+ importer: string;
158
+ fileName: string;
159
+ totalRows: number;
160
+ }): Promise<string | number>;
161
+ finishImport(id: string | number, data: {
162
+ processedRows: number;
163
+ successfulRows: number;
164
+ }): Promise<void>;
165
+ recordFailedImportRow(importId: string | number, row: Record<string, unknown>, error: string): Promise<void>;
166
+ startExport(data: {
167
+ userId: string | number;
168
+ exporter: string;
169
+ fileName: string;
170
+ totalRows: number;
171
+ }): Promise<string | number>;
172
+ finishExport(id: string | number, data: {
173
+ successfulRows: number;
174
+ }): Promise<void>;
175
+ }
176
+ type Query = (table: string) => any;
177
+ /** History in `imports`, `exports` and `failed_import_rows` tables (create them with `importExportSchema()`). */
178
+ export declare function knexImportExportHistory(db: Query): ImportExportHistory;
179
+ /** Creates the history tables when missing (call it from a migration). */
180
+ export declare function importExportSchema(knex: any): Promise<void>;
181
+ /** Imports the rows of a CSV or XLSX file: each row is validated, then creates or updates a record through the data adapter. */
182
+ export declare class ImportAction {
183
+ static make(name?: string): ImportActionInstance;
184
+ }
185
+ export {};