@happyvertical/smrt-reports 0.55.24 → 0.56.1

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 (91) hide show
  1. package/AGENTS.md +26 -3
  2. package/README.md +11 -2
  3. package/dist/index.d.ts +4 -1
  4. package/dist/index.d.ts.map +1 -1
  5. package/dist/index.js +476 -109
  6. package/dist/index.js.map +1 -1
  7. package/dist/manifest.json +174 -5
  8. package/dist/materialized-host.d.ts +72 -0
  9. package/dist/materialized-host.d.ts.map +1 -0
  10. package/dist/playground.d.ts +2 -0
  11. package/dist/playground.d.ts.map +1 -0
  12. package/dist/playground.js +154 -0
  13. package/dist/playground.js.map +1 -0
  14. package/dist/recipes.d.ts +55 -0
  15. package/dist/recipes.d.ts.map +1 -1
  16. package/dist/runtime-report.d.ts +9 -0
  17. package/dist/runtime-report.d.ts.map +1 -1
  18. package/dist/runtime-server.d.ts +77 -0
  19. package/dist/runtime-server.d.ts.map +1 -0
  20. package/dist/runtime-spec.d.ts +2 -1
  21. package/dist/runtime-spec.d.ts.map +1 -1
  22. package/dist/smrt-knowledge.json +203 -11
  23. package/dist/state.js +1 -1
  24. package/dist/state.js.map +1 -1
  25. package/dist/svelte/MaterializedReportTable.svelte +104 -0
  26. package/dist/svelte/MaterializedReportTable.svelte.d.ts +14 -0
  27. package/dist/svelte/MaterializedReportTable.svelte.d.ts.map +1 -0
  28. package/dist/svelte/ReportConfirmation.svelte +99 -0
  29. package/dist/svelte/ReportConfirmation.svelte.d.ts +15 -0
  30. package/dist/svelte/ReportConfirmation.svelte.d.ts.map +1 -0
  31. package/dist/svelte/ReportDetail.svelte +69 -0
  32. package/dist/svelte/ReportDetail.svelte.d.ts +11 -0
  33. package/dist/svelte/ReportDetail.svelte.d.ts.map +1 -0
  34. package/dist/svelte/ReportPicker.svelte +73 -0
  35. package/dist/svelte/ReportPicker.svelte.d.ts +16 -0
  36. package/dist/svelte/ReportPicker.svelte.d.ts.map +1 -0
  37. package/dist/svelte/ReportResult.svelte +69 -0
  38. package/dist/svelte/ReportResult.svelte.d.ts +10 -0
  39. package/dist/svelte/ReportResult.svelte.d.ts.map +1 -0
  40. package/dist/svelte/RuntimeReportChartWidget.svelte +20 -0
  41. package/dist/svelte/RuntimeReportChartWidget.svelte.d.ts +11 -0
  42. package/dist/svelte/RuntimeReportChartWidget.svelte.d.ts.map +1 -0
  43. package/dist/svelte/RuntimeReportDetailRoute.svelte +67 -0
  44. package/dist/svelte/RuntimeReportDetailRoute.svelte.d.ts +21 -0
  45. package/dist/svelte/RuntimeReportDetailRoute.svelte.d.ts.map +1 -0
  46. package/dist/svelte/RuntimeReportToolResult.svelte +26 -0
  47. package/dist/svelte/RuntimeReportToolResult.svelte.d.ts +8 -0
  48. package/dist/svelte/RuntimeReportToolResult.svelte.d.ts.map +1 -0
  49. package/dist/svelte/RuntimeReportWidgetOptions.svelte +58 -0
  50. package/dist/svelte/RuntimeReportWidgetOptions.svelte.d.ts +14 -0
  51. package/dist/svelte/RuntimeReportWidgetOptions.svelte.d.ts.map +1 -0
  52. package/dist/svelte/RuntimeReportsRoute.svelte +67 -0
  53. package/dist/svelte/RuntimeReportsRoute.svelte.d.ts +19 -0
  54. package/dist/svelte/RuntimeReportsRoute.svelte.d.ts.map +1 -0
  55. package/dist/svelte/SavedReports.svelte +114 -0
  56. package/dist/svelte/SavedReports.svelte.d.ts +11 -0
  57. package/dist/svelte/SavedReports.svelte.d.ts.map +1 -0
  58. package/dist/svelte/browser-client.d.ts +10 -0
  59. package/dist/svelte/browser-client.d.ts.map +1 -0
  60. package/dist/svelte/browser-client.js +16 -0
  61. package/dist/svelte/client.d.ts +15 -0
  62. package/dist/svelte/client.d.ts.map +1 -0
  63. package/dist/svelte/client.js +179 -0
  64. package/dist/svelte/index.d.ts +17 -0
  65. package/dist/svelte/index.d.ts.map +1 -0
  66. package/dist/svelte/index.js +14 -0
  67. package/dist/svelte/materialized.d.ts +19 -0
  68. package/dist/svelte/materialized.d.ts.map +1 -0
  69. package/dist/svelte/materialized.js +1 -0
  70. package/dist/svelte/messages.d.ts +72 -0
  71. package/dist/svelte/messages.d.ts.map +1 -0
  72. package/dist/svelte/messages.js +72 -0
  73. package/dist/svelte/playground.d.ts +132 -0
  74. package/dist/svelte/playground.d.ts.map +1 -0
  75. package/dist/svelte/playground.js +62 -0
  76. package/dist/svelte/preview-data.d.ts +7 -0
  77. package/dist/svelte/preview-data.d.ts.map +1 -0
  78. package/dist/svelte/preview-data.js +59 -0
  79. package/dist/svelte/result.d.ts +8 -0
  80. package/dist/svelte/result.d.ts.map +1 -0
  81. package/dist/svelte/result.js +99 -0
  82. package/dist/svelte/spec.d.ts +5 -0
  83. package/dist/svelte/spec.d.ts.map +1 -0
  84. package/dist/svelte/spec.js +282 -0
  85. package/dist/svelte/tool-result.d.ts +11 -0
  86. package/dist/svelte/tool-result.d.ts.map +1 -0
  87. package/dist/svelte/tool-result.js +19 -0
  88. package/dist/svelte/types.d.ts +38 -0
  89. package/dist/svelte/types.d.ts.map +1 -0
  90. package/dist/svelte/types.js +1 -0
  91. package/package.json +36 -12
