@salesforcedevs/docs-components 1.28.4 → 1.28.5-redoc-alpha
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 +2 -2
- package/src/modules/doc/amfReference/amfReference.html +12 -1
- package/src/modules/doc/amfReference/amfReference.ts +79 -2
- package/src/modules/doc/amfReference/constants.ts +4 -0
- package/src/modules/doc/amfReference/types.ts +13 -0
- package/src/modules/doc/redocReference/redocReference.css +24 -0
- package/src/modules/doc/redocReference/redocReference.html +16 -0
- package/src/modules/doc/redocReference/redocReference.ts +29 -1
- package/.npmrc +0 -1
package/package.json
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@salesforcedevs/docs-components",
|
|
3
|
-
"version": "1.28.
|
|
3
|
+
"version": "1.28.5-redoc-alpha",
|
|
4
4
|
"description": "Docs Lightning web components for DSC",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"main": "index.js",
|
|
7
7
|
"engines": {
|
|
8
|
-
"node": "
|
|
8
|
+
"node": "22.x"
|
|
9
9
|
},
|
|
10
10
|
"publishConfig": {
|
|
11
11
|
"access": "public"
|
|
@@ -42,7 +42,18 @@
|
|
|
42
42
|
latest-version={latestVersion}
|
|
43
43
|
></doc-version-picker>
|
|
44
44
|
</div>
|
|
45
|
-
<template lwc:if={
|
|
45
|
+
<template lwc:if={showRedocReference}>
|
|
46
|
+
<doc-redoc-reference
|
|
47
|
+
reference-config={redocReferenceConfig}
|
|
48
|
+
doc-phase-info={docPhaseInfo}
|
|
49
|
+
project-title={projectTitle}
|
|
50
|
+
spec-title={redocSpecTitle}
|
|
51
|
+
origin={origin}
|
|
52
|
+
>
|
|
53
|
+
<div class="redoc-container"></div>
|
|
54
|
+
</doc-redoc-reference>
|
|
55
|
+
</template>
|
|
56
|
+
<template lwc:elseif={showSpecBasedReference}>
|
|
46
57
|
<div class="container">
|
|
47
58
|
<div class="api-documentation">
|
|
48
59
|
<doc-amf-topic
|
|
@@ -24,6 +24,7 @@ import {
|
|
|
24
24
|
NAVIGATION_ITEMS,
|
|
25
25
|
URL_CONFIG,
|
|
26
26
|
REFERENCE_TYPES,
|
|
27
|
+
RENDER_WITH,
|
|
27
28
|
oldReferenceIdNewReferenceIdMap
|
|
28
29
|
} from "./constants";
|
|
29
30
|
import { restoreScroll } from "dx/scrollManager";
|
|
@@ -44,6 +45,12 @@ export default class AmfReference extends LightningElement {
|
|
|
44
45
|
/** Optional Twitter "via" handle (e.g. SalesforceDevs) for social share; passed to doc-content-layout. */
|
|
45
46
|
@api twitterVia: string | null = null;
|
|
46
47
|
@api sidebarHeader!: string;
|
|
48
|
+
/**
|
|
49
|
+
* Project title shown by `<doc-header>` (as its `subtitle`). Forwarded to
|
|
50
|
+
* `<doc-redoc-reference>` so it can surface the same project title inside
|
|
51
|
+
* the Redoc-rendered UI.
|
|
52
|
+
*/
|
|
53
|
+
@api projectTitle: string | null = null;
|
|
47
54
|
@api tocTitle?: string;
|
|
48
55
|
@api tocOptions?: string;
|
|
49
56
|
@api tocAriaLevel?: string;
|
|
@@ -69,7 +76,48 @@ export default class AmfReference extends LightningElement {
|
|
|
69
76
|
* Gives if the currently selected reference is spec based or not
|
|
70
77
|
*/
|
|
71
78
|
get showSpecBasedReference(): boolean {
|
|
72
|
-
return
|
|
79
|
+
return (
|
|
80
|
+
this.isSpecBasedReference(this._currentReferenceId) &&
|
|
81
|
+
!this.showRedocReference
|
|
82
|
+
);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Whether the currently selected reference is rendered with Redoc.
|
|
87
|
+
* Driven by the backend-supplied `renderWith` attribute on the AmfConfig.
|
|
88
|
+
*/
|
|
89
|
+
get showRedocReference(): boolean {
|
|
90
|
+
return this.isRedocReference(this._currentReferenceId);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Serialized config consumed by `<doc-redoc-reference>`. Built from the
|
|
95
|
+
* currently selected redoc reference so Redoc has a single spec to render.
|
|
96
|
+
*/
|
|
97
|
+
get redocReferenceConfig(): string {
|
|
98
|
+
const ref = this.getAmfConfigWithId(this._currentReferenceId);
|
|
99
|
+
if (!ref) {
|
|
100
|
+
return JSON.stringify({ refList: [] });
|
|
101
|
+
}
|
|
102
|
+
return JSON.stringify({
|
|
103
|
+
refList: [
|
|
104
|
+
{
|
|
105
|
+
source: ref.source || ref.amf || "",
|
|
106
|
+
href: ref.href,
|
|
107
|
+
isSelected: true,
|
|
108
|
+
docPhase: ref.docPhase ?? null
|
|
109
|
+
}
|
|
110
|
+
]
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Title of the currently selected spec. Forwarded to `<doc-redoc-reference>`
|
|
116
|
+
* so it can label the spec inside the Redoc UI.
|
|
117
|
+
*/
|
|
118
|
+
get redocSpecTitle(): string {
|
|
119
|
+
const ref = this.getAmfConfigWithId(this._currentReferenceId);
|
|
120
|
+
return ref?.title ?? "";
|
|
73
121
|
}
|
|
74
122
|
|
|
75
123
|
@api
|
|
@@ -296,6 +344,16 @@ export default class AmfReference extends LightningElement {
|
|
|
296
344
|
: false;
|
|
297
345
|
}
|
|
298
346
|
|
|
347
|
+
/**
|
|
348
|
+
* @param referenceId
|
|
349
|
+
* @returns whether the reference should be rendered with Redoc rather than
|
|
350
|
+
* the AMF-based topic renderer.
|
|
351
|
+
*/
|
|
352
|
+
private isRedocReference(referenceId: string): boolean {
|
|
353
|
+
const selectedReference = this.getAmfConfigWithId(referenceId);
|
|
354
|
+
return selectedReference?.renderWith === RENDER_WITH.redoc;
|
|
355
|
+
}
|
|
356
|
+
|
|
299
357
|
/*
|
|
300
358
|
* Refactor below method when sidebar allows sending extraData along with the name for each item.
|
|
301
359
|
* See if we can refactor the below method using regex.
|
|
@@ -442,7 +500,11 @@ export default class AmfReference extends LightningElement {
|
|
|
442
500
|
for (const [index, amfConfig] of this._amfConfigList.entries()) {
|
|
443
501
|
let navItemChildren = [] as ParsedMarkdownTopic[];
|
|
444
502
|
let isChildrenLoading = false;
|
|
445
|
-
if (amfConfig.
|
|
503
|
+
if (amfConfig.renderWith === RENDER_WITH.redoc) {
|
|
504
|
+
// Redoc-rendered specs have no AMF model and no sub-tree; they
|
|
505
|
+
// appear as leaf items in the sidebar and open the Redoc UI on
|
|
506
|
+
// selection.
|
|
507
|
+
} else if (amfConfig.referenceType !== REFERENCE_TYPES.markdown) {
|
|
446
508
|
if (amfConfig.isSelected) {
|
|
447
509
|
const amfPromise = this.fetchAmf(amfConfig).then(
|
|
448
510
|
(amfJson) => {
|
|
@@ -862,6 +924,12 @@ export default class AmfReference extends LightningElement {
|
|
|
862
924
|
const specBasedReference = this.isSpecBasedReference(
|
|
863
925
|
this._currentReferenceId
|
|
864
926
|
);
|
|
927
|
+
if (this.isRedocReference(this._currentReferenceId)) {
|
|
928
|
+
// Redoc reads its own state from referenceConfig + window.location;
|
|
929
|
+
// no metadata to sync from URL on our side.
|
|
930
|
+
restoreScroll();
|
|
931
|
+
return;
|
|
932
|
+
}
|
|
865
933
|
if (specBasedReference) {
|
|
866
934
|
const currentMeta: RouteMeta | undefined =
|
|
867
935
|
this.getReferenceMetaInfo(window.location.href);
|
|
@@ -896,6 +964,9 @@ export default class AmfReference extends LightningElement {
|
|
|
896
964
|
* @param event
|
|
897
965
|
*/
|
|
898
966
|
protected onApiNavigationChanged(): void {
|
|
967
|
+
if (this.isRedocReference(this._currentReferenceId)) {
|
|
968
|
+
return;
|
|
969
|
+
}
|
|
899
970
|
const specBasedReference = this.isSpecBasedReference(
|
|
900
971
|
this._currentReferenceId
|
|
901
972
|
);
|
|
@@ -1165,6 +1236,12 @@ export default class AmfReference extends LightningElement {
|
|
|
1165
1236
|
}
|
|
1166
1237
|
|
|
1167
1238
|
const specBasedReference = this.isSpecBasedReference(referenceId);
|
|
1239
|
+
const redocReference = this.isRedocReference(referenceId);
|
|
1240
|
+
if (redocReference) {
|
|
1241
|
+
// Redoc-rendered references have no AMF model; the redoc component
|
|
1242
|
+
// handles its own URL/spec resolution from referenceConfig.
|
|
1243
|
+
return;
|
|
1244
|
+
}
|
|
1168
1245
|
if (specBasedReference) {
|
|
1169
1246
|
// Wait till the AMF is loaded.
|
|
1170
1247
|
this.amfFetchPromiseMap[referenceId].then(() => {
|
|
@@ -61,6 +61,10 @@ export const REFERENCE_TYPES = {
|
|
|
61
61
|
oa3: "rest-oa3"
|
|
62
62
|
};
|
|
63
63
|
|
|
64
|
+
export const RENDER_WITH = {
|
|
65
|
+
redoc: "redoc"
|
|
66
|
+
};
|
|
67
|
+
|
|
64
68
|
const oldReferenceIdNewReferenceIdMap: Record<string, string> = {
|
|
65
69
|
"commerce-api-assignments": "assignments",
|
|
66
70
|
"commerce-api-campaigns": "campaigns",
|
|
@@ -78,6 +78,19 @@ export interface AmfConfig {
|
|
|
78
78
|
|
|
79
79
|
// required for markdown based references
|
|
80
80
|
topic?: ParsedMarkdownTopic;
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Optional renderer override sent by the backend.
|
|
84
|
+
* When "redoc", spec-based references are rendered with Redoc instead of
|
|
85
|
+
* the AMF-based topic view. Other values fall back to the default pipeline.
|
|
86
|
+
*/
|
|
87
|
+
renderWith?: string;
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Spec URL consumed by alternate renderers (e.g. Redoc). For redoc-rendered
|
|
91
|
+
* references this is the OpenAPI document URL.
|
|
92
|
+
*/
|
|
93
|
+
source?: string;
|
|
81
94
|
}
|
|
82
95
|
|
|
83
96
|
export interface ParsedTopicModel {
|
|
@@ -5,3 +5,27 @@
|
|
|
5
5
|
var(--dx-g-spacing-xl)
|
|
6
6
|
);
|
|
7
7
|
}
|
|
8
|
+
|
|
9
|
+
.redoc-project-header {
|
|
10
|
+
display: flex;
|
|
11
|
+
flex-direction: column;
|
|
12
|
+
gap: var(--dx-g-spacing-2xs);
|
|
13
|
+
padding: var(--dx-g-spacing-s) var(--dx-g-spacing-m);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
.redoc-project-back {
|
|
17
|
+
display: inline-flex;
|
|
18
|
+
align-items: center;
|
|
19
|
+
gap: var(--dx-g-spacing-xs);
|
|
20
|
+
color: var(--dx-g-blue-vibrant-50);
|
|
21
|
+
text-decoration: none;
|
|
22
|
+
width: fit-content;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
.redoc-project-back:hover .redoc-project-title {
|
|
26
|
+
text-decoration: underline;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
.redoc-spec-title {
|
|
30
|
+
margin: 0;
|
|
31
|
+
}
|
|
@@ -8,6 +8,22 @@
|
|
|
8
8
|
></dx-error>
|
|
9
9
|
</template>
|
|
10
10
|
<template lwc:else>
|
|
11
|
+
<div lwc:if={showRedocHeader} class="redoc-project-header">
|
|
12
|
+
<a
|
|
13
|
+
lwc:if={projectTitle}
|
|
14
|
+
class="redoc-project-back"
|
|
15
|
+
href="#"
|
|
16
|
+
onclick={onBackClick}
|
|
17
|
+
>
|
|
18
|
+
<dx-icon sprite="utility" symbol="back" size="small"></dx-icon>
|
|
19
|
+
<span class="redoc-project-title dx-text-body-4">
|
|
20
|
+
{projectTitle}
|
|
21
|
+
</span>
|
|
22
|
+
</a>
|
|
23
|
+
<h2 lwc:if={specTitle} class="redoc-spec-title dx-text-display-6">
|
|
24
|
+
{specTitle}
|
|
25
|
+
</h2>
|
|
26
|
+
</div>
|
|
11
27
|
<slot></slot>
|
|
12
28
|
</template>
|
|
13
29
|
</template>
|
|
@@ -71,6 +71,28 @@ export default class RedocReference extends LightningElement {
|
|
|
71
71
|
/** Optional origin URL for the footer MFE (e.g. wp-json endpoint). Passed through to dx-footer. */
|
|
72
72
|
@api origin: string | null = null;
|
|
73
73
|
|
|
74
|
+
/**
|
|
75
|
+
* Project title (same value passed to `<doc-header>` as `subtitle`). Used
|
|
76
|
+
* inside the Redoc-rendered UI to label the parent project.
|
|
77
|
+
*/
|
|
78
|
+
@api projectTitle: string | null = null;
|
|
79
|
+
|
|
80
|
+
/** Title of the currently selected spec, shown beneath the project title. */
|
|
81
|
+
@api specTitle: string | null = null;
|
|
82
|
+
|
|
83
|
+
get showRedocHeader(): boolean {
|
|
84
|
+
return !!(this.projectTitle || this.specTitle);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Navigates back to the previous history entry when the user clicks the
|
|
89
|
+
* project-title back link rendered above the Redoc UI.
|
|
90
|
+
*/
|
|
91
|
+
private onBackClick(event: Event): void {
|
|
92
|
+
event.preventDefault();
|
|
93
|
+
window.history.back();
|
|
94
|
+
}
|
|
95
|
+
|
|
74
96
|
/** When origin is provided, pass it to the footer; otherwise use dx-footer's default. */
|
|
75
97
|
get effectiveFooterOrigin(): string {
|
|
76
98
|
return (
|
|
@@ -108,7 +130,13 @@ export default class RedocReference extends LightningElement {
|
|
|
108
130
|
}
|
|
109
131
|
|
|
110
132
|
private getRedocContainer(): HTMLElement | null {
|
|
111
|
-
|
|
133
|
+
// Prefer the slotted container in the consumer's light DOM so this
|
|
134
|
+
// component composes inside shadow trees; fall back to a global
|
|
135
|
+
// `.redoc-container` for legacy page-level integrations.
|
|
136
|
+
return (
|
|
137
|
+
this.querySelector<HTMLElement>(".redoc-container") ||
|
|
138
|
+
document.querySelector<HTMLElement>(".redoc-container")
|
|
139
|
+
);
|
|
112
140
|
}
|
|
113
141
|
|
|
114
142
|
private getSelectedReference(): ReferenceItem | null {
|
package/.npmrc
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
//registry.npmjs.org/:_authToken=${SFDOCS_NPM_AUTH_TOKEN}
|