@smallwebco/tinypivot-core 1.0.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/dist/export/index.d.ts +43 -0
- package/dist/export/index.d.ts.map +1 -0
- package/dist/export/index.js +164 -0
- package/dist/export/index.js.map +1 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +15 -0
- package/dist/index.js.map +1 -0
- package/dist/license/index.d.ts +38 -0
- package/dist/license/index.d.ts.map +1 -0
- package/dist/license/index.js +159 -0
- package/dist/license/index.js.map +1 -0
- package/dist/pivot/index.d.ts +62 -0
- package/dist/pivot/index.d.ts.map +1 -0
- package/dist/pivot/index.js +328 -0
- package/dist/pivot/index.js.map +1 -0
- package/dist/types/index.d.ts +154 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +6 -0
- package/dist/types/index.js.map +1 -0
- package/dist/utils/index.d.ts +48 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +176 -0
- package/dist/utils/index.js.map +1 -0
- package/package.json +25 -0
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TinyPivot Core - Export Utilities
|
|
3
|
+
* CSV export, clipboard operations - no framework dependencies
|
|
4
|
+
*/
|
|
5
|
+
import type { ExportOptions, PivotValueField, SelectionBounds } from '../types';
|
|
6
|
+
/**
|
|
7
|
+
* Pivot table export interface
|
|
8
|
+
*/
|
|
9
|
+
export interface PivotExportData {
|
|
10
|
+
headers: string[][];
|
|
11
|
+
rowHeaders: string[][];
|
|
12
|
+
data: Array<Array<{
|
|
13
|
+
formattedValue: string;
|
|
14
|
+
}>>;
|
|
15
|
+
rowTotals?: Array<{
|
|
16
|
+
formattedValue: string;
|
|
17
|
+
}>;
|
|
18
|
+
columnTotals?: Array<{
|
|
19
|
+
formattedValue: string;
|
|
20
|
+
}>;
|
|
21
|
+
grandTotal?: {
|
|
22
|
+
formattedValue: string;
|
|
23
|
+
};
|
|
24
|
+
showRowTotals?: boolean;
|
|
25
|
+
showColumnTotals?: boolean;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* CSV Export functionality
|
|
29
|
+
*/
|
|
30
|
+
export declare function exportToCSV<T extends Record<string, unknown>>(data: T[], columns: string[], options?: ExportOptions): void;
|
|
31
|
+
/**
|
|
32
|
+
* Export pivot table to CSV
|
|
33
|
+
*/
|
|
34
|
+
export declare function exportPivotToCSV(pivotData: PivotExportData, rowFields: string[], _columnFields: string[], valueFields: PivotValueField[], options?: ExportOptions): void;
|
|
35
|
+
/**
|
|
36
|
+
* Copy text to clipboard
|
|
37
|
+
*/
|
|
38
|
+
export declare function copyToClipboard(text: string, onSuccess?: () => void, onError?: (err: Error) => void): void;
|
|
39
|
+
/**
|
|
40
|
+
* Format selected cells for clipboard (tab-separated)
|
|
41
|
+
*/
|
|
42
|
+
export declare function formatSelectionForClipboard<T extends Record<string, unknown>>(rows: T[], columns: string[], selectionBounds: SelectionBounds): string;
|
|
43
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/export/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,EAAE,aAAa,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,UAAU,CAAA;AAE/E;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,EAAE,EAAE,CAAA;IACnB,UAAU,EAAE,MAAM,EAAE,EAAE,CAAA;IACtB,IAAI,EAAE,KAAK,CAAC,KAAK,CAAC;QAAE,cAAc,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC,CAAA;IAC9C,SAAS,CAAC,EAAE,KAAK,CAAC;QAAE,cAAc,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;IAC7C,YAAY,CAAC,EAAE,KAAK,CAAC;QAAE,cAAc,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;IAChD,UAAU,CAAC,EAAE;QAAE,cAAc,EAAE,MAAM,CAAA;KAAE,CAAA;IACvC,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,gBAAgB,CAAC,EAAE,OAAO,CAAA;CAC3B;AAcD;;GAEG;AACH,wBAAgB,WAAW,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC3D,IAAI,EAAE,CAAC,EAAE,EACT,OAAO,EAAE,MAAM,EAAE,EACjB,OAAO,GAAE,aAAkB,GAC1B,IAAI,CAgBN;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAC9B,SAAS,EAAE,eAAe,EAC1B,SAAS,EAAE,MAAM,EAAE,EACnB,aAAa,EAAE,MAAM,EAAE,EACvB,WAAW,EAAE,eAAe,EAAE,EAC9B,OAAO,GAAE,aAAkB,GAC1B,IAAI,CAiGN;AAmBD;;GAEG;AACH,wBAAgB,eAAe,CAC7B,IAAI,EAAE,MAAM,EACZ,SAAS,CAAC,EAAE,MAAM,IAAI,EACtB,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,KAAK,KAAK,IAAI,GAC7B,IAAI,CAEN;AAED;;GAEG;AACH,wBAAgB,2BAA2B,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC3E,IAAI,EAAE,CAAC,EAAE,EACT,OAAO,EAAE,MAAM,EAAE,EACjB,eAAe,EAAE,eAAe,GAC/B,MAAM,CAkBR"}
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Escape CSV value
|
|
3
|
+
*/
|
|
4
|
+
function escapeCSV(value, delimiter = ',') {
|
|
5
|
+
if (value === null || value === undefined)
|
|
6
|
+
return '';
|
|
7
|
+
const str = String(value);
|
|
8
|
+
if (str.includes(delimiter) || str.includes('"') || str.includes('\n')) {
|
|
9
|
+
return `"${str.replace(/"/g, '""')}"`;
|
|
10
|
+
}
|
|
11
|
+
return str;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* CSV Export functionality
|
|
15
|
+
*/
|
|
16
|
+
export function exportToCSV(data, columns, options = {}) {
|
|
17
|
+
const { filename = 'export.csv', includeHeaders = true, delimiter = ',' } = options;
|
|
18
|
+
const rows = [];
|
|
19
|
+
if (includeHeaders) {
|
|
20
|
+
rows.push(columns.map(col => escapeCSV(col, delimiter)).join(delimiter));
|
|
21
|
+
}
|
|
22
|
+
for (const row of data) {
|
|
23
|
+
const values = columns.map(col => escapeCSV(row[col], delimiter));
|
|
24
|
+
rows.push(values.join(delimiter));
|
|
25
|
+
}
|
|
26
|
+
const csvContent = rows.join('\n');
|
|
27
|
+
downloadFile(csvContent, filename, 'text/csv;charset=utf-8;');
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Export pivot table to CSV
|
|
31
|
+
*/
|
|
32
|
+
export function exportPivotToCSV(pivotData, rowFields, _columnFields, valueFields, options = {}) {
|
|
33
|
+
const { filename = 'pivot-export.csv', delimiter = ',' } = options;
|
|
34
|
+
const rows = [];
|
|
35
|
+
const { headers, rowHeaders, data, rowTotals, columnTotals, grandTotal, showRowTotals, showColumnTotals } = pivotData;
|
|
36
|
+
// Calculate number of row header columns
|
|
37
|
+
const rowHeaderColCount = rowFields.length || 1;
|
|
38
|
+
// Build column headers
|
|
39
|
+
if (headers.length > 0) {
|
|
40
|
+
// Multi-level column headers
|
|
41
|
+
for (let level = 0; level < headers.length; level++) {
|
|
42
|
+
const headerRow = [];
|
|
43
|
+
// Empty cells for row field columns
|
|
44
|
+
for (let i = 0; i < rowHeaderColCount; i++) {
|
|
45
|
+
headerRow.push(level === headers.length - 1 ? escapeCSV(rowFields[i] || '', delimiter) : '');
|
|
46
|
+
}
|
|
47
|
+
// Column header values
|
|
48
|
+
for (const val of headers[level]) {
|
|
49
|
+
headerRow.push(escapeCSV(val, delimiter));
|
|
50
|
+
}
|
|
51
|
+
// Row totals header
|
|
52
|
+
if (showRowTotals && rowTotals && rowTotals.length > 0) {
|
|
53
|
+
if (level === headers.length - 1) {
|
|
54
|
+
for (const vf of valueFields) {
|
|
55
|
+
headerRow.push(escapeCSV(`Total (${vf.aggregation})`, delimiter));
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
for (let i = 0; i < valueFields.length; i++) {
|
|
60
|
+
headerRow.push('');
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
rows.push(headerRow.join(delimiter));
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
else {
|
|
68
|
+
// Simple header with value fields only
|
|
69
|
+
const headerRow = [];
|
|
70
|
+
for (let i = 0; i < rowHeaderColCount; i++) {
|
|
71
|
+
headerRow.push(escapeCSV(rowFields[i] || '', delimiter));
|
|
72
|
+
}
|
|
73
|
+
for (const vf of valueFields) {
|
|
74
|
+
headerRow.push(escapeCSV(`${vf.field} (${vf.aggregation})`, delimiter));
|
|
75
|
+
}
|
|
76
|
+
if (showRowTotals && rowTotals && rowTotals.length > 0) {
|
|
77
|
+
headerRow.push(escapeCSV('Total', delimiter));
|
|
78
|
+
}
|
|
79
|
+
rows.push(headerRow.join(delimiter));
|
|
80
|
+
}
|
|
81
|
+
// Build data rows
|
|
82
|
+
for (let rowIdx = 0; rowIdx < rowHeaders.length; rowIdx++) {
|
|
83
|
+
const csvRow = [];
|
|
84
|
+
// Row headers
|
|
85
|
+
const rowHeader = rowHeaders[rowIdx] || [];
|
|
86
|
+
for (let i = 0; i < rowHeaderColCount; i++) {
|
|
87
|
+
csvRow.push(escapeCSV(rowHeader[i] || '', delimiter));
|
|
88
|
+
}
|
|
89
|
+
// Data cells
|
|
90
|
+
const rowData = data[rowIdx] || [];
|
|
91
|
+
for (const cell of rowData) {
|
|
92
|
+
csvRow.push(escapeCSV(cell?.formattedValue || '', delimiter));
|
|
93
|
+
}
|
|
94
|
+
// Row total
|
|
95
|
+
if (showRowTotals && rowTotals && rowTotals[rowIdx]) {
|
|
96
|
+
csvRow.push(escapeCSV(rowTotals[rowIdx].formattedValue || '', delimiter));
|
|
97
|
+
}
|
|
98
|
+
rows.push(csvRow.join(delimiter));
|
|
99
|
+
}
|
|
100
|
+
// Column totals row
|
|
101
|
+
if (showColumnTotals && columnTotals && columnTotals.length > 0) {
|
|
102
|
+
const totalsRow = [];
|
|
103
|
+
// Label for totals row
|
|
104
|
+
totalsRow.push(escapeCSV('Total', delimiter));
|
|
105
|
+
for (let i = 1; i < rowHeaderColCount; i++) {
|
|
106
|
+
totalsRow.push('');
|
|
107
|
+
}
|
|
108
|
+
// Column total values
|
|
109
|
+
for (const cell of columnTotals) {
|
|
110
|
+
totalsRow.push(escapeCSV(cell?.formattedValue || '', delimiter));
|
|
111
|
+
}
|
|
112
|
+
// Grand total
|
|
113
|
+
if (showRowTotals && grandTotal) {
|
|
114
|
+
totalsRow.push(escapeCSV(grandTotal.formattedValue || '', delimiter));
|
|
115
|
+
}
|
|
116
|
+
rows.push(totalsRow.join(delimiter));
|
|
117
|
+
}
|
|
118
|
+
const csvContent = rows.join('\n');
|
|
119
|
+
downloadFile(csvContent, filename, 'text/csv;charset=utf-8;');
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Download file helper
|
|
123
|
+
*/
|
|
124
|
+
function downloadFile(content, filename, mimeType) {
|
|
125
|
+
const blob = new Blob([content], { type: mimeType });
|
|
126
|
+
const url = URL.createObjectURL(blob);
|
|
127
|
+
const link = document.createElement('a');
|
|
128
|
+
link.href = url;
|
|
129
|
+
link.download = filename;
|
|
130
|
+
link.style.display = 'none';
|
|
131
|
+
document.body.appendChild(link);
|
|
132
|
+
link.click();
|
|
133
|
+
document.body.removeChild(link);
|
|
134
|
+
URL.revokeObjectURL(url);
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Copy text to clipboard
|
|
138
|
+
*/
|
|
139
|
+
export function copyToClipboard(text, onSuccess, onError) {
|
|
140
|
+
navigator.clipboard.writeText(text).then(onSuccess).catch(onError);
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Format selected cells for clipboard (tab-separated)
|
|
144
|
+
*/
|
|
145
|
+
export function formatSelectionForClipboard(rows, columns, selectionBounds) {
|
|
146
|
+
const { minRow, maxRow, minCol, maxCol } = selectionBounds;
|
|
147
|
+
const lines = [];
|
|
148
|
+
for (let r = minRow; r <= maxRow; r++) {
|
|
149
|
+
const row = rows[r];
|
|
150
|
+
if (!row)
|
|
151
|
+
continue;
|
|
152
|
+
const values = [];
|
|
153
|
+
for (let c = minCol; c <= maxCol; c++) {
|
|
154
|
+
const colId = columns[c];
|
|
155
|
+
if (!colId)
|
|
156
|
+
continue;
|
|
157
|
+
const value = row[colId];
|
|
158
|
+
values.push(value === null || value === undefined ? '' : String(value));
|
|
159
|
+
}
|
|
160
|
+
lines.push(values.join('\t'));
|
|
161
|
+
}
|
|
162
|
+
return lines.join('\n');
|
|
163
|
+
}
|
|
164
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/export/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TinyPivot Core
|
|
3
|
+
* Framework-agnostic core logic for pivot tables and data grids
|
|
4
|
+
*
|
|
5
|
+
* @packageDocumentation
|
|
6
|
+
*/
|
|
7
|
+
export type { ColumnStats, GridOptions, AggregationFunction, PivotField, PivotValueField, PivotConfig, PivotCell, PivotResult, FieldStats, DataGridProps, PivotTableProps, LicenseType, LicenseInfo, LicenseFeatures, FilterEvent, SortEvent, CellClickEvent, SelectionChangeEvent, RowSelectionChangeEvent, ExportEvent, CopyEvent, PaginationOptions, ExportOptions, SelectionBounds, ColumnFilter, ActiveFilter, } from './types';
|
|
8
|
+
export { detectColumnType, detectFieldType, getColumnUniqueValues, formatCellValue, formatNumber, makeKey, parseKey, naturalSort, debounce, clamp, } from './utils';
|
|
9
|
+
export { aggregate, formatAggregatedValue, getAggregationLabel, getAggregationSymbol, AGGREGATION_OPTIONS, computeAvailableFields, getUnassignedFields, isPivotConfigured, computePivotResult, generateStorageKey, savePivotConfig, loadPivotConfig, isConfigValidForFields, } from './pivot';
|
|
10
|
+
export { validateLicenseKey, configureLicenseSecret, getDemoLicenseInfo, getFreeLicenseInfo, canUsePivot, isPro, shouldShowWatermark, logProRequired, } from './license';
|
|
11
|
+
export { exportToCSV, exportPivotToCSV, copyToClipboard, formatSelectionForClipboard, } from './export';
|
|
12
|
+
export type { PivotExportData } from './export';
|
|
13
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,YAAY,EAEV,WAAW,EACX,WAAW,EAGX,mBAAmB,EACnB,UAAU,EACV,eAAe,EACf,WAAW,EACX,SAAS,EACT,WAAW,EACX,UAAU,EAGV,aAAa,EACb,eAAe,EAGf,WAAW,EACX,WAAW,EACX,eAAe,EAGf,WAAW,EACX,SAAS,EACT,cAAc,EACd,oBAAoB,EACpB,uBAAuB,EACvB,WAAW,EACX,SAAS,EAGT,iBAAiB,EACjB,aAAa,EACb,eAAe,EACf,YAAY,EACZ,YAAY,GACb,MAAM,SAAS,CAAA;AAGhB,OAAO,EACL,gBAAgB,EAChB,eAAe,EACf,qBAAqB,EACrB,eAAe,EACf,YAAY,EACZ,OAAO,EACP,QAAQ,EACR,WAAW,EACX,QAAQ,EACR,KAAK,GACN,MAAM,SAAS,CAAA;AAGhB,OAAO,EACL,SAAS,EACT,qBAAqB,EACrB,mBAAmB,EACnB,oBAAoB,EACpB,mBAAmB,EACnB,sBAAsB,EACtB,mBAAmB,EACnB,iBAAiB,EACjB,kBAAkB,EAClB,kBAAkB,EAClB,eAAe,EACf,eAAe,EACf,sBAAsB,GACvB,MAAM,SAAS,CAAA;AAGhB,OAAO,EACL,kBAAkB,EAClB,sBAAsB,EACtB,kBAAkB,EAClB,kBAAkB,EAClB,WAAW,EACX,KAAK,EACL,mBAAmB,EACnB,cAAc,GACf,MAAM,WAAW,CAAA;AAGlB,OAAO,EACL,WAAW,EACX,gBAAgB,EAChB,eAAe,EACf,2BAA2B,GAC5B,MAAM,UAAU,CAAA;AACjB,YAAY,EAAE,eAAe,EAAE,MAAM,UAAU,CAAA"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TinyPivot Core
|
|
3
|
+
* Framework-agnostic core logic for pivot tables and data grids
|
|
4
|
+
*
|
|
5
|
+
* @packageDocumentation
|
|
6
|
+
*/
|
|
7
|
+
// Utility Functions
|
|
8
|
+
export { detectColumnType, detectFieldType, getColumnUniqueValues, formatCellValue, formatNumber, makeKey, parseKey, naturalSort, debounce, clamp, } from './utils';
|
|
9
|
+
// Pivot Table Logic
|
|
10
|
+
export { aggregate, formatAggregatedValue, getAggregationLabel, getAggregationSymbol, AGGREGATION_OPTIONS, computeAvailableFields, getUnassignedFields, isPivotConfigured, computePivotResult, generateStorageKey, savePivotConfig, loadPivotConfig, isConfigValidForFields, } from './pivot';
|
|
11
|
+
// License Management
|
|
12
|
+
export { validateLicenseKey, configureLicenseSecret, getDemoLicenseInfo, getFreeLicenseInfo, canUsePivot, isPro, shouldShowWatermark, logProRequired, } from './license';
|
|
13
|
+
// Export Utilities
|
|
14
|
+
export { exportToCSV, exportPivotToCSV, copyToClipboard, formatSelectionForClipboard, } from './export';
|
|
15
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AA2CH,oBAAoB;AACpB,OAAO,EACL,gBAAgB,EAChB,eAAe,EACf,qBAAqB,EACrB,eAAe,EACf,YAAY,EACZ,OAAO,EACP,QAAQ,EACR,WAAW,EACX,QAAQ,EACR,KAAK,GACN,MAAM,SAAS,CAAA;AAEhB,oBAAoB;AACpB,OAAO,EACL,SAAS,EACT,qBAAqB,EACrB,mBAAmB,EACnB,oBAAoB,EACpB,mBAAmB,EACnB,sBAAsB,EACtB,mBAAmB,EACnB,iBAAiB,EACjB,kBAAkB,EAClB,kBAAkB,EAClB,eAAe,EACf,eAAe,EACf,sBAAsB,GACvB,MAAM,SAAS,CAAA;AAEhB,qBAAqB;AACrB,OAAO,EACL,kBAAkB,EAClB,sBAAsB,EACtB,kBAAkB,EAClB,kBAAkB,EAClB,WAAW,EACX,KAAK,EACL,mBAAmB,EACnB,cAAc,GACf,MAAM,WAAW,CAAA;AAElB,mBAAmB;AACnB,OAAO,EACL,WAAW,EACX,gBAAgB,EAChB,eAAe,EACf,2BAA2B,GAC5B,MAAM,UAAU,CAAA"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TinyPivot Core - License Management
|
|
3
|
+
* Framework-agnostic license validation logic
|
|
4
|
+
*/
|
|
5
|
+
import type { LicenseInfo } from '../types';
|
|
6
|
+
/**
|
|
7
|
+
* Validate a license key and extract info
|
|
8
|
+
*/
|
|
9
|
+
export declare function validateLicenseKey(key: string): Promise<LicenseInfo>;
|
|
10
|
+
/**
|
|
11
|
+
* Configure the license secret (for SSR/build-time injection)
|
|
12
|
+
*/
|
|
13
|
+
export declare function configureLicenseSecret(secret: string): void;
|
|
14
|
+
/**
|
|
15
|
+
* Get demo mode license info
|
|
16
|
+
*/
|
|
17
|
+
export declare function getDemoLicenseInfo(): LicenseInfo;
|
|
18
|
+
/**
|
|
19
|
+
* Get free license info
|
|
20
|
+
*/
|
|
21
|
+
export declare function getFreeLicenseInfo(): LicenseInfo;
|
|
22
|
+
/**
|
|
23
|
+
* Check if license allows pivot feature
|
|
24
|
+
*/
|
|
25
|
+
export declare function canUsePivot(info: LicenseInfo): boolean;
|
|
26
|
+
/**
|
|
27
|
+
* Check if license is pro (any tier)
|
|
28
|
+
*/
|
|
29
|
+
export declare function isPro(info: LicenseInfo): boolean;
|
|
30
|
+
/**
|
|
31
|
+
* Check if watermark should be shown
|
|
32
|
+
*/
|
|
33
|
+
export declare function shouldShowWatermark(info: LicenseInfo, isDemo: boolean): boolean;
|
|
34
|
+
/**
|
|
35
|
+
* Log pro requirement warning
|
|
36
|
+
*/
|
|
37
|
+
export declare function logProRequired(feature: string): void;
|
|
38
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/license/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,EAAE,WAAW,EAAgC,MAAM,UAAU,CAAA;AAqFzE;;GAEG;AACH,wBAAsB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAoD1E;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAE3D;AAED;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,WAAW,CAEhD;AAED;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,WAAW,CAEhD;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,WAAW,GAAG,OAAO,CAEtD;AAED;;GAEG;AACH,wBAAgB,KAAK,CAAC,IAAI,EAAE,WAAW,GAAG,OAAO,CAEhD;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,OAAO,GAAG,OAAO,CAE/E;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAKpD"}
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
const FREE_LICENSE = {
|
|
2
|
+
type: 'free',
|
|
3
|
+
isValid: true,
|
|
4
|
+
features: {
|
|
5
|
+
pivot: false,
|
|
6
|
+
advancedAggregations: false,
|
|
7
|
+
percentageMode: false,
|
|
8
|
+
sessionPersistence: false,
|
|
9
|
+
noWatermark: false,
|
|
10
|
+
},
|
|
11
|
+
};
|
|
12
|
+
const INVALID_LICENSE = {
|
|
13
|
+
type: 'free',
|
|
14
|
+
isValid: false,
|
|
15
|
+
features: {
|
|
16
|
+
pivot: false,
|
|
17
|
+
advancedAggregations: false,
|
|
18
|
+
percentageMode: false,
|
|
19
|
+
sessionPersistence: false,
|
|
20
|
+
noWatermark: false,
|
|
21
|
+
},
|
|
22
|
+
};
|
|
23
|
+
const DEMO_LICENSE = {
|
|
24
|
+
type: 'free',
|
|
25
|
+
isValid: true,
|
|
26
|
+
features: {
|
|
27
|
+
pivot: true,
|
|
28
|
+
advancedAggregations: true,
|
|
29
|
+
percentageMode: true,
|
|
30
|
+
sessionPersistence: true,
|
|
31
|
+
noWatermark: false, // Still show watermark in demo
|
|
32
|
+
},
|
|
33
|
+
};
|
|
34
|
+
/**
|
|
35
|
+
* HMAC-SHA256 based license signature verification
|
|
36
|
+
* Must match the server-side generation algorithm
|
|
37
|
+
*/
|
|
38
|
+
async function verifySignature(typeCode, signature, expiry) {
|
|
39
|
+
// The secret must be configured before license validation can work
|
|
40
|
+
const secret = globalThis.__TP_LICENSE_SECRET__;
|
|
41
|
+
if (!secret) {
|
|
42
|
+
console.warn('[TinyPivot] License secret not configured. Call configureLicenseSecret() first.');
|
|
43
|
+
return false;
|
|
44
|
+
}
|
|
45
|
+
const payload = `TP-${typeCode}-${expiry}`;
|
|
46
|
+
try {
|
|
47
|
+
const encoder = new TextEncoder();
|
|
48
|
+
const keyData = encoder.encode(secret);
|
|
49
|
+
const msgData = encoder.encode(payload);
|
|
50
|
+
const cryptoKey = await crypto.subtle.importKey('raw', keyData, { name: 'HMAC', hash: 'SHA-256' }, false, ['sign']);
|
|
51
|
+
const sig = await crypto.subtle.sign('HMAC', cryptoKey, msgData);
|
|
52
|
+
const sigArray = Array.from(new Uint8Array(sig));
|
|
53
|
+
const expectedSig = sigArray
|
|
54
|
+
.map(b => b.toString(16).padStart(2, '0'))
|
|
55
|
+
.join('')
|
|
56
|
+
.slice(0, 12)
|
|
57
|
+
.toUpperCase();
|
|
58
|
+
return signature === expectedSig;
|
|
59
|
+
}
|
|
60
|
+
catch {
|
|
61
|
+
// Fallback for environments without crypto.subtle (SSR, older browsers)
|
|
62
|
+
return false;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Validate a license key and extract info
|
|
67
|
+
*/
|
|
68
|
+
export async function validateLicenseKey(key) {
|
|
69
|
+
// Free tier - no key needed
|
|
70
|
+
if (!key || key === '') {
|
|
71
|
+
return FREE_LICENSE;
|
|
72
|
+
}
|
|
73
|
+
// License key format: TP-{TYPE}-{SIGNATURE}-{EXPIRY}
|
|
74
|
+
// Example: TP-PRO1-A1B2C3D4E5F6-20251231
|
|
75
|
+
const parts = key.split('-');
|
|
76
|
+
if (parts.length !== 4 || parts[0] !== 'TP') {
|
|
77
|
+
return INVALID_LICENSE;
|
|
78
|
+
}
|
|
79
|
+
const typeCode = parts[1];
|
|
80
|
+
const signature = parts[2];
|
|
81
|
+
const expiryStr = parts[3];
|
|
82
|
+
// Verify cryptographic signature
|
|
83
|
+
const isValidSignature = await verifySignature(typeCode, signature, expiryStr);
|
|
84
|
+
if (!isValidSignature) {
|
|
85
|
+
return INVALID_LICENSE;
|
|
86
|
+
}
|
|
87
|
+
// Parse expiry date
|
|
88
|
+
const year = Number.parseInt(expiryStr.slice(0, 4));
|
|
89
|
+
const month = Number.parseInt(expiryStr.slice(4, 6)) - 1;
|
|
90
|
+
const day = Number.parseInt(expiryStr.slice(6, 8));
|
|
91
|
+
const expiresAt = new Date(year, month, day);
|
|
92
|
+
if (expiresAt < new Date()) {
|
|
93
|
+
return { ...INVALID_LICENSE, expiresAt };
|
|
94
|
+
}
|
|
95
|
+
// Determine license type
|
|
96
|
+
let type = 'free';
|
|
97
|
+
if (typeCode === 'PRO1')
|
|
98
|
+
type = 'pro-single';
|
|
99
|
+
else if (typeCode === 'PROU')
|
|
100
|
+
type = 'pro-unlimited';
|
|
101
|
+
else if (typeCode === 'PROT')
|
|
102
|
+
type = 'pro-team';
|
|
103
|
+
return {
|
|
104
|
+
type,
|
|
105
|
+
isValid: true,
|
|
106
|
+
expiresAt,
|
|
107
|
+
features: {
|
|
108
|
+
pivot: type !== 'free',
|
|
109
|
+
advancedAggregations: type !== 'free',
|
|
110
|
+
percentageMode: type !== 'free',
|
|
111
|
+
sessionPersistence: type !== 'free',
|
|
112
|
+
noWatermark: type !== 'free',
|
|
113
|
+
},
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Configure the license secret (for SSR/build-time injection)
|
|
118
|
+
*/
|
|
119
|
+
export function configureLicenseSecret(secret) {
|
|
120
|
+
globalThis.__TP_LICENSE_SECRET__ = secret;
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Get demo mode license info
|
|
124
|
+
*/
|
|
125
|
+
export function getDemoLicenseInfo() {
|
|
126
|
+
return DEMO_LICENSE;
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Get free license info
|
|
130
|
+
*/
|
|
131
|
+
export function getFreeLicenseInfo() {
|
|
132
|
+
return FREE_LICENSE;
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Check if license allows pivot feature
|
|
136
|
+
*/
|
|
137
|
+
export function canUsePivot(info) {
|
|
138
|
+
return info.features.pivot;
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Check if license is pro (any tier)
|
|
142
|
+
*/
|
|
143
|
+
export function isPro(info) {
|
|
144
|
+
return info.isValid && info.type !== 'free';
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Check if watermark should be shown
|
|
148
|
+
*/
|
|
149
|
+
export function shouldShowWatermark(info, isDemo) {
|
|
150
|
+
return isDemo || !info.features.noWatermark;
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Log pro requirement warning
|
|
154
|
+
*/
|
|
155
|
+
export function logProRequired(feature) {
|
|
156
|
+
console.warn(`[TinyPivot] "${feature}" requires a Pro license. ` +
|
|
157
|
+
`Visit https://tiny-pivot.com/#pricing to upgrade.`);
|
|
158
|
+
}
|
|
159
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/license/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TinyPivot Core - Pivot Table Logic
|
|
3
|
+
* Pure pivot table computation with no framework dependencies
|
|
4
|
+
*/
|
|
5
|
+
import type { AggregationFunction, FieldStats, PivotConfig, PivotResult, PivotValueField } from '../types';
|
|
6
|
+
/**
|
|
7
|
+
* Aggregate values based on function type
|
|
8
|
+
*/
|
|
9
|
+
export declare function aggregate(values: number[], fn: AggregationFunction): number | null;
|
|
10
|
+
/**
|
|
11
|
+
* Format aggregated value for display
|
|
12
|
+
*/
|
|
13
|
+
export declare function formatAggregatedValue(value: number | null, fn: AggregationFunction): string;
|
|
14
|
+
/**
|
|
15
|
+
* Get aggregation function display label
|
|
16
|
+
*/
|
|
17
|
+
export declare function getAggregationLabel(fn: AggregationFunction): string;
|
|
18
|
+
/**
|
|
19
|
+
* Get aggregation function symbol
|
|
20
|
+
*/
|
|
21
|
+
export declare function getAggregationSymbol(fn: AggregationFunction): string;
|
|
22
|
+
/**
|
|
23
|
+
* Aggregation options for UI
|
|
24
|
+
*/
|
|
25
|
+
export declare const AGGREGATION_OPTIONS: Array<{
|
|
26
|
+
value: AggregationFunction;
|
|
27
|
+
label: string;
|
|
28
|
+
symbol: string;
|
|
29
|
+
}>;
|
|
30
|
+
/**
|
|
31
|
+
* Compute available fields from data
|
|
32
|
+
*/
|
|
33
|
+
export declare function computeAvailableFields(data: Record<string, unknown>[]): FieldStats[];
|
|
34
|
+
/**
|
|
35
|
+
* Get unassigned fields (not in row, column, or value fields)
|
|
36
|
+
*/
|
|
37
|
+
export declare function getUnassignedFields(availableFields: FieldStats[], rowFields: string[], columnFields: string[], valueFields: PivotValueField[]): FieldStats[];
|
|
38
|
+
/**
|
|
39
|
+
* Check if pivot is configured
|
|
40
|
+
*/
|
|
41
|
+
export declare function isPivotConfigured(config: PivotConfig): boolean;
|
|
42
|
+
/**
|
|
43
|
+
* Build pivot result from data and config
|
|
44
|
+
*/
|
|
45
|
+
export declare function computePivotResult(data: Record<string, unknown>[], config: PivotConfig): PivotResult | null;
|
|
46
|
+
/**
|
|
47
|
+
* Generate a storage key based on column names
|
|
48
|
+
*/
|
|
49
|
+
export declare function generateStorageKey(columns: string[]): string;
|
|
50
|
+
/**
|
|
51
|
+
* Save pivot config to sessionStorage
|
|
52
|
+
*/
|
|
53
|
+
export declare function savePivotConfig(key: string, config: PivotConfig): void;
|
|
54
|
+
/**
|
|
55
|
+
* Load pivot config from sessionStorage
|
|
56
|
+
*/
|
|
57
|
+
export declare function loadPivotConfig(key: string): PivotConfig | null;
|
|
58
|
+
/**
|
|
59
|
+
* Check if config fields exist in available fields
|
|
60
|
+
*/
|
|
61
|
+
export declare function isConfigValidForFields(config: PivotConfig, availableFieldNames: string[]): boolean;
|
|
62
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/pivot/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,EACV,mBAAmB,EACnB,UAAU,EAEV,WAAW,EACX,WAAW,EACX,eAAe,EAChB,MAAM,UAAU,CAAA;AAGjB;;GAEG;AACH,wBAAgB,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,mBAAmB,GAAG,MAAM,GAAG,IAAI,CAmBlF;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,EAAE,EAAE,EAAE,mBAAmB,GAAG,MAAM,CAY3F;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,EAAE,EAAE,mBAAmB,GAAG,MAAM,CAUnE;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,EAAE,EAAE,mBAAmB,GAAG,MAAM,CAUpE;AAED;;GAEG;AACH,eAAO,MAAM,mBAAmB,EAAE,KAAK,CAAC;IACtC,KAAK,EAAE,mBAAmB,CAAA;IAC1B,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,MAAM,CAAA;CACf,CAOA,CAAA;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,UAAU,EAAE,CAKpF;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,eAAe,EAAE,UAAU,EAAE,EAC7B,SAAS,EAAE,MAAM,EAAE,EACnB,YAAY,EAAE,MAAM,EAAE,EACtB,WAAW,EAAE,eAAe,EAAE,GAC7B,UAAU,EAAE,CAOd;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAE9D;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,EAC/B,MAAM,EAAE,WAAW,GAClB,WAAW,GAAG,IAAI,CAuMpB;AAKD;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,MAAM,CAI5D;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,GAAG,IAAI,CAMtE;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI,CAU/D;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,WAAW,EAAE,mBAAmB,EAAE,MAAM,EAAE,GAAG,OAAO,CAQlG"}
|