@@ -0,0 +1,72 @@
1
+ export declare const M: {
2
+ readonly 'reports.title': "reports.title";
3
+ readonly 'reports.only_mine': "reports.only_mine";
4
+ readonly 'reports.archived': "reports.archived";
5
+ readonly 'reports.archive': "reports.archive";
6
+ readonly 'reports.unarchive': "reports.unarchive";
7
+ readonly 'reports.loading': "reports.loading";
8
+ readonly 'reports.running': "reports.running";
9
+ readonly 'reports.empty': "reports.empty";
10
+ readonly 'reports.no_rows': "reports.no_rows";
11
+ readonly 'reports.unavailable': "reports.unavailable";
12
+ readonly 'reports.error': "reports.error";
13
+ readonly 'reports.denied': "reports.denied";
14
+ readonly 'reports.invalid': "reports.invalid";
15
+ readonly 'reports.retry': "reports.retry";
16
+ readonly 'reports.rerun': "reports.rerun";
17
+ readonly 'reports.table': "reports.table";
18
+ readonly 'reports.chart': "reports.chart";
19
+ readonly 'reports.source': "reports.source";
20
+ readonly 'reports.author': "reports.author";
21
+ readonly 'reports.last_run': "reports.last_run";
22
+ readonly 'reports.never_run': "reports.never_run";
23
+ readonly 'reports.truncated': "reports.truncated";
24
+ readonly 'reports.yes': "reports.yes";
25
+ readonly 'reports.no': "reports.no";
26
+ readonly 'reports.select_report': "reports.select_report";
27
+ readonly 'reports.select_measure': "reports.select_measure";
28
+ readonly 'reports.choose_report': "reports.choose_report";
29
+ readonly 'reports.choose_measure': "reports.choose_measure";
30
+ readonly 'reports.select_dimension': "reports.select_dimension";
31
+ readonly 'reports.choose_dimension': "reports.choose_dimension";
32
+ readonly 'reports.options_invalid': "reports.options_invalid";
33
+ readonly 'reports.cancel': "reports.cancel";
34
+ readonly 'reports.save': "reports.save";
35
+ readonly 'reports.confirm_title': "reports.confirm_title";
36
+ readonly 'reports.saved': "reports.saved";
37
+ readonly 'reports.declined': "reports.declined";
38
+ readonly 'reports.groupings': "reports.groupings";
39
+ readonly 'reports.measures': "reports.measures";
40
+ readonly 'reports.filters': "reports.filters";
41
+ readonly 'reports.having': "reports.having";
42
+ readonly 'reports.none': "reports.none";
43
+ readonly 'reports.rows': "reports.rows";
44
+ readonly 'reports.saving': "reports.saving";
45
+ readonly 'reports.approve': "reports.approve";
46
+ readonly 'reports.decline': "reports.decline";
47
+ readonly 'reports.aggregate.count': "reports.aggregate.count";
48
+ readonly 'reports.aggregate.countDistinct': "reports.aggregate.countDistinct";
49
+ readonly 'reports.aggregate.sum': "reports.aggregate.sum";
50
+ readonly 'reports.aggregate.avg': "reports.aggregate.avg";
51
+ readonly 'reports.aggregate.min': "reports.aggregate.min";
52
+ readonly 'reports.aggregate.max': "reports.aggregate.max";
53
+ readonly 'reports.operator.eq': "reports.operator.eq";
54
+ readonly 'reports.operator.ne': "reports.operator.ne";
55
+ readonly 'reports.operator.gt': "reports.operator.gt";
56
+ readonly 'reports.operator.gte': "reports.operator.gte";
57
+ readonly 'reports.operator.lt': "reports.operator.lt";
58
+ readonly 'reports.operator.lte': "reports.operator.lte";
59
+ readonly 'reports.operator.in': "reports.operator.in";
60
+ readonly 'reports.operator.notIn': "reports.operator.notIn";
61
+ readonly 'reports.operator.contains': "reports.operator.contains";
62
+ readonly 'reports.operator.isNull': "reports.operator.isNull";
63
+ readonly 'reports.operator.isNotNull': "reports.operator.isNotNull";
64
+ readonly 'reports.bucket.minute': "reports.bucket.minute";
65
+ readonly 'reports.bucket.hour': "reports.bucket.hour";
66
+ readonly 'reports.bucket.day': "reports.bucket.day";
67
+ readonly 'reports.bucket.week': "reports.bucket.week";
68
+ readonly 'reports.bucket.month': "reports.bucket.month";
69
+ readonly 'reports.bucket.quarter': "reports.bucket.quarter";
70
+ readonly 'reports.bucket.year': "reports.bucket.year";
71
+ };
72
+ //# sourceMappingURL=messages.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"messages.d.ts","sourceRoot":"","sources":["../../src/svelte/messages.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAyEZ,CAAC"}
@@ -0,0 +1,72 @@
1
+ import { defineMessages } from '@happyvertical/smrt-ui/i18n';
2
+ export const M = defineMessages({
3
+ 'reports.title': 'Reports',
4
+ 'reports.only_mine': 'Only mine',
5
+ 'reports.archived': 'Show archived reports',
6
+ 'reports.archive': 'Archive',
7
+ 'reports.unarchive': 'Unarchive',
8
+ 'reports.loading': 'Loading reports…',
9
+ 'reports.running': 'Running report…',
10
+ 'reports.empty': 'No saved reports. Ask the assistant to create a report, then approve its proposal.',
11
+ 'reports.no_rows': 'No results match this report.',
12
+ 'reports.unavailable': 'Reports are unavailable because this host has no server.',
13
+ 'reports.error': 'The report request failed. Please try again.',
14
+ 'reports.denied': 'You do not have permission to read this report or one of its fields.',
15
+ 'reports.invalid': 'The report returned an invalid result.',
16
+ 'reports.retry': 'Try again',
17
+ 'reports.rerun': 'Re-run',
18
+ 'reports.table': 'Table view',
19
+ 'reports.chart': 'Chart view',
20
+ 'reports.source': 'Source',
21
+ 'reports.author': 'Author',
22
+ 'reports.last_run': 'Last run: {time}',
23
+ 'reports.never_run': 'No recent run',
24
+ 'reports.truncated': 'Showing a bounded sample; more rows are available.',
25
+ 'reports.yes': 'Yes',
26
+ 'reports.no': 'No',
27
+ 'reports.select_report': 'Report',
28
+ 'reports.select_measure': 'Measure',
29
+ 'reports.choose_report': 'Choose a saved report',
30
+ 'reports.choose_measure': 'Choose a measure',
31
+ 'reports.select_dimension': 'Dimension',
32
+ 'reports.choose_dimension': 'Choose a dimension',
33
+ 'reports.options_invalid': 'Choose a report and measure before saving.',
34
+ 'reports.cancel': 'Cancel',
35
+ 'reports.save': 'Save',
36
+ 'reports.confirm_title': 'Review report proposal',
37
+ 'reports.saved': 'Report saved.',
38
+ 'reports.declined': 'Report declined. Nothing was saved.',
39
+ 'reports.groupings': 'Group by',
40
+ 'reports.measures': 'Measures',
41
+ 'reports.filters': 'Filters',
42
+ 'reports.having': 'Measure filters',
43
+ 'reports.none': 'None',
44
+ 'reports.rows': 'rows',
45
+ 'reports.saving': 'Saving…',
46
+ 'reports.approve': 'Approve',
47
+ 'reports.decline': 'Decline',
48
+ 'reports.aggregate.count': 'Count of {field}',
49
+ 'reports.aggregate.countDistinct': 'Distinct count of {field}',
50
+ 'reports.aggregate.sum': 'Sum of {field}',
51
+ 'reports.aggregate.avg': 'Average of {field}',
52
+ 'reports.aggregate.min': 'Minimum of {field}',
53
+ 'reports.aggregate.max': 'Maximum of {field}',
54
+ 'reports.operator.eq': 'equals',
55
+ 'reports.operator.ne': 'does not equal',
56
+ 'reports.operator.gt': 'is greater than',
57
+ 'reports.operator.gte': 'is at least',
58
+ 'reports.operator.lt': 'is less than',
59
+ 'reports.operator.lte': 'is at most',
60
+ 'reports.operator.in': 'is one of',
61
+ 'reports.operator.notIn': 'is not one of',
62
+ 'reports.operator.contains': 'contains',
63
+ 'reports.operator.isNull': 'is empty',
64
+ 'reports.operator.isNotNull': 'is not empty',
65
+ 'reports.bucket.minute': 'Minute',
66
+ 'reports.bucket.hour': 'Hour',
67
+ 'reports.bucket.day': 'Day',
68
+ 'reports.bucket.week': 'Week',
69
+ 'reports.bucket.month': 'Month',
70
+ 'reports.bucket.quarter': 'Quarter',
71
+ 'reports.bucket.year': 'Year',
72
+ });
@@ -0,0 +1,132 @@
1
+ declare const _default: {
2
+ packageName: string;
3
+ displayName: string;
4
+ description: string;
5
+ entries: ({
6
+ id: string;
7
+ title: string;
8
+ description: string;
9
+ loadComponent: () => Promise<import("svelte").Component<import("./SavedReports.svelte").Props, {}, "">>;
10
+ props: {
11
+ client: import("./types.js").RuntimeReportsClient;
12
+ id?: undefined;
13
+ locale?: undefined;
14
+ proposal?: undefined;
15
+ confirm?: undefined;
16
+ reportId?: undefined;
17
+ measure?: undefined;
18
+ dimension?: undefined;
19
+ onchange?: undefined;
20
+ serverAvailable?: undefined;
21
+ result?: undefined;
22
+ };
23
+ order: number;
24
+ } | {
25
+ id: string;
26
+ title: string;
27
+ description: string;
28
+ loadComponent: () => Promise<import("svelte").Component<import("./ReportDetail.svelte").Props, {}, "">>;
29
+ props: {
30
+ id: string;
31
+ client: import("./types.js").RuntimeReportsClient;
32
+ locale: string;
33
+ proposal?: undefined;
34
+ confirm?: undefined;
35
+ reportId?: undefined;
36
+ measure?: undefined;
37
+ dimension?: undefined;
38
+ onchange?: undefined;
39
+ serverAvailable?: undefined;
40
+ result?: undefined;
41
+ };
42
+ order: number;
43
+ } | {
44
+ id: string;
45
+ title: string;
46
+ description: string;
47
+ loadComponent: () => Promise<import("svelte").Component<import("./ReportConfirmation.svelte").Props, {}, "">>;
48
+ props: {
49
+ proposal: import("./types.js").RuntimeReportProposal;
50
+ confirm: () => Promise<import("./types.js").SavedRuntimeReport>;
51
+ client?: undefined;
52
+ id?: undefined;
53
+ locale?: undefined;
54
+ reportId?: undefined;
55
+ measure?: undefined;
56
+ dimension?: undefined;
57
+ onchange?: undefined;
58
+ serverAvailable?: undefined;
59
+ result?: undefined;
60
+ };
61
+ order: number;
62
+ } | {
63
+ id: string;
64
+ title: string;
65
+ description: string;
66
+ loadComponent: () => Promise<import("svelte").Component<import("./ReportPicker.svelte").Props, {}, "">>;
67
+ props: {
68
+ client: import("./types.js").RuntimeReportsClient;
69
+ reportId: string;
70
+ measure: string;
71
+ dimension: string;
72
+ onchange: () => void;
73
+ id?: undefined;
74
+ locale?: undefined;
75
+ proposal?: undefined;
76
+ confirm?: undefined;
77
+ serverAvailable?: undefined;
78
+ result?: undefined;
79
+ };
80
+ order: number;
81
+ } | {
82
+ id: string;
83
+ title: string;
84
+ description: string;
85
+ loadComponent: () => Promise<import("svelte").Component<import("./RuntimeReportsRoute.svelte").Props, {}, "">>;
86
+ props: {
87
+ serverAvailable: boolean;
88
+ client?: undefined;
89
+ id?: undefined;
90
+ locale?: undefined;
91
+ proposal?: undefined;
92
+ confirm?: undefined;
93
+ reportId?: undefined;
94
+ measure?: undefined;
95
+ dimension?: undefined;
96
+ onchange?: undefined;
97
+ result?: undefined;
98
+ };
99
+ order: number;
100
+ } | {
101
+ id: string;
102
+ title: string;
103
+ description: string;
104
+ loadComponent: () => Promise<import("svelte").Component<import("./ReportResult.svelte").Props, {}, "">>;
105
+ props: {
106
+ result: {
107
+ rows: never[];
108
+ rowCount: number;
109
+ version: 1;
110
+ specHash: string;
111
+ title: string;
112
+ columns: import("../runtime-compiler.js").RuntimeReportColumn[];
113
+ truncated: boolean;
114
+ ranAt: string;
115
+ chart: import("../runtime-spec.js").RuntimeReportChart;
116
+ };
117
+ client?: undefined;
118
+ id?: undefined;
119
+ locale?: undefined;
120
+ proposal?: undefined;
121
+ confirm?: undefined;
122
+ reportId?: undefined;
123
+ measure?: undefined;
124
+ dimension?: undefined;
125
+ onchange?: undefined;
126
+ serverAvailable?: undefined;
127
+ };
128
+ order: number;
129
+ })[];
130
+ };
131
+ export default _default;
132
+ //# sourceMappingURL=playground.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"playground.d.ts","sourceRoot":"","sources":["../../src/svelte/playground.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEA,wBAkEE"}
@@ -0,0 +1,62 @@
1
+ import { client, proposal, result, saved } from './preview-data.js';
2
+ export default {
3
+ packageName: '@happyvertical/smrt-reports',
4
+ displayName: 'Reports',
5
+ description: 'Saved runtime reports and live results.',
6
+ entries: [
7
+ {
8
+ id: 'saved-reports',
9
+ title: 'Saved reports',
10
+ description: 'Shared reports, author filter, and archive controls.',
11
+ loadComponent: () => import('./SavedReports.svelte').then((m) => m.default),
12
+ props: { client: client() },
13
+ order: 1,
14
+ },
15
+ {
16
+ id: 'report-detail',
17
+ title: 'Report detail',
18
+ description: 'Money values with chart and table views.',
19
+ loadComponent: () => import('./ReportDetail.svelte').then((m) => m.default),
20
+ props: { id: saved.id, client: client(), locale: 'en-US' },
21
+ order: 2,
22
+ },
23
+ {
24
+ id: 'report-confirmation',
25
+ title: 'Report confirmation',
26
+ description: 'Review a bounded proposal before saving.',
27
+ loadComponent: () => import('./ReportConfirmation.svelte').then((m) => m.default),
28
+ props: { proposal, confirm: async () => saved },
29
+ order: 3,
30
+ },
31
+ {
32
+ id: 'report-picker',
33
+ title: 'Report picker',
34
+ description: 'Choose a saved report and its measure.',
35
+ loadComponent: () => import('./ReportPicker.svelte').then((m) => m.default),
36
+ props: {
37
+ client: client(),
38
+ reportId: saved.id,
39
+ measure: 'total',
40
+ dimension: 'region',
41
+ onchange: () => { },
42
+ },
43
+ order: 4,
44
+ },
45
+ {
46
+ id: 'reports-unavailable',
47
+ title: 'Reports unavailable',
48
+ description: 'Static hosts do not make server requests.',
49
+ loadComponent: () => import('./RuntimeReportsRoute.svelte').then((m) => m.default),
50
+ props: { serverAvailable: false },
51
+ order: 5,
52
+ },
53
+ {
54
+ id: 'report-empty',
55
+ title: 'Empty report',
56
+ description: 'A valid report with no matching rows.',
57
+ loadComponent: () => import('./ReportResult.svelte').then((m) => m.default),
58
+ props: { result: { ...result, rows: [], rowCount: 0 } },
59
+ order: 6,
60
+ },
61
+ ],
62
+ };
@@ -0,0 +1,7 @@
1
+ import type { RuntimeReportProposal, RuntimeReportResult, RuntimeReportSpec, RuntimeReportsClient, SavedRuntimeReport } from './types.js';
2
+ export declare const spec: RuntimeReportSpec;
3
+ export declare const result: RuntimeReportResult;
4
+ export declare const saved: SavedRuntimeReport;
5
+ export declare const proposal: RuntimeReportProposal;
6
+ export declare function client(overrides?: Partial<RuntimeReportsClient>): RuntimeReportsClient;
7
+ //# sourceMappingURL=preview-data.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"preview-data.d.ts","sourceRoot":"","sources":["../../src/svelte/preview-data.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,qBAAqB,EACrB,mBAAmB,EACnB,iBAAiB,EACjB,oBAAoB,EACpB,kBAAkB,EACnB,MAAM,YAAY,CAAC;AAEpB,eAAO,MAAM,IAAI,EAAE,iBAWlB,CAAC;AACF,eAAO,MAAM,MAAM,EAAE,mBAmBpB,CAAC;AACF,eAAO,MAAM,KAAK,EAAE,kBAQnB,CAAC;AACF,eAAO,MAAM,QAAQ,EAAE,qBAOtB,CAAC;AACF,wBAAgB,MAAM,CACpB,SAAS,GAAE,OAAO,CAAC,oBAAoB,CAAM,GAC5C,oBAAoB,CAStB"}
@@ -0,0 +1,59 @@
1
+ export const spec = {
2
+ version: 1,
3
+ title: 'Sales by region',
4
+ source: 'sales',
5
+ dimensions: [{ field: 'region', as: 'region' }],
6
+ measures: [{ fn: 'sum', field: 'amount', as: 'total' }],
7
+ filters: [],
8
+ having: [],
9
+ sort: [],
10
+ limit: 100,
11
+ chart: { type: 'bar', x: 'region', y: ['total'] },
12
+ };
13
+ export const result = {
14
+ version: 1,
15
+ specHash: 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',
16
+ title: spec.title,
17
+ columns: [
18
+ { id: 'region', label: 'Region', role: 'dimension', type: 'string' },
19
+ {
20
+ id: 'total',
21
+ label: 'Total',
22
+ role: 'measure',
23
+ type: 'integer',
24
+ format: 'money',
25
+ },
26
+ ],
27
+ rows: [{ region: 'West', total: 12345 }],
28
+ rowCount: 1,
29
+ truncated: false,
30
+ ranAt: '2026-10-13T12:00:00Z',
31
+ chart: spec.chart,
32
+ };
33
+ export const saved = {
34
+ id: 'report-1',
35
+ title: spec.title,
36
+ sourceId: 'sales',
37
+ createdByUserId: 'alice',
38
+ status: 'active',
39
+ spec,
40
+ canArchive: true,
41
+ };
42
+ export const proposal = {
43
+ status: 'awaiting_confirmation',
44
+ specHash: result.specHash,
45
+ spec,
46
+ preview: result,
47
+ sourceLabel: 'Sales',
48
+ confirmPath: '/api/_reports/runtime/confirm',
49
+ };
50
+ export function client(overrides = {}) {
51
+ return {
52
+ list: async () => [saved],
53
+ get: async () => saved,
54
+ run: async () => result,
55
+ archive: async () => { },
56
+ confirm: async () => saved,
57
+ ...overrides,
58
+ };
59
+ }
@@ -0,0 +1,8 @@
1
+ import type { RuntimeReportResult } from './types.js';
2
+ export declare function reportError(error: unknown): 'reports.denied' | 'reports.invalid' | 'reports.error';
3
+ /** Validate untrusted result data before formatting, including integer precision. */
4
+ export declare function validReportResult(value: unknown): value is RuntimeReportResult;
5
+ export declare function reportCell(value: unknown, column: RuntimeReportResult['columns'][number], locale: string, currency: string): string;
6
+ /** Narrow the UI projection; canonical spec validation remains server-owned. */
7
+ export declare function validReportProposal(value: unknown): value is import('./types.js').RuntimeReportProposal;
8
+ //# sourceMappingURL=result.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"result.d.ts","sourceRoot":"","sources":["../../src/svelte/result.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAEtD,wBAAgB,WAAW,CACzB,KAAK,EAAE,OAAO,GACb,gBAAgB,GAAG,iBAAiB,GAAG,eAAe,CAQxD;AAED,qFAAqF;AACrF,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,OAAO,GACb,KAAK,IAAI,mBAAmB,CAkD9B;AAED,wBAAgB,UAAU,CACxB,KAAK,EAAE,OAAO,EACd,MAAM,EAAE,mBAAmB,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,EAC9C,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,GACf,MAAM,CAcR;AAED,gFAAgF;AAChF,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,OAAO,GACb,KAAK,IAAI,OAAO,YAAY,EAAE,qBAAqB,CA8BrD"}
@@ -0,0 +1,99 @@
1
+ import { formatWidgetValue } from '@happyvertical/smrt-ui/charts/format';
2
+ import { validRuntimeReportSpec } from './spec.js';
3
+ export function reportError(error) {
4
+ if (error && typeof error === 'object') {
5
+ const e = error;
6
+ if (e.status === 401 || e.status === 403 || e.code === 'unknown_field')
7
+ return 'reports.denied';
8
+ if (e.code === 'invalid_result')
9
+ return 'reports.invalid';
10
+ }
11
+ return 'reports.error';
12
+ }
13
+ /** Validate untrusted result data before formatting, including integer precision. */
14
+ export function validReportResult(value) {
15
+ if (!value || typeof value !== 'object')
16
+ return false;
17
+ const r = value;
18
+ return (r.version === 1 &&
19
+ typeof r.title === 'string' &&
20
+ typeof r.specHash === 'string' &&
21
+ typeof r.ranAt === 'string' &&
22
+ typeof r.truncated === 'boolean' &&
23
+ Array.isArray(r.columns) &&
24
+ r.columns.length > 0 &&
25
+ r.columns.length <= 10 &&
26
+ new Set(r.columns.map((c) => c?.id)).size === r.columns.length &&
27
+ r.columns.every((c) => c &&
28
+ typeof c.id === 'string' &&
29
+ typeof c.label === 'string' &&
30
+ ['dimension', 'measure'].includes(c.role) &&
31
+ ['string', 'integer', 'decimal', 'boolean', 'datetime', 'id'].includes(c.type)) &&
32
+ Array.isArray(r.rows) &&
33
+ r.rows.length <= 1000 &&
34
+ r.rowCount === r.rows.length &&
35
+ r.rows.every((row) => row &&
36
+ typeof row === 'object' &&
37
+ r.columns.every((c) => {
38
+ const v = row[c.id];
39
+ if (v === null)
40
+ return true;
41
+ if (c.type === 'integer')
42
+ return typeof v === 'number' && Number.isSafeInteger(v);
43
+ if (c.type === 'decimal')
44
+ return typeof v === 'number' && Number.isFinite(v);
45
+ if (c.type === 'boolean')
46
+ return typeof v === 'boolean';
47
+ return typeof v === 'string';
48
+ })) &&
49
+ !!r.chart &&
50
+ ['bar', 'line', 'table', 'pie', 'stat'].includes(r.chart.type) &&
51
+ (r.chart.y === undefined ||
52
+ (Array.isArray(r.chart.y) &&
53
+ r.chart.y.every((id) => r.columns.some((c) => c.id === id && c.role === 'measure')))) &&
54
+ (r.chart.x === undefined || r.columns.some((c) => c.id === r.chart.x)));
55
+ }
56
+ export function reportCell(value, column, locale, currency) {
57
+ if (value === null || value === undefined)
58
+ return '–';
59
+ if (typeof value === 'number')
60
+ return formatWidgetValue(value, {
61
+ format: column.format === 'money'
62
+ ? 'money'
63
+ : column.type === 'integer'
64
+ ? 'integer'
65
+ : 'decimal',
66
+ locale,
67
+ currency,
68
+ });
69
+ return String(value);
70
+ }
71
+ /** Narrow the UI projection; canonical spec validation remains server-owned. */
72
+ export function validReportProposal(value) {
73
+ if (!value || typeof value !== 'object')
74
+ return false;
75
+ const p = value;
76
+ if (p.status !== 'awaiting_confirmation' ||
77
+ typeof p.specHash !== 'string' ||
78
+ !/^[a-f0-9]{64}$/.test(p.specHash) ||
79
+ typeof p.sourceLabel !== 'string' ||
80
+ p.sourceLabel.length < 1 ||
81
+ p.sourceLabel.length > 120 ||
82
+ typeof p.confirmPath !== 'string' ||
83
+ p.confirmPath.length > 2048 ||
84
+ !p.confirmPath.startsWith('/') ||
85
+ p.confirmPath.startsWith('//') ||
86
+ !validReportResult(p.preview) ||
87
+ p.preview.specHash !== p.specHash ||
88
+ !p.spec)
89
+ return false;
90
+ if (!validRuntimeReportSpec(p.spec) || p.preview.title !== p.spec.title)
91
+ return false;
92
+ const roles = new Map([
93
+ ...p.spec.dimensions.map((entry) => [entry.as, 'dimension']),
94
+ ...p.spec.measures.map((entry) => [entry.as, 'measure']),
95
+ ]);
96
+ return (p.preview.columns.length === roles.size &&
97
+ p.preview.columns.every((column) => roles.get(column.id) === column.role) &&
98
+ JSON.stringify(p.preview.chart) === JSON.stringify(p.spec.chart));
99
+ }
@@ -0,0 +1,5 @@
1
+ import type { RuntimeReportSpec } from './types.js';
2
+ /** Browser-safe validation of the server's already-normalized closed grammar. */
3
+ export declare function validRuntimeReportSpec(value: unknown): value is RuntimeReportSpec;
4
+ export declare function runtimeReportSpecFromWire(value: unknown): RuntimeReportSpec | null;
5
+ //# sourceMappingURL=spec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spec.d.ts","sourceRoot":"","sources":["../../src/svelte/spec.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AA+JpD,iFAAiF;AACjF,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,OAAO,GACb,KAAK,IAAI,iBAAiB,CA4I5B;AAED,wBAAgB,yBAAyB,CACvC,KAAK,EAAE,OAAO,GACb,iBAAiB,GAAG,IAAI,CAW1B"}