@assure-one/design-system 1.38.0 → 1.39.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +15 -0
- package/codemods/README.md +54 -20
- package/codemods/lib/entry-map.mjs +315 -0
- package/codemods/lib/registry.mjs +1 -0
- package/codemods/transforms/cm-01-entry-imports.mjs +202 -0
- package/dist/brand-theme-B6rem2II.d.ts +59 -0
- package/dist/css/components.css +1 -1
- package/dist/css/tokens.css +6 -6
- package/dist/design-system-provider-BM_F1C13.d.ts +143 -0
- package/dist/icons/index.d.ts +441 -3
- package/dist/icons/index.js.map +1 -1
- package/dist/index-BAAuIQqP.d.ts +2579 -0
- package/dist/index-DxBjmBBp.d.ts +1038 -0
- package/dist/index.d.ts +48 -3476
- package/dist/index.js +5997 -5899
- package/dist/index.js.map +1 -1
- package/dist/legacy/index.d.ts +9 -0
- package/dist/legacy/index.js +3 -0
- package/dist/legacy/index.js.map +1 -0
- package/dist/next/index.d.ts +2 -1
- package/dist/reference-BkDbrPIB.d.ts +310 -0
- package/dist/styles.css +1 -1
- package/dist/suite/index.d.ts +4 -0
- package/dist/suite/index.js +3 -0
- package/dist/suite/index.js.map +1 -0
- package/dist/{system-CyAVbHhM.d.ts → system-DfJIVBlJ.d.ts} +1 -310
- package/dist/tokens/index.d.ts +3 -61
- package/dist/tokens/index.js +3 -3
- package/dist/tokens/index.js.map +1 -1
- package/dist/{design-system-provider-B5MbvbRc.d.ts → types-k_kjwipx.d.ts} +9 -142
- package/dist/vocab-DornLJbW.d.ts +76 -0
- package/docs/components.md +27 -25
- package/docs/components.registry.json +16 -2
- package/package.json +14 -3
- package/public/brand/assure-audit-mark.svg +6 -0
- package/public/brand/assure-audit.svg +8 -0
- package/public/brand/assure-books-mark.svg +6 -0
- package/public/brand/assure-books.svg +8 -0
- package/public/brand/assure-pro-mark.svg +6 -0
- package/public/brand/assure-pro.svg +8 -0
- package/public/brand/assure-tax-mark.svg +6 -0
- package/public/brand/assure-tax.svg +8 -0
- package/public/brand/mycpe-teams-mark.svg +36 -0
- package/public/brand/mycpe-teams.svg +66 -0
- package/dist/index-vztxMSfl.d.ts +0 -512
package/README.md
CHANGED
|
@@ -89,6 +89,21 @@ canvas, and guarantees WCAG AA for every foreground it emits. The seed shape is
|
|
|
89
89
|
gated by decision D7 and may change while that decision is open — see
|
|
90
90
|
[`docs/integration/css.md`](./docs/integration/css.md#5-runtime-brand-theming).
|
|
91
91
|
|
|
92
|
+
### Brand artwork
|
|
93
|
+
|
|
94
|
+
The Assure wordmarks and marks `Logo` renders ship inside the package, under
|
|
95
|
+
`public/brand/`. They are served by your app, not imported, so copy them once
|
|
96
|
+
into your public folder:
|
|
97
|
+
|
|
98
|
+
```sh
|
|
99
|
+
cp -R node_modules/@assure-one/design-system/public/brand public/brand
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
An app served from a subpath calls `setAssetBasePath("/my-base")` once before
|
|
103
|
+
first render instead of (or as well as) moving the files. A `Logo` whose
|
|
104
|
+
artwork does not load falls back to the brand glyph + text lockup, so nothing
|
|
105
|
+
is required to get a readable lockup.
|
|
106
|
+
|
|
92
107
|
### The provider and the `/next` entry (experimental)
|
|
93
108
|
|
|
94
109
|
Nothing requires a provider: every component renders English strings, formats
|
package/codemods/README.md
CHANGED
|
@@ -107,28 +107,62 @@ the list a human has to pick up — spread props, dynamic expressions, conflicti
|
|
|
107
107
|
|
|
108
108
|
## Codemods
|
|
109
109
|
|
|
110
|
-
| Id | Class | What it does
|
|
111
|
-
| ----- | ----- |
|
|
112
|
-
| CM-
|
|
113
|
-
| CM-
|
|
114
|
-
| CM-
|
|
115
|
-
| CM-
|
|
116
|
-
| CM-
|
|
117
|
-
| CM-
|
|
118
|
-
| CM-
|
|
119
|
-
| CM-
|
|
120
|
-
| CM-
|
|
121
|
-
| CM-
|
|
110
|
+
| Id | Class | What it does |
|
|
111
|
+
| ----- | ----- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
112
|
+
| CM-01 | R | Root imports of suite, legacy and product-owned names → `@assure-one/design-system/suite` and `/legacy` (same references, pure path change); `import * as DS` → report |
|
|
113
|
+
| CM-05 | A | Button family `iconLeft` / `iconRight` → `iconStart` / `iconEnd` (pure rename; both names of one slot, spreads → "could not be transformed") |
|
|
114
|
+
| CM-13 | A | `Tooltip delayMs` → `delayDuration` (pure rename, literal or dynamic value; both names, spreads → "could not be transformed") |
|
|
115
|
+
| CM-07 | A | `inputSize` → `size` on `Input`, `Textarea`, `SearchInput` (pure rename, literal or dynamic value; both names, spreads → "could not be transformed") |
|
|
116
|
+
| CM-02 | A | Button explicit default size: `size="md"` on every `Button`, `SubmitButton` and `LinkButton` that passes no `size` (pixel-neutral) |
|
|
117
|
+
| CM-04 | R | Button family legacy `variant` → `variant` + `intent` pair (`primary` → `solid`, `destructive` → `solid` + `danger`, …); `accent`, `dashed`, dynamic → report |
|
|
118
|
+
| CM-06 | R | `tone` → `intent` on StatusDot, IconTile, Spinner, SegmentedProgress, SuiteProgress (`pro` → `brand`, listed for review); product hues → report |
|
|
119
|
+
| CM-19 | R | ProgressBar/ProgressRing: `variant` → `intent`, and the value → colour rule written down as an explicit `intent` where the value is a literal; dynamic values → report |
|
|
120
|
+
| CM-12 | R | Button `type="submit"` where the intent is evident (inside `<form>` in the same file, no `onClick`); everything else untyped → report |
|
|
121
|
+
| CM-10 | R | `DatePicker onChange={e => f(e.target.value)}` → `onValueChange={value => f(value)}` for the recognisable arrow shapes; handlers by reference, other shapes → report |
|
|
122
|
+
| CM-08 | R | `SearchSelect` → `Combobox`: single-mode call sites rewritten (tag, import, `{id,label}` accessors, placeholder → `aria-label`); multi API, extras and unnamed sites → report |
|
|
122
123
|
| CM-09 | R | `SideDrawer` → `Sheet`: drawers with a `SideDrawer.Header` rewritten (root → `Sheet` + `SheetContent side size`, `onClose` → `onOpenChange`, header → `SheetHeader`/`SheetTitle`/`SheetDescription`, Body/Footer → `SheetBody`/`SheetFooter`, import); no header, dynamic width, spreads → report |
|
|
123
|
-
| CM-18 | A | `DataTable*` presentational parts → `Table*` (`DataTableHead` → `TableHeader`, `Body`, `Row`, `Cell`, `DataTableHeader` → `TableHead`) where the mapping is 1:1; uncontrolled sorting, a dynamic `sortable` and spreads → "could not be transformed"
|
|
124
|
-
| CM-14 | X | hidden-input mirror finder: hidden `<input name>` a consumer added because a design-system control posts nothing
|
|
125
|
-
| CM-15 | X | DOM-selector finder: consumer code that depends on the internal DOM of design-system components, mapped to registry `C-DOM-*` ids
|
|
126
|
-
| CM-16 | X | `globals.css` analyser: `@source` into the package, duplicate preflight, colliding `@theme` keys, unlayered globals, legacy `var()`
|
|
127
|
-
| CM-20 | X | Select sentinel finder: option values standing in for "no value", and the line where each is converted back
|
|
124
|
+
| CM-18 | A | `DataTable*` presentational parts → `Table*` (`DataTableHead` → `TableHeader`, `Body`, `Row`, `Cell`, `DataTableHeader` → `TableHead`) where the mapping is 1:1; uncontrolled sorting, a dynamic `sortable` and spreads → "could not be transformed" |
|
|
125
|
+
| CM-14 | X | hidden-input mirror finder: hidden `<input name>` a consumer added because a design-system control posts nothing |
|
|
126
|
+
| CM-15 | X | DOM-selector finder: consumer code that depends on the internal DOM of design-system components, mapped to registry `C-DOM-*` ids |
|
|
127
|
+
| CM-16 | X | `globals.css` analyser: `@source` into the package, duplicate preflight, colliding `@theme` keys, unlayered globals, legacy `var()` |
|
|
128
|
+
| CM-20 | X | Select sentinel finder: option values standing in for "no value", and the line where each is converted back |
|
|
128
129
|
|
|
129
130
|
The remaining ids of plan §29 land with the waves that ship their replacement
|
|
130
131
|
APIs.
|
|
131
132
|
|
|
133
|
+
### CM-01 — root imports → `/suite` and `/legacy`
|
|
134
|
+
|
|
135
|
+
Class R. W8-02 gave the shared Assure patterns the `/suite` entry and the
|
|
136
|
+
frozen and product-owned modules `/legacy`. Both are re-export barrels over the
|
|
137
|
+
same module instances the root exports, so moving an import is a pure path
|
|
138
|
+
change: no duplicated React context, no behaviour difference. The root keeps
|
|
139
|
+
every name through 1.x (registry `C-ROOT-SUITE`) and drops them in 2.0, so
|
|
140
|
+
running this codemod early costs nothing and running it late is a 2.0 blocker.
|
|
141
|
+
|
|
142
|
+
```tsx
|
|
143
|
+
import { Button, AgreementViewer, TimeLogger } from "@assure-one/design-system";
|
|
144
|
+
// becomes
|
|
145
|
+
import { Button } from "@assure-one/design-system";
|
|
146
|
+
import { AgreementViewer } from "@assure-one/design-system/suite";
|
|
147
|
+
import { TimeLogger } from "@assure-one/design-system/legacy";
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
A declaration whose names all move keeps its shape and only its module
|
|
151
|
+
specifier changes. `import type`, per-specifier `type` prefixes, aliases,
|
|
152
|
+
quote style and a default import are preserved; the default import stays on the
|
|
153
|
+
root.
|
|
154
|
+
|
|
155
|
+
| rule | action | severity | meaning |
|
|
156
|
+
| ------------------ | ------- | -------- | --------------------------------------------------------------------------------- |
|
|
157
|
+
| `moved-to-suite` | applied | low | shared Assure patterns now import from `/suite` |
|
|
158
|
+
| `moved-to-legacy` | applied | low | frozen modules with no known consumer now import from `/legacy` |
|
|
159
|
+
| `product-owned` | applied | medium | the import moved to `/legacy`, but the module is leaving for a product repository |
|
|
160
|
+
| `namespace-import` | review | high | `import * as DS` cannot be split; import the moved members by name first |
|
|
161
|
+
|
|
162
|
+
Which entry owns which name comes from `codemods/lib/entry-map.mjs`, generated
|
|
163
|
+
from `architecture/entry-map.json` by `pnpm entry-map`, so an installed copy of
|
|
164
|
+
the codemod always carries the map of its own design-system version.
|
|
165
|
+
|
|
132
166
|
### CM-05 — Button family `iconLeft` / `iconRight` → `iconStart` / `iconEnd`
|
|
133
167
|
|
|
134
168
|
Class A. W3-07 named the two icon slots of `Button`, `LinkButton` and
|
|
@@ -515,9 +549,9 @@ sorted). What changes in the DOM is the `data-slot` value (`table-*` instead of
|
|
|
515
549
|
column header already. Classes and pixels are the same, because since W6-03 the
|
|
516
550
|
`DataTable*` parts render the `Table*` parts.
|
|
517
551
|
|
|
518
|
-
| rule
|
|
519
|
-
|
|
|
520
|
-
| `part-renamed`
|
|
552
|
+
| rule | Contract | What happens |
|
|
553
|
+
| -------------- | ---------- | -------------------------------------------------------------- |
|
|
554
|
+
| `part-renamed` | C-DT-PARTS | tag, closing tag and the named import rewritten (applied, low) |
|
|
521
555
|
|
|
522
556
|
Reported under "could not be transformed": `DataTableHeader sortable` with no
|
|
523
557
|
controlled `sort`, or with `defaultSort` (`uncontrolled-sort` — `TableHead` has
|
|
@@ -0,0 +1,315 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GENERATED by scripts/architecture/entry-map.mjs from architecture/entry-map.json
|
|
3
|
+
* — do not edit. `pnpm entry-map` rewrites it; `pnpm entry-map:check` fails
|
|
4
|
+
* when it is stale.
|
|
5
|
+
*
|
|
6
|
+
* The half of the entry map CM-01 needs, published inside the package so a
|
|
7
|
+
* consumer runs the codemod that matches its design-system version (W8-01/02).
|
|
8
|
+
*/
|
|
9
|
+
export const ENTRY_SPECIFIER = {
|
|
10
|
+
suite: "@assure-one/design-system/suite",
|
|
11
|
+
legacy: "@assure-one/design-system/legacy",
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
/** Public root export → the entry that owns it. Root-owned names are absent. */
|
|
15
|
+
export const ENTRY_BY_SYMBOL = {
|
|
16
|
+
AgreementFirm: "suite",
|
|
17
|
+
AgreementPaneHeading: "suite",
|
|
18
|
+
AgreementPaneHeadingProps: "suite",
|
|
19
|
+
AgreementStatus: "suite",
|
|
20
|
+
AgreementStep: "suite",
|
|
21
|
+
AgreementViewer: "suite",
|
|
22
|
+
AgreementViewerProps: "suite",
|
|
23
|
+
ProposalAddOn: "suite",
|
|
24
|
+
ProposalAddOnProps: "suite",
|
|
25
|
+
ProposalBillingMode: "suite",
|
|
26
|
+
ProposalBillingRow: "suite",
|
|
27
|
+
ProposalBillingTerms: "suite",
|
|
28
|
+
ProposalBillingTermsProps: "suite",
|
|
29
|
+
ProposalConsentGate: "suite",
|
|
30
|
+
ProposalConsentGateProps: "suite",
|
|
31
|
+
ProposalCustomPage: "suite",
|
|
32
|
+
ProposalCustomPageKind: "suite",
|
|
33
|
+
ProposalCustomPageProps: "suite",
|
|
34
|
+
ProposalNote: "suite",
|
|
35
|
+
ProposalNoteProps: "suite",
|
|
36
|
+
ProposalPackageCard: "suite",
|
|
37
|
+
ProposalPackageCardProps: "suite",
|
|
38
|
+
ProposalPackageMode: "suite",
|
|
39
|
+
ProposalPaymentCapture: "suite",
|
|
40
|
+
ProposalPaymentCaptureProps: "suite",
|
|
41
|
+
ProposalPricingSummary: "suite",
|
|
42
|
+
ProposalPricingSummaryProps: "suite",
|
|
43
|
+
ProposalServiceRow: "suite",
|
|
44
|
+
ProposalServiceRowProps: "suite",
|
|
45
|
+
ProposalSignatureBlock: "suite",
|
|
46
|
+
ProposalSignatureBlockProps: "suite",
|
|
47
|
+
ProposalSigner: "suite",
|
|
48
|
+
ProposalSignerList: "suite",
|
|
49
|
+
ProposalSignerListProps: "suite",
|
|
50
|
+
ProposalSignerStatus: "suite",
|
|
51
|
+
Grid: "suite",
|
|
52
|
+
GridColumn: "suite",
|
|
53
|
+
GridInputType: "suite",
|
|
54
|
+
GridProps: "suite",
|
|
55
|
+
GridRow: "suite",
|
|
56
|
+
GridValue: "suite",
|
|
57
|
+
QUESTION_TYPES: "suite",
|
|
58
|
+
QUESTION_TYPE_CONTRACT_VERSION: "suite",
|
|
59
|
+
QuestionAddressValue: "suite",
|
|
60
|
+
QuestionFileValue: "suite",
|
|
61
|
+
QuestionHelp: "suite",
|
|
62
|
+
QuestionLabeledColumn: "suite",
|
|
63
|
+
QuestionLabeledRow: "suite",
|
|
64
|
+
QuestionLabeledValue: "suite",
|
|
65
|
+
QuestionNameValue: "suite",
|
|
66
|
+
QuestionOption: "suite",
|
|
67
|
+
QuestionTableColumn: "suite",
|
|
68
|
+
QuestionTableRow: "suite",
|
|
69
|
+
QuestionType: "suite",
|
|
70
|
+
Questions: "suite",
|
|
71
|
+
QuestionsProps: "suite",
|
|
72
|
+
DocumentDetailActions: "suite",
|
|
73
|
+
DocumentDetailActionsProps: "suite",
|
|
74
|
+
DocumentDetailBody: "suite",
|
|
75
|
+
DocumentDetailBodyProps: "suite",
|
|
76
|
+
DocumentDetailHeader: "suite",
|
|
77
|
+
DocumentDetailHeaderProps: "suite",
|
|
78
|
+
DocumentDetailMetaRow: "suite",
|
|
79
|
+
DocumentDetailMetaRowProps: "suite",
|
|
80
|
+
DocumentDetailPanel: "suite",
|
|
81
|
+
DocumentDetailPanelProps: "suite",
|
|
82
|
+
DocumentDetailRequester: "suite",
|
|
83
|
+
DocumentDetailRequesterProps: "suite",
|
|
84
|
+
DocumentDetailTitle: "suite",
|
|
85
|
+
DocumentDetailTitleProps: "suite",
|
|
86
|
+
DocumentList: "suite",
|
|
87
|
+
DocumentListProps: "suite",
|
|
88
|
+
DocumentListSection: "suite",
|
|
89
|
+
DocumentListSectionProps: "suite",
|
|
90
|
+
DocumentRow: "suite",
|
|
91
|
+
DocumentRowProps: "suite",
|
|
92
|
+
ClientSelect: "suite",
|
|
93
|
+
ClientSelectOption: "suite",
|
|
94
|
+
AssureAuditBrandIcon: "suite",
|
|
95
|
+
AssureBooksBrandIcon: "suite",
|
|
96
|
+
AssureProBrandIcon: "suite",
|
|
97
|
+
AssureTaxBrandIcon: "suite",
|
|
98
|
+
BRAND_PRODUCTS: "suite",
|
|
99
|
+
BrandIconProps: "suite",
|
|
100
|
+
BrandProduct: "suite",
|
|
101
|
+
Logo: "suite",
|
|
102
|
+
SidebarBrandSwitcher: "suite",
|
|
103
|
+
SidebarBrandSwitcherExtra: "suite",
|
|
104
|
+
SidebarBrandSwitcherItem: "suite",
|
|
105
|
+
SidebarBrandSwitcherProps: "suite",
|
|
106
|
+
SidebarBrandSwitcherTile: "suite",
|
|
107
|
+
brandLabel: "suite",
|
|
108
|
+
ComingSoon: "suite",
|
|
109
|
+
ComingSoonProps: "suite",
|
|
110
|
+
TimeLogger: "legacy",
|
|
111
|
+
TimeLoggerActions: "legacy",
|
|
112
|
+
TimeLoggerActionsProps: "legacy",
|
|
113
|
+
TimeLoggerBillable: "legacy",
|
|
114
|
+
TimeLoggerBillableProps: "legacy",
|
|
115
|
+
TimeLoggerContextRow: "legacy",
|
|
116
|
+
TimeLoggerContextRowProps: "legacy",
|
|
117
|
+
TimeLoggerEntry: "legacy",
|
|
118
|
+
TimeLoggerEntryList: "legacy",
|
|
119
|
+
TimeLoggerEntryListProps: "legacy",
|
|
120
|
+
TimeLoggerEntryProps: "legacy",
|
|
121
|
+
TimeLoggerField: "legacy",
|
|
122
|
+
TimeLoggerFieldProps: "legacy",
|
|
123
|
+
TimeLoggerFooter: "legacy",
|
|
124
|
+
TimeLoggerFooterProps: "legacy",
|
|
125
|
+
TimeLoggerHeader: "legacy",
|
|
126
|
+
TimeLoggerHeaderProps: "legacy",
|
|
127
|
+
TimeLoggerNotes: "legacy",
|
|
128
|
+
TimeLoggerNotesProps: "legacy",
|
|
129
|
+
TimeLoggerPhase: "legacy",
|
|
130
|
+
TimeLoggerProps: "legacy",
|
|
131
|
+
TimeLoggerTier: "legacy",
|
|
132
|
+
TimeLoggerTimer: "legacy",
|
|
133
|
+
TimeLoggerTimerProps: "legacy",
|
|
134
|
+
UseStopwatchReturn: "legacy",
|
|
135
|
+
formatClock: "legacy",
|
|
136
|
+
formatCurrency: "legacy",
|
|
137
|
+
formatDuration: "legacy",
|
|
138
|
+
parseDuration: "legacy",
|
|
139
|
+
useStopwatch: "legacy",
|
|
140
|
+
ClientRailGroupHeader: "legacy",
|
|
141
|
+
ClientRailGroupHeaderProps: "legacy",
|
|
142
|
+
ClientRailItem: "legacy",
|
|
143
|
+
ClientRailItemProps: "legacy",
|
|
144
|
+
DocumentFileCard: "legacy",
|
|
145
|
+
DocumentFileCardProps: "legacy",
|
|
146
|
+
DocumentFileLine: "legacy",
|
|
147
|
+
DocumentFileLineProps: "legacy",
|
|
148
|
+
DocumentFileRow: "legacy",
|
|
149
|
+
DocumentFileRowProps: "legacy",
|
|
150
|
+
DocumentRequestActivityKind: "legacy",
|
|
151
|
+
DocumentRequestAssigneeOption: "legacy",
|
|
152
|
+
DocumentRequestCard: "legacy",
|
|
153
|
+
DocumentRequestCardProps: "legacy",
|
|
154
|
+
DocumentRequestDetail: "legacy",
|
|
155
|
+
DocumentRequestDetailActivityEvent: "legacy",
|
|
156
|
+
DocumentRequestDetailComment: "legacy",
|
|
157
|
+
DocumentRequestDetailDoc: "legacy",
|
|
158
|
+
DocumentRequestDetailProps: "legacy",
|
|
159
|
+
DocumentRequestDetailTab: "legacy",
|
|
160
|
+
DocumentRequestItemSummary: "legacy",
|
|
161
|
+
DocumentRequestRequestedItem: "legacy",
|
|
162
|
+
DocumentRequestReviewStatusOption: "legacy",
|
|
163
|
+
DocumentRequestTone: "legacy",
|
|
164
|
+
Blockquote: "legacy",
|
|
165
|
+
Section: "legacy",
|
|
166
|
+
SectionHead: "legacy",
|
|
167
|
+
SectionHeader: "legacy",
|
|
168
|
+
Stat: "legacy",
|
|
169
|
+
PillStatus: "legacy",
|
|
170
|
+
StatusPill: "legacy",
|
|
171
|
+
StatusPillProps: "legacy",
|
|
172
|
+
Assignee: "legacy",
|
|
173
|
+
Dash: "legacy",
|
|
174
|
+
MoneyCell: "legacy",
|
|
175
|
+
StagePill: "legacy",
|
|
176
|
+
TagsCell: "legacy",
|
|
177
|
+
AIReceiptPanel: "legacy",
|
|
178
|
+
AIReceiptPanelProps: "legacy",
|
|
179
|
+
AIReceiptResult: "legacy",
|
|
180
|
+
AiDraftCard: "legacy",
|
|
181
|
+
AiDraftCardProps: "legacy",
|
|
182
|
+
AiDraftState: "legacy",
|
|
183
|
+
AttentionItem: "legacy",
|
|
184
|
+
AttentionItemProps: "legacy",
|
|
185
|
+
AttentionUrgency: "legacy",
|
|
186
|
+
BottomNav: "legacy",
|
|
187
|
+
BottomNavProps: "legacy",
|
|
188
|
+
BottomNavTab: "legacy",
|
|
189
|
+
CategoryDivider: "legacy",
|
|
190
|
+
CategoryDividerProps: "legacy",
|
|
191
|
+
CategoryTag: "legacy",
|
|
192
|
+
CategoryTagProps: "legacy",
|
|
193
|
+
CategoryTone: "legacy",
|
|
194
|
+
ChannelTabItem: "legacy",
|
|
195
|
+
ChannelTabs: "legacy",
|
|
196
|
+
ChannelTabsProps: "legacy",
|
|
197
|
+
ChannelTone: "legacy",
|
|
198
|
+
DashGrid: "legacy",
|
|
199
|
+
DashGridProps: "legacy",
|
|
200
|
+
DashWidget: "legacy",
|
|
201
|
+
DocumentChecklist: "legacy",
|
|
202
|
+
DocumentChecklistFile: "legacy",
|
|
203
|
+
DocumentChecklistItem: "legacy",
|
|
204
|
+
DocumentChecklistProps: "legacy",
|
|
205
|
+
DocumentChecklistStatus: "legacy",
|
|
206
|
+
DocumentItemState: "legacy",
|
|
207
|
+
DocumentRequestField: "legacy",
|
|
208
|
+
DocumentRequestFieldProps: "legacy",
|
|
209
|
+
DocumentRequestUpload: "legacy",
|
|
210
|
+
DocumentRequestUploadFile: "legacy",
|
|
211
|
+
DocumentRequestUploadProps: "legacy",
|
|
212
|
+
DocumentSource: "legacy",
|
|
213
|
+
DocumentSourceFilter: "legacy",
|
|
214
|
+
DocumentSourceFilterProps: "legacy",
|
|
215
|
+
DocumentSourceFilterValue: "legacy",
|
|
216
|
+
DocumentSourceTag: "legacy",
|
|
217
|
+
DocumentSourceTagProps: "legacy",
|
|
218
|
+
DocumentsWorkspaceLayout: "legacy",
|
|
219
|
+
DocumentsWorkspaceLayoutProps: "legacy",
|
|
220
|
+
EmailMessageCard: "legacy",
|
|
221
|
+
EmailMessageCardProps: "legacy",
|
|
222
|
+
EngagementCard: "legacy",
|
|
223
|
+
EngagementCardProps: "legacy",
|
|
224
|
+
EngagementTimeline: "legacy",
|
|
225
|
+
EngagementTimelineProps: "legacy",
|
|
226
|
+
EngagementTimelineStep: "legacy",
|
|
227
|
+
EngagementTimelineStepProps: "legacy",
|
|
228
|
+
IntentBadge: "legacy",
|
|
229
|
+
IntentBadgeProps: "legacy",
|
|
230
|
+
IntentTone: "legacy",
|
|
231
|
+
MissingDocumentItem: "legacy",
|
|
232
|
+
MissingDocumentsPanel: "legacy",
|
|
233
|
+
MissingDocumentsPanelProps: "legacy",
|
|
234
|
+
NewMenu: "legacy",
|
|
235
|
+
NewMenuAction: "legacy",
|
|
236
|
+
NewMenuGroup: "legacy",
|
|
237
|
+
NewMenuProps: "legacy",
|
|
238
|
+
SignatureEditor: "legacy",
|
|
239
|
+
SignatureEditorProps: "legacy",
|
|
240
|
+
SuggestionPills: "legacy",
|
|
241
|
+
SuggestionPillsProps: "legacy",
|
|
242
|
+
TeamMemberSelect: "legacy",
|
|
243
|
+
TimelineState: "legacy",
|
|
244
|
+
};
|
|
245
|
+
|
|
246
|
+
/** Product-owned names → the repository they are moving to (reported, never written). */
|
|
247
|
+
export const PRODUCT_TARGET = {
|
|
248
|
+
TimeLogger: "assure-pro/frontend/src/components/billing/time-logger/*",
|
|
249
|
+
TimeLoggerActions: "assure-pro/frontend/src/components/billing/time-logger/*",
|
|
250
|
+
TimeLoggerActionsProps: "assure-pro/frontend/src/components/billing/time-logger/*",
|
|
251
|
+
TimeLoggerBillable: "assure-pro/frontend/src/components/billing/time-logger/*",
|
|
252
|
+
TimeLoggerBillableProps: "assure-pro/frontend/src/components/billing/time-logger/*",
|
|
253
|
+
TimeLoggerContextRow: "assure-pro/frontend/src/components/billing/time-logger/*",
|
|
254
|
+
TimeLoggerContextRowProps: "assure-pro/frontend/src/components/billing/time-logger/*",
|
|
255
|
+
TimeLoggerEntry: "assure-pro/frontend/src/components/billing/time-logger/*",
|
|
256
|
+
TimeLoggerEntryList: "assure-pro/frontend/src/components/billing/time-logger/*",
|
|
257
|
+
TimeLoggerEntryListProps: "assure-pro/frontend/src/components/billing/time-logger/*",
|
|
258
|
+
TimeLoggerEntryProps: "assure-pro/frontend/src/components/billing/time-logger/*",
|
|
259
|
+
TimeLoggerField: "assure-pro/frontend/src/components/billing/time-logger/*",
|
|
260
|
+
TimeLoggerFieldProps: "assure-pro/frontend/src/components/billing/time-logger/*",
|
|
261
|
+
TimeLoggerFooter: "assure-pro/frontend/src/components/billing/time-logger/*",
|
|
262
|
+
TimeLoggerFooterProps: "assure-pro/frontend/src/components/billing/time-logger/*",
|
|
263
|
+
TimeLoggerHeader: "assure-pro/frontend/src/components/billing/time-logger/*",
|
|
264
|
+
TimeLoggerHeaderProps: "assure-pro/frontend/src/components/billing/time-logger/*",
|
|
265
|
+
TimeLoggerNotes: "assure-pro/frontend/src/components/billing/time-logger/*",
|
|
266
|
+
TimeLoggerNotesProps: "assure-pro/frontend/src/components/billing/time-logger/*",
|
|
267
|
+
TimeLoggerPhase: "assure-pro/frontend/src/components/billing/time-logger/*",
|
|
268
|
+
TimeLoggerProps: "assure-pro/frontend/src/components/billing/time-logger/*",
|
|
269
|
+
TimeLoggerTier: "assure-pro/frontend/src/components/billing/time-logger/*",
|
|
270
|
+
TimeLoggerTimer: "assure-pro/frontend/src/components/billing/time-logger/*",
|
|
271
|
+
TimeLoggerTimerProps: "assure-pro/frontend/src/components/billing/time-logger/*",
|
|
272
|
+
UseStopwatchReturn: "assure-pro/frontend/src/components/billing/time-logger/*",
|
|
273
|
+
formatClock: "assure-pro/frontend/src/components/billing/time-logger/*",
|
|
274
|
+
formatCurrency: "assure-pro/frontend/src/components/billing/time-logger/*",
|
|
275
|
+
formatDuration: "assure-pro/frontend/src/components/billing/time-logger/*",
|
|
276
|
+
parseDuration: "assure-pro/frontend/src/components/billing/time-logger/*",
|
|
277
|
+
useStopwatch: "assure-pro/frontend/src/components/billing/time-logger/*",
|
|
278
|
+
ClientRailGroupHeader: "assure-pro (documents feature)",
|
|
279
|
+
ClientRailGroupHeaderProps: "assure-pro (documents feature)",
|
|
280
|
+
ClientRailItem: "assure-pro (documents feature)",
|
|
281
|
+
ClientRailItemProps: "assure-pro (documents feature)",
|
|
282
|
+
DocumentFileCard: "assure-pro (documents feature)",
|
|
283
|
+
DocumentFileCardProps: "assure-pro (documents feature)",
|
|
284
|
+
DocumentFileLine: "assure-pro (documents feature)",
|
|
285
|
+
DocumentFileLineProps: "assure-pro (documents feature)",
|
|
286
|
+
DocumentFileRow: "assure-pro (documents feature)",
|
|
287
|
+
DocumentFileRowProps: "assure-pro (documents feature)",
|
|
288
|
+
DocumentRequestActivityKind: "assure-pro (documents feature)",
|
|
289
|
+
DocumentRequestAssigneeOption: "assure-pro (documents feature)",
|
|
290
|
+
DocumentRequestCard: "assure-pro (documents feature)",
|
|
291
|
+
DocumentRequestCardProps: "assure-pro (documents feature)",
|
|
292
|
+
DocumentRequestDetail: "assure-pro (documents feature)",
|
|
293
|
+
DocumentRequestDetailActivityEvent: "assure-pro (documents feature)",
|
|
294
|
+
DocumentRequestDetailComment: "assure-pro (documents feature)",
|
|
295
|
+
DocumentRequestDetailDoc: "assure-pro (documents feature)",
|
|
296
|
+
DocumentRequestDetailProps: "assure-pro (documents feature)",
|
|
297
|
+
DocumentRequestDetailTab: "assure-pro (documents feature)",
|
|
298
|
+
DocumentRequestItemSummary: "assure-pro (documents feature)",
|
|
299
|
+
DocumentRequestRequestedItem: "assure-pro (documents feature)",
|
|
300
|
+
DocumentRequestReviewStatusOption: "assure-pro (documents feature)",
|
|
301
|
+
DocumentRequestTone: "assure-pro (documents feature)",
|
|
302
|
+
Blockquote: "assure-pro (landing pages)",
|
|
303
|
+
Section: "assure-pro (landing pages)",
|
|
304
|
+
SectionHead: "assure-pro (landing pages)",
|
|
305
|
+
SectionHeader: "assure-pro (landing pages)",
|
|
306
|
+
Stat: "assure-pro (landing pages)",
|
|
307
|
+
PillStatus: "assure-pro status map over core `StatusBadge`",
|
|
308
|
+
StatusPill: "assure-pro status map over core `StatusBadge`",
|
|
309
|
+
StatusPillProps: "assure-pro status map over core `StatusBadge`",
|
|
310
|
+
Assignee: "assure-tax `table-cells.tsx`",
|
|
311
|
+
Dash: "assure-tax `table-cells.tsx`",
|
|
312
|
+
MoneyCell: "assure-tax `table-cells.tsx`",
|
|
313
|
+
StagePill: "assure-tax `table-cells.tsx`",
|
|
314
|
+
TagsCell: "assure-tax `table-cells.tsx`",
|
|
315
|
+
};
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
* codemods listed here can be run by id; the sequence is the plan's.
|
|
4
4
|
*/
|
|
5
5
|
export const CODEMODS = [
|
|
6
|
+
{ id: "CM-01", module: "../transforms/cm-01-entry-imports.mjs" },
|
|
6
7
|
{ id: "CM-05", module: "../transforms/cm-05-button-icon-slots.mjs" },
|
|
7
8
|
{ id: "CM-13", module: "../transforms/cm-13-tooltip-delay.mjs" },
|
|
8
9
|
{ id: "CM-07", module: "../transforms/cm-07-input-size.mjs" },
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CM-01 — root imports → `/suite` and `/legacy` (class R; plan §29 seq 1,
|
|
3
|
+
* registry `C-ROOT-SUITE`, lands with W8-02).
|
|
4
|
+
*
|
|
5
|
+
* W8-02 gave the shared Assure patterns their own entry and put the frozen and
|
|
6
|
+
* product-owned modules behind `/legacy`. Both are re-export barrels over the
|
|
7
|
+
* very same module instances the root exports, so moving an import is a pure
|
|
8
|
+
* path change: no duplicated context, no behaviour difference, nothing to test
|
|
9
|
+
* afterwards. The root keeps the names through 1.x and drops them in 2.0.
|
|
10
|
+
*
|
|
11
|
+
* ## What it rewrites
|
|
12
|
+
*
|
|
13
|
+
* ```tsx
|
|
14
|
+
* import { Button, AgreementViewer, TimeLogger } from "@assure-one/design-system";
|
|
15
|
+
* ```
|
|
16
|
+
*
|
|
17
|
+
* becomes
|
|
18
|
+
*
|
|
19
|
+
* ```tsx
|
|
20
|
+
* import { Button } from "@assure-one/design-system";
|
|
21
|
+
* import { AgreementViewer } from "@assure-one/design-system/suite";
|
|
22
|
+
* import { TimeLogger } from "@assure-one/design-system/legacy";
|
|
23
|
+
* ```
|
|
24
|
+
*
|
|
25
|
+
* A declaration whose names all move keeps its shape and only its module
|
|
26
|
+
* specifier changes. `import type` and per-specifier `type` prefixes, aliases
|
|
27
|
+
* (`X as Y`), quote style and a default import are preserved; the default
|
|
28
|
+
* import always stays on the root.
|
|
29
|
+
*
|
|
30
|
+
* Which entry owns which name comes from `codemods/lib/entry-map.mjs`, which
|
|
31
|
+
* `pnpm entry-map` generates from `architecture/entry-map.json` — so the
|
|
32
|
+
* installed copy of the codemod always knows the map of its own version.
|
|
33
|
+
*
|
|
34
|
+
* ## What it reports
|
|
35
|
+
*
|
|
36
|
+
* | rule | action | severity | why |
|
|
37
|
+
* | ------------------ | ------- | -------- | --------------------------------------------------------------------------------------- |
|
|
38
|
+
* | `moved-to-suite` | applied | low | shared Assure patterns now import from `/suite` |
|
|
39
|
+
* | `moved-to-legacy` | applied | low | frozen modules with no known consumer now import from `/legacy` |
|
|
40
|
+
* | `product-owned` | applied | medium | the import moved to `/legacy`, but the module is leaving for a product repository |
|
|
41
|
+
* | `namespace-import` | review | high | `import * as DS` cannot be split; the named members have to be imported one by one first |
|
|
42
|
+
*
|
|
43
|
+
* Imports already on `/suite` or `/legacy` are not touched (idempotency), and
|
|
44
|
+
* neither is a name the root still owns. Test files are skipped.
|
|
45
|
+
*/
|
|
46
|
+
import { ENTRY_BY_SYMBOL, ENTRY_SPECIFIER, PRODUCT_TARGET } from "../lib/entry-map.mjs";
|
|
47
|
+
import { applyEdits } from "../lib/jsx-edit.mjs";
|
|
48
|
+
import { analyseForms } from "../lib/forms.mjs";
|
|
49
|
+
|
|
50
|
+
export const meta = {
|
|
51
|
+
id: "CM-01",
|
|
52
|
+
title: "Root imports of suite, legacy and product-owned names → /suite and /legacy",
|
|
53
|
+
class: "R",
|
|
54
|
+
oneShot: false,
|
|
55
|
+
requires: { codemods: [], dsVersion: null },
|
|
56
|
+
parses: ["code"],
|
|
57
|
+
includeTests: false,
|
|
58
|
+
usesTypeScript: true,
|
|
59
|
+
usesPostcss: false,
|
|
60
|
+
registryIds: ["C-ROOT-SUITE"],
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
export const RULES = {
|
|
64
|
+
"moved-to-suite": { action: "applied", severity: "low" },
|
|
65
|
+
"moved-to-legacy": { action: "applied", severity: "low" },
|
|
66
|
+
"product-owned": { action: "applied", severity: "medium" },
|
|
67
|
+
"namespace-import": { action: "review", severity: "high" },
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
const ROOT = "@assure-one/design-system";
|
|
71
|
+
|
|
72
|
+
/** The entry that owns an imported name, or `null` when the root keeps it. */
|
|
73
|
+
export const entryOf = (name) => ENTRY_BY_SYMBOL[name] ?? null;
|
|
74
|
+
|
|
75
|
+
const ruleFor = (name, entry) =>
|
|
76
|
+
PRODUCT_TARGET[name] ? "product-owned" : entry === "suite" ? "moved-to-suite" : "moved-to-legacy";
|
|
77
|
+
|
|
78
|
+
/** One `import …` statement built from the specifiers of the original one. */
|
|
79
|
+
function declaration({ typeOnly, defaultName, specifiers, quote, semi }, specifier) {
|
|
80
|
+
const clause = [defaultName, specifiers.length ? `{ ${specifiers.join(", ")} }` : null].filter(
|
|
81
|
+
Boolean,
|
|
82
|
+
);
|
|
83
|
+
return `import ${typeOnly ? "type " : ""}${clause.join(", ")} from ${quote}${specifier}${quote}${semi}`;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
export function transform(file, { ts }) {
|
|
87
|
+
const facts = analyseForms(ts, file.source, file.rel);
|
|
88
|
+
const sf = facts.sf;
|
|
89
|
+
const findings = [];
|
|
90
|
+
const edits = [];
|
|
91
|
+
|
|
92
|
+
for (const stmt of sf.statements) {
|
|
93
|
+
if (!ts.isImportDeclaration(stmt) || !ts.isStringLiteral(stmt.moduleSpecifier)) continue;
|
|
94
|
+
if (stmt.moduleSpecifier.text !== ROOT) continue;
|
|
95
|
+
const clause = stmt.importClause;
|
|
96
|
+
if (!clause) continue;
|
|
97
|
+
|
|
98
|
+
const line = sf.getLineAndCharacterOfPosition(stmt.getStart(sf)).line + 1;
|
|
99
|
+
const base = { line, registryId: "C-ROOT-SUITE", component: null, gate: null };
|
|
100
|
+
|
|
101
|
+
// `import * as DS` — the members are reached through the namespace, so the
|
|
102
|
+
// import cannot be split by name. Only worth reporting when the file
|
|
103
|
+
// actually reads a name that moved.
|
|
104
|
+
if (clause.namedBindings && ts.isNamespaceImport(clause.namedBindings)) {
|
|
105
|
+
const ns = clause.namedBindings.name.text;
|
|
106
|
+
const used = new Set();
|
|
107
|
+
const visit = (node) => {
|
|
108
|
+
if (
|
|
109
|
+
ts.isPropertyAccessExpression(node) &&
|
|
110
|
+
ts.isIdentifier(node.expression) &&
|
|
111
|
+
node.expression.text === ns &&
|
|
112
|
+
entryOf(node.name.text)
|
|
113
|
+
) {
|
|
114
|
+
used.add(node.name.text);
|
|
115
|
+
}
|
|
116
|
+
if (ts.isQualifiedName(node) && ts.isIdentifier(node.left) && node.left.text === ns) {
|
|
117
|
+
if (entryOf(node.right.text)) used.add(node.right.text);
|
|
118
|
+
}
|
|
119
|
+
ts.forEachChild(node, visit);
|
|
120
|
+
};
|
|
121
|
+
ts.forEachChild(sf, visit);
|
|
122
|
+
if (used.size) {
|
|
123
|
+
findings.push({
|
|
124
|
+
...base,
|
|
125
|
+
rule: "namespace-import",
|
|
126
|
+
...RULES["namespace-import"],
|
|
127
|
+
match: `import * as ${ns}`,
|
|
128
|
+
detail: { namespace: ns, symbols: [...used].sort() },
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
continue;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
const named = clause.namedBindings;
|
|
135
|
+
if (!named || !ts.isNamedImports(named)) continue;
|
|
136
|
+
|
|
137
|
+
const buckets = { root: [], suite: [], legacy: [] };
|
|
138
|
+
const movedNames = { suite: [], legacy: [] };
|
|
139
|
+
for (const element of named.elements) {
|
|
140
|
+
const imported = (element.propertyName ?? element.name).text;
|
|
141
|
+
const entry = entryOf(imported);
|
|
142
|
+
const bucket = entry ?? "root";
|
|
143
|
+
buckets[bucket].push(element.getText(sf));
|
|
144
|
+
if (entry) movedNames[entry].push(imported);
|
|
145
|
+
}
|
|
146
|
+
if (!movedNames.suite.length && !movedNames.legacy.length) continue;
|
|
147
|
+
|
|
148
|
+
const text = stmt.getText(sf);
|
|
149
|
+
const shape = {
|
|
150
|
+
typeOnly: clause.isTypeOnly,
|
|
151
|
+
defaultName: clause.name ? clause.name.text : null,
|
|
152
|
+
quote: stmt.moduleSpecifier.getText(sf)[0],
|
|
153
|
+
semi: text.endsWith(";") ? ";" : "",
|
|
154
|
+
};
|
|
155
|
+
const rows = [];
|
|
156
|
+
if (buckets.root.length || shape.defaultName) {
|
|
157
|
+
rows.push(declaration({ ...shape, specifiers: buckets.root }, ROOT));
|
|
158
|
+
}
|
|
159
|
+
for (const entry of ["suite", "legacy"]) {
|
|
160
|
+
if (!buckets[entry].length) continue;
|
|
161
|
+
rows.push(
|
|
162
|
+
declaration(
|
|
163
|
+
{ ...shape, defaultName: null, specifiers: buckets[entry] },
|
|
164
|
+
ENTRY_SPECIFIER[entry],
|
|
165
|
+
),
|
|
166
|
+
);
|
|
167
|
+
}
|
|
168
|
+
edits.push({ pos: stmt.getStart(sf), end: stmt.getEnd(), text: rows.join("\n") });
|
|
169
|
+
|
|
170
|
+
for (const entry of ["suite", "legacy"]) {
|
|
171
|
+
const byRule = new Map();
|
|
172
|
+
for (const name of movedNames[entry]) {
|
|
173
|
+
const rule = ruleFor(name, entry);
|
|
174
|
+
if (!byRule.has(rule)) byRule.set(rule, []);
|
|
175
|
+
byRule.get(rule).push(name);
|
|
176
|
+
}
|
|
177
|
+
for (const [rule, names] of byRule) {
|
|
178
|
+
findings.push({
|
|
179
|
+
...base,
|
|
180
|
+
rule,
|
|
181
|
+
...RULES[rule],
|
|
182
|
+
match: `{ ${names.sort().join(", ")} }`,
|
|
183
|
+
detail: {
|
|
184
|
+
from: ROOT,
|
|
185
|
+
to: ENTRY_SPECIFIER[entry],
|
|
186
|
+
symbols: names,
|
|
187
|
+
...(rule === "product-owned"
|
|
188
|
+
? { owners: [...new Set(names.map((n) => PRODUCT_TARGET[n]))].sort() }
|
|
189
|
+
: {}),
|
|
190
|
+
},
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
return {
|
|
197
|
+
output: edits.length ? applyEdits(file.source, edits) : file.source,
|
|
198
|
+
findings,
|
|
199
|
+
notTransformed: [],
|
|
200
|
+
parseErrors: facts.parseErrors,
|
|
201
|
+
};
|
|
202
|
+
}
|