pivotkit-report 0.0.0-stage → 0.2.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/CHANGELOG.md +88 -0
- package/LICENSE +21 -0
- package/README.md +44 -2
- package/package.json +78 -4
- package/src/default-template.js +33 -0
- package/src/html-table.js +104 -0
- package/src/index.js +24 -0
- package/src/operations.js +808 -0
- package/src/render.js +279 -0
- package/src/report-css.js +61 -0
- package/src/svg.js +170 -0
- package/src/template.js +324 -0
- package/src/texts.js +63 -0
- package/src/tokens.js +180 -0
- package/types/default-template.d.ts +2 -0
- package/types/html-table.d.ts +36 -0
- package/types/index.d.ts +13 -0
- package/types/operations.d.ts +362 -0
- package/types/render.d.ts +177 -0
- package/types/report-css.d.ts +14 -0
- package/types/svg.d.ts +39 -0
- package/types/template.d.ts +37 -0
- package/types/texts.d.ts +44 -0
- package/types/tokens.d.ts +114 -0
|
@@ -0,0 +1,362 @@
|
|
|
1
|
+
import { describeSource } from "pivotkit-core";
|
|
2
|
+
/** The codes of OperationError, each with the HTTP status a REST front end answers with. */
|
|
3
|
+
export declare const OPERATION_ERRORS: Readonly<{
|
|
4
|
+
INVALID_INPUT: 400;
|
|
5
|
+
FILES_NOT_ALLOWED: 403;
|
|
6
|
+
NOT_ALLOWED: 403;
|
|
7
|
+
SOURCE_NOT_FOUND: 404;
|
|
8
|
+
FILE_NOT_AVAILABLE: 404;
|
|
9
|
+
NO_OUTPUT: 409;
|
|
10
|
+
NO_LINK: 409;
|
|
11
|
+
NOT_SCHEDULABLE: 409;
|
|
12
|
+
LIMIT_EXCEEDED: 413;
|
|
13
|
+
UNSUPPORTED_FORMAT: 415;
|
|
14
|
+
INVALID_FILE: 422;
|
|
15
|
+
NOT_REGULAR_FILE: 422;
|
|
16
|
+
HARD_LINK: 422;
|
|
17
|
+
INVALID_TEMPLATE: 422;
|
|
18
|
+
BUSY: 503;
|
|
19
|
+
NOT_READY: 503;
|
|
20
|
+
TIMEOUT: 504;
|
|
21
|
+
INTERNAL: 500;
|
|
22
|
+
}>;
|
|
23
|
+
/** An error of an operation a front end shows as it is: a stable code and a message without file content. */
|
|
24
|
+
export declare class OperationError extends Error {
|
|
25
|
+
code: "BUSY" | "FILES_NOT_ALLOWED" | "FILE_NOT_AVAILABLE" | "HARD_LINK" | "INTERNAL" | "INVALID_FILE" | "INVALID_INPUT" | "INVALID_TEMPLATE" | "LIMIT_EXCEEDED" | "NOT_ALLOWED" | "NOT_READY" | "NOT_REGULAR_FILE" | "NOT_SCHEDULABLE" | "NO_LINK" | "NO_OUTPUT" | "SOURCE_NOT_FOUND" | "TIMEOUT" | "UNSUPPORTED_FORMAT";
|
|
26
|
+
status: 400 | 403 | 404 | 409 | 413 | 415 | 422 | 500 | 503 | 504;
|
|
27
|
+
/**
|
|
28
|
+
* @param {keyof typeof OPERATION_ERRORS} code
|
|
29
|
+
* @param {string} message
|
|
30
|
+
*/
|
|
31
|
+
constructor(code: keyof typeof OPERATION_ERRORS, message: string);
|
|
32
|
+
}
|
|
33
|
+
export type Finding = {
|
|
34
|
+
severity: "error" | "warning" | "info";
|
|
35
|
+
code: string;
|
|
36
|
+
path: string;
|
|
37
|
+
message: string;
|
|
38
|
+
/**
|
|
39
|
+
* the name or item meant ("did you mean")
|
|
40
|
+
*/
|
|
41
|
+
suggestion?: string;
|
|
42
|
+
};
|
|
43
|
+
/**
|
|
44
|
+
* @typedef {object} Finding
|
|
45
|
+
* @property {"error" | "warning" | "info"} severity
|
|
46
|
+
* @property {string} code
|
|
47
|
+
* @property {string} path
|
|
48
|
+
* @property {string} message
|
|
49
|
+
* @property {string} [suggestion] the name or item meant ("did you mean")
|
|
50
|
+
*/
|
|
51
|
+
/** The most characters of a name, path or message from outside an operation puts into a finding. */
|
|
52
|
+
export declare const FINDING_TEXT = 200;
|
|
53
|
+
/** Text from a view or the data, as a finding carries it: no control or direction characters, capped. */
|
|
54
|
+
export declare function findingText(text: any): string;
|
|
55
|
+
/**
|
|
56
|
+
* An issue of pivotkit-core (or a reader's note) as a finding.
|
|
57
|
+
* @param {{ severity?: string, code?: string, path?: string, message?: string, params?: { suggestion?: string } }} issue
|
|
58
|
+
* @returns {Finding}
|
|
59
|
+
*/
|
|
60
|
+
export declare function findingOf(issue: {
|
|
61
|
+
severity?: string;
|
|
62
|
+
code?: string;
|
|
63
|
+
path?: string;
|
|
64
|
+
message?: string;
|
|
65
|
+
params?: {
|
|
66
|
+
suggestion?: string;
|
|
67
|
+
};
|
|
68
|
+
}): Finding;
|
|
69
|
+
export type OperationEnv = {
|
|
70
|
+
/**
|
|
71
|
+
* the data of a source (encoded, or only its fields)
|
|
72
|
+
*/
|
|
73
|
+
data?: (source: string) => Promise<SourceData>;
|
|
74
|
+
/**
|
|
75
|
+
* the sources this caller may use
|
|
76
|
+
*/
|
|
77
|
+
sources?: () => Promise<SourceInfo[]>;
|
|
78
|
+
/**
|
|
79
|
+
* where a link to the source's report goes
|
|
80
|
+
*/
|
|
81
|
+
link?: (source: string) => Promise<{
|
|
82
|
+
url: string;
|
|
83
|
+
key?: string | null;
|
|
84
|
+
} | null>;
|
|
85
|
+
/**
|
|
86
|
+
* the print template of a source (the operator's, never the caller's)
|
|
87
|
+
*/
|
|
88
|
+
template?: (source: string) => Promise<string | undefined>;
|
|
89
|
+
/**
|
|
90
|
+
* the ECharts module, for svg and a report with its chart
|
|
91
|
+
*/
|
|
92
|
+
echarts?: {
|
|
93
|
+
init: Function;
|
|
94
|
+
};
|
|
95
|
+
limits?: Partial<import("pivotkit-core").Limits>;
|
|
96
|
+
locale?: string;
|
|
97
|
+
timeZone?: string;
|
|
98
|
+
now?: Date | number | string;
|
|
99
|
+
/**
|
|
100
|
+
* a front end's own render options (the CLI's template, bom, size)
|
|
101
|
+
*/
|
|
102
|
+
renderOptions?: Record<string, unknown>;
|
|
103
|
+
};
|
|
104
|
+
export type SourceData = {
|
|
105
|
+
/**
|
|
106
|
+
* encoded data, or only the fields (a view file's source.fields)
|
|
107
|
+
*/
|
|
108
|
+
data: import("pivotkit-core").Encoded | Array<{
|
|
109
|
+
name: string;
|
|
110
|
+
type: string;
|
|
111
|
+
}>;
|
|
112
|
+
/**
|
|
113
|
+
* how a report names the data (a file's base name, a source's title)
|
|
114
|
+
*/
|
|
115
|
+
name: string;
|
|
116
|
+
/**
|
|
117
|
+
* what reading it noticed
|
|
118
|
+
*/
|
|
119
|
+
notes?: Finding[];
|
|
120
|
+
/**
|
|
121
|
+
* a schedule may run over it (false for a file a person handed in)
|
|
122
|
+
*/
|
|
123
|
+
schedulable?: boolean;
|
|
124
|
+
};
|
|
125
|
+
export type SourceInfo = {
|
|
126
|
+
id: string;
|
|
127
|
+
title: string;
|
|
128
|
+
description?: string;
|
|
129
|
+
kind: "source" | "file";
|
|
130
|
+
/**
|
|
131
|
+
* create_link works for it
|
|
132
|
+
*/
|
|
133
|
+
link: boolean;
|
|
134
|
+
schedulable: boolean;
|
|
135
|
+
};
|
|
136
|
+
export type OperationOutcome = {
|
|
137
|
+
/**
|
|
138
|
+
* what the output schema describes
|
|
139
|
+
*/
|
|
140
|
+
result: Record<string, any>;
|
|
141
|
+
/**
|
|
142
|
+
* a file the front end writes, sends or shows
|
|
143
|
+
*/
|
|
144
|
+
file?: {
|
|
145
|
+
bytes: Uint8Array;
|
|
146
|
+
mediaType: string;
|
|
147
|
+
extension: string;
|
|
148
|
+
name: string;
|
|
149
|
+
};
|
|
150
|
+
};
|
|
151
|
+
export type Operation = {
|
|
152
|
+
name: string;
|
|
153
|
+
title: string;
|
|
154
|
+
/**
|
|
155
|
+
* one paragraph: an MCP tool's description, an OpenAPI operation's, a CLI command's help line
|
|
156
|
+
*/
|
|
157
|
+
description: string;
|
|
158
|
+
/**
|
|
159
|
+
* the CLI command it is, or null
|
|
160
|
+
*/
|
|
161
|
+
cli: string | null;
|
|
162
|
+
http: {
|
|
163
|
+
method: "GET" | "POST";
|
|
164
|
+
path: string;
|
|
165
|
+
};
|
|
166
|
+
needs: Array<keyof OperationEnv>;
|
|
167
|
+
annotations: {
|
|
168
|
+
readOnly: boolean;
|
|
169
|
+
idempotent: boolean;
|
|
170
|
+
writesFile: boolean;
|
|
171
|
+
};
|
|
172
|
+
/**
|
|
173
|
+
* JSON Schema of the input (draft 2020-12)
|
|
174
|
+
*/
|
|
175
|
+
input: Record<string, unknown>;
|
|
176
|
+
/**
|
|
177
|
+
* JSON Schema of `result`
|
|
178
|
+
*/
|
|
179
|
+
output: Record<string, unknown>;
|
|
180
|
+
run: (input: any, env: OperationEnv) => Promise<OperationOutcome>;
|
|
181
|
+
};
|
|
182
|
+
/** How a note of viewFromLayout or suggestLayout counts as a finding. */
|
|
183
|
+
export declare const LAYOUT_NOTE_SEVERITY: Readonly<{
|
|
184
|
+
noSuggestion: "error";
|
|
185
|
+
dateGrouped: "info";
|
|
186
|
+
unusedGroup: "warning";
|
|
187
|
+
unusedMap: "warning";
|
|
188
|
+
}>;
|
|
189
|
+
/**
|
|
190
|
+
* A view from field names, the one way the operations and pivotkit-cli make one: pivotkit-core's
|
|
191
|
+
* viewFromLayout over the source's field description. With `suggest`, suggestLayout's picks come
|
|
192
|
+
* first and the layout's parts replace them (a suggested grouping stays only while its field stays
|
|
193
|
+
* where the suggestion put it); nothing to group by (noSuggestion) counts only while the layout places
|
|
194
|
+
* no field itself. A layout of another shape is INVALID_INPUT, one too large LIMIT_EXCEEDED.
|
|
195
|
+
* @param {ReturnType<typeof describeSource>} description
|
|
196
|
+
* @param {import("pivotkit-core").Layout} layout
|
|
197
|
+
* @param {{ suggest?: boolean, locale?: string }} [options]
|
|
198
|
+
* @returns {{ view: Record<string, any>, name: string, picks: import("pivotkit-core").LayoutPick[], notes: import("pivotkit-core").LayoutNote[] }}
|
|
199
|
+
*/
|
|
200
|
+
export declare function viewOfLayout(description: ReturnType<typeof describeSource>, layout?: import("pivotkit-core").Layout, options?: {
|
|
201
|
+
suggest?: boolean;
|
|
202
|
+
locale?: string;
|
|
203
|
+
}): {
|
|
204
|
+
view: Record<string, any>;
|
|
205
|
+
name: string;
|
|
206
|
+
picks: import("pivotkit-core").LayoutPick[];
|
|
207
|
+
notes: import("pivotkit-core").LayoutNote[];
|
|
208
|
+
};
|
|
209
|
+
/**
|
|
210
|
+
* Two or three views built from a data set's own fields, for a model or a person to start from: a
|
|
211
|
+
* measure is a number field that is no identifier.
|
|
212
|
+
* @param {Array<{ name: string, type: string }>} fields
|
|
213
|
+
*/
|
|
214
|
+
export declare function exampleViews(fields: Array<{
|
|
215
|
+
name: string;
|
|
216
|
+
type: string;
|
|
217
|
+
}>): any[];
|
|
218
|
+
/** The view guide: the format of a view in short, its vocabulary from pivotkit-core's CATALOG, and examples. */
|
|
219
|
+
export declare const VIEW_GUIDE: Readonly<{
|
|
220
|
+
text: string;
|
|
221
|
+
catalog: Readonly<{
|
|
222
|
+
aggregators: readonly string[];
|
|
223
|
+
deriveUnits: readonly string[];
|
|
224
|
+
filterTypes: readonly string[];
|
|
225
|
+
filterFields: Readonly<{
|
|
226
|
+
[k: string]: readonly string[];
|
|
227
|
+
}>;
|
|
228
|
+
textOps: readonly string[];
|
|
229
|
+
compareOps: readonly string[];
|
|
230
|
+
relativeUnits: readonly string[];
|
|
231
|
+
relativeDirections: readonly string[];
|
|
232
|
+
relativeAnchors: readonly string[];
|
|
233
|
+
filterBlanks: readonly string[];
|
|
234
|
+
showAs: readonly string[];
|
|
235
|
+
formats: readonly string[];
|
|
236
|
+
chartTypes: readonly string[];
|
|
237
|
+
displayModes: readonly string[];
|
|
238
|
+
}>;
|
|
239
|
+
examples: readonly ({
|
|
240
|
+
title: string;
|
|
241
|
+
view: {
|
|
242
|
+
version: number;
|
|
243
|
+
rows: string[];
|
|
244
|
+
values: {
|
|
245
|
+
field: string;
|
|
246
|
+
agg: string;
|
|
247
|
+
}[];
|
|
248
|
+
cols?: undefined;
|
|
249
|
+
filters?: undefined;
|
|
250
|
+
derived?: undefined;
|
|
251
|
+
display?: undefined;
|
|
252
|
+
chart?: undefined;
|
|
253
|
+
};
|
|
254
|
+
} | {
|
|
255
|
+
title: string;
|
|
256
|
+
view: {
|
|
257
|
+
version: number;
|
|
258
|
+
rows: string[];
|
|
259
|
+
cols: string[];
|
|
260
|
+
derived: {
|
|
261
|
+
name: string;
|
|
262
|
+
field: string;
|
|
263
|
+
by: string;
|
|
264
|
+
}[];
|
|
265
|
+
values: {
|
|
266
|
+
field: string;
|
|
267
|
+
agg: string;
|
|
268
|
+
}[];
|
|
269
|
+
filters?: undefined;
|
|
270
|
+
display?: undefined;
|
|
271
|
+
chart?: undefined;
|
|
272
|
+
};
|
|
273
|
+
} | {
|
|
274
|
+
title: string;
|
|
275
|
+
view: {
|
|
276
|
+
cols?: undefined;
|
|
277
|
+
version: number;
|
|
278
|
+
rows: string[];
|
|
279
|
+
values: {
|
|
280
|
+
field: string;
|
|
281
|
+
agg: string;
|
|
282
|
+
}[];
|
|
283
|
+
filters: ({
|
|
284
|
+
field: string;
|
|
285
|
+
type: string;
|
|
286
|
+
direction: string;
|
|
287
|
+
count: number;
|
|
288
|
+
unit: string;
|
|
289
|
+
anchor: string;
|
|
290
|
+
blanks: string;
|
|
291
|
+
by?: undefined;
|
|
292
|
+
} | {
|
|
293
|
+
direction?: undefined;
|
|
294
|
+
unit?: undefined;
|
|
295
|
+
anchor?: undefined;
|
|
296
|
+
blanks?: undefined;
|
|
297
|
+
field: string;
|
|
298
|
+
type: string;
|
|
299
|
+
count: number;
|
|
300
|
+
by: {
|
|
301
|
+
field: string;
|
|
302
|
+
agg: string;
|
|
303
|
+
};
|
|
304
|
+
})[];
|
|
305
|
+
derived?: undefined;
|
|
306
|
+
display?: undefined;
|
|
307
|
+
chart?: undefined;
|
|
308
|
+
};
|
|
309
|
+
} | {
|
|
310
|
+
title: string;
|
|
311
|
+
view: {
|
|
312
|
+
cols?: undefined;
|
|
313
|
+
filters?: undefined;
|
|
314
|
+
version: number;
|
|
315
|
+
rows: string[];
|
|
316
|
+
derived: {
|
|
317
|
+
name: string;
|
|
318
|
+
field: string;
|
|
319
|
+
by: string;
|
|
320
|
+
}[];
|
|
321
|
+
values: {
|
|
322
|
+
agg: string;
|
|
323
|
+
}[];
|
|
324
|
+
display: string;
|
|
325
|
+
chart: {
|
|
326
|
+
type: string;
|
|
327
|
+
};
|
|
328
|
+
};
|
|
329
|
+
} | {
|
|
330
|
+
title: string;
|
|
331
|
+
view: {
|
|
332
|
+
cols?: undefined;
|
|
333
|
+
filters?: undefined;
|
|
334
|
+
derived?: undefined;
|
|
335
|
+
display?: undefined;
|
|
336
|
+
chart?: undefined;
|
|
337
|
+
version: number;
|
|
338
|
+
rows: string[];
|
|
339
|
+
values: {
|
|
340
|
+
field: string;
|
|
341
|
+
agg: string;
|
|
342
|
+
showAs: {
|
|
343
|
+
type: string;
|
|
344
|
+
};
|
|
345
|
+
}[];
|
|
346
|
+
};
|
|
347
|
+
})[];
|
|
348
|
+
}>;
|
|
349
|
+
/**
|
|
350
|
+
* Checks an input against an operation's input schema, for the JSON Schema keywords the table uses
|
|
351
|
+
* (type, enum, required, properties, additionalProperties: false, items, min/max length, items and
|
|
352
|
+
* value, pattern, uniqueItems, maxProperties, additionalProperties as a schema). Every `run` calls it first, so a front end without a validator of its
|
|
353
|
+
* own (a REST service, a script) gets INVALID_INPUT naming the place, never a TypeError.
|
|
354
|
+
* @param {Record<string, unknown>} schema
|
|
355
|
+
* @param {unknown} value
|
|
356
|
+
* @param {string} [path]
|
|
357
|
+
*/
|
|
358
|
+
export declare function checkInput(schema: Record<string, unknown>, value: unknown, path?: string): void;
|
|
359
|
+
/** @type {Readonly<Record<string, Operation>>} */
|
|
360
|
+
export declare const OPERATIONS: Readonly<Record<string, Operation>>;
|
|
361
|
+
/** The operations' names, in the table's order. */
|
|
362
|
+
export declare const OPERATION_NAMES: readonly string[];
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
/** The formats: media type, file extension, and whether the body is text (`text` is set). */
|
|
2
|
+
export declare const RENDER_FORMATS: Readonly<{
|
|
3
|
+
json: Readonly<{
|
|
4
|
+
mediaType: "application/json";
|
|
5
|
+
extension: "json";
|
|
6
|
+
text: true;
|
|
7
|
+
}>;
|
|
8
|
+
csv: Readonly<{
|
|
9
|
+
mediaType: "text/csv;charset=utf-8";
|
|
10
|
+
extension: "csv";
|
|
11
|
+
text: true;
|
|
12
|
+
}>;
|
|
13
|
+
xlsx: Readonly<{
|
|
14
|
+
mediaType: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
|
|
15
|
+
extension: "xlsx";
|
|
16
|
+
text: false;
|
|
17
|
+
}>;
|
|
18
|
+
svg: Readonly<{
|
|
19
|
+
mediaType: "image/svg+xml";
|
|
20
|
+
extension: "svg";
|
|
21
|
+
text: true;
|
|
22
|
+
}>;
|
|
23
|
+
html: Readonly<{
|
|
24
|
+
mediaType: "text/html;charset=utf-8";
|
|
25
|
+
extension: "html";
|
|
26
|
+
text: true;
|
|
27
|
+
}>;
|
|
28
|
+
}>;
|
|
29
|
+
/**
|
|
30
|
+
* What a report allows at most, besides pivotkit-core's LIMITS: the characters of a template, the size
|
|
31
|
+
* of a chart in px, the cells of a report's table (a larger table is cut after the last whole row, and
|
|
32
|
+
* says so), the categories of a chart (the first ones, as on the screen).
|
|
33
|
+
*/
|
|
34
|
+
export declare const REPORT_LIMITS: Readonly<{
|
|
35
|
+
template: 262144;
|
|
36
|
+
chartWidth: 8000;
|
|
37
|
+
chartHeight: 8000;
|
|
38
|
+
tableCells: 200000;
|
|
39
|
+
categories: 50;
|
|
40
|
+
}>;
|
|
41
|
+
/** The default size of a chart in px. */
|
|
42
|
+
export declare const CHART_SIZE: Readonly<{
|
|
43
|
+
width: 800;
|
|
44
|
+
height: 480;
|
|
45
|
+
}>;
|
|
46
|
+
/** Issues of a report itself (warnings), besides a view's (VIEW_ISSUES). */
|
|
47
|
+
export declare const REPORT_ISSUE_CODES: readonly string[];
|
|
48
|
+
export type RenderOptions = {
|
|
49
|
+
/**
|
|
50
|
+
* default "html"
|
|
51
|
+
*/
|
|
52
|
+
format?: "json" | "csv" | "xlsx" | "svg" | "html";
|
|
53
|
+
/**
|
|
54
|
+
* used when the view names none; default "en-US"
|
|
55
|
+
*/
|
|
56
|
+
locale?: string;
|
|
57
|
+
/**
|
|
58
|
+
* of rows that are not encoded yet (encode()), and of the "generated" time; default "UTC"
|
|
59
|
+
*/
|
|
60
|
+
timeZone?: string;
|
|
61
|
+
/**
|
|
62
|
+
* "today" of relative date filters and the "generated" time; fix it for output that is the same on every run
|
|
63
|
+
*/
|
|
64
|
+
now?: Date | number | string;
|
|
65
|
+
/**
|
|
66
|
+
* pivotkit-core's limits
|
|
67
|
+
*/
|
|
68
|
+
limits?: Partial<import("pivotkit-core").Limits>;
|
|
69
|
+
/**
|
|
70
|
+
* the view is the host's own: the host's limits instead of outsideLimits() (default false)
|
|
71
|
+
*/
|
|
72
|
+
trusted?: boolean;
|
|
73
|
+
/**
|
|
74
|
+
* no body when the view has an error (default false: the normalized view is rendered)
|
|
75
|
+
*/
|
|
76
|
+
strict?: boolean;
|
|
77
|
+
/**
|
|
78
|
+
* pivotkit-core's texts (totals, value names)
|
|
79
|
+
*/
|
|
80
|
+
labels?: Partial<import("pivotkit-core").Labels>;
|
|
81
|
+
/**
|
|
82
|
+
* the report's words around the table
|
|
83
|
+
*/
|
|
84
|
+
texts?: Partial<import("./texts.js").ReportTexts>;
|
|
85
|
+
/**
|
|
86
|
+
* --pk-* colours over the light ones (the chart and the report)
|
|
87
|
+
*/
|
|
88
|
+
tokens?: Record<string, string>;
|
|
89
|
+
/**
|
|
90
|
+
* the report's title; default the view file's name, the chart's title, "Report"
|
|
91
|
+
*/
|
|
92
|
+
title?: string;
|
|
93
|
+
/**
|
|
94
|
+
* default the view file's description
|
|
95
|
+
*/
|
|
96
|
+
description?: string;
|
|
97
|
+
/**
|
|
98
|
+
* where the data comes from, for the report's details (a file name)
|
|
99
|
+
*/
|
|
100
|
+
source?: string;
|
|
101
|
+
/**
|
|
102
|
+
* html: a print template (parseTemplate), default DEFAULT_TEMPLATE
|
|
103
|
+
*/
|
|
104
|
+
template?: string;
|
|
105
|
+
/**
|
|
106
|
+
* html: with the chart; "auto" (default) when the view shows the chart
|
|
107
|
+
*/
|
|
108
|
+
chart?: boolean | "auto";
|
|
109
|
+
/**
|
|
110
|
+
* html: the chart as a data: image (default) or as inline SVG
|
|
111
|
+
*/
|
|
112
|
+
chartEmbed?: "image" | "inline";
|
|
113
|
+
/**
|
|
114
|
+
* the ECharts module (with its SVG renderer): svg, and html with a chart
|
|
115
|
+
*/
|
|
116
|
+
echarts?: {
|
|
117
|
+
init: Function;
|
|
118
|
+
};
|
|
119
|
+
/**
|
|
120
|
+
* of the chart in px, default 800 x 480
|
|
121
|
+
*/
|
|
122
|
+
size?: {
|
|
123
|
+
width?: number;
|
|
124
|
+
height?: number;
|
|
125
|
+
};
|
|
126
|
+
/**
|
|
127
|
+
* html: cells of the table at most, default REPORT_LIMITS.tableCells
|
|
128
|
+
*/
|
|
129
|
+
tableCells?: number;
|
|
130
|
+
/**
|
|
131
|
+
* csv: start with a byte order mark, so Excel reads it as UTF-8 (default true)
|
|
132
|
+
*/
|
|
133
|
+
bom?: boolean;
|
|
134
|
+
};
|
|
135
|
+
export type RenderResult = {
|
|
136
|
+
format: string;
|
|
137
|
+
mediaType: string;
|
|
138
|
+
extension: string;
|
|
139
|
+
/**
|
|
140
|
+
* the file; null when `strict` and the view has an error
|
|
141
|
+
*/
|
|
142
|
+
body: Uint8Array | null;
|
|
143
|
+
/**
|
|
144
|
+
* the body as text, for json, csv, svg and html
|
|
145
|
+
*/
|
|
146
|
+
text?: string;
|
|
147
|
+
/**
|
|
148
|
+
* the view's issues, then the report's (REPORT_ISSUE_CODES)
|
|
149
|
+
*/
|
|
150
|
+
issues: import("pivotkit-core").Issue[];
|
|
151
|
+
/**
|
|
152
|
+
* no issue of severity "error"
|
|
153
|
+
*/
|
|
154
|
+
ok: boolean;
|
|
155
|
+
/**
|
|
156
|
+
* the table's body rows and columns, the data's rows, the rows its filters keep, whether a part was cut
|
|
157
|
+
*/
|
|
158
|
+
summary: {
|
|
159
|
+
rows: number;
|
|
160
|
+
columns: number;
|
|
161
|
+
sourceRows: number;
|
|
162
|
+
keptRows: number;
|
|
163
|
+
truncated: boolean;
|
|
164
|
+
} | null;
|
|
165
|
+
/**
|
|
166
|
+
* the normalized view that was rendered
|
|
167
|
+
*/
|
|
168
|
+
view: import("pivotkit-core").View | null;
|
|
169
|
+
};
|
|
170
|
+
/**
|
|
171
|
+
* Renders a view over data as a file.
|
|
172
|
+
* @param {unknown} view a view, a view file or a template { name, view }, as an object or JSON text
|
|
173
|
+
* @param {unknown} data rows, columnar data ({ columns, types, data }) or encode()'s result
|
|
174
|
+
* @param {RenderOptions} [options]
|
|
175
|
+
* @returns {Promise<RenderResult>}
|
|
176
|
+
*/
|
|
177
|
+
export declare function render(view: unknown, data: unknown, options?: RenderOptions): Promise<RenderResult>;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/** Columns from which a printed table is turned to landscape, and from which its font gets smaller. */
|
|
2
|
+
export declare const PRINT_WIDE: Readonly<{
|
|
3
|
+
landscape: 8;
|
|
4
|
+
small: 16;
|
|
5
|
+
}>;
|
|
6
|
+
/**
|
|
7
|
+
* @param {{ columns: number, tokens?: Record<string, string>, extra?: string }} options
|
|
8
|
+
* columns: the table's; tokens: the host's (cleaned), over the light ones; extra: the cells' colour rules
|
|
9
|
+
*/
|
|
10
|
+
export declare function reportCss({ columns, tokens, extra }: {
|
|
11
|
+
columns: number;
|
|
12
|
+
tokens?: Record<string, string>;
|
|
13
|
+
extra?: string;
|
|
14
|
+
}): string;
|
package/types/svg.d.ts
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Checks an SVG string and makes it safe to open and to show under a strict Content-Security-Policy:
|
|
3
|
+
* only the elements an ECharts chart draws, no event handler attribute, no link but to a fragment or
|
|
4
|
+
* a data: image, no attribute name but a plain one, no namespace but SVG's and xlink's, no text that is not escaped; every `style` attribute becomes presentation attributes
|
|
5
|
+
* (a policy without 'unsafe-inline' blocks style attributes, not those) and a <style> element (ECharts'
|
|
6
|
+
* hover states) and characters XML does not allow, also as numeric references, are left out. Throws INVALID_ARGUMENT
|
|
7
|
+
* (`details.reason`) for anything else.
|
|
8
|
+
* @param {string} svg
|
|
9
|
+
* @returns {string}
|
|
10
|
+
*/
|
|
11
|
+
export declare function cleanSvg(svg: string): string;
|
|
12
|
+
/**
|
|
13
|
+
* The chart of a pivot as SVG, as pivotkit-react draws it: chartPlan's type (the view's, or what
|
|
14
|
+
* "auto" picks; rows and columns swapped for the chart where it says so), the theme's colours from
|
|
15
|
+
* `style`, the axis labels laid out for the size, at most `maxCategories` categories.
|
|
16
|
+
* @param {import("pivotkit-core").PivotResult} result
|
|
17
|
+
* @param {{ echarts: { init: Function }, style: { getPropertyValue(name: string): string }, width: number, height: number,
|
|
18
|
+
* locale: string, labels?: object, limits?: object, now?: any, maxCategories: number }} options
|
|
19
|
+
* @returns {{ svg: string, categories: number, of: number }}
|
|
20
|
+
*/
|
|
21
|
+
export declare function chartSvg(result: import("pivotkit-core").PivotResult, { echarts, style, width, height, locale, labels, limits, now, maxCategories }: {
|
|
22
|
+
echarts: {
|
|
23
|
+
init: Function;
|
|
24
|
+
};
|
|
25
|
+
style: {
|
|
26
|
+
getPropertyValue(name: string): string;
|
|
27
|
+
};
|
|
28
|
+
width: number;
|
|
29
|
+
height: number;
|
|
30
|
+
locale: string;
|
|
31
|
+
labels?: object;
|
|
32
|
+
limits?: object;
|
|
33
|
+
now?: any;
|
|
34
|
+
maxCategories: number;
|
|
35
|
+
}): {
|
|
36
|
+
svg: string;
|
|
37
|
+
categories: number;
|
|
38
|
+
of: number;
|
|
39
|
+
};
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/** Characters a template may have. */
|
|
2
|
+
export declare const TEMPLATE_LIMIT = 262144;
|
|
3
|
+
/**
|
|
4
|
+
* The placeholders: text (escaped) and markup (built by pivotkit from escaped parts).
|
|
5
|
+
* @type {Readonly<Record<string, "text" | "markup">>}
|
|
6
|
+
*/
|
|
7
|
+
export declare const PLACEHOLDERS: Readonly<Record<string, "text" | "markup">>;
|
|
8
|
+
/** Attributes whose quoted value may hold a text placeholder. */
|
|
9
|
+
export declare const ATTRIBUTES: readonly string[];
|
|
10
|
+
export type Slot = {
|
|
11
|
+
name: string;
|
|
12
|
+
kind: "text" | "markup";
|
|
13
|
+
};
|
|
14
|
+
export type Template = {
|
|
15
|
+
parts: Array<string | Slot>;
|
|
16
|
+
names: string[];
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* @typedef {{ name: string, kind: "text" | "markup" }} Slot
|
|
20
|
+
* @typedef {{ parts: Array<string | Slot>, names: string[] }} Template the template's text cut at its placeholders
|
|
21
|
+
*/
|
|
22
|
+
/** Escapes text for HTML text content and quoted attribute values; bidi controls are left out. */
|
|
23
|
+
export declare function escapeHtml(text: any): string;
|
|
24
|
+
/**
|
|
25
|
+
* Checks a template and cuts it at its placeholders. Throws INVALID_TEMPLATE (see above).
|
|
26
|
+
* @param {string} source
|
|
27
|
+
* @returns {Template}
|
|
28
|
+
*/
|
|
29
|
+
export declare function parseTemplate(source: string): Template;
|
|
30
|
+
/**
|
|
31
|
+
* The template with its placeholders filled: text values escaped, markup values as given (built by
|
|
32
|
+
* pivotkit). A placeholder without a value is empty.
|
|
33
|
+
* @param {Template} template from parseTemplate()
|
|
34
|
+
* @param {Partial<Record<string, string>>} values
|
|
35
|
+
* @returns {string}
|
|
36
|
+
*/
|
|
37
|
+
export declare function fillTemplate(template: Template, values: Partial<Record<string, string>>): string;
|
package/types/texts.d.ts
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The characters that change the direction of text, as pivotkit-core's import leaves them out: a report
|
|
3
|
+
* writes none of them (HTML, SVG), so no name reads as another one ("invoice\u202Etxt.exe").
|
|
4
|
+
*/
|
|
5
|
+
export declare const BIDI_CONTROLS: RegExp;
|
|
6
|
+
export declare const REPORT_TEXTS: Readonly<{
|
|
7
|
+
en: Readonly<{
|
|
8
|
+
untitled: "Report";
|
|
9
|
+
source: "Source";
|
|
10
|
+
rows: "Rows";
|
|
11
|
+
rowsCount: "{count} rows";
|
|
12
|
+
generated: "Generated";
|
|
13
|
+
filters: "Filters";
|
|
14
|
+
noFilters: "None";
|
|
15
|
+
chart: "Chart";
|
|
16
|
+
tableCut: "The table shows the first {shown} of {count} rows. Export it as Excel or CSV for all of them.";
|
|
17
|
+
chartCut: "The chart shows the first {shown} of {count} categories.";
|
|
18
|
+
chartUnavailable: "The chart is left out: ECharts is not available.";
|
|
19
|
+
}>;
|
|
20
|
+
de: Readonly<{
|
|
21
|
+
untitled: "Bericht";
|
|
22
|
+
source: "Quelle";
|
|
23
|
+
rows: "Zeilen";
|
|
24
|
+
rowsCount: "{count} Zeilen";
|
|
25
|
+
generated: "Erstellt";
|
|
26
|
+
filters: "Filter";
|
|
27
|
+
noFilters: "Keine";
|
|
28
|
+
chart: "Diagramm";
|
|
29
|
+
tableCut: "Die Tabelle zeigt die ersten {shown} von {count} Zeilen. Für alle als Excel oder CSV exportieren.";
|
|
30
|
+
chartCut: "Das Diagramm zeigt die ersten {shown} von {count} Kategorien.";
|
|
31
|
+
chartUnavailable: "Das Diagramm fehlt: ECharts ist nicht verfügbar.";
|
|
32
|
+
}>;
|
|
33
|
+
}>;
|
|
34
|
+
export type ReportTexts = typeof REPORT_TEXTS.en;
|
|
35
|
+
/** @typedef {typeof REPORT_TEXTS.en} ReportTexts */
|
|
36
|
+
/**
|
|
37
|
+
* The texts for a locale, the host's over them.
|
|
38
|
+
* @param {string} locale
|
|
39
|
+
* @param {Partial<ReportTexts>} [own]
|
|
40
|
+
* @returns {ReportTexts}
|
|
41
|
+
*/
|
|
42
|
+
export declare function textsFor(locale: string, own?: Partial<ReportTexts>): ReportTexts;
|
|
43
|
+
/** "{count} rows" with its values. */
|
|
44
|
+
export declare const fill: (text: any, values: any) => any;
|