react-semaphor 0.1.540 → 0.1.542

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 (118) hide show
  1. package/dist/analytics-protocol/index.js +75 -75
  2. package/dist/assistant-context/index.js +1 -1
  3. package/dist/brand-studio/index.js +3 -3
  4. package/dist/briefings/index.js +50 -45
  5. package/dist/chunks/apply-dashboard-operations-Btbp2-6v.js +2260 -0
  6. package/dist/chunks/{assistant-chat-ya7xopaC.js → assistant-chat-oHF5lTjA.js} +12 -12
  7. package/dist/chunks/bookmark-state-CXw7lZ50.js +118 -0
  8. package/dist/chunks/{calendar-day-equality-Bpl15IBo.js → calendar-day-equality-BmJAWduY.js} +180 -207
  9. package/dist/chunks/comparison-window-caption-ChIyd_-L.js +1618 -0
  10. package/dist/chunks/custom-visual-inputs-DUtpYZOk.js +323 -0
  11. package/dist/chunks/{dashboard-briefing-launcher-DJI-zfEq.js → dashboard-briefing-launcher-B-cm719R.js} +18 -18
  12. package/dist/chunks/{dashboard-controls-Dh7HqoKy.js → dashboard-controls-CIn22Qgp.js} +69 -70
  13. package/dist/chunks/{dashboard-filter-value-compatibility-D95O4nd7.js → dashboard-filter-value-compatibility-CwQ_iSNb.js} +2 -2
  14. package/dist/chunks/{dashboard-json-BnmlB71h.js → dashboard-json-ZUYsIExq.js} +4 -4
  15. package/dist/chunks/{dashboard-B6Bithfl.js → dashboard-s5WJBcK8.js} +1 -1
  16. package/dist/chunks/{document-dashboard-inputs-BrYYlRVo.js → document-dashboard-inputs-C6MJVyoI.js} +2357 -4948
  17. package/dist/chunks/document-sheet-utils-BsZUnHRl.js +3619 -0
  18. package/dist/chunks/{edit-dashboard-visual-CydOkSko.js → edit-dashboard-visual-DLdereA7.js} +728 -728
  19. package/dist/chunks/{filter-value-text-BhWugPWE.js → filter-value-text-CYsVYPuD.js} +18 -19
  20. package/dist/chunks/index-CV5rHq5D.js +2673 -0
  21. package/dist/chunks/{matrix-analytical-definition-bcprSe4u.js → matrix-analytical-definition-C7Gb0e12.js} +1 -1
  22. package/dist/chunks/{matrix-card-CJn1hB5V.js → matrix-card-DjwWcCo8.js} +2 -2
  23. package/dist/chunks/{matrix-formatter-DQ8avoIQ.js → matrix-formatter-BnsTX90d.js} +430 -417
  24. package/dist/chunks/{matrix-member-presentation-BNPSDKBG.js → matrix-member-presentation-CQGdVks6.js} +1 -1
  25. package/dist/chunks/{matrix-operation-contract-B8PBF1Gd.js → matrix-operation-contract-8OIO4gob.js} +65 -65
  26. package/dist/chunks/metric-comparison-DEwi9uc2.js +498 -0
  27. package/dist/chunks/numeric-presentation-BSAqPpHt.js +5227 -0
  28. package/dist/chunks/{pivot-header-presentation-MkcKnjn3.js → pivot-header-presentation-DHcx1XGQ.js} +1 -1
  29. package/dist/chunks/{pivot-result-identity-D6hhcRXi.js → pivot-result-identity-DJhXXcns.js} +1 -1
  30. package/dist/chunks/pivot-result-lifecycle-BBlAfBA0.js +1155 -0
  31. package/dist/chunks/raw-temporal-presentation-CZ2r0Vb_.js +585 -0
  32. package/dist/chunks/{report-preferences-dialog-neMDolLg.js → report-preferences-dialog-MRUWpMcJ.js} +75 -75
  33. package/dist/chunks/{report-runtime-context-B984Nq1E.js → report-runtime-context-Dq8XyODK.js} +1 -1
  34. package/dist/chunks/{saved-dashboard-context-CCrLpfSQ.js → saved-dashboard-context-DjPqgFly.js} +233 -206
  35. package/dist/chunks/{selection-reducer-vKIb_jS6.js → selection-reducer-Dj_8xD69.js} +1 -1
  36. package/dist/chunks/{semaphor-ready-indicator--4DWtVBu.js → semaphor-ready-indicator-BWSpRsPj.js} +38555 -40449
  37. package/dist/chunks/{shelf-drop-preview-context-CpdB5ois.js → shelf-drop-preview-context-CQbFLm3q.js} +6 -6
  38. package/dist/chunks/sort-target-MT1WK1vX.js +29 -0
  39. package/dist/chunks/{source-entity-resolution-CVA1a85c.js → source-entity-resolution-BYn9giz3.js} +1 -1
  40. package/dist/chunks/{switch-DWEWiv1J.js → switch-C3jLxlG0.js} +2 -2
  41. package/dist/chunks/table-export-sheet-BHSnuZHd.js +949 -0
  42. package/dist/chunks/table-settings-CLZocegs.js +501 -0
  43. package/dist/chunks/temporal-bucket-D7NBrrtL.js +2071 -0
  44. package/dist/chunks/{token-types-bxUxXDX2.js → token-types-DBbZVQsm.js} +1 -1
  45. package/dist/chunks/{use-create-flow-overlay-state-8g6Zhphh.js → use-create-flow-overlay-state-BJDNqdOh.js} +151 -151
  46. package/dist/chunks/{validators-Ej1DdCXa.js → validators-DMHTpf7a.js} +73 -73
  47. package/dist/dashboard/index.js +2 -2
  48. package/dist/dashboard-authoring/index.js +399 -380
  49. package/dist/data-app-sdk/index.js +5 -5
  50. package/dist/data-app-sdk-adapters/index.js +2 -2
  51. package/dist/data-app-sdk-validation/index.js +9 -9
  52. package/dist/format-utils/index.js +346 -238
  53. package/dist/index.js +174 -175
  54. package/dist/pdf-export-policy/index.js +20 -10
  55. package/dist/report-runtime-context/index.js +1 -1
  56. package/dist/surfboard/index.js +2 -2
  57. package/dist/types/briefings/attachment-outcomes.d.ts +23 -0
  58. package/dist/types/briefings/attachments.d.ts +17 -1
  59. package/dist/types/briefings/index.d.ts +6 -3
  60. package/dist/types/index.js +48 -48
  61. package/dist/types/lib/api/exports-api.d.ts +11 -65
  62. package/dist/types/lib/dashboard-inputs/control-contract-overrides.d.ts +17 -0
  63. package/dist/types/lib/dashboard-viewer/export-table-view.d.ts +2 -0
  64. package/dist/types/lib/hooks/use-dashboard-card.d.ts +2 -0
  65. package/dist/types/lib/hooks/use-dashboard.d.ts +3 -6
  66. package/dist/types/lib/matrix-table/matrix-delivery-policy.d.ts +8 -2
  67. package/dist/types/lib/matrix-table/matrix-delivery.d.ts +8 -6
  68. package/dist/types/lib/query-context/build-dashboard-card-query-contract.d.ts +50 -0
  69. package/dist/types/lib/query-context/card-server-request.d.ts +5 -1
  70. package/dist/types/lib/types/common-types.d.ts +7 -0
  71. package/dist/types/lib/types/explorer-types.d.ts +8 -2
  72. package/dist/types/shared/analytics-protocol/matrix-definition-contract.d.ts +3 -3
  73. package/dist/types/shared/assistant-context/index.d.ts +1 -1
  74. package/dist/types/shared/assistant-context/saved-dashboard-context.d.ts +23 -6
  75. package/dist/types/shared/dashboard-authoring/card-export-request.d.ts +173 -0
  76. package/dist/types/shared/dashboard-authoring/card-query-request.d.ts +20 -0
  77. package/dist/types/shared/dashboard-authoring/index.d.ts +1 -0
  78. package/dist/types/shared/dashboard-authoring/matrix-delivery.d.ts +4 -3
  79. package/dist/types/shared/format-utils/attachment-filter-line.d.ts +14 -0
  80. package/dist/types/shared/format-utils/exporters/export-cells.d.ts +90 -0
  81. package/dist/types/shared/format-utils/exporters/export-file-format.d.ts +44 -0
  82. package/dist/types/shared/format-utils/exporters/index.d.ts +6 -0
  83. package/dist/types/shared/format-utils/exporters/xlsx-file.d.ts +90 -0
  84. package/dist/types/shared/format-utils/filter-line.d.ts +7 -0
  85. package/dist/types/shared/format-utils/formatters/date-formatter.d.ts +8 -12
  86. package/dist/types/shared/format-utils/formatters/index.d.ts +1 -1
  87. package/dist/types/shared/format-utils/formatters/matrix-formatter.d.ts +2 -0
  88. package/dist/types/shared/format-utils/index.d.ts +3 -0
  89. package/dist/types/shared/format-utils/matrix-continuation.d.ts +55 -9
  90. package/dist/types/shared/format-utils/matrix-export-presentation.d.ts +21 -1
  91. package/dist/types/shared/format-utils/matrix-export-xlsx.d.ts +27 -0
  92. package/dist/types/shared/format-utils/pdf-export-policy.d.ts +9 -0
  93. package/dist/types/shared/format-utils/presentation-execution.d.ts +27 -2
  94. package/dist/types/shared/format-utils/raw-temporal.d.ts +8 -0
  95. package/dist/types/shared/format-utils/table-export/index.d.ts +8 -0
  96. package/dist/types/shared/format-utils/table-export/prepare-table-export.d.ts +50 -0
  97. package/dist/types/shared/format-utils/table-export/table-export-formatting.d.ts +47 -0
  98. package/dist/types/shared/format-utils/table-export/table-export-raw-temporal.d.ts +40 -0
  99. package/dist/types/shared/format-utils/table-export/table-export-result.d.ts +31 -0
  100. package/dist/types/shared/format-utils/table-export/table-export-sheet.d.ts +38 -0
  101. package/dist/types/shared/format-utils/temporal-bucket.d.ts +9 -0
  102. package/package.json +2 -1
  103. package/dist/chunks/aggregate-table-row-presentation-BjK9YfMI.js +0 -979
  104. package/dist/chunks/apply-dashboard-operations-C-iahGka.js +0 -402
  105. package/dist/chunks/bookmark-state-k7y5SNGf.js +0 -331
  106. package/dist/chunks/calculated-field-identity-DcBS2NPP.js +0 -2161
  107. package/dist/chunks/canonical-result-keys-CEQefvdO.js +0 -33
  108. package/dist/chunks/common-types-CUf03Htv.js +0 -288
  109. package/dist/chunks/csv-utils-GUfKyT1J.js +0 -56
  110. package/dist/chunks/custom-visual-inputs-BrUOIwln.js +0 -3288
  111. package/dist/chunks/document-sheet-utils-C1eEldxs.js +0 -1076
  112. package/dist/chunks/index-CqMiAkay.js +0 -3164
  113. package/dist/chunks/matrix-definition-DQDI2okF.js +0 -206
  114. package/dist/chunks/metric-comparison-CojWeLqx.js +0 -392
  115. package/dist/chunks/pivot-result-lifecycle-8qCDmpKc.js +0 -804
  116. package/dist/chunks/raw-temporal-D61lr48Y.js +0 -1464
  117. package/dist/chunks/temporal-bucket-D8JF7zKz.js +0 -575
  118. package/dist/chunks/temporal-bucket-contract-DaOajRC7.js +0 -108
@@ -0,0 +1,173 @@
1
+ import { TFilterValue } from '../../components/surfboard/filter/types.js';
2
+ import { DashboardCardQueryRequestPayloadBase } from '../../lib/query-context/build-dashboard-card-query-contract.js';
3
+ import { ControlBinding, ControlDefinition, TCard } from '../../lib/types/common-types.js';
4
+ import { DataSource, TableTotalsRequest, CardConfig, QueryColumnKeyMap } from '../../lib/types/explorer-types.js';
5
+ import { ResolvedPrimaryDateField } from '../../lib/types/semantic-runtime-types.js';
6
+ import { ComparisonMetadataMap } from '../../lib/types/query-types.js';
7
+ import { ComparisonPresentationSpec, GlobalDateComparisonContext, SemaphorResultColumn } from '../analytics-protocol/index.js';
8
+ import { ReportRuntimeContext } from '../report-runtime-context/index.js';
9
+ import { CanonicalPivotResultTransport, CsvDelimiter, CsvEncoding, ExportFileFormat, PresentationExecutionSnapshot } from '../format-utils/index.js';
10
+ import { TemporalResultOwner } from './temporal-result-owner.js';
11
+ import { ExportViewerTable } from '../../lib/dashboard-viewer/export-table-view.js';
12
+ /** Formatting configuration passed to the export job */
13
+ export interface ExportFormattingConfig {
14
+ useFormattedValues: boolean;
15
+ timezone: string;
16
+ browserTimezone?: string;
17
+ isSqlCard?: boolean;
18
+ delimiter: CsvDelimiter;
19
+ /** Resolved by the caller: the person's or attachment's choice, else the dashboard's setting. */
20
+ csvEncoding: CsvEncoding;
21
+ includeHeaders: boolean;
22
+ columnSettings?: Record<string, unknown>;
23
+ visibleColumns?: string[];
24
+ columnLabels?: Record<string, string>;
25
+ tableTotalsLabelColumnKey?: string;
26
+ presentationExecutionSnapshot?: PresentationExecutionSnapshot;
27
+ comparisonPresentation?: ComparisonPresentationSpec;
28
+ }
29
+ export type AuthoritativeExportFormattingConfig = ExportFormattingConfig & {
30
+ comparisonPresentation: ComparisonPresentationSpec;
31
+ presentationExecutionSnapshot: PresentationExecutionSnapshot;
32
+ };
33
+ /** Request to create a new export job */
34
+ export interface CreateExportRequest {
35
+ type: 'visual' | 'card';
36
+ dashboardId: string;
37
+ visualId?: string;
38
+ cardId: string;
39
+ title?: string;
40
+ connection_id: string;
41
+ cardType: string;
42
+ sql: string;
43
+ python: string;
44
+ resultOwner: TemporalResultOwner;
45
+ cardConfig: CardConfig;
46
+ cardDataSource: DataSource;
47
+ active_filters: TFilterValue[];
48
+ controlValues?: Record<string, unknown>;
49
+ controlDefinitions?: ControlDefinition[];
50
+ cardControlDefinitions?: ControlDefinition[];
51
+ controlBindings?: ControlBinding[];
52
+ resolvedPrimaryDateField?: ResolvedPrimaryDateField;
53
+ globalDateComparison?: GlobalDateComparisonContext;
54
+ tableTotalsRequest?: TableTotalsRequest;
55
+ totalRows: number;
56
+ /** The file the job writes: CSV, or Excel for Table and Detail Table. */
57
+ format: ExportFileFormat;
58
+ formatOptions: AuthoritativeExportFormattingConfig;
59
+ }
60
+ /** The facts a result gives an export: a viewer's loaded result, or the server's sizing query. */
61
+ export type CardResultFacts = {
62
+ totalRows: number;
63
+ resultColumns: readonly SemaphorResultColumn[];
64
+ columnKeyMap?: QueryColumnKeyMap;
65
+ comparisonMetadata?: ComparisonMetadataMap;
66
+ };
67
+ /** File options a viewer or an attachment chose. */
68
+ export type CardExportFileOptions = {
69
+ format: ExportFileFormat;
70
+ /** False writes stored values. */
71
+ useFormattedValues: boolean;
72
+ includeHeaders: boolean;
73
+ /** CSV only; ignored for Excel. */
74
+ delimiter: CsvDelimiter;
75
+ /** CSV only; ignored for Excel. */
76
+ csvEncoding: CsvEncoding;
77
+ /** The viewer's table settings at the click; absent for a scheduled attachment (the author's view). */
78
+ viewerTable?: ExportViewerTable;
79
+ };
80
+ /**
81
+ * The `formatOptions` a table export request carries, from the result: the
82
+ * visible columns, order and labels of the one table view resolver, and the
83
+ * card's saved column settings. The background export and the browser file
84
+ * both start here. Null when the columns cannot be resolved.
85
+ */
86
+ export declare function buildTableExportFormatOptions(input: {
87
+ card: TCard;
88
+ effectiveCardConfig?: CardConfig;
89
+ rows: readonly Record<string, unknown>[];
90
+ /**
91
+ * The output keys when no row is loaded: a scheduled export's sizing page
92
+ * that a cleanup step emptied names its columns from the result's columns.
93
+ */
94
+ resultKeys?: readonly string[];
95
+ result: Pick<CardResultFacts, 'resultColumns' | 'columnKeyMap' | 'comparisonMetadata'>;
96
+ reportContext: ReportRuntimeContext;
97
+ file: CardExportFileOptions;
98
+ }): {
99
+ view: import('../../lib/dashboard-viewer/table-view.js').TableView;
100
+ formatOptions: {
101
+ useFormattedValues: boolean;
102
+ timezone: string;
103
+ delimiter: "," | ";" | "\t";
104
+ csvEncoding: "utf-8-bom" | "utf-8";
105
+ includeHeaders: boolean;
106
+ columnSettings: Record<string, unknown> | undefined;
107
+ visibleColumns: string[];
108
+ columnLabels: {
109
+ [k: string]: string;
110
+ };
111
+ };
112
+ } | null;
113
+ export { buildCardServerRequest as buildCardExportQueryContext, type CardServerRequest as CardExportQueryContext, } from '../../lib/query-context/card-server-request.js';
114
+ type CardExportPresentationParams = {
115
+ card: TCard;
116
+ dashboardId: string;
117
+ reportContext: ReportRuntimeContext;
118
+ totalRows: number;
119
+ formatOptions: ExportFormattingConfig;
120
+ comparisonMetadata?: ComparisonMetadataMap;
121
+ requestPayloadBase: DashboardCardQueryRequestPayloadBase;
122
+ resultColumns?: SemaphorResultColumn[];
123
+ columnKeyMap?: QueryColumnKeyMap;
124
+ canonicalPivotResult?: CanonicalPivotResultTransport;
125
+ effectiveCardConfig?: CardConfig;
126
+ };
127
+ /**
128
+ * The presentation half of a card export request: `formatOptions` with the
129
+ * captured presentation snapshot, the totals label column and the totals
130
+ * request. A browser download formats with exactly this; a background export
131
+ * sends it with the card's query context (`buildCardExportRequest`).
132
+ */
133
+ export declare function buildCardExportFormatOptions(params: CardExportPresentationParams): {
134
+ formatOptions: CreateExportRequest['formatOptions'];
135
+ tableTotalsRequest?: CreateExportRequest['tableTotalsRequest'];
136
+ };
137
+ /** The request from formatOptions already built: the dialog's request, and tests of the presentation half. */
138
+ export declare function buildCardExportRequestFromOptions(params: CardExportPresentationParams & {
139
+ title: string;
140
+ format: ExportFileFormat;
141
+ }): CreateExportRequest;
142
+ /** Why a card has no export request. */
143
+ export type CardExportRequestRefusal =
144
+ /** Comparison columns without their metadata (SPEC §3.0 case 28). */
145
+ 'comparison_metadata_missing'
146
+ /** Only Table and Detail Table export through this request. */
147
+ | 'not_a_table'
148
+ /** No visible column could be resolved from the result. */
149
+ | 'columns_unresolved';
150
+ /**
151
+ * A Table or Detail Table background export request (SPEC §3.5): the card's
152
+ * query, the columns and presentation its result gives, and the file the
153
+ * viewer or attachment chose. The dialog's "Export full dataset" and a
154
+ * scheduled attachment the server starts call exactly this (XL-SI-14).
155
+ */
156
+ export declare function buildCardExportRequest(input: {
157
+ card: TCard;
158
+ dashboardId: string;
159
+ title: string;
160
+ query: DashboardCardQueryRequestPayloadBase;
161
+ effectiveCardConfig?: CardConfig;
162
+ result: CardResultFacts;
163
+ /** The rows the columns are read from: the viewer's loaded rows, or the server's sizing page. */
164
+ rows: readonly Record<string, unknown>[];
165
+ reportContext: ReportRuntimeContext;
166
+ file: CardExportFileOptions;
167
+ }): {
168
+ status: 'ready';
169
+ request: CreateExportRequest;
170
+ } | {
171
+ status: 'refused';
172
+ reason: CardExportRequestRefusal;
173
+ };
@@ -70,7 +70,27 @@ export type CardQueryRequestExtras = {
70
70
  pageSize: number;
71
71
  };
72
72
  tableTotalsRequest?: TableTotalsRequest;
73
+ /** Strict table print only; never sent with `pagination`. */
74
+ sourceRowProbe?: CardQuerySourceRowProbe;
73
75
  };
76
+ /**
77
+ * Ask acquisition whether the source had more rows than `limit`, counted
78
+ * before any Python step or pivot (report attachment delivery RA-D15, RA-D17).
79
+ */
80
+ export type CardQuerySourceRowProbe = {
81
+ limit: number;
82
+ };
83
+ /**
84
+ * What acquisition reports for a `CardQuerySourceRowProbe`: `true` when the
85
+ * source had more rows than the limit, `false` when not. Absent when nobody
86
+ * asked or the answer is unknown, and never read as `false`.
87
+ */
88
+ export type CardQuerySourceRowEvidence = {
89
+ sourceRowOverflow?: boolean;
90
+ };
91
+ type DecidedExtrasField = 'pagination' | 'tableTotalsRequest' | 'sourceRowProbe';
92
+ /** Every extras field is parsed here and built by `resolveCardRequestExtras`. */
93
+ export type CardQueryRequestExtrasDecided = AssertNever<Exclude<keyof CardQueryRequestExtras, DecidedExtrasField>>;
74
94
  /** The context fields any query body may carry, checked the same way for every reader. */
75
95
  export type CardQueryRequestContext = Pick<CardQueryRequest, 'calendarContext' | 'resolvedPrimaryDateField' | 'globalDateComparison'>;
76
96
  /**
@@ -28,6 +28,7 @@ export * from './control-value-resolution.js';
28
28
  export * from './control-execution-contract.js';
29
29
  export * from './resolved-primary-date-field-validation.js';
30
30
  export * from './card-query-request.js';
31
+ export * from './card-export-request.js';
31
32
  export * from './calculated-field-identity.js';
32
33
  export * from './calculated-field-placement.js';
33
34
  export * from './matrix-control-resolution.js';
@@ -7,7 +7,8 @@ export declare function captureMatrixExport(input: {
7
7
  config: MatrixConfig;
8
8
  session?: MatrixViewState;
9
9
  content: MatrixExportContent;
10
- format: 'csv' | 'pdf';
10
+ /** A data file (CSV or Excel) or a PDF; Flat content is a data file only. */
11
+ format: 'csv' | 'xlsx' | 'pdf';
11
12
  purpose: 'manual' | 'schedule';
12
13
  }): {
13
14
  mode: "layout";
@@ -585,7 +586,7 @@ export declare function captureMatrixExport(input: {
585
586
  }[];
586
587
  } | undefined;
587
588
  };
588
- format: "csv";
589
+ format: "csv" | "xlsx";
589
590
  spec: {
590
591
  source: {
591
592
  kind: "semantic";
@@ -1371,7 +1372,7 @@ export declare function buildMatrixDeliveryEnvelope<TSource extends {
1371
1372
  }[];
1372
1373
  } | undefined;
1373
1374
  };
1374
- format: "csv";
1375
+ format: "csv" | "xlsx";
1375
1376
  spec: {
1376
1377
  source: {
1377
1378
  kind: "semantic";
@@ -0,0 +1,14 @@
1
+ import { FilterLineValue } from './filter-line.js';
2
+ /**
3
+ * The filter values a scheduled attachment's filter line is made of, read
4
+ * from its saved settings: values with a name and a values list, each saved
5
+ * relative date read through the shared reader (a malformed one is dropped so
6
+ * the value keeps its fixed dates, as the dashboard's own replay does).
7
+ *
8
+ * One owner for the run's PDF header (semaphor-app `buildRunFilterLine`) and
9
+ * the schedule dialog. It ignores `includeFilters`: that switch only hides the
10
+ * printed line, and the filters still apply to the data.
11
+ */
12
+ export declare function readAttachmentFilterLineValues(settings: {
13
+ filterValues?: readonly unknown[];
14
+ } | undefined): FilterLineValue[];
@@ -0,0 +1,90 @@
1
+ import { ExactNumericValue } from '../../analytics-protocol/scalar-value.js';
2
+ import { MeasureCanonicalFormat } from '../types/format-types.js';
3
+ export type ExportDataType = 'string' | 'number' | 'boolean' | 'date' | 'datetime' | 'unknown';
4
+ /** What an export path knows about one column. Input to resolveXlsxColumn. */
5
+ export type XlsxColumnInput = {
6
+ key: string;
7
+ /** The column's header label. */
8
+ label: string;
9
+ /** "Use formatted values". False means stored values. */
10
+ formattedValues: boolean;
11
+ /** Authoritative: from the result's `resultColumns` (SemaphorResultColumn.dataType); 'unknown' when absent. */
12
+ dataType: ExportDataType;
13
+ /** The presentation that made this column's display text, if any. */
14
+ presentation?: XlsxColumnPresentation;
15
+ };
16
+ export type XlsxColumnPresentation =
17
+ /** A numeric or duration measure format (from the presentation snapshot). */
18
+ {
19
+ kind: 'measure';
20
+ format: MeasureCanonicalFormat;
21
+ }
22
+ /** A grouped date. `grain` from the bucket metadata; an unlisted grain is 'custom'. */
23
+ | {
24
+ kind: 'temporal_bucket';
25
+ grain: 'second' | 'minute' | 'hour' | 'day' | 'week' | 'month' | 'quarter' | 'year' | 'fiscal' | 'custom';
26
+ }
27
+ /** A raw date or datetime column, or a column with date settings. `dateOnly` when its values carry no time. */
28
+ | {
29
+ kind: 'datetime';
30
+ dateOnly: boolean;
31
+ }
32
+ /** Shown as text, including epoch numbers shown as dates. */
33
+ | {
34
+ kind: 'text';
35
+ };
36
+ /** A column as the Excel writer needs it. Built only by resolveXlsxColumn. */
37
+ export type XlsxColumn = {
38
+ readonly key: string;
39
+ readonly label: string;
40
+ /** 'by_value' types each value by its JS type: stored-value exports and columns of unknown type. */
41
+ readonly cellType: 'number' | 'date' | 'boolean' | 'text' | 'by_value';
42
+ /** Excel number format code for number and date cells; undefined means General. */
43
+ readonly numberFormat?: string;
44
+ };
45
+ /** One exported cell. `text` is its display text. */
46
+ export type ExportCell = {
47
+ kind: 'empty';
48
+ } | {
49
+ kind: 'text';
50
+ text: string;
51
+ } | {
52
+ kind: 'number';
53
+ text: string;
54
+ /** A JS number, an exact decimal, or plain decimal text. */
55
+ value: number | ExactNumericValue | string;
56
+ } | {
57
+ kind: 'date';
58
+ text: string;
59
+ serial: number;
60
+ } | {
61
+ kind: 'boolean';
62
+ text: string;
63
+ value: boolean;
64
+ };
65
+ /** A calendar date and time with no zone, as a temporal owner interpreted it for display. */
66
+ export type ExportWallClock = {
67
+ year: number;
68
+ month: number;
69
+ day: number;
70
+ hour: number;
71
+ minute: number;
72
+ second: number;
73
+ };
74
+ /** Pure. Never throws. The complete rule is the two tables in the Excel exports spec (§2.2). */
75
+ export declare function resolveXlsxColumn(input: XlsxColumnInput): XlsxColumn;
76
+ /** A plain decimal: optional '-', digits, optional '.digits', optional exponent. No grouping separators, no spaces. */
77
+ export declare function parsePlainNumericString(value: string): string | undefined;
78
+ /**
79
+ * The cell rule. Pure; never throws. `text` is the display text the path made.
80
+ * `wallClock` is supplied for date columns by the temporal owner that made
81
+ * `text`; this module never parses dates. First matching rule wins (spec §2.3).
82
+ */
83
+ export declare function toExportCell(input: {
84
+ value: unknown;
85
+ text: string;
86
+ column: XlsxColumn;
87
+ wallClock?: ExportWallClock;
88
+ }): ExportCell;
89
+ /** The display text: '' for empty, otherwise `text`. */
90
+ export declare function exportCellText(cell: ExportCell): string;
@@ -0,0 +1,44 @@
1
+ /**
2
+ * The export file format owner: what a CSV or Excel export file is called,
3
+ * typed, keyed and stored as. Every export producer (browser downloads, the
4
+ * app's export routes, the chunk and compaction Lambdas, Briefing
5
+ * attachments) reads these traits instead of writing its own extension,
6
+ * content type or storage-key suffix. See "Excel file standard" in the
7
+ * format-utils README.
8
+ * IMPORTANT: No React or browser-specific imports allowed
9
+ */
10
+ /** Data file formats a Table, Detail Table or Matrix export can produce. */
11
+ export declare const EXPORT_FILE_FORMATS: readonly ["csv", "xlsx"];
12
+ export type ExportFileFormat = (typeof EXPORT_FILE_FORMATS)[number];
13
+ /** Content type of every delivered Excel workbook. */
14
+ export declare const XLSX_CONTENT_TYPE = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
15
+ export type ExportFileTraits = {
16
+ format: ExportFileFormat;
17
+ /** File name extension without the dot: 'csv' | 'xlsx'. */
18
+ extension: 'csv' | 'xlsx';
19
+ /** CSV_CONTENT_TYPE | XLSX_CONTENT_TYPE. */
20
+ contentType: string;
21
+ /** Extension of one chunk or Matrix batch object before compaction: 'csv' | 'xml'. */
22
+ partExtension: 'csv' | 'xml';
23
+ /** Content type that object is stored with: 'text/csv' (as Matrix attempts have always been stored) | 'application/xml'. */
24
+ partContentType: 'text/csv' | 'application/xml';
25
+ /** File name of the compacted background artifact: 'export.csv.gz' | 'export.xlsx'. */
26
+ compactedFileName: 'export.csv.gz' | 'export.xlsx';
27
+ /** How the compacted artifact is stored: CSV gzipped, a workbook as is (already a zip). */
28
+ storedEncoding: 'gzip' | 'identity';
29
+ /** Stored form: Prisma ExportFormat value and the export job config's `format`. */
30
+ storedValue: 'CSV' | 'XLSX';
31
+ /** Customer-facing name: 'CSV' | 'Excel'. */
32
+ label: 'CSV' | 'Excel';
33
+ };
34
+ export declare function parseExportFileFormat(value: unknown): ExportFileFormat | undefined;
35
+ export declare function exportFileTraits(format: ExportFileFormat): ExportFileTraits;
36
+ export declare function exportFileFormatFromStored(value: 'CSV' | 'XLSX'): ExportFileFormat;
37
+ /** For a client reading a server response: the format whose contentType matches (ignoring parameters), else undefined. */
38
+ export declare function exportFileFormatFromContentType(contentType: string | null): ExportFileFormat | undefined;
39
+ /** `${safeTitle}-${UTC timestamp}.${extension}`. The only export file name builder. */
40
+ export declare function exportFileName(input: {
41
+ format: ExportFileFormat;
42
+ title: string | null | undefined;
43
+ at?: Date;
44
+ }): string;
@@ -1,2 +1,8 @@
1
1
  export { CSV_ENCODINGS, DEFAULT_CSV_ENCODING, CSV_DELIMITERS, CSV_RECORD_SEPARATOR, CSV_CONTENT_TYPE, parseCsvEncoding, parseCsvDelimiter, resolveCsvEncoding, csvFilePreamble, toCsvCell, escapeCSVValue, protectCSVText, csvRecord, csvRecords, encodeCsvFile, } from './csv-utils.js';
2
2
  export type { CsvEncoding, CsvDelimiter, CsvCell } from './csv-utils.js';
3
+ export { EXPORT_FILE_FORMATS, XLSX_CONTENT_TYPE, parseExportFileFormat, exportFileTraits, exportFileFormatFromStored, exportFileFormatFromContentType, exportFileName, } from './export-file-format.js';
4
+ export type { ExportFileFormat, ExportFileTraits } from './export-file-format.js';
5
+ export { resolveXlsxColumn, exportCellText } from './export-cells.js';
6
+ export type { ExportDataType, XlsxColumnInput, XlsxColumnPresentation, XlsxColumn, ExportCell, ExportWallClock, } from './export-cells.js';
7
+ export { XlsxLimitError, isXlsxLimitError, XLSX_LIMIT_FAILURE_REASONS, xlsxLimitFailureReason, assertXlsxColumnCount, defineXlsxSheet, serializeXlsxSheet, parseXlsxSheet, withXlsxSheetColumns, serializeXlsxColumns, parseXlsxColumns, xlsxColumnsFingerprint, encodeXlsxFile, encodeXlsxRows, streamXlsxFile, } from './xlsx-file.js';
8
+ export type { XlsxSheet, XlsxRow, XlsxMerge, XlsxLimitFailureReason } from './xlsx-file.js';
@@ -0,0 +1,90 @@
1
+ import { ExportCell, XlsxColumn } from './export-cells.js';
2
+ /** The only error the Excel modules throw on purpose. Its message is customer-facing and product-neutral. */
3
+ export declare class XlsxLimitError extends Error {
4
+ /** `size` counts sheet XML bytes. */
5
+ readonly limit: 'rows' | 'columns' | 'size';
6
+ readonly actual: number;
7
+ readonly max: number;
8
+ constructor(limit: 'rows' | 'columns' | 'size', actual: number, max: number);
9
+ }
10
+ /**
11
+ * The export failure catalog reason for each Excel limit (SPEC §2.6). A worker
12
+ * that hits a limit inside a job reports this reason; the app's catalog holds
13
+ * the message. Nothing ever recovers a reason from message text.
14
+ */
15
+ export declare const XLSX_LIMIT_FAILURE_REASONS: readonly ["excel_row_limit", "excel_column_limit", "excel_size_limit"];
16
+ export type XlsxLimitFailureReason = (typeof XLSX_LIMIT_FAILURE_REASONS)[number];
17
+ export declare function xlsxLimitFailureReason(error: XlsxLimitError): XlsxLimitFailureReason;
18
+ /** Throws XlsxLimitError('columns') when a sheet would be wider than Excel allows: for callers that know the width before any rows exist (XL-D33). */
19
+ export declare function assertXlsxColumnCount(count: number): void;
20
+ /** Structural, so an error from another copy of this module still counts. */
21
+ export declare function isXlsxLimitError(error: unknown): error is XlsxLimitError;
22
+ export type XlsxMerge = {
23
+ row: number;
24
+ firstColumn: number;
25
+ lastColumn: number;
26
+ };
27
+ /** A validated sheet layout that every writer of one file shares. Built only by defineXlsxSheet. */
28
+ export type XlsxSheet = {
29
+ readonly name: string;
30
+ readonly columns: readonly XlsxColumn[];
31
+ /** Header rows above the data, top first. Empty when headers are off. */
32
+ readonly headerRows: readonly (readonly string[])[];
33
+ /** Horizontal merges inside header rows (Matrix column bands). Zero-based. */
34
+ readonly merges: readonly XlsxMerge[];
35
+ /** Column widths in characters, one per column. */
36
+ readonly widths: readonly number[];
37
+ };
38
+ /**
39
+ * Validates and freezes a sheet. Throws XlsxLimitError('columns') above 16,384
40
+ * columns. `sampleRows` only tunes widths.
41
+ */
42
+ export declare function defineXlsxSheet(input: {
43
+ title: string;
44
+ columns: readonly XlsxColumn[];
45
+ headerRows: readonly (readonly string[])[];
46
+ /** Explicit header merges. The caller derives them from identity (Matrix: member paths and roles); the writer only validates and writes them. */
47
+ merges?: readonly XlsxMerge[];
48
+ sampleRows?: readonly (readonly ExportCell[])[];
49
+ }): XlsxSheet;
50
+ /** JSON form, for workers that share one sheet (the first chunk or layout batch writes it; compaction reads it). */
51
+ export declare function serializeXlsxSheet(sheet: XlsxSheet): string;
52
+ /**
53
+ * The same sheet with settled columns, one per existing column. A background
54
+ * job's first chunk writes the sheet; a column its rows could not type takes
55
+ * the type the other chunks found (row fragments do not depend on it: styles
56
+ * go by column position).
57
+ */
58
+ export declare function withXlsxSheetColumns(sheet: XlsxSheet, columns: readonly XlsxColumn[]): XlsxSheet;
59
+ /** A column list as JSON and back, checked as a sheet's columns are. */
60
+ export declare function serializeXlsxColumns(columns: readonly XlsxColumn[]): string;
61
+ export declare function parseXlsxColumns(value: unknown): XlsxColumn[];
62
+ export declare function parseXlsxSheet(json: string): XlsxSheet;
63
+ /** Stable hash of a column list; equal for structurally equal columns. */
64
+ export declare function xlsxColumnsFingerprint(columns: readonly XlsxColumn[]): string;
65
+ export type XlsxRow = {
66
+ role: 'body' | 'total';
67
+ cells: readonly ExportCell[];
68
+ };
69
+ /** Joinable sheet XML for some rows (one chunk, one Matrix batch, or a totals row). Pure. */
70
+ export declare function encodeXlsxRows(sheet: XlsxSheet, rows: Iterable<XlsxRow>): string;
71
+ /** A whole workbook in memory: browser downloads and Matrix direct. */
72
+ export declare function encodeXlsxFile(sheet: XlsxSheet, rows: Iterable<XlsxRow>): Uint8Array;
73
+ /**
74
+ * The whole workbook as zip bytes, from row fragments made by encodeXlsxRows,
75
+ * in order. A totals row is just a last fragment. `rowCount` counts every
76
+ * row in the fragments (body and total); `fragmentBytes` is their UTF-8 size
77
+ * (the stored size of the chunk or batch objects). Backpressure follows the
78
+ * consumer: the next fragment is read only after the bytes before it were
79
+ * taken. Throws XlsxLimitError('rows') or ('size') here, before anything is
80
+ * written. Fragments that turn out larger than `fragmentBytes` fail with
81
+ * XlsxLimitError('size') before the sheet passes the limit, and any other
82
+ * mismatch fails with TypeError before the file is finished, so a wrong count
83
+ * never yields a complete file.
84
+ */
85
+ export declare function streamXlsxFile(input: {
86
+ sheet: XlsxSheet;
87
+ fragments: AsyncIterable<string | Uint8Array>;
88
+ rowCount: number;
89
+ fragmentBytes: number;
90
+ }): AsyncIterable<Uint8Array>;
@@ -13,6 +13,13 @@ export type FilterLineValue = {
13
13
  };
14
14
  type FormatFilterLineOptions = {
15
15
  timezone?: string;
16
+ /**
17
+ * 'label': every relative window prints by its label ("Last 7 days"), for a
18
+ * reader that shows saved values rather than a run's resolved dates (the
19
+ * schedule dialog). Absent: quarter, year and latest-data windows print by
20
+ * name and every other window prints its dates, as a run's PDF header does.
21
+ */
22
+ relativeDates?: 'label';
16
23
  };
17
24
  type FormatFilterConditionOptions = FormatFilterLineOptions & {
18
25
  /** The filter's display name; defaults to its column name in title case. */
@@ -1,15 +1,4 @@
1
- /**
2
- * Date formatting utilities with timezone support
3
- * IMPORTANT: No React imports allowed in this file
4
- *
5
- * Uses date-fns and date-fns-tz for consistent behavior in browser and Node.js
6
- *
7
- * This module provides the canonical date formatting functions used by:
8
- * - data-table component
9
- * - pivot-table component
10
- * - aggregated-table component
11
- * - Lambda CSV export (chunk-processor)
12
- */
1
+ import { ExportWallClock } from '../exporters/export-cells.js';
13
2
  /**
14
3
  * Resolve which timezone to use for formatting
15
4
  * Priority: column-specific > context timezone
@@ -52,6 +41,13 @@ export declare function parseWithSourceTimezone(dateString: string, sourceTimezo
52
41
  * formatDate('2024-01-15T10:30:00Z', 'MM/dd/yyyy HH:mm', 'America/Chicago') // '01/15/2024 04:30'
53
42
  */
54
43
  export declare const formatDate: (dateString: string | null | undefined, formatPattern: string | undefined, displayTimezone?: string, sourceTimezone?: string) => string;
44
+ /**
45
+ * The calendar date and time `formatDate` shows for the same inputs, with no
46
+ * zone: the same source-zone interpretation and display-zone conversion.
47
+ * Undefined when `formatDate` would return the input unchanged (empty or not
48
+ * a date). Excel exports write it as a date serial (Excel exports plan XL-D35).
49
+ */
50
+ export declare function dateWallClock(dateString: string | null | undefined, displayTimezone?: string, sourceTimezone?: string): ExportWallClock | undefined;
55
51
  /**
56
52
  * Format relative time using date-fns (e.g., "2 days ago")
57
53
  *
@@ -1,6 +1,6 @@
1
1
  export { formatNumber, formatCurrency, formatPercent, formatScientific, formatNumericCanonical, formatMeasureCanonical, formatNumberWithColumnSettings, formatNumberCustom, } from './number-formatter.js';
2
2
  export { formatDuration, formatDurationCanonical } from './duration-formatter.js';
3
3
  export { formatMetricComparison, type FormattedMetricComparison, type FormattedMetricComparisonPart, type FormatMetricComparisonOptions, type MetricComparisonDisplayMode, } from './metric-comparison-formatter.js';
4
- export { formatDate, formatRelativeTime, resolveTimezone, getTimezoneAbbreviation, getTimezoneName, parseWithSourceTimezone, } from './date-formatter.js';
4
+ export { formatDate, formatRelativeTime, dateWallClock, resolveTimezone, getTimezoneAbbreviation, getTimezoneName, parseWithSourceTimezone, } from './date-formatter.js';
5
5
  export { formatCellValue, formatRowForExport } from './cell-formatter.js';
6
6
  export type { CellAbsencePresentation } from './cell-formatter.js';
@@ -1,5 +1,6 @@
1
1
  import { MatrixPath, MatrixPresentation, MatrixWindow, SemaphorScalarValue, SemaphorValueFormat } from '../../analytics-protocol/index.js';
2
2
  import { ReportRuntimeContext } from '../../report-runtime-context/index.js';
3
+ import { MeasureCanonicalFormat } from '../types/index.js';
3
4
  /** Null hierarchy members stay identifiable even when null cells render blank. */
4
5
  export declare function matrixMemberLabel(path: MatrixPath, levels?: ReadonlyMap<string, (value: SemaphorScalarValue) => string>): string;
5
6
  /**
@@ -39,6 +40,7 @@ export declare function prepareMatrixFormatting(descriptors: MatrixWindow['descr
39
40
  isNumeric: boolean;
40
41
  hasTextAffixes: boolean;
41
42
  }>;
43
+ measureFormats: Map<string, MeasureCanonicalFormat>;
42
44
  absence: {
43
45
  emptyText: string;
44
46
  nullText: string;
@@ -18,6 +18,7 @@ export * from './exporters/index.js';
18
18
  export * from './export-policy.js';
19
19
  export * from './matrix-continuation.js';
20
20
  export * from './matrix-export-presentation.js';
21
+ export * from './matrix-export-xlsx.js';
21
22
  export * from './matrix-print.js';
22
23
  export { fromSemanticFormat } from './semantic-format.js';
23
24
  export type * from './table-structure.js';
@@ -30,7 +31,9 @@ export * from './temporal-bucket.js';
30
31
  export * from './raw-temporal.js';
31
32
  export * from './temporal-input-presentation.js';
32
33
  export * from './flat-table-export-totals.js';
34
+ export * from './table-export/index.js';
33
35
  export * from './filter-line.js';
36
+ export * from './attachment-filter-line.js';
34
37
  export { describeFilterValueInFullDetail, type FullDetailFilterValue, } from './filter-value-text.js';
35
38
  export { describeConditionInFullDetail, type FilterClauseText } from './filter-detail.js';
36
39
  export { formatCanonicalComparisonRange } from '../../lib/utils/comparison-window-caption.js';