@salesforcedevs/docs-components 0.54.0-alpha02 → 0.54.0-alpha05

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@salesforcedevs/docs-components",
3
- "version": "0.54.0-alpha02",
3
+ "version": "0.54.0-alpha05",
4
4
  "description": "Docs Lightning web components for DSC",
5
5
  "license": "MIT",
6
6
  "main": "index.js",
@@ -17,7 +17,8 @@
17
17
  "kagekiri": "^1.4.1",
18
18
  "lodash.orderby": "^4.6.0",
19
19
  "lodash.uniqby": "^4.7.0",
20
- "query-string": "^7.1.1"
20
+ "query-string": "^7.1.1",
21
+ "sentence-case": "^3.0.4"
21
22
  },
22
23
  "devDependencies": {
23
24
  "@types/classnames": "^2.2.10",
@@ -0,0 +1,41 @@
1
+ ## AMF Reference
2
+
3
+ AMF refers to MuleSoft’s AML Modeling Framework for modeling documentation and it’s metadata. In this context, AMF is leveraged to parse and normalize API documentation from varying sources and formats, to one format which is the AMF file. We then leverage HTML Web Components created by MuleSoft to render this API documentation by passing it the generated AMF. These HTML Web Components may be referred to as API Console components, ARC (advanced rest components) components, or api documentation components (for the npm package).
4
+
5
+ Ref:
6
+ https://a.ml/docs/amf/
7
+ https://github.com/aml-org/amf
8
+
9
+ ## AMF Reference Component
10
+
11
+ _Components:_ doc-amf-reference, apihub-amf-topic
12
+
13
+ The AMF Reference Component is a LWC component defined within the developer website’s theme. This component is rendered on the API Reference pages.
14
+
15
+ Ref: https://github.com/salesforcedevs/developer-website/tree/main/theme/src/modules/apihub
16
+
17
+ This component takes as input a list of JSON metadata containing the URL information of the reference spec data files. This JSON configuration is generated for each writer repository that contains reference content, and is generated by the SFDocs framework.
18
+
19
+ This component
20
+
21
+ - Takes as input the reference data files (as AMF JSON)
22
+ - Parses the AML data into a model
23
+ - Plugs the model into the ARC components to surface documentation content
24
+ - Handles navigation events to browse the content
25
+
26
+ ### AMF Parser
27
+
28
+ Ref: https://github.com/salesforcedevs/developer-website/blob/main/theme/src/modules/apihub/amfReference/amf-parser.js
29
+
30
+ This class parses the AMF JSON data for one spec and extrapolates the data specific to rendering sections of that specs topic documentation.
31
+
32
+ The parsed data includes:
33
+
34
+ - Title
35
+ - Topics:
36
+ - Summary
37
+ - Endpoints
38
+ - Methods
39
+ - Types
40
+ - Docs
41
+ - Security
@@ -1,5 +1,9 @@
1
1
  import { LightningElement, api, track } from "lwc";
2
+ import { noCase } from "no-case";
3
+ import { sentenceCase } from "sentence-case";
2
4
  import qs from "query-string";
5
+ import { AmfModelParser } from "./utils";
6
+ import { RouteMeta } from "./route-meta";
3
7
  import type {
4
8
  AmfConfig,
5
9
  AmfMetadataTopic,
@@ -12,8 +16,6 @@ import type {
12
16
  ReferenceSetConfig,
13
17
  AmfMetaTopicType
14
18
  } from "./types";
15
- import { AmfModelParser } from "./utils";
16
- import { RouteMeta } from "./route-meta";
17
19
 
18
20
  const NAVIGATION_ITEMS = [
19
21
  {
@@ -191,10 +193,12 @@ export default class AmfReference extends LightningElement {
191
193
 
192
194
  constructor() {
193
195
  super();
194
- this._boundOnApiNavigationChanged =
195
- this.onApiNavigationChanged.bind(this);
196
- this._boundUpdateSelectedItemFromUrlQuery =
197
- this.updateSelectedItemFromUrlQuery.bind(this);
196
+ this._boundOnApiNavigationChanged = this.onApiNavigationChanged.bind(
197
+ this
198
+ );
199
+ this._boundUpdateSelectedItemFromUrlQuery = this.updateSelectedItemFromUrlQuery.bind(
200
+ this
201
+ );
198
202
  }
199
203
 
200
204
  connectedCallback(): void {
@@ -294,38 +298,15 @@ export default class AmfReference extends LightningElement {
294
298
  }
295
299
 
296
300
  /**
297
- * Maps a single endpoint model to a nav item.
298
- * Populates the children of this endpoints nav item
299
- * with the list of methods if they exist.
300
- * Adds the endpoint and any associated methods to the metadata.
301
- * @param {Object} model Endpoint Model
302
- * @returns {Object} Navigation item object model for dx-sidebar
301
+ * Convert any case to a readable Title
302
+ * ex: snake_case => Snake case
303
+ * ex: camelCase => Camel case
304
+ * ex: PascalCase => Pascal case
305
+ * @param label
306
+ * @returns string
303
307
  */
304
- private createEndpointNavItem(
305
- referenceId: string,
306
- model: ParsedTopicModel
307
- ): NavItem {
308
- const { label, methods = [] } = model;
309
- const meta = this.addToMetadata(referenceId, "endpoint", model);
310
-
311
- const navItem: NavItem = {
312
- name: this.getReferencePathWithMeta(meta),
313
- label
314
- };
315
-
316
- if (methods.length) {
317
- // assign the endpoint methods as its children
318
- navItem.children = methods.map((method) => {
319
- const _meta = this.addToMetadata(referenceId, "method", method);
320
- return Object.assign(method, {
321
- name: this.getReferencePathWithMeta(_meta),
322
- label: method.label || method.method
323
- });
324
- });
325
- navItem.isExpanded = false;
326
- }
327
-
328
- return navItem;
308
+ private getTitleForLabel(label: string): string {
309
+ return sentenceCase(noCase(label));
329
310
  }
330
311
 
331
312
  /**
@@ -341,71 +322,22 @@ export default class AmfReference extends LightningElement {
341
322
  referenceId: string,
342
323
  items: ParsedTopicModel[]
343
324
  ): NavItem[] {
344
- const indentStack = [];
345
- let prevIndent = -1;
325
+ const methodList = [];
346
326
 
347
327
  items.forEach((item) => {
348
- // 'indent' only present for AMF data parsed from RAML spec.
349
- // 'indent' is not present for AMF data parsed from OAS spec where endpoints cannot be nested
350
- // thus we default indent at 0 to reflect the flat structure for OAS spec
351
- const { indent = 0 } = item;
352
- const endpoint = this.createEndpointNavItem(referenceId, item);
353
-
354
- if (indent > prevIndent) {
355
- // new or equivalent endpoint indentation level
356
- // create new indent group
357
- const indentGroup = {
358
- indent,
359
- children: [endpoint]
360
- };
361
- // push to stack
362
- indentStack.push(indentGroup);
363
- } else if (indent === prevIndent) {
364
- // no change in indentation level
365
- const lastIndentGroup = indentStack[indentStack.length - 1];
366
- lastIndentGroup.children.push(endpoint);
367
- } else {
368
- // indent < prevIndent: back out to last matching indentation level
369
- let indentGroup = indentStack.pop();
370
- // hold on to the last indent group's children
371
- let lastIndentGroupChildren = indentGroup.children;
372
-
373
- while (indent < indentGroup.indent) {
374
- // back out another indentation level
375
- indentGroup = indentStack.pop();
376
- // append children to next level's last child
377
- const lastChild =
378
- indentGroup.children[indentGroup.children.length - 1];
379
- lastChild.children = (lastChild.children || []).concat(
380
- lastIndentGroupChildren
381
- );
382
- lastIndentGroupChildren = indentGroup.children;
383
- }
384
- indentGroup.children.push(endpoint);
385
- indentStack.push(indentGroup);
386
- }
387
-
388
- // update prevIndent
389
- prevIndent = indent;
390
- });
391
-
392
- // fold remaining indent levels up to the root
393
- if (prevIndent > 0) {
394
- let indentGroup = indentStack.pop();
395
- let lastIndentGroupChildren = indentGroup.children;
396
- while (indentGroup.indent > 0) {
397
- indentGroup = indentStack.pop();
398
- const lastChild =
399
- indentGroup.children[indentGroup.children.length - 1];
400
- lastChild.children = (lastChild.children || []).concat(
401
- lastIndentGroupChildren
328
+ item.methods?.forEach((method) => {
329
+ const meta = this.addToMetadata(referenceId, "method", method);
330
+ methodList.push(
331
+ Object.assign(method, {
332
+ name: this.getReferencePathWithMeta(meta),
333
+ label:
334
+ this.getTitleForLabel(method.label) || method.method
335
+ })
402
336
  );
403
- lastIndentGroupChildren = indentGroup.children;
404
- }
405
- indentStack.push(indentGroup);
406
- }
337
+ });
338
+ });
407
339
 
408
- return indentStack[0].children;
340
+ return methodList;
409
341
  }
410
342
 
411
343
  private getReferencePathWithMeta(meta: string): string {
@@ -678,8 +610,12 @@ export default class AmfReference extends LightningElement {
678
610
  const currentMeta: RouteMeta | null = this.getCurrentRefMeta();
679
611
  const metadata = currentMeta && this.getMetadataByUrlQuery(currentMeta);
680
612
  if (metadata) {
681
- const { referenceId, amfId, type, elementId }: AmfMetadataTopic =
682
- metadata;
613
+ const {
614
+ referenceId,
615
+ amfId,
616
+ type,
617
+ elementId
618
+ }: AmfMetadataTopic = metadata;
683
619
  this.loadContent(
684
620
  referenceId,
685
621
  amfId,
@@ -691,12 +627,15 @@ export default class AmfReference extends LightningElement {
691
627
  }
692
628
  protected onApiNavigationChanged(): void {
693
629
  // The API Navigation event will always intend to navigate within the current reference
694
- const metadata =
695
- this.metadata[
696
- this.getReferencePathWithMeta(this.selectedTopic.meta)
697
- ];
698
- const { referenceId, amfId, type, elementId }: AmfMetadataTopic =
699
- metadata;
630
+ const metadata = this.metadata[
631
+ this.getReferencePathWithMeta(this.selectedTopic.meta)
632
+ ];
633
+ const {
634
+ referenceId,
635
+ amfId,
636
+ type,
637
+ elementId
638
+ }: AmfMetadataTopic = metadata;
700
639
  this.loadContent(referenceId, amfId, type, elementId, metadata.meta);
701
640
  this.updateUrlWithSelected();
702
641
  }
@@ -48,4 +48,4 @@
48
48
 
49
49
  .dx-callout-base_column > dx-type-badge-group {
50
50
  margin-bottom: var(--dx-g-spacing-sm);
51
- }
51
+ }
@@ -1,4 +1,3 @@
1
-
2
1
  import { LightningElement, track } from "lwc";
3
2
 
4
3
  /**
@@ -76,7 +75,9 @@ export abstract class LightningElementWithState<
76
75
  };
77
76
  this._didInitializeState = true;
78
77
  } else {
79
- throw new Error("To mutate state after initialization, use `this.setState`.");
78
+ throw new Error(
79
+ "To mutate state after initialization, use `this.setState`."
80
+ );
80
81
  }
81
82
  }
82
83
 
@@ -90,4 +91,3 @@ export abstract class LightningElementWithState<
90
91
  };
91
92
  };
92
93
  }
93
-
@@ -25,7 +25,9 @@ doc-phase::part(container) {
25
25
 
26
26
  @media screen and (min-width: 1496px) {
27
27
  doc-phase::part(container) {
28
- margin-right: calc(var(--dx-g-page-padding-horizontal) - var(--dx-g-spacing-lg));
28
+ margin-right: calc(
29
+ var(--dx-g-page-padding-horizontal) - var(--dx-g-spacing-lg)
30
+ );
29
31
  }
30
32
  }
31
33
 
@@ -4,7 +4,9 @@ export interface SearchSyncerConstructorArgs {
4
4
  onUrlChange?: (nextSearchString: string) => unknown;
5
5
  };
6
6
  eventName: string;
7
- historyMethod?: typeof window.history.pushState | typeof window.history.replaceState;
7
+ historyMethod?:
8
+ | typeof window.history.pushState
9
+ | typeof window.history.replaceState;
8
10
  searchParam: string;
9
11
  shouldStopPropagation?: boolean;
10
12
  target: EventTarget;
@@ -40,7 +42,10 @@ export class SearchSyncer {
40
42
  };
41
43
 
42
44
  public dispose = (): void => {
43
- this.target.removeEventListener(this.eventName, this.handleSearchChange);
45
+ this.target.removeEventListener(
46
+ this.eventName,
47
+ this.handleSearchChange
48
+ );
44
49
  this.target.removeEventListener("popstate", this.handlePopState);
45
50
  this.target = undefined;
46
51
  this.callbacks.onSearchChange = undefined;