@servicetitan/docs-uikit 28.1.1 → 28.3.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/docs/launchdarkly-service.mdx +336 -0
- package/docs/log-service.mdx +1 -1
- package/docs/web-components.mdx +53 -0
- package/package.json +2 -2
|
@@ -0,0 +1,336 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: LaunchDarkly Service
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
#### [CHANGELOG (@servicetitan/launchdarkly-service)](https://github.com/servicetitan/uikit/blob/master/packages/launchdarkly-service/CHANGELOG.md)
|
|
6
|
+
|
|
7
|
+
ServiceTitan's LaunchDarkly platform has multiple "projects" (e.g., Dispatch Center, Contact Center, FleetPro),
|
|
8
|
+
each with its own set of feature flags and client-side IDs that authorize connections.
|
|
9
|
+
|
|
10
|
+
LaunchDarkly's SDKs require applications to create a separate client connection to the LaunchDarkly backend for each project.
|
|
11
|
+
However, if applications and MFEs create multiple, independent connections to the same LaunchDarkly project, it can degrade performance
|
|
12
|
+
and cause the UI to behave inconsistently. It also harms performance to teardown and recreate connections each time an
|
|
13
|
+
MFE is unloaded and reloaded.
|
|
14
|
+
|
|
15
|
+
To prevent these issues **@servicetitan/launchdarkly-service** implements a coordinated approach for creating
|
|
16
|
+
and reusing client connections for LaunchDarkly projects.
|
|
17
|
+
Instead of using **LDProvider**, **withLDProvider** or **withAsyncLDProvider** from the LaunchDarkly React SDK, use **LDProvider** from **@servicetitan/launchdarkly-service**.
|
|
18
|
+
|
|
19
|
+
## Usage
|
|
20
|
+
|
|
21
|
+
**@servicetitan/launchdarkly-service** allows host applications and MFEs to share and reuse connections to LaunchDarkly. It ensures that only one connection is created for each LaunchDarkly project. To use:
|
|
22
|
+
|
|
23
|
+
1. Wrap the MFE application (or code within the host) with [`LDProvider`](#ldprovider) from `@servicetitan/launchdarkly-service`.
|
|
24
|
+
2. Wrap the host application with [`LDServiceProvider`](#ldserviceprovider) (if applicable).
|
|
25
|
+
3. Use the standard [hooks](https://docs.launchdarkly.com/sdk/client-side/react/react-web#hooks) from the [launchdarkly-react-client-sdk](https://docs.launchdarkly.com/sdk/client-side/react/react-web) to access feature flags and the client object.
|
|
26
|
+
|
|
27
|
+
## API
|
|
28
|
+
|
|
29
|
+
### LDProvider
|
|
30
|
+
|
|
31
|
+
`LDProvider` provides LaunchDarkly feature flags within hosts and MFEs.
|
|
32
|
+
It ensures that hosts and MFEs share one client connection to each LaunchDarkly project (as identified by the client-side ID)
|
|
33
|
+
and automatically [provides a store](#use-flags-in-mobx-store) that allows flag values to be used in MobX stores.
|
|
34
|
+
|
|
35
|
+
#### Props
|
|
36
|
+
|
|
37
|
+
| Name | Type | Description |
|
|
38
|
+
| :---------------------- | :-------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
39
|
+
| `clientSideID` | `string` | The client-side ID that authorizes the client to connect to a particular LaunchDarkly project. The [getValueForEnvironment](./web-components#getvalueforenvironment) helper provides a convenient way to map Monolith environments to the corresponding client-side ID. |
|
|
40
|
+
| `projectName` | `string` | The name of the LaunchDarkly project, for logs and error messages. |
|
|
41
|
+
| `context` | `object` | (Optional) Context for targeting rules. Defaults to anonymous user. Use LaunchDarkly's [`identify`](https://docs.launchdarkly.com/sdk/features/identify) method to change the context after initialization. |
|
|
42
|
+
| `waitForInitialization` | `boolean` | (Optional) Whether or not to wait until flags values are available before rendering children. Defaults to `true` |
|
|
43
|
+
|
|
44
|
+
:::caution
|
|
45
|
+
When a `context` is provided, only the initial value takes affect. Subsequent calls with the same client-side ID reuse the client that was created with the initial context.
|
|
46
|
+
|
|
47
|
+
This is typically only a problem when different code paths call `LDProvider` with different contexts. To avoid this, create a standard `LDProvider` wrapper for each project (see example below).
|
|
48
|
+
If that isn't practical, you can use [`getContext`](https://launchdarkly.github.io/js-client-sdk/interfaces/LDClient.html#getContext) and [`identify`](https://launchdarkly.github.io/js-client-sdk/interfaces/LDClient.html#identify) to fetch and amend the active context.
|
|
49
|
+
:::
|
|
50
|
+
|
|
51
|
+
:::note
|
|
52
|
+
When `waitForInitialization` is set to false, `LDProvider` renders children immediately, possibly with no flag values,
|
|
53
|
+
then automatically re-renders when the flags become available.
|
|
54
|
+
:::
|
|
55
|
+
|
|
56
|
+
#### Examples
|
|
57
|
+
|
|
58
|
+
For example, to provide feature flags for the TitanAdvisor project, create a `TitanAdvisorLDProvider` component that wraps its children with the appropriate `LDProvider`:
|
|
59
|
+
|
|
60
|
+
```tsx title="titan-advisor-ld-provider.tsx"
|
|
61
|
+
import { LDProvider } from '@servicetitan/launchdarkly-service';
|
|
62
|
+
import { getValueForEnvironment } from '@servicetitan/web-components'
|
|
63
|
+
import { FC, PropsWithChildren, useMemo } from 'react';
|
|
64
|
+
|
|
65
|
+
export const TitanAdvisorLDProvider: FC<PropsWithChildren> = ({ children }) => {
|
|
66
|
+
const clientSideID = useMemo(() => {
|
|
67
|
+
return getValueForEnvironment({
|
|
68
|
+
dev: '669fe6e5cc97eb103be7a620',
|
|
69
|
+
go: '669fe5bff00a0c0fa60b25e4',
|
|
70
|
+
next: '669fe5bff00a0c0fa60b25e4' // using 'go' here, but could also be 'qa'
|
|
71
|
+
qa: '669fe6d6f00a0c0fa60b2721',
|
|
72
|
+
stage: '669fe65979abf310b860236e',
|
|
73
|
+
});
|
|
74
|
+
}, []);
|
|
75
|
+
|
|
76
|
+
if (!clientSideID) {
|
|
77
|
+
// This only happens in the "test" environment, because "test" was omitted above.
|
|
78
|
+
return children;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
return (
|
|
82
|
+
<LDProvider clientSideID={clientSideID} projectName="TitanAdvisor">
|
|
83
|
+
{children}
|
|
84
|
+
</LDProvider>
|
|
85
|
+
);
|
|
86
|
+
};
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
Then, to provide those flags globally to the entire TitanAdvisor MFE, wrap the MFE's `App`:
|
|
90
|
+
|
|
91
|
+
```tsx title="app.tsx"
|
|
92
|
+
import { FC, StrictMode } from 'react';
|
|
93
|
+
|
|
94
|
+
import { TitanAdvisorLDProvider } from './titan-advisor-ld-provider';
|
|
95
|
+
|
|
96
|
+
export const App: FC = () => {
|
|
97
|
+
return (
|
|
98
|
+
<StrictMode>
|
|
99
|
+
<TitanAdvisorLDProvider>
|
|
100
|
+
{...}
|
|
101
|
+
</TitanAdvisorLDProvider>
|
|
102
|
+
</StrictMode>
|
|
103
|
+
);
|
|
104
|
+
};
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
Or, to provide TitanAdvisor flags to a component in the Monolith, wrap the component:
|
|
108
|
+
|
|
109
|
+
```tsx
|
|
110
|
+
// Rename original Component to ComponentUnwrapped
|
|
111
|
+
const ComponentUnwrapped: FC<ComponentProps> = props => {};
|
|
112
|
+
|
|
113
|
+
// Export wrapped Component
|
|
114
|
+
export const Component: FC<ComponentProps> = props => {
|
|
115
|
+
return (
|
|
116
|
+
<TitanAdvisorLDProvider>
|
|
117
|
+
<ComponentUnwrapped {...props} />
|
|
118
|
+
</TitanAdvisorLDProvider>
|
|
119
|
+
);
|
|
120
|
+
};
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### LDServiceProvider
|
|
124
|
+
|
|
125
|
+
`LDServiceProvider` enables sharing and reusing LaunchDarkly clients outside the Monolith.
|
|
126
|
+
Simply wrap the host with `LDServiceProvider` to ensure that it and embedded MFEs use a single connection for each LaunchDarkly project.
|
|
127
|
+
|
|
128
|
+
```tsx
|
|
129
|
+
import { FC, StrictMode } from 'react';
|
|
130
|
+
import { LogService } from '@servicetitan/launchdarkly-service';
|
|
131
|
+
|
|
132
|
+
export const HostApp: FC = () => {
|
|
133
|
+
return(
|
|
134
|
+
<StrictMode>
|
|
135
|
+
<LDServiceProvider>
|
|
136
|
+
{...}
|
|
137
|
+
</LDServiceProvider>
|
|
138
|
+
</StrictMode>
|
|
139
|
+
);
|
|
140
|
+
};
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
### FeatureFlagStore
|
|
144
|
+
|
|
145
|
+
`LDProvider` automatically provides a `FeatureFlagStore` that allows you to access
|
|
146
|
+
feature flags in MobX stores.
|
|
147
|
+
To use [@inject](./react-ioc#inject) where needed.
|
|
148
|
+
|
|
149
|
+
#### Props
|
|
150
|
+
|
|
151
|
+
| Name | Type | Description |
|
|
152
|
+
| :------ | :---------- | :------------------------------ |
|
|
153
|
+
| `flags` | `LDFlagSet` | The LaunchDarkly feature flags. |
|
|
154
|
+
|
|
155
|
+
#### Example
|
|
156
|
+
|
|
157
|
+
```tsx
|
|
158
|
+
import { FeatureFlagStore } from '@servicetitan/launchdarkly-service';
|
|
159
|
+
|
|
160
|
+
class ConsumerStore {
|
|
161
|
+
constructor(@inject(FeatureFlagStore) private readonly featureFlagStore: FeatureFlagStore) {
|
|
162
|
+
// this.featureFlagStore.flags contains feature flags
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
### WithFeatureFlag
|
|
168
|
+
|
|
169
|
+
`WithFeatureFlag` conditionally renders content depending on the value of a feature flag.
|
|
170
|
+
|
|
171
|
+
#### Props
|
|
172
|
+
|
|
173
|
+
| Name | Type | Description |
|
|
174
|
+
| :-------- | :-------------------- | :---------------------------------------------------------------------------------------------------------------------------------- |
|
|
175
|
+
| `flagKey` | `string` | The feature flag's key. To type check `flagKey`, pass a type argument that defines the flag set (see [below](#type-check-flag-key)) |
|
|
176
|
+
| `on` | `React.ComponentType` | (Optional) Component to render when the flag is turned on. Defaults to `children` prop. |
|
|
177
|
+
| `off` | `React.ComponentType` | (Optional) Component to render when the flag is turned off. Defaults to `null`. |
|
|
178
|
+
| `value` | `LDFlagValue` | (Optional) Flag value that indicates the flag is turned on. Defaults to treating any truthy value as "on". |
|
|
179
|
+
|
|
180
|
+
#### Examples
|
|
181
|
+
|
|
182
|
+
Render children when flag is turned on:
|
|
183
|
+
|
|
184
|
+
```tsx
|
|
185
|
+
<WithFeatureFlag flagKey={flagKey}>
|
|
186
|
+
<Text>Flag is ON</Text>
|
|
187
|
+
</WithFeatureFlag>
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
Render children when flag has specific value:
|
|
191
|
+
|
|
192
|
+
```tsx
|
|
193
|
+
<WithFeatureFlag flagKey={flagKey} value={false}>
|
|
194
|
+
<Text>Flag is false</Text>
|
|
195
|
+
</WithFeatureFlag>
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
Render children when flag is on, and render other component when flag is turned off:
|
|
199
|
+
|
|
200
|
+
```tsx
|
|
201
|
+
<WithFeatureFlag flagKey={flagKey} off={ComponentV1}>
|
|
202
|
+
<ComponentV2 />
|
|
203
|
+
</WithFeatureFlag>
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
Render component when flag is on, and render other component when flag is turned off:
|
|
207
|
+
|
|
208
|
+
```tsx
|
|
209
|
+
<WithFeatureFlag flagKey={flagKey} on={ComponentV2} off={ComponentV1} />
|
|
210
|
+
|
|
211
|
+
<WithFeatureFlag flagKey={flagKey} on={() => 'Flag is ON'} off={() => 'Flag is OFF'} />
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
## Examples
|
|
215
|
+
|
|
216
|
+
### Using flag values in React component
|
|
217
|
+
|
|
218
|
+
Use the `useFlags` hook from the LaunchDarkly React SDK to access flags in React components. E.g.,
|
|
219
|
+
|
|
220
|
+
```tsx
|
|
221
|
+
import { useFlags } from 'launchdarkly-react-client-sdk';
|
|
222
|
+
|
|
223
|
+
export const Component: FC = () => {
|
|
224
|
+
const { enableRedesign } = useFlags();
|
|
225
|
+
return enableRedesign ? <NewDesign /> : <OldDesign />;
|
|
226
|
+
};
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
Or, use this package's [WithFeatureFlag](#withfeatureflag) helper:
|
|
230
|
+
|
|
231
|
+
```tsx
|
|
232
|
+
import { WithFeatureFlag } from '@servicetitan/launchdarkly-service';
|
|
233
|
+
|
|
234
|
+
export const Component: FC = () => (
|
|
235
|
+
<WithFeatureFlag flagKey="enableRedesign" on={NewDesign} off={OldDesign} />
|
|
236
|
+
);
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
### Using flag values in MobX store {#use-flags-in-mobx-store}
|
|
240
|
+
|
|
241
|
+
To use flag values in MobX stores, inject the [FeatureFlagStore](#featureflagstore) provided by `LDProvider`.
|
|
242
|
+
For example,
|
|
243
|
+
|
|
244
|
+
```tsx
|
|
245
|
+
import { FeatureFlagStore } from '@servicetitan/launchdarkly-service';
|
|
246
|
+
|
|
247
|
+
@injectable()
|
|
248
|
+
export class DataStore extends Store {
|
|
249
|
+
constructor(@inject(FeatureFlagStore) private readonly featureFlagStore: FeatureFlagStore) {
|
|
250
|
+
// Use this.featureFlagStore.flags to access feature flags
|
|
251
|
+
if (this.featureFlagStore.flags.enableDataV2) {
|
|
252
|
+
this.initializeDataV2();
|
|
253
|
+
} else {
|
|
254
|
+
this.initializeData();
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
### Type checking WithFeatureFlag key {#type-check-flag-key}
|
|
261
|
+
|
|
262
|
+
To type check the `flagKey` passed to `WithFeatureFlag`, pass a type argument that defines the flag set.
|
|
263
|
+
For example,
|
|
264
|
+
|
|
265
|
+
```tsx title='fleet-flag-set.ts'
|
|
266
|
+
export interface FleetFlagSet {
|
|
267
|
+
enablePermissions: boolean;
|
|
268
|
+
enableBreadcrumbPage: boolean;
|
|
269
|
+
enableAlertsRedesign: boolean;
|
|
270
|
+
}
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
```tsx
|
|
274
|
+
<WithFeatureFlag<FleetFlagSet> flagKey={flagKey} /> // Enforces that flagKey is in FleetFlagSet
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
Or, create a custom wrapper that does this automatically. For example,
|
|
278
|
+
|
|
279
|
+
```tsx title='with-fleet-feature-flag.tsx'
|
|
280
|
+
import { WithFeatureFlag, WithFeatureFlagProps } from '@servicetitan/launchdarkly-service';
|
|
281
|
+
import { FleetFlagSet } from './fleet-flag-set';
|
|
282
|
+
|
|
283
|
+
export const WithFleetFeatureFlag = <T extends keyof FleetFlagSet>(
|
|
284
|
+
props: WithFeatureFlagProps<FleetFlagSet, T>
|
|
285
|
+
) => <WithFeatureFlag<FleetFlagSet, T> {...props} />;
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
```tsx
|
|
289
|
+
<WithFleetFeatureFlag flagKey={flagKey} /> // Enforces that flagKey is in FleetFlagSet
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
### Type checking WithFeatureFlag value
|
|
293
|
+
|
|
294
|
+
To type check the `value` passed to `WithFeatureFlag`, use the `createFlagKeys` helper.
|
|
295
|
+
It returns an object with keys that enable type checking against the passed `value`. For example,
|
|
296
|
+
|
|
297
|
+
```tsx title='fleet-flag-set.ts'
|
|
298
|
+
import { createFlagKeys } from '@servicetitan/launchdarkly-service';
|
|
299
|
+
|
|
300
|
+
export interface FleetFlagSet {
|
|
301
|
+
enablePermissions: boolean;
|
|
302
|
+
enableBreadcrumbPage: boolean;
|
|
303
|
+
enableAlertsRedesign: boolean;
|
|
304
|
+
triStateFlag: 0 | 1 | 2; // flag has non-boolean value
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
export const FleetFlagKeys = createFlagKeys<FleetFlagSet>( // generates type-aware keys
|
|
308
|
+
'enablePermissions',
|
|
309
|
+
'enableBreadcrumbPage',
|
|
310
|
+
'enableAlertsRedesign',
|
|
311
|
+
'triStateFlag'
|
|
312
|
+
);
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
```tsx
|
|
316
|
+
// Use generated key to enforce that value is correct type, in this case, 0, 1 or 2
|
|
317
|
+
<WithFeatureFlag flagKey={FleetFlagKeys.triStateFlag} value={2} />
|
|
318
|
+
|
|
319
|
+
// Use generated key to type check value passed to custom wrapper
|
|
320
|
+
<WithFleetFeatureFlag flagKey={FleetFlagKeys.triStateFlag} value={2} />
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
### Type checking FeatureFlagStore
|
|
324
|
+
|
|
325
|
+
To type check `FeatureFlagStore` keys, pass a type argument that defines the flag set.
|
|
326
|
+
For example,
|
|
327
|
+
|
|
328
|
+
```tsx title='consumer-store.ts'
|
|
329
|
+
class ConsumerStore {
|
|
330
|
+
constructor(
|
|
331
|
+
@inject(FeatureFlagStore)
|
|
332
|
+
// Establishes that type of this.featureFlagStore.flags is FleetFlagSet
|
|
333
|
+
private readonly featureFlagStore: FeatureFlagStore<FleetFlagSet>
|
|
334
|
+
) {}
|
|
335
|
+
}
|
|
336
|
+
```
|
package/docs/log-service.mdx
CHANGED
package/docs/web-components.mdx
CHANGED
|
@@ -153,6 +153,59 @@ The following metadata about an MFE is available from `useMFEMetadataContext` ho
|
|
|
153
153
|
| `shadowRoot` | ShadowRoot | ShadowRoot root node of which the MFE is rendered within |
|
|
154
154
|
| `portalShadowRoot` | ShadowRoot | ShadowRoot root node of the "portal" tied to the MFE, which is used to render elements in a div directly under the body element |
|
|
155
155
|
|
|
156
|
+
### getValueForEnvironment
|
|
157
|
+
|
|
158
|
+
`getValueForEnvironment` detects the Monolith environment and returns a corresponding value.
|
|
159
|
+
|
|
160
|
+
:::caution
|
|
161
|
+
When no value is provided for the detected environment, `getValueForEnvironment` returns `undefined`.
|
|
162
|
+
:::
|
|
163
|
+
|
|
164
|
+
#### Props
|
|
165
|
+
|
|
166
|
+
| Name | Type | Description |
|
|
167
|
+
| :------------------- | :----------------------------- | :----------------------------------------------------------------------------------------- |
|
|
168
|
+
| `values` | `Record<Environment, string>` | Object that maps each environment to a value (see below). |
|
|
169
|
+
| `defaultEnvironment` | `Environment` | The environment to use when the current environment is not recognized. Defaults to `"qa"`. |
|
|
170
|
+
| `hostname` | `string` | The hostname of the current environment. Defaults to `window.location.hostname` |
|
|
171
|
+
|
|
172
|
+
The recognized environments are:
|
|
173
|
+
|
|
174
|
+
| Environment | Description |
|
|
175
|
+
| :---------- | :-------------------------------------------------------------- |
|
|
176
|
+
| **dev** | Development environment (e.g., `localhost`) |
|
|
177
|
+
| **go** | Production environment |
|
|
178
|
+
| **qa** | QA environment |
|
|
179
|
+
| **next** | Next environment |
|
|
180
|
+
| **stage** | Staging environment |
|
|
181
|
+
| **test** | Unit test environment (i.e., `process.env.NODE_ENV === 'test'`) |
|
|
182
|
+
|
|
183
|
+
#### Examples
|
|
184
|
+
|
|
185
|
+
Determine LaunchDarkly client-side ID for TitanAdvisor project.
|
|
186
|
+
|
|
187
|
+
```tsx
|
|
188
|
+
function useTitanAdvisorClientSideID() {
|
|
189
|
+
return useMemo(() => {
|
|
190
|
+
return getValueForEnvironment({
|
|
191
|
+
dev: '669fe6e5cc97eb103be7a620',
|
|
192
|
+
go: '669fe5bff00a0c0fa60b25e4',
|
|
193
|
+
next: '669fe5bff00a0c0fa60b25e4', // same a 'go' but could also be 'qa'
|
|
194
|
+
qa: '669fe6d6f00a0c0fa60b2721',
|
|
195
|
+
stage: '669fe65979abf310b860236e',
|
|
196
|
+
});
|
|
197
|
+
}, []);
|
|
198
|
+
}
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
:::info
|
|
202
|
+
Note that because the environment is fixed for the life the application, it is safe to memoize the return value.
|
|
203
|
+
:::
|
|
204
|
+
|
|
205
|
+
:::caution
|
|
206
|
+
Do not call `getValueForEnvironment` globally, outside a React component or hook. That usage assumes that all the information needed to determine the environment is available immediately when the Javascript runtime loads and before the application is initialized. While that might work it might also change in the future.
|
|
207
|
+
:::
|
|
208
|
+
|
|
156
209
|
### EVENT_BUS_TOKEN - Emitting Events to MFEs
|
|
157
210
|
|
|
158
211
|
Sometimes you may need to send events from the host to the MFE or the other way around, the EventBus ([mitt](https://github.com/developit/mitt) is used under the hood) should cover these needs. Starting <code>v22.1.0</code> you can also send payload.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@servicetitan/docs-uikit",
|
|
3
|
-
"version": "28.
|
|
3
|
+
"version": "28.3.0",
|
|
4
4
|
"description": "",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -16,5 +16,5 @@
|
|
|
16
16
|
"cli": {
|
|
17
17
|
"webpack": false
|
|
18
18
|
},
|
|
19
|
-
"gitHead": "
|
|
19
|
+
"gitHead": "63ce3ca18966fc5522a3b61df5e4c55f82b4272e"
|
|
20
20
|
}
|