@aglyn/shared-data-enums 1.0.0-beta.143

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 (42) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +3 -0
  3. package/package.json +39 -0
  4. package/src/enums.d.ts +26 -0
  5. package/src/enums.js +27 -0
  6. package/src/enums.js.map +1 -0
  7. package/src/index.d.ts +17 -0
  8. package/src/index.js +18 -0
  9. package/src/index.js.map +1 -0
  10. package/src/lib/aglyn-applications.d.ts +39 -0
  11. package/src/lib/aglyn-applications.js +53 -0
  12. package/src/lib/aglyn-applications.js.map +1 -0
  13. package/src/lib/aglyn.d.ts +49 -0
  14. package/src/lib/aglyn.js +86 -0
  15. package/src/lib/aglyn.js.map +1 -0
  16. package/src/lib/breakpoint-span.d.ts +66 -0
  17. package/src/lib/breakpoint-span.js +117 -0
  18. package/src/lib/breakpoint-span.js.map +1 -0
  19. package/src/lib/data-table.d.ts +107 -0
  20. package/src/lib/data-table.js +225 -0
  21. package/src/lib/data-table.js.map +1 -0
  22. package/src/lib/firebase-auth.d.ts +73 -0
  23. package/src/lib/firebase-auth.js +178 -0
  24. package/src/lib/firebase-auth.js.map +1 -0
  25. package/src/lib/global.d.ts +32 -0
  26. package/src/lib/global.js +33 -0
  27. package/src/lib/global.js.map +1 -0
  28. package/src/lib/http.d.ts +145 -0
  29. package/src/lib/http.js +155 -0
  30. package/src/lib/http.js.map +1 -0
  31. package/src/lib/icons.d.ts +108 -0
  32. package/src/lib/icons.js +130 -0
  33. package/src/lib/icons.js.map +1 -0
  34. package/src/lib/palette-token-css-var.d.ts +111 -0
  35. package/src/lib/palette-token-css-var.js +221 -0
  36. package/src/lib/palette-token-css-var.js.map +1 -0
  37. package/src/lib/styles.d.ts +170 -0
  38. package/src/lib/styles.js +315 -0
  39. package/src/lib/styles.js.map +1 -0
  40. package/src/lib/sx-property-aliases.d.ts +129 -0
  41. package/src/lib/sx-property-aliases.js +231 -0
  42. package/src/lib/sx-property-aliases.js.map +1 -0
@@ -0,0 +1,66 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Aglyn LLC
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+ /**
18
+ * The responsive span/offset syntax the besigner persists for MUI Grid
19
+ * (AGL-2486).
20
+ *
21
+ * A Grid cell's `size` and `offset` are stored as ONE string in the node's
22
+ * props — `"6"`, `"auto"`, `"xs:12 md:6"` — because MUI v6+ replaced the
23
+ * per-breakpoint `xs=`/`md=` props with a single value-or-object prop. That
24
+ * string is the persisted format and it does not change here; what changes is
25
+ * that the attributes panel no longer asks an author to TYPE it (a developer
26
+ * syntax nobody outside the docs knows). Parse and serialize live together in
27
+ * this shared module, the same arrangement `parseCssDimension`/
28
+ * `buildCssDimension` above have, so the editor and the renderer cannot drift
29
+ * into two different readings of the same stored string.
30
+ *
31
+ * `raw` is the escape hatch that keeps the editor from destroying what it
32
+ * cannot model — a half-typed pair, a `{{token}}` binding, an unknown
33
+ * breakpoint. The string comes back untouched instead of collapsing to
34
+ * whatever a lenient parse salvaged.
35
+ */
36
+ /** Breakpoint keys MUI's responsive `size`/`offset` objects accept. */
37
+ export declare const SPAN_BREAKPOINTS: readonly ["xs", "sm", "md", "lg", "xl"];
38
+ export type SpanBreakpoint = (typeof SPAN_BREAKPOINTS)[number];
39
+ /** One span: a column count, or one of MUI's two sizing keywords. */
40
+ export type SpanValue = number | 'auto' | 'grow';
41
+ export interface BreakpointSpan {
42
+ /**
43
+ * A value authored with NO breakpoint (`"6"`, `"auto"`). MUI applies it at
44
+ * every size, and it is mutually exclusive with {@link values} — the prop
45
+ * is either a scalar or an object, never both.
46
+ */
47
+ base?: SpanValue;
48
+ /** Per-breakpoint values, normalized into {@link SPAN_BREAKPOINTS} order. */
49
+ values?: Partial<Record<SpanBreakpoint, SpanValue>>;
50
+ /** Set ONLY when the string is not a span this module can model. */
51
+ raw?: string;
52
+ }
53
+ /**
54
+ * Reads a stored span string into {@link BreakpointSpan}.
55
+ *
56
+ * A partly-parseable list comes back as `raw`, never as a partial object: a
57
+ * half-applied breakpoint map is a layout that silently differs from what the
58
+ * author typed, which is worse than no layout at all.
59
+ */
60
+ export declare function parseBreakpointSpan(value: string | number | undefined | null): BreakpointSpan;
61
+ /**
62
+ * Serializes a {@link BreakpointSpan} back to the single string that gets
63
+ * persisted. The inverse of {@link parseBreakpointSpan}: an empty span
64
+ * serializes to an empty string, never to a partial pair like `md:`.
65
+ */
66
+ export declare function buildBreakpointSpan(span?: BreakpointSpan): string;
@@ -0,0 +1,117 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Aglyn LLC
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */ /**
17
+ * The responsive span/offset syntax the besigner persists for MUI Grid
18
+ * (AGL-2486).
19
+ *
20
+ * A Grid cell's `size` and `offset` are stored as ONE string in the node's
21
+ * props — `"6"`, `"auto"`, `"xs:12 md:6"` — because MUI v6+ replaced the
22
+ * per-breakpoint `xs=`/`md=` props with a single value-or-object prop. That
23
+ * string is the persisted format and it does not change here; what changes is
24
+ * that the attributes panel no longer asks an author to TYPE it (a developer
25
+ * syntax nobody outside the docs knows). Parse and serialize live together in
26
+ * this shared module, the same arrangement `parseCssDimension`/
27
+ * `buildCssDimension` above have, so the editor and the renderer cannot drift
28
+ * into two different readings of the same stored string.
29
+ *
30
+ * `raw` is the escape hatch that keeps the editor from destroying what it
31
+ * cannot model — a half-typed pair, a `{{token}}` binding, an unknown
32
+ * breakpoint. The string comes back untouched instead of collapsing to
33
+ * whatever a lenient parse salvaged.
34
+ */ /** Breakpoint keys MUI's responsive `size`/`offset` objects accept. */ export const SPAN_BREAKPOINTS = [
35
+ 'xs',
36
+ 'sm',
37
+ 'md',
38
+ 'lg',
39
+ 'xl'
40
+ ];
41
+ /** `12`, `-4`, `2.5` — a bare quantity with no breakpoint attached. */ const BARE_NUMBER = /^-?\d+(\.\d+)?$/;
42
+ /** `md:6`, `XS = auto` — one breakpoint pair, in either separator style. */ const PAIR = /^([a-z]+)\s*[:=]\s*(auto|grow|-?\d+(?:\.\d+)?)$/i;
43
+ const isBreakpoint = (key)=>SPAN_BREAKPOINTS.includes(key);
44
+ /**
45
+ * Reads a stored span string into {@link BreakpointSpan}.
46
+ *
47
+ * A partly-parseable list comes back as `raw`, never as a partial object: a
48
+ * half-applied breakpoint map is a layout that silently differs from what the
49
+ * author typed, which is worse than no layout at all.
50
+ */ export function parseBreakpointSpan(value) {
51
+ // `value === 0` is a real span the author can mean, so this tests for
52
+ // absence explicitly rather than for falsiness (strictNullChecks is off
53
+ // repo-wide, and `!value` would swallow the zero).
54
+ if (value === undefined || value === null || value === '') return {};
55
+ if (typeof value === 'number') {
56
+ return Number.isFinite(value) ? {
57
+ base: value
58
+ } : {};
59
+ }
60
+ const text = `${value}`.trim();
61
+ if (!text) return {};
62
+ if (text === 'auto' || text === 'grow') return {
63
+ base: text
64
+ };
65
+ if (BARE_NUMBER.test(text)) return {
66
+ base: Number(text)
67
+ };
68
+ const pairs = text.split(/[\s,]+/).filter(Boolean);
69
+ const values = {};
70
+ for (const pair of pairs){
71
+ var _match_, _match_1;
72
+ const match = PAIR.exec(pair);
73
+ if (!match) return {
74
+ raw: text
75
+ };
76
+ const key = ((_match_ = match[1]) != null ? _match_ : '').toLowerCase();
77
+ if (!isBreakpoint(key)) return {
78
+ raw: text
79
+ };
80
+ const span = (_match_1 = match[2]) != null ? _match_1 : '';
81
+ values[key] = span === 'auto' || span === 'grow' ? span : Number(span);
82
+ }
83
+ if (!Object.keys(values).length) return {
84
+ raw: text
85
+ };
86
+ // Normalized to breakpoint order so the serialized string is stable no
87
+ // matter what order the author wrote the pairs in.
88
+ const ordered = {};
89
+ for (const key of SPAN_BREAKPOINTS){
90
+ if (values[key] !== undefined) ordered[key] = values[key];
91
+ }
92
+ return {
93
+ values: ordered
94
+ };
95
+ }
96
+ /**
97
+ * Serializes a {@link BreakpointSpan} back to the single string that gets
98
+ * persisted. The inverse of {@link parseBreakpointSpan}: an empty span
99
+ * serializes to an empty string, never to a partial pair like `md:`.
100
+ */ export function buildBreakpointSpan(span) {
101
+ if (!span) return '';
102
+ if (span.raw !== undefined) return span.raw;
103
+ if (span.base !== undefined) return `${span.base}`;
104
+ const values = span.values;
105
+ if (!values) return '';
106
+ const pairs = [];
107
+ for (const key of SPAN_BREAKPOINTS){
108
+ const value = values[key];
109
+ if (value === undefined || value === null || value === '') {
110
+ continue;
111
+ }
112
+ pairs.push(`${key}:${value}`);
113
+ }
114
+ return pairs.join(' ');
115
+ }
116
+
117
+ //# sourceMappingURL=breakpoint-span.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../../libs/shared/data/enums/src/lib/breakpoint-span.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * The responsive span/offset syntax the besigner persists for MUI Grid\n * (AGL-2486).\n *\n * A Grid cell's `size` and `offset` are stored as ONE string in the node's\n * props — `\"6\"`, `\"auto\"`, `\"xs:12 md:6\"` — because MUI v6+ replaced the\n * per-breakpoint `xs=`/`md=` props with a single value-or-object prop. That\n * string is the persisted format and it does not change here; what changes is\n * that the attributes panel no longer asks an author to TYPE it (a developer\n * syntax nobody outside the docs knows). Parse and serialize live together in\n * this shared module, the same arrangement `parseCssDimension`/\n * `buildCssDimension` above have, so the editor and the renderer cannot drift\n * into two different readings of the same stored string.\n *\n * `raw` is the escape hatch that keeps the editor from destroying what it\n * cannot model — a half-typed pair, a `{{token}}` binding, an unknown\n * breakpoint. The string comes back untouched instead of collapsing to\n * whatever a lenient parse salvaged.\n */\n\n/** Breakpoint keys MUI's responsive `size`/`offset` objects accept. */\nexport const SPAN_BREAKPOINTS = ['xs', 'sm', 'md', 'lg', 'xl'] as const\n\nexport type SpanBreakpoint = (typeof SPAN_BREAKPOINTS)[number]\n\n/** One span: a column count, or one of MUI's two sizing keywords. */\nexport type SpanValue = number | 'auto' | 'grow'\n\nexport interface BreakpointSpan {\n /**\n * A value authored with NO breakpoint (`\"6\"`, `\"auto\"`). MUI applies it at\n * every size, and it is mutually exclusive with {@link values} — the prop\n * is either a scalar or an object, never both.\n */\n base?: SpanValue\n /** Per-breakpoint values, normalized into {@link SPAN_BREAKPOINTS} order. */\n values?: Partial<Record<SpanBreakpoint, SpanValue>>\n /** Set ONLY when the string is not a span this module can model. */\n raw?: string\n}\n\n/** `12`, `-4`, `2.5` — a bare quantity with no breakpoint attached. */\nconst BARE_NUMBER = /^-?\\d+(\\.\\d+)?$/\n/** `md:6`, `XS = auto` — one breakpoint pair, in either separator style. */\nconst PAIR = /^([a-z]+)\\s*[:=]\\s*(auto|grow|-?\\d+(?:\\.\\d+)?)$/i\n\nconst isBreakpoint = (key: string): key is SpanBreakpoint =>\n (SPAN_BREAKPOINTS as readonly string[]).includes(key)\n\n/**\n * Reads a stored span string into {@link BreakpointSpan}.\n *\n * A partly-parseable list comes back as `raw`, never as a partial object: a\n * half-applied breakpoint map is a layout that silently differs from what the\n * author typed, which is worse than no layout at all.\n */\nexport function parseBreakpointSpan(\n value: string | number | undefined | null,\n): BreakpointSpan {\n // `value === 0` is a real span the author can mean, so this tests for\n // absence explicitly rather than for falsiness (strictNullChecks is off\n // repo-wide, and `!value` would swallow the zero).\n if (value === undefined || value === null || value === '') return {}\n if (typeof value === 'number') {\n return Number.isFinite(value) ? { base: value } : {}\n }\n\n const text = `${value}`.trim()\n if (!text) return {}\n if (text === 'auto' || text === 'grow') return { base: text }\n if (BARE_NUMBER.test(text)) return { base: Number(text) }\n\n const pairs = text.split(/[\\s,]+/).filter(Boolean)\n const values: Partial<Record<SpanBreakpoint, SpanValue>> = {}\n for (const pair of pairs) {\n const match = PAIR.exec(pair)\n if (!match) return { raw: text }\n const key = (match[1] ?? '').toLowerCase()\n if (!isBreakpoint(key)) return { raw: text }\n const span = match[2] ?? ''\n values[key] =\n span === 'auto' || span === 'grow' ? (span as SpanValue) : Number(span)\n }\n if (!Object.keys(values).length) return { raw: text }\n\n // Normalized to breakpoint order so the serialized string is stable no\n // matter what order the author wrote the pairs in.\n const ordered: Partial<Record<SpanBreakpoint, SpanValue>> = {}\n for (const key of SPAN_BREAKPOINTS) {\n if (values[key] !== undefined) ordered[key] = values[key]\n }\n return { values: ordered }\n}\n\n/**\n * Serializes a {@link BreakpointSpan} back to the single string that gets\n * persisted. The inverse of {@link parseBreakpointSpan}: an empty span\n * serializes to an empty string, never to a partial pair like `md:`.\n */\nexport function buildBreakpointSpan(span?: BreakpointSpan): string {\n if (!span) return ''\n if (span.raw !== undefined) return span.raw\n if (span.base !== undefined) return `${span.base}`\n const values = span.values\n if (!values) return ''\n const pairs: string[] = []\n for (const key of SPAN_BREAKPOINTS) {\n const value = values[key]\n if (value === undefined || value === null || (value as unknown) === '') {\n continue\n }\n pairs.push(`${key}:${value}`)\n }\n return pairs.join(' ')\n}\n"],"names":["SPAN_BREAKPOINTS","BARE_NUMBER","PAIR","isBreakpoint","key","includes","parseBreakpointSpan","value","undefined","Number","isFinite","base","text","trim","test","pairs","split","filter","Boolean","values","pair","match","exec","raw","toLowerCase","span","Object","keys","length","ordered","buildBreakpointSpan","push","join"],"mappings":"AAAA;;;;;;;;;;;;;;;CAeC,GAED;;;;;;;;;;;;;;;;;;CAkBC,GAED,qEAAqE,GACrE,OAAO,MAAMA,mBAAmB;IAAC;IAAM;IAAM;IAAM;IAAM;CAAK,CAAS;AAoBvE,qEAAqE,GACrE,MAAMC,cAAc;AACpB,0EAA0E,GAC1E,MAAMC,OAAO;AAEb,MAAMC,eAAe,CAACC,MACpB,AAACJ,iBAAuCK,QAAQ,CAACD;AAEnD;;;;;;CAMC,GACD,OAAO,SAASE,oBACdC,KAAyC;IAEzC,sEAAsE;IACtE,wEAAwE;IACxE,mDAAmD;IACnD,IAAIA,UAAUC,aAAaD,UAAU,QAAQA,UAAU,IAAI,OAAO,CAAC;IACnE,IAAI,OAAOA,UAAU,UAAU;QAC7B,OAAOE,OAAOC,QAAQ,CAACH,SAAS;YAAEI,MAAMJ;QAAM,IAAI,CAAC;IACrD;IAEA,MAAMK,OAAO,GAAGL,OAAO,CAACM,IAAI;IAC5B,IAAI,CAACD,MAAM,OAAO,CAAC;IACnB,IAAIA,SAAS,UAAUA,SAAS,QAAQ,OAAO;QAAED,MAAMC;IAAK;IAC5D,IAAIX,YAAYa,IAAI,CAACF,OAAO,OAAO;QAAED,MAAMF,OAAOG;IAAM;IAExD,MAAMG,QAAQH,KAAKI,KAAK,CAAC,UAAUC,MAAM,CAACC;IAC1C,MAAMC,SAAqD,CAAC;IAC5D,KAAK,MAAMC,QAAQL,MAAO;YAGXM,SAEAA;QAJb,MAAMA,QAAQnB,KAAKoB,IAAI,CAACF;QACxB,IAAI,CAACC,OAAO,OAAO;YAAEE,KAAKX;QAAK;QAC/B,MAAMR,MAAM,EAACiB,UAAAA,KAAK,CAAC,EAAE,YAARA,UAAY,IAAIG,WAAW;QACxC,IAAI,CAACrB,aAAaC,MAAM,OAAO;YAAEmB,KAAKX;QAAK;QAC3C,MAAMa,QAAOJ,WAAAA,KAAK,CAAC,EAAE,YAARA,WAAY;QACzBF,MAAM,CAACf,IAAI,GACTqB,SAAS,UAAUA,SAAS,SAAUA,OAAqBhB,OAAOgB;IACtE;IACA,IAAI,CAACC,OAAOC,IAAI,CAACR,QAAQS,MAAM,EAAE,OAAO;QAAEL,KAAKX;IAAK;IAEpD,uEAAuE;IACvE,mDAAmD;IACnD,MAAMiB,UAAsD,CAAC;IAC7D,KAAK,MAAMzB,OAAOJ,iBAAkB;QAClC,IAAImB,MAAM,CAACf,IAAI,KAAKI,WAAWqB,OAAO,CAACzB,IAAI,GAAGe,MAAM,CAACf,IAAI;IAC3D;IACA,OAAO;QAAEe,QAAQU;IAAQ;AAC3B;AAEA;;;;CAIC,GACD,OAAO,SAASC,oBAAoBL,IAAqB;IACvD,IAAI,CAACA,MAAM,OAAO;IAClB,IAAIA,KAAKF,GAAG,KAAKf,WAAW,OAAOiB,KAAKF,GAAG;IAC3C,IAAIE,KAAKd,IAAI,KAAKH,WAAW,OAAO,GAAGiB,KAAKd,IAAI,EAAE;IAClD,MAAMQ,SAASM,KAAKN,MAAM;IAC1B,IAAI,CAACA,QAAQ,OAAO;IACpB,MAAMJ,QAAkB,EAAE;IAC1B,KAAK,MAAMX,OAAOJ,iBAAkB;QAClC,MAAMO,QAAQY,MAAM,CAACf,IAAI;QACzB,IAAIG,UAAUC,aAAaD,UAAU,QAAQ,AAACA,UAAsB,IAAI;YACtE;QACF;QACAQ,MAAMgB,IAAI,CAAC,GAAG3B,IAAI,CAAC,EAAEG,OAAO;IAC9B;IACA,OAAOQ,MAAMiB,IAAI,CAAC;AACpB"}
@@ -0,0 +1,107 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Aglyn LLC
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+ /**
18
+ * The grid behind the Table element (AGL-2543).
19
+ *
20
+ * ONE parser, shared by the renderer and the attributes-panel editor. Two
21
+ * implementations of "what does this string mean" is how a table comes to
22
+ * look right in the canvas and wrong on the page, and the two are written by
23
+ * different people months apart.
24
+ *
25
+ * The persisted prop is a single string, following the house pattern used by
26
+ * `CSS_DIMENSION` and `CSS_GRADIENT`: the rich editor is an input affordance,
27
+ * not a shape change, so nothing downstream has to learn a new type and a
28
+ * value the editor cannot model is never clobbered.
29
+ *
30
+ * Pipe-delimited, one row per line — deliberately the markdown table body's
31
+ * own syntax, so the comparison tables already authored in Markdown elements
32
+ * paste straight in. A leading and trailing pipe are optional, which is what
33
+ * a copied markdown table has.
34
+ */
35
+ /** Column alignments the editor offers and the renderer honours. */
36
+ export declare const DATA_TABLE_ALIGNMENTS: readonly ["left", "center", "right"];
37
+ export type DataTableAlignment = (typeof DATA_TABLE_ALIGNMENTS)[number];
38
+ export declare const DATA_TABLE_ALIGNMENT_DEFAULT: DataTableAlignment;
39
+ /**
40
+ * The alignments a pasted markdown divider row encodes, or `null` when the
41
+ * line is not one. `:--` is left, `:-:` centre, `--:` right.
42
+ */
43
+ export declare function alignmentsFromDivider(line: string): DataTableAlignment[] | null;
44
+ /**
45
+ * The grid a stored value describes.
46
+ *
47
+ * Rows are padded to the widest one so the renderer and the editor always see
48
+ * a rectangle: a short row is an authoring accident, and a table that renders
49
+ * with a missing cell is harder to fix than one with an empty one.
50
+ */
51
+ export declare function parseDataTableRows(value: unknown): string[][];
52
+ /**
53
+ * The alignments a stored value carries, padded to the table's width.
54
+ *
55
+ * Alignment lives in the SAME string as the grid, as a markdown divider row,
56
+ * rather than in a prop of its own. A field editor is handed one prop, so a
57
+ * second prop could not be reached from the grid's own per-column controls —
58
+ * and encoding it the way markdown already does means a pasted table keeps
59
+ * the alignment it was authored with instead of silently flattening to left.
60
+ */
61
+ export declare function readDataTableAlignments(value: unknown, columnCount: number): DataTableAlignment[];
62
+ /** A row of a table the author pasted, and the alignments it carried. */
63
+ export interface PastedDataTable {
64
+ rows: string[][];
65
+ alignments: DataTableAlignment[];
66
+ }
67
+ /**
68
+ * The table a pasted string describes, or `null` when it is not one
69
+ * (AGL-2568).
70
+ *
71
+ * Reading it is the migration path off the Markdown workaround: the tables
72
+ * this element replaces are already authored as pipe syntax, and the
73
+ * alternative to importing them is retyping thirty cells of dated competitor
74
+ * pricing by hand, which is the content least safe to retype.
75
+ *
76
+ * `null` rather than a best effort is the important half. This runs on every
77
+ * paste into every cell, and an author pasting `Pro | Business` as a cell
78
+ * VALUE must get those characters, not a two-column table. So a paste is only
79
+ * read as a table when it could not sensibly be anything else: more than one
80
+ * line, every one of them carrying an unescaped pipe, and at least two
81
+ * columns once parsed. A single line never qualifies, however many pipes it
82
+ * has.
83
+ */
84
+ export declare function readPastedDataTable(value: unknown): PastedDataTable | null;
85
+ /**
86
+ * The stored form of a grid plus its alignments.
87
+ *
88
+ * The divider is written after the first row, where markdown puts it, and
89
+ * only when some column is not the default — an all-left table stays a plain
90
+ * pipe grid rather than growing a row of dashes nobody asked for.
91
+ */
92
+ export declare function serializeDataTable(rows: string[][], alignments?: readonly DataTableAlignment[]): string;
93
+ /**
94
+ * The 1-based column to emphasise, or `0` for none.
95
+ *
96
+ * 1-based because the control says "column 3" to an author who is looking at
97
+ * the third column; `0` rather than `null` so "none" survives a form field
98
+ * that only speaks numbers. Out-of-range values mean none, so deleting a
99
+ * column cannot leave a table pointing at one that is gone.
100
+ */
101
+ export declare function normalizeEmphasisColumn(value: unknown, columnCount: number): number;
102
+ /** A grid with `count` empty columns appended to every row. */
103
+ export declare function withColumnAdded(rows: string[][], at?: number): string[][];
104
+ export declare function withColumnRemoved(rows: string[][], at: number): string[][];
105
+ export declare function withRowAdded(rows: string[][], at?: number): string[][];
106
+ export declare function withRowRemoved(rows: string[][], at: number): string[][];
107
+ export declare function withCellSet(rows: string[][], rowIndex: number, columnIndex: number, value: string): string[][];
@@ -0,0 +1,225 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Aglyn LLC
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */ /**
17
+ * The grid behind the Table element (AGL-2543).
18
+ *
19
+ * ONE parser, shared by the renderer and the attributes-panel editor. Two
20
+ * implementations of "what does this string mean" is how a table comes to
21
+ * look right in the canvas and wrong on the page, and the two are written by
22
+ * different people months apart.
23
+ *
24
+ * The persisted prop is a single string, following the house pattern used by
25
+ * `CSS_DIMENSION` and `CSS_GRADIENT`: the rich editor is an input affordance,
26
+ * not a shape change, so nothing downstream has to learn a new type and a
27
+ * value the editor cannot model is never clobbered.
28
+ *
29
+ * Pipe-delimited, one row per line — deliberately the markdown table body's
30
+ * own syntax, so the comparison tables already authored in Markdown elements
31
+ * paste straight in. A leading and trailing pipe are optional, which is what
32
+ * a copied markdown table has.
33
+ */ /** Column alignments the editor offers and the renderer honours. */ export const DATA_TABLE_ALIGNMENTS = [
34
+ 'left',
35
+ 'center',
36
+ 'right'
37
+ ];
38
+ export const DATA_TABLE_ALIGNMENT_DEFAULT = 'left';
39
+ /**
40
+ * A markdown alignment divider — `|---|:--:|---:|`.
41
+ *
42
+ * Dropped rather than rendered as a row of dashes. It carries no content, and
43
+ * an author pasting a markdown table has no reason to expect it to survive as
44
+ * data; its alignment intent is read out separately by
45
+ * {@link alignmentsFromDivider}.
46
+ */ const DIVIDER_CELL = /^:?-{2,}:?$/;
47
+ function splitRow(line) {
48
+ // `\|` is a literal pipe, so a cell may contain one. Split on unescaped
49
+ // pipes only, then unescape — doing it in the other order would turn an
50
+ // escaped pipe into a column break.
51
+ const cells = line.replace(/^\s*\|/, '').replace(/\|\s*$/, '').split(/(?<!\\)\|/).map((cell)=>cell.replace(/\\\|/g, '|').trim());
52
+ return cells;
53
+ }
54
+ function isDividerRow(cells) {
55
+ return cells.length > 0 && cells.every((cell)=>DIVIDER_CELL.test(cell));
56
+ }
57
+ /**
58
+ * The alignments a pasted markdown divider row encodes, or `null` when the
59
+ * line is not one. `:--` is left, `:-:` centre, `--:` right.
60
+ */ export function alignmentsFromDivider(line) {
61
+ const cells = splitRow(String(line != null ? line : ''));
62
+ if (!isDividerRow(cells)) return null;
63
+ return cells.map((cell)=>{
64
+ const left = cell.startsWith(':');
65
+ const right = cell.endsWith(':');
66
+ if (left && right) return 'center';
67
+ if (right) return 'right';
68
+ return 'left';
69
+ });
70
+ }
71
+ /**
72
+ * The grid a stored value describes.
73
+ *
74
+ * Rows are padded to the widest one so the renderer and the editor always see
75
+ * a rectangle: a short row is an authoring accident, and a table that renders
76
+ * with a missing cell is harder to fix than one with an empty one.
77
+ */ export function parseDataTableRows(value) {
78
+ const text = typeof value === 'string' ? value : '';
79
+ const rows = text.split(/\r?\n/).map((line)=>line.trim()).filter((line)=>line.length > 0).map(splitRow).filter((cells)=>!isDividerRow(cells));
80
+ const width = rows.reduce((widest, row)=>Math.max(widest, row.length), 0);
81
+ return rows.map((row)=>[
82
+ ...row,
83
+ ...Array.from({
84
+ length: width - row.length
85
+ }, ()=>'')
86
+ ]);
87
+ }
88
+ /**
89
+ * The alignments a stored value carries, padded to the table's width.
90
+ *
91
+ * Alignment lives in the SAME string as the grid, as a markdown divider row,
92
+ * rather than in a prop of its own. A field editor is handed one prop, so a
93
+ * second prop could not be reached from the grid's own per-column controls —
94
+ * and encoding it the way markdown already does means a pasted table keeps
95
+ * the alignment it was authored with instead of silently flattening to left.
96
+ */ export function readDataTableAlignments(value, columnCount) {
97
+ const found = String(value != null ? value : '').split(/\r?\n/).map((line)=>alignmentsFromDivider(line)).find((alignments)=>alignments !== null);
98
+ return Array.from({
99
+ length: Math.max(0, columnCount)
100
+ }, (_, index)=>{
101
+ const candidate = found == null ? void 0 : found[index];
102
+ return candidate != null ? candidate : DATA_TABLE_ALIGNMENT_DEFAULT;
103
+ });
104
+ }
105
+ /** A pipe that breaks a column, as opposed to a `\|` inside a cell. */ function hasUnescapedPipe(line) {
106
+ return /(?<!\\)\|/.test(line);
107
+ }
108
+ /**
109
+ * The table a pasted string describes, or `null` when it is not one
110
+ * (AGL-2568).
111
+ *
112
+ * Reading it is the migration path off the Markdown workaround: the tables
113
+ * this element replaces are already authored as pipe syntax, and the
114
+ * alternative to importing them is retyping thirty cells of dated competitor
115
+ * pricing by hand, which is the content least safe to retype.
116
+ *
117
+ * `null` rather than a best effort is the important half. This runs on every
118
+ * paste into every cell, and an author pasting `Pro | Business` as a cell
119
+ * VALUE must get those characters, not a two-column table. So a paste is only
120
+ * read as a table when it could not sensibly be anything else: more than one
121
+ * line, every one of them carrying an unescaped pipe, and at least two
122
+ * columns once parsed. A single line never qualifies, however many pipes it
123
+ * has.
124
+ */ export function readPastedDataTable(value) {
125
+ var _ref;
126
+ var _rows_;
127
+ const text = typeof value === 'string' ? value : '';
128
+ const lines = text.split(/\r?\n/).map((line)=>line.trim()).filter((line)=>line.length > 0);
129
+ if (lines.length < 2 || !lines.every(hasUnescapedPipe)) return null;
130
+ const rows = parseDataTableRows(text);
131
+ const width = (_ref = (_rows_ = rows[0]) == null ? void 0 : _rows_.length) != null ? _ref : 0;
132
+ if (rows.length === 0 || width < 2) return null;
133
+ return {
134
+ rows,
135
+ alignments: readDataTableAlignments(text, width)
136
+ };
137
+ }
138
+ /** The markdown divider encoding one column's alignment. */ function dividerCell(alignment) {
139
+ if (alignment === 'center') return ':---:';
140
+ if (alignment === 'right') return '---:';
141
+ return '---';
142
+ }
143
+ /**
144
+ * The stored form of a grid plus its alignments.
145
+ *
146
+ * The divider is written after the first row, where markdown puts it, and
147
+ * only when some column is not the default — an all-left table stays a plain
148
+ * pipe grid rather than growing a row of dashes nobody asked for.
149
+ */ export function serializeDataTable(rows, alignments) {
150
+ var _ref, _ref1;
151
+ var _rows_;
152
+ const body = (rows != null ? rows : []).map((row)=>(row != null ? row : []).map((cell)=>String(cell != null ? cell : '').replace(/\|/g, '\\|')).join(' | '));
153
+ const meaningful = (_ref = alignments == null ? void 0 : alignments.some((alignment)=>alignment && alignment !== DATA_TABLE_ALIGNMENT_DEFAULT)) != null ? _ref : false;
154
+ if (!meaningful || body.length === 0) return body.join('\n');
155
+ const width = (_ref1 = (_rows_ = rows[0]) == null ? void 0 : _rows_.length) != null ? _ref1 : 0;
156
+ const divider = Array.from({
157
+ length: width
158
+ }, (_, index)=>{
159
+ var _ref;
160
+ return dividerCell((_ref = alignments == null ? void 0 : alignments[index]) != null ? _ref : DATA_TABLE_ALIGNMENT_DEFAULT);
161
+ }).join(' | ');
162
+ return [
163
+ body[0],
164
+ divider,
165
+ ...body.slice(1)
166
+ ].join('\n');
167
+ }
168
+ /**
169
+ * The 1-based column to emphasise, or `0` for none.
170
+ *
171
+ * 1-based because the control says "column 3" to an author who is looking at
172
+ * the third column; `0` rather than `null` so "none" survives a form field
173
+ * that only speaks numbers. Out-of-range values mean none, so deleting a
174
+ * column cannot leave a table pointing at one that is gone.
175
+ */ export function normalizeEmphasisColumn(value, columnCount) {
176
+ const parsed = Math.trunc(Number(value));
177
+ if (!Number.isFinite(parsed) || parsed < 1 || parsed > columnCount) return 0;
178
+ return parsed;
179
+ }
180
+ /** A grid with `count` empty columns appended to every row. */ export function withColumnAdded(rows, at) {
181
+ var _ref;
182
+ var _rows_;
183
+ const width = (_ref = (_rows_ = rows[0]) == null ? void 0 : _rows_.length) != null ? _ref : 0;
184
+ const index = at == null ? width : Math.max(0, Math.min(at, width));
185
+ return (rows.length ? rows : [
186
+ []
187
+ ]).map((row)=>{
188
+ const next = [
189
+ ...row
190
+ ];
191
+ next.splice(index, 0, '');
192
+ return next;
193
+ });
194
+ }
195
+ export function withColumnRemoved(rows, at) {
196
+ var _ref;
197
+ var _rows_;
198
+ const width = (_ref = (_rows_ = rows[0]) == null ? void 0 : _rows_.length) != null ? _ref : 0;
199
+ // Never leave a table with no columns: a zero-column grid cannot be typed
200
+ // back into through the editor, so the last column is not removable.
201
+ if (width <= 1) return rows;
202
+ return rows.map((row)=>row.filter((_, index)=>index !== at));
203
+ }
204
+ export function withRowAdded(rows, at) {
205
+ var _ref;
206
+ var _rows_;
207
+ const width = (_ref = (_rows_ = rows[0]) == null ? void 0 : _rows_.length) != null ? _ref : 1;
208
+ const blank = Array.from({
209
+ length: width
210
+ }, ()=>'');
211
+ const next = [
212
+ ...rows
213
+ ];
214
+ next.splice(at == null ? rows.length : Math.max(0, Math.min(at, rows.length)), 0, blank);
215
+ return next;
216
+ }
217
+ export function withRowRemoved(rows, at) {
218
+ if (rows.length <= 1) return rows;
219
+ return rows.filter((_, index)=>index !== at);
220
+ }
221
+ export function withCellSet(rows, rowIndex, columnIndex, value) {
222
+ return rows.map((row, r)=>r === rowIndex ? row.map((cell, c)=>c === columnIndex ? value : cell) : row);
223
+ }
224
+
225
+ //# sourceMappingURL=data-table.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../../libs/shared/data/enums/src/lib/data-table.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * The grid behind the Table element (AGL-2543).\n *\n * ONE parser, shared by the renderer and the attributes-panel editor. Two\n * implementations of \"what does this string mean\" is how a table comes to\n * look right in the canvas and wrong on the page, and the two are written by\n * different people months apart.\n *\n * The persisted prop is a single string, following the house pattern used by\n * `CSS_DIMENSION` and `CSS_GRADIENT`: the rich editor is an input affordance,\n * not a shape change, so nothing downstream has to learn a new type and a\n * value the editor cannot model is never clobbered.\n *\n * Pipe-delimited, one row per line — deliberately the markdown table body's\n * own syntax, so the comparison tables already authored in Markdown elements\n * paste straight in. A leading and trailing pipe are optional, which is what\n * a copied markdown table has.\n */\n\n/** Column alignments the editor offers and the renderer honours. */\nexport const DATA_TABLE_ALIGNMENTS = ['left', 'center', 'right'] as const\n\nexport type DataTableAlignment = (typeof DATA_TABLE_ALIGNMENTS)[number]\n\nexport const DATA_TABLE_ALIGNMENT_DEFAULT: DataTableAlignment = 'left'\n\n/**\n * A markdown alignment divider — `|---|:--:|---:|`.\n *\n * Dropped rather than rendered as a row of dashes. It carries no content, and\n * an author pasting a markdown table has no reason to expect it to survive as\n * data; its alignment intent is read out separately by\n * {@link alignmentsFromDivider}.\n */\nconst DIVIDER_CELL = /^:?-{2,}:?$/\n\nfunction splitRow(line: string): string[] {\n // `\\|` is a literal pipe, so a cell may contain one. Split on unescaped\n // pipes only, then unescape — doing it in the other order would turn an\n // escaped pipe into a column break.\n const cells = line\n .replace(/^\\s*\\|/, '')\n .replace(/\\|\\s*$/, '')\n .split(/(?<!\\\\)\\|/)\n .map((cell) => cell.replace(/\\\\\\|/g, '|').trim())\n return cells\n}\n\nfunction isDividerRow(cells: string[]): boolean {\n return cells.length > 0 && cells.every((cell) => DIVIDER_CELL.test(cell))\n}\n\n/**\n * The alignments a pasted markdown divider row encodes, or `null` when the\n * line is not one. `:--` is left, `:-:` centre, `--:` right.\n */\nexport function alignmentsFromDivider(\n line: string,\n): DataTableAlignment[] | null {\n const cells = splitRow(String(line ?? ''))\n if (!isDividerRow(cells)) return null\n return cells.map((cell) => {\n const left = cell.startsWith(':')\n const right = cell.endsWith(':')\n if (left && right) return 'center'\n if (right) return 'right'\n return 'left'\n })\n}\n\n/**\n * The grid a stored value describes.\n *\n * Rows are padded to the widest one so the renderer and the editor always see\n * a rectangle: a short row is an authoring accident, and a table that renders\n * with a missing cell is harder to fix than one with an empty one.\n */\nexport function parseDataTableRows(value: unknown): string[][] {\n const text = typeof value === 'string' ? value : ''\n const rows = text\n .split(/\\r?\\n/)\n .map((line) => line.trim())\n .filter((line) => line.length > 0)\n .map(splitRow)\n .filter((cells) => !isDividerRow(cells))\n const width = rows.reduce((widest, row) => Math.max(widest, row.length), 0)\n return rows.map((row) => [\n ...row,\n ...Array.from({ length: width - row.length }, () => ''),\n ])\n}\n\n/**\n * The alignments a stored value carries, padded to the table's width.\n *\n * Alignment lives in the SAME string as the grid, as a markdown divider row,\n * rather than in a prop of its own. A field editor is handed one prop, so a\n * second prop could not be reached from the grid's own per-column controls —\n * and encoding it the way markdown already does means a pasted table keeps\n * the alignment it was authored with instead of silently flattening to left.\n */\nexport function readDataTableAlignments(\n value: unknown,\n columnCount: number,\n): DataTableAlignment[] {\n const found = String(value ?? '')\n .split(/\\r?\\n/)\n .map((line) => alignmentsFromDivider(line))\n .find((alignments) => alignments !== null)\n return Array.from({ length: Math.max(0, columnCount) }, (_, index) => {\n const candidate = found?.[index]\n return candidate ?? DATA_TABLE_ALIGNMENT_DEFAULT\n })\n}\n\n/** A row of a table the author pasted, and the alignments it carried. */\nexport interface PastedDataTable {\n rows: string[][]\n alignments: DataTableAlignment[]\n}\n\n/** A pipe that breaks a column, as opposed to a `\\|` inside a cell. */\nfunction hasUnescapedPipe(line: string): boolean {\n return /(?<!\\\\)\\|/.test(line)\n}\n\n/**\n * The table a pasted string describes, or `null` when it is not one\n * (AGL-2568).\n *\n * Reading it is the migration path off the Markdown workaround: the tables\n * this element replaces are already authored as pipe syntax, and the\n * alternative to importing them is retyping thirty cells of dated competitor\n * pricing by hand, which is the content least safe to retype.\n *\n * `null` rather than a best effort is the important half. This runs on every\n * paste into every cell, and an author pasting `Pro | Business` as a cell\n * VALUE must get those characters, not a two-column table. So a paste is only\n * read as a table when it could not sensibly be anything else: more than one\n * line, every one of them carrying an unescaped pipe, and at least two\n * columns once parsed. A single line never qualifies, however many pipes it\n * has.\n */\nexport function readPastedDataTable(value: unknown): PastedDataTable | null {\n const text = typeof value === 'string' ? value : ''\n const lines = text\n .split(/\\r?\\n/)\n .map((line) => line.trim())\n .filter((line) => line.length > 0)\n if (lines.length < 2 || !lines.every(hasUnescapedPipe)) return null\n const rows = parseDataTableRows(text)\n const width = rows[0]?.length ?? 0\n if (rows.length === 0 || width < 2) return null\n return { rows, alignments: readDataTableAlignments(text, width) }\n}\n\n/** The markdown divider encoding one column's alignment. */\nfunction dividerCell(alignment: DataTableAlignment): string {\n if (alignment === 'center') return ':---:'\n if (alignment === 'right') return '---:'\n return '---'\n}\n\n/**\n * The stored form of a grid plus its alignments.\n *\n * The divider is written after the first row, where markdown puts it, and\n * only when some column is not the default — an all-left table stays a plain\n * pipe grid rather than growing a row of dashes nobody asked for.\n */\nexport function serializeDataTable(\n rows: string[][],\n alignments?: readonly DataTableAlignment[],\n): string {\n const body = (rows ?? []).map((row) =>\n (row ?? [])\n .map((cell) => String(cell ?? '').replace(/\\|/g, '\\\\|'))\n .join(' | '),\n )\n const meaningful =\n alignments?.some(\n (alignment) => alignment && alignment !== DATA_TABLE_ALIGNMENT_DEFAULT,\n ) ?? false\n if (!meaningful || body.length === 0) return body.join('\\n')\n const width = rows[0]?.length ?? 0\n const divider = Array.from({ length: width }, (_, index) =>\n dividerCell(alignments?.[index] ?? DATA_TABLE_ALIGNMENT_DEFAULT),\n ).join(' | ')\n return [body[0], divider, ...body.slice(1)].join('\\n')\n}\n\n/**\n * The 1-based column to emphasise, or `0` for none.\n *\n * 1-based because the control says \"column 3\" to an author who is looking at\n * the third column; `0` rather than `null` so \"none\" survives a form field\n * that only speaks numbers. Out-of-range values mean none, so deleting a\n * column cannot leave a table pointing at one that is gone.\n */\nexport function normalizeEmphasisColumn(\n value: unknown,\n columnCount: number,\n): number {\n const parsed = Math.trunc(Number(value))\n if (!Number.isFinite(parsed) || parsed < 1 || parsed > columnCount) return 0\n return parsed\n}\n\n/** A grid with `count` empty columns appended to every row. */\nexport function withColumnAdded(rows: string[][], at?: number): string[][] {\n const width = rows[0]?.length ?? 0\n const index = at == null ? width : Math.max(0, Math.min(at, width))\n return (rows.length ? rows : [[]]).map((row) => {\n const next = [...row]\n next.splice(index, 0, '')\n return next\n })\n}\n\nexport function withColumnRemoved(rows: string[][], at: number): string[][] {\n const width = rows[0]?.length ?? 0\n // Never leave a table with no columns: a zero-column grid cannot be typed\n // back into through the editor, so the last column is not removable.\n if (width <= 1) return rows\n return rows.map((row) => row.filter((_, index) => index !== at))\n}\n\nexport function withRowAdded(rows: string[][], at?: number): string[][] {\n const width = rows[0]?.length ?? 1\n const blank = Array.from({ length: width }, () => '')\n const next = [...rows]\n next.splice(at == null ? rows.length : Math.max(0, Math.min(at, rows.length)), 0, blank)\n return next\n}\n\nexport function withRowRemoved(rows: string[][], at: number): string[][] {\n if (rows.length <= 1) return rows\n return rows.filter((_, index) => index !== at)\n}\n\nexport function withCellSet(\n rows: string[][],\n rowIndex: number,\n columnIndex: number,\n value: string,\n): string[][] {\n return rows.map((row, r) =>\n r === rowIndex\n ? row.map((cell, c) => (c === columnIndex ? value : cell))\n : row,\n )\n}\n"],"names":["DATA_TABLE_ALIGNMENTS","DATA_TABLE_ALIGNMENT_DEFAULT","DIVIDER_CELL","splitRow","line","cells","replace","split","map","cell","trim","isDividerRow","length","every","test","alignmentsFromDivider","String","left","startsWith","right","endsWith","parseDataTableRows","value","text","rows","filter","width","reduce","widest","row","Math","max","Array","from","readDataTableAlignments","columnCount","found","find","alignments","_","index","candidate","hasUnescapedPipe","readPastedDataTable","lines","dividerCell","alignment","serializeDataTable","body","join","meaningful","some","divider","slice","normalizeEmphasisColumn","parsed","trunc","Number","isFinite","withColumnAdded","at","min","next","splice","withColumnRemoved","withRowAdded","blank","withRowRemoved","withCellSet","rowIndex","columnIndex","r","c"],"mappings":"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"}
@@ -0,0 +1,73 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2023 Aglyn LLC
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+ import { type AuthError, AuthErrorCodes, type OAuthCredential, type UserCredential } from 'firebase/auth';
18
+ export declare const AuthAppErrorCodes: {
19
+ /** Google resolved SSO against the wrong signed-in account. */
20
+ readonly SSO_ACCOUNT_MISMATCH: "auth/sso-account-mismatch";
21
+ /** No SSO configured for the email domain the user typed. */
22
+ readonly SSO_NOT_CONFIGURED: "auth/sso-not-configured";
23
+ /** The user submitted the SSO gate without a usable email. */
24
+ readonly SSO_INPUT_REQUIRED: "auth/sso-input-required";
25
+ /** Authenticated with the IdP, but not a member of the organization. */
26
+ readonly SSO_NOT_AUTHORIZED: "auth/sso-not-authorized";
27
+ /**
28
+ * The IdP window closed without a result. On the SSO path this is NOT the
29
+ * plain cancel it is elsewhere: when Google refuses the SAML request it
30
+ * renders its own error page inside that window, so the user closing it
31
+ * looks identical to a cancel. Suppressing it — as the shared
32
+ * `AuthErrorIgnore` list does for popup-closed — is what left the desktop
33
+ * flow with Google's raw error and nothing from us.
34
+ */
35
+ readonly SSO_INCOMPLETE: "auth/sso-incomplete";
36
+ /** SSO failed for a reason we could not classify. */
37
+ readonly SSO_FAILED: "auth/sso-failed";
38
+ /**
39
+ * The WebAuthn ceremony ended without an assertion (AGL-1417).
40
+ *
41
+ * Deliberately NOT called "cancelled". The spec overloads
42
+ * `NotAllowedError` to cover a dismissed prompt, a timeout, AND no
43
+ * discoverable credential for the RP ID — the last on purpose, so a site
44
+ * cannot probe for a credential's existence. Naming this "cancelled" is
45
+ * what let "you have no passkey on this device" render as nothing at all.
46
+ */
47
+ readonly PASSKEY_NOT_COMPLETED: "auth/passkey-not-completed";
48
+ /** The ceremony ran but the server refused the assertion. */
49
+ readonly PASSKEY_SIGNIN_FAILED: "auth/passkey-signin-failed";
50
+ };
51
+ export type AuthAppCode = (typeof AuthAppErrorCodes)[keyof typeof AuthAppErrorCodes];
52
+ export type AuthCode = IndexOf<typeof AuthErrorCodes> | AuthAppCode | 'general';
53
+ export type AuthResultError = AuthError;
54
+ export type AuthResultUser = UserCredential & {
55
+ credential?: OAuthCredential;
56
+ };
57
+ export type AuthCallbackResult = Promise<UserCredential>;
58
+ export declare const AuthErrorIgnore: {
59
+ "auth/user-cancelled": boolean;
60
+ "auth/redirect-cancelled-by-user": boolean;
61
+ "auth/popup-closed-by-user": boolean;
62
+ };
63
+ export declare const AuthErrorNotice: {
64
+ "auth/user-signed-out": boolean;
65
+ "auth/requires-recent-login": boolean;
66
+ "auth/sso-account-mismatch": boolean;
67
+ "auth/sso-not-configured": boolean;
68
+ "auth/sso-input-required": boolean;
69
+ "auth/sso-incomplete": boolean;
70
+ "auth/passkey-not-completed": boolean;
71
+ };
72
+ export declare const AuthErrorMessage: Partial<Record<AuthCode, string>>;
73
+ export declare const COOKIE_KEY_USER_TOKEN = "aglyn-user-token";