@servicetitan/docs-uikit 30.3.0 → 31.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,373 @@
1
+ ---
2
+ title: review
3
+ ---
4
+
5
+ The `startup review` command is a static analysis tool for monorepos using `@servicetitan/startup`.
6
+ It checks your workspace for common configuration and dependency issues using a set of pluggable rules.
7
+ This helps maintain consistency, avoid dependency hell, and enforce best practices across all packages in your repository.
8
+
9
+ ## Usage
10
+
11
+ ```sh
12
+ npx startup review
13
+ ```
14
+
15
+ - Run from the root of your workspace (where your root `package.json` and `package-lock.json` are located).
16
+ - The command will scan all packages (as defined by your workspace configuration) and report any errors or warnings found by the enabled rules.
17
+
18
+ ---
19
+
20
+ ## How It Works
21
+
22
+ 1. **Workspace Discovery**: Finds all packages in your monorepo using your workspace configuration.
23
+ 2. **Dependency Analysis**: Builds a dependency graph and collects all installed versions from `package-lock.json`.
24
+ 3. **Rule Execution**: Runs each enabled rule against your project and packages.
25
+ 4. **Reporting**: Outputs a summary of all problems found, grouped by file and severity.
26
+
27
+ ---
28
+
29
+ ## Output
30
+
31
+ - Errors and warnings are grouped by location.
32
+ - The summary includes the total number of problems, broken down by severity.
33
+ - Errors will cause the command to exit with a non-zero status.
34
+
35
+ ---
36
+
37
+ ## Troubleshooting
38
+
39
+ - Make sure you run the command from the workspace root.
40
+ - If you see unexpected results, check your configuration and ensure your `package-lock.json` is up to date.
41
+
42
+ ---
43
+
44
+ ## Options
45
+
46
+ ### --fix
47
+
48
+ You can run `startup review` with the `--fix` flag to automatically fix certain problems detected by enabled rules.
49
+
50
+ ```sh
51
+ npx startup review --fix
52
+ ```
53
+
54
+ - When `--fix` is provided, rules that support autofix will attempt to update your configuration, as needed.
55
+ - Not all rules support autofix. For those that do, the documentation indicates what is fixable.
56
+ - When `--fix` is used with [`--rule`](#--rule), only the specified rules are fixed.
57
+
58
+ #### "Highest" versions
59
+
60
+ When fixing conflicting versions (see for example [require-one-package-version](#require-one-package-version))
61
+ `--fix` selects the semver string with the highest possible matching version.
62
+ If there's a tie, it picks the one with the higher lowest possible matching version.
63
+
64
+ For example,
65
+
66
+ - `^1.0.0` is higher than `~1.0.0`
67
+ - `>=2` is higher than `>=1`, because `>=2` has a higher lowest version
68
+
69
+ ### --rule
70
+
71
+ Run `startup review` with the `--rule` flag to limit its checks to one or more rules.
72
+
73
+ ```sh
74
+ npx startup review --rule require-project-version-in-root-node-modules
75
+ ```
76
+
77
+ - Use `--rule` multiple times to limit checks to the specified rules.
78
+ - When `--rule` is used with [`--fix`](#--fix), only the specified rules are fixed.
79
+
80
+ ---
81
+
82
+ ## Configuration
83
+
84
+ By default, all rules enabled with a pre-defined severity.
85
+ You can customize the behavior and configure which rules are enabled, their severity, and rule-specific options in your root `package.json`.
86
+
87
+ ### Example Configuration in root `package.json`
88
+
89
+ ```json
90
+ {
91
+ "cli": {
92
+ "review": {
93
+ "rules": {
94
+ "no-typescript-entry-point": "warn",
95
+ "require-explicit-side-effects": ["error", { "exclude": ["utils"] }],
96
+ "require-one-anvil-uikit-contrib-version": "warn",
97
+ "require-npmrc": "off"
98
+ }
99
+ }
100
+ }
101
+ }
102
+ ```
103
+
104
+ Rules accept a lone severity level, or an array `[level, options]` with rule-specific options.
105
+
106
+ ### Severity levels
107
+
108
+ | Level | Description |
109
+ | :-------- | :------------------------------------------------------ |
110
+ | `"error"` | Treat violations as errors (fail the command). |
111
+ | `"warn"` | Treat violations as warnings (do not fail the command). |
112
+ | `"off"` | Disable the rule. |
113
+
114
+ :::tip
115
+ Use `"off"` to temporarily disable a rule, or `"warn"` to see issues without failing your CI.
116
+ :::
117
+
118
+ ### Options
119
+
120
+ #### `exclude`
121
+
122
+ Array of package names to exclude from the check.
123
+ For example, this configuration allows `@servicetitan/datetime-utils` to have a
124
+ different version from other `anvil-uikit-contrib` packages.
125
+
126
+ ```json
127
+ "require-one-anvil-uikit-contrib-version": [
128
+ "error",
129
+ { "exclude": ["@servicetitan/datetime-utils"] }
130
+ ]
131
+ ```
132
+
133
+ And, this configuration requires all libraries except `utils` to have explicit `sideEffects`.
134
+
135
+ ```json
136
+ "require-explicit-side-effects": ["error", { "exclude": ["utils"] }],
137
+ ```
138
+
139
+ ---
140
+
141
+ ## Rules
142
+
143
+ ### no-typescript-entry-point
144
+
145
+ Ensures that no package uses a TypeScript file as its main entry point or in its `exports`.
146
+
147
+ Because `startup` compiles and builds in separate steps, packages should export
148
+ the compiled Javascript output instead of the TypeScript source files. For example,
149
+
150
+ ```json title="package.json"
151
+ {
152
+ "main": "./dist/index.js",
153
+ "typings": "./dist/index.d.ts"
154
+ }
155
+ ```
156
+
157
+ :::note
158
+ The Webpack documentation suggests using a configuration that directs webpack to
159
+ enter through `./src/index.ts` and load all `.ts` and `.tsx` files through `ts-loader`.
160
+ However, because `startup` precompiles Typescript files, this is redundant and
161
+ webpack should be configured to load the compiled Javascript.
162
+ :::
163
+
164
+ #### ✅ Autofix
165
+
166
+ This rule supports autofix.
167
+ It changes the Typescript entry point to the corresponding `.js` file
168
+ in the package's output folder. For example, given:
169
+
170
+ ```json title="packages/lib/package.json"
171
+ {
172
+ "main": "src/index.ts"
173
+ }
174
+ ```
175
+
176
+ And,
177
+
178
+ ```json title="packages/lib/tsconfig.json"
179
+ {
180
+ "compilerOptions": {
181
+ "rootDir": "src",
182
+ "outDir": "dist"
183
+ }
184
+ }
185
+ ```
186
+
187
+ It runs:
188
+
189
+ ```sh
190
+ npm pkg set "main"="dist/index.js" -w packages/lib
191
+ ```
192
+
193
+ ---
194
+
195
+ ### require-explicit-side-effects
196
+
197
+ Warns if a package is missing the `sideEffects` property in its `package.json`.
198
+
199
+ Including the `sideEffects` property in a package’s `package.json` is important for the following reasons:
200
+
201
+ - **Tree-shaking Optimization**
202
+ The `sideEffects` property tells bundlers (like Webpack) which files in your package are "pure" (i.e., have no side effects when imported). This allows bundlers to safely remove unused code during the build process, resulting in smaller bundle sizes and faster load times.
203
+
204
+ - **Preventing Broken Code**
205
+ If your package does have files with side effects (such as polyfills, global CSS imports, or code that modifies global state), you can explicitly list them in the `sideEffects` array. This ensures that bundlers do not accidentally remove these files, which could otherwise break your application.
206
+
207
+ - **Best Practice for Libraries**
208
+ For libraries, explicitly setting `"sideEffects": false` (if your package is side-effect free) or providing an array of files with side effects is considered a best practice. It signals to consumers and tools that your package is optimized for modern build workflows.
209
+
210
+ **Example**
211
+
212
+ ```json
213
+ { "sideEffects": false }
214
+ ```
215
+
216
+ Or, if only some files have side effects:
217
+
218
+ ```json
219
+ {
220
+ "sideEffects": ["./src/polyfills.js", "./src/styles/global.css"]
221
+ }
222
+ ```
223
+
224
+ #### ❌ Autofix
225
+
226
+ This rule is not fixable automatically.
227
+ You must determine whether any files in the package have side effects and manually add the appropriate `sideEffects` property. E.g.,
228
+
229
+ ```sh
230
+ npm pkg set sideEffects=false -w @servicetitan/package
231
+ ```
232
+
233
+ ---
234
+
235
+ ### require-npmrc
236
+
237
+ Checks that your project contains a `.npmrc` file with `legacy-peer-deps=true`.
238
+
239
+ ```text title=".npmrc"
240
+ legacy-peer-deps=true
241
+ ```
242
+
243
+ Setting `legacy-peer-deps=true` tells npm to use the older, more permissive peer dependency resolution algorithm (as in npm v6). This can help avoid installation failures when packages in your dependency tree have conflicting or unmet peer dependencies, which is common in large monorepos or when using older packages.
244
+
245
+ #### ✅ Autofix
246
+
247
+ This rule supports autofix.
248
+ It creates or updates your `.npmrc` file to include `legacy-peer-deps=true`. E.g.,
249
+
250
+ ```sh
251
+ npm config set --location=project legacy-peer-deps=true
252
+ ```
253
+
254
+ ---
255
+
256
+ ### require-one-anvil-uikit-contrib-version
257
+
258
+ Ensures the same version of related `anvil-uikit-contrib` packages is installed across the workspace.
259
+
260
+ Different versions of related `anvil-uikit-contrib` packages may have breaking changes or incompatible APIs. If some packages use an older version while others use a newer one, you may encounter runtime errors, unexpected behavior, or subtle bugs that are difficult to diagnose.
261
+
262
+ Having the same version of each `anvil-uikit-contrib` package also reduces the risk of dependency duplication, which can bloat your `node_modules` and increase build times.
263
+
264
+ #### ✅ Autofix
265
+
266
+ This rule supports autofix.
267
+ It sets all related `anvil-uikit-contrib` packages to the most common version in the repo.
268
+ If multiple versions tie for the most common, it uses the [highest](#highest-versions) version among the top contenders.
269
+
270
+ ---
271
+
272
+ ### require-one-package-version
273
+
274
+ Ensures that your project directly depends on only one version of each dependency.
275
+ This is important because:
276
+
277
+ - **Avoids Conflicts and Bugs**
278
+ Multiple versions of the same package can lead to subtle bugs, type mismatches, and unpredictable behavior, especially if different parts of your codebase expect different versions of the same API.
279
+
280
+ - **Reduces Bundle Size**
281
+ Having only one version of a package prevents duplication in your `node_modules` and in your production bundles, resulting in smaller, faster builds.
282
+
283
+ - **Simplifies Dependency Management**
284
+ Upgrading, debugging, and maintaining dependencies is much easier when there is only one version to track and update.
285
+
286
+ #### ✅ Autofix
287
+
288
+ This rule supports autofix.
289
+ It sets the version of each dependency to the [highest](#highest-versions) of the conflicting versions.
290
+
291
+ ---
292
+
293
+ ### require-one-uikit-version
294
+
295
+ Ensures the same version of related `uikit` packages is installed across the workspace.
296
+
297
+ Different versions of related `uikit` packages may have breaking changes or incompatible APIs. If some packages use an older version while others use a newer one, you may encounter runtime errors, unexpected behavior, or subtle bugs that are difficult to diagnose.
298
+
299
+ Having the same version of each `uikit` package also reduces the risk of dependency duplication, which can bloat your `node_modules` and increase build times.
300
+
301
+ #### ✅ Autofix
302
+
303
+ This rule supports autofix.
304
+ It sets all related `uikit` packages to the most common version in the repo.
305
+ If multiple versions tie for the most common, it uses the [highest](#highest-versions) version among the top contenders.
306
+
307
+ ---
308
+
309
+ ### require-project-version-in-root-node-modules
310
+
311
+ Checks that, when multiple versions of a dependency are installed, the version in the root `node_modules` matches one of the versions used by your project.
312
+
313
+ If the root `node_modules` contains a version that is not referenced anywhere in your project, some packages may accidentally import the wrong version, leading to subtle bugs, type mismatches, or runtime errors.
314
+
315
+ #### ✅ Autofix
316
+
317
+ This rule supports autofix.
318
+ It hoists the version that the project directly depends on to the root `node_modules`.
319
+ If the project depends directly on multiple versions of a package, it hoists the [highest](#highest-versions) version.
320
+
321
+ #### How to fix manually
322
+
323
+ To manually hoist packages to the root `node_modules`:
324
+
325
+ 1. Add the package(s) to the root `package.json`. E.g.,
326
+
327
+ ```sh
328
+ npm pkg set dependencies[<name>]=<version>
329
+ ```
330
+
331
+ Where `<name>` is the package name and `<version>` is the package version to hoist.
332
+
333
+ 2. Update the `package-lock.json`:
334
+
335
+ ```sh
336
+ npm install --legacy-peer-deps --package-lock-only --prefer-dedupe
337
+ ```
338
+
339
+ 3. Remove the package(s) from the root `package.json`. E.g.,
340
+
341
+ ```sh
342
+ npm pkg delete dependencies[<name>]
343
+ ```
344
+
345
+ 4. Update `package-lock.json` a final time:
346
+
347
+ ```sh
348
+ npm install --legacy-peer-deps --package-lock-only --prefer-dedupe
349
+ ```
350
+
351
+ ---
352
+
353
+ ### require-servicetitan-scope
354
+
355
+ Checks that public packages are scoped to the `@servicetitan` namespace.
356
+ This is important because:
357
+
358
+ - **Avoids Naming Conflicts**
359
+ Scoping ensures ServiceTitan package names are unique within the npm ecosystem, preventing accidental clashes with public or third-party packages.
360
+
361
+ - **Improves Security**
362
+ Using a scoped namespace helps prevent dependency confusion attacks, where malicious actors publish packages with the same name as ServiceTitan internal packages.
363
+
364
+ - **Enables Scoped Publishing and Access Control**
365
+ ServiceTitan can control access, permissions, and publishing rights at the scope level, making it easier to manage private and public packages.
366
+
367
+ #### ❌ Autofix
368
+
369
+ This rule is not fixable automatically.
370
+
371
+ - If the package is private and not published to NPM, add `private: true` to its `package.json`.
372
+ - If the package is published to NPM, you must manually change the package name and update affected documentation, applications and workflows
373
+ to use the new name.
@@ -0,0 +1,18 @@
1
+ ---
2
+ title: start
3
+ ---
4
+
5
+ Runs package in the development mode. Applications will be hosted on sequential free ports starting from 8080. Pages will automatically reload on changes to the code.
6
+
7
+ #### Arguments
8
+
9
+ - `--scope <glob>` - Include only packages with names matching the given glob.
10
+ - `--ignore <glob>` - Exclude packages with names matching the given glob.
11
+ - `--code-coverage` - Add [instrumentation](https://github.com/JS-DevTools/coverage-istanbul-loader) to bundled code in order to collect code coverage
12
+ - `--use-tsc` - Use TSC for TypeScript compilation
13
+
14
+ ## Start steps
15
+
16
+ The `start` command executes the same steps as the `build` command, then watches for changes and automatically reruns each step as needed.
17
+
18
+ See [Build Steps](/docs/startup/build#build-steps).