@nshipster/sosumi 1.0.4 → 1.0.6
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 +1 -1
- package/src/lib/reference/render.ts +145 -9
- package/src/lib/types.ts +10 -0
package/package.json
CHANGED
|
@@ -5,7 +5,9 @@
|
|
|
5
5
|
import type {
|
|
6
6
|
AppleDocJSON,
|
|
7
7
|
ContentItem,
|
|
8
|
+
Declaration,
|
|
8
9
|
IndexContentItem,
|
|
10
|
+
Platform,
|
|
9
11
|
PossibleValueItem,
|
|
10
12
|
PropertyItem,
|
|
11
13
|
TopicSection,
|
|
@@ -66,6 +68,8 @@ export async function renderFromJSON(
|
|
|
66
68
|
}
|
|
67
69
|
}
|
|
68
70
|
|
|
71
|
+
markdown += renderDeprecationNotice(jsonData, jsonData.references, options.externalOrigin)
|
|
72
|
+
|
|
69
73
|
// Add declaration
|
|
70
74
|
if (jsonData.primaryContentSections) {
|
|
71
75
|
const declarationSection = jsonData.primaryContentSections.find(
|
|
@@ -192,6 +196,10 @@ function generateFrontMatterFromJSON(jsonData: AppleDocJSON, sourceUrl: string):
|
|
|
192
196
|
frontMatter.source = sourceUrl
|
|
193
197
|
frontMatter.timestamp = new Date().toISOString()
|
|
194
198
|
|
|
199
|
+
if (isSymbolDeprecated(jsonData)) {
|
|
200
|
+
frontMatter.deprecated = "true"
|
|
201
|
+
}
|
|
202
|
+
|
|
195
203
|
// Convert to YAML format
|
|
196
204
|
const yamlLines = Object.entries(frontMatter).map(([key, value]) => `${key}: ${value}`)
|
|
197
205
|
return `---\n${yamlLines.join("\n")}\n---\n\n`
|
|
@@ -227,10 +235,25 @@ function generateBreadcrumbs(sourceUrl: string, externalOrigin?: string): string
|
|
|
227
235
|
return `${breadcrumbs}\n\n`
|
|
228
236
|
}
|
|
229
237
|
|
|
238
|
+
/**
|
|
239
|
+
* Map a DocC language code to a Markdown code-fence identifier. DocC uses
|
|
240
|
+
* `occ` for Objective-C internally, but Markdown highlighters expect `objc`.
|
|
241
|
+
*/
|
|
242
|
+
function normalizeFenceLanguage(syntax: string): string {
|
|
243
|
+
return syntax === "occ" ? "objc" : syntax
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
/**
|
|
247
|
+
* Tab titles DocC uses for language-variant code examples. Used to detect
|
|
248
|
+
* whether a `tabNavigator` is a language switch (so we can default to Swift)
|
|
249
|
+
* versus some other tabbed content we should leave alone.
|
|
250
|
+
*/
|
|
251
|
+
const LANGUAGE_TAB_TITLES = new Set(["Swift", "Objective-C"])
|
|
252
|
+
|
|
230
253
|
/**
|
|
231
254
|
* Render declaration sections
|
|
232
255
|
*/
|
|
233
|
-
function renderDeclarations(declarations:
|
|
256
|
+
function renderDeclarations(declarations: Declaration[]): string {
|
|
234
257
|
let markdown = ""
|
|
235
258
|
|
|
236
259
|
for (const decl of declarations) {
|
|
@@ -242,7 +265,8 @@ function renderDeclarations(declarations: Array<{ tokens?: Array<{ text?: string
|
|
|
242
265
|
.join("")
|
|
243
266
|
.trim()
|
|
244
267
|
|
|
245
|
-
|
|
268
|
+
const fence = decl.languages?.includes("occ") ? "objc" : "swift"
|
|
269
|
+
markdown += `\`\`\`${fence}\n${code}\n\`\`\`\n\n`
|
|
246
270
|
}
|
|
247
271
|
}
|
|
248
272
|
|
|
@@ -399,7 +423,7 @@ function renderContentArray(
|
|
|
399
423
|
} else {
|
|
400
424
|
code = String(item.code || "")
|
|
401
425
|
}
|
|
402
|
-
const syntax = item.syntax || "swift"
|
|
426
|
+
const syntax = normalizeFenceLanguage(item.syntax || "swift")
|
|
403
427
|
|
|
404
428
|
markdown += `\`\`\`${syntax}\n${code}\n\`\`\`\n\n`
|
|
405
429
|
} else if (item.type === "unorderedList") {
|
|
@@ -435,14 +459,29 @@ function renderContentArray(
|
|
|
435
459
|
? renderContentArray(item.content, references, depth + 1, externalOrigin)
|
|
436
460
|
: ""
|
|
437
461
|
const cleanContent = asideContent.trim().replace(/\n/g, "\n> ")
|
|
438
|
-
|
|
462
|
+
const deprecatedLabel = style.toLowerCase() === "deprecated" ? "**Deprecated**\n>\n> " : ""
|
|
463
|
+
markdown += `> [!${calloutType}]\n> ${deprecatedLabel}${cleanContent}\n\n`
|
|
439
464
|
} else if (item.type === "table") {
|
|
440
465
|
markdown += renderTable(item, references, depth, externalOrigin)
|
|
441
466
|
} else if (item.type === "tabNavigator" && item.tabs?.length) {
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
467
|
+
// Only filter when every tab is a known language tab — otherwise
|
|
468
|
+
// `tabNavigator` may carry non-language content (e.g. platform or
|
|
469
|
+
// theme variants) that we shouldn't drop.
|
|
470
|
+
const allLanguageTabs = item.tabs.every(
|
|
471
|
+
(tab) => tab.title != null && LANGUAGE_TAB_TITLES.has(tab.title.trim()),
|
|
472
|
+
)
|
|
473
|
+
let tabsToRender = item.tabs
|
|
474
|
+
if (allLanguageTabs) {
|
|
475
|
+
const swiftTabs = item.tabs.filter((tab) => tab.title?.trim() === "Swift")
|
|
476
|
+
tabsToRender = swiftTabs.length > 0 ? swiftTabs : item.tabs
|
|
477
|
+
}
|
|
478
|
+
const showLabel = tabsToRender.length > 1
|
|
479
|
+
for (const tab of tabsToRender) {
|
|
480
|
+
if (showLabel) {
|
|
481
|
+
const label = tab.title?.trim()
|
|
482
|
+
if (label) {
|
|
483
|
+
markdown += `**${label}**\n\n`
|
|
484
|
+
}
|
|
446
485
|
}
|
|
447
486
|
if (tab.content?.length) {
|
|
448
487
|
markdown += renderContentArray(tab.content, references, depth + 1, externalOrigin)
|
|
@@ -594,7 +633,8 @@ function renderTopicSections(
|
|
|
594
633
|
? reference.abstract.map((a: { text: string }) => a.text).join("")
|
|
595
634
|
: ""
|
|
596
635
|
|
|
597
|
-
|
|
636
|
+
const deprecatedLabel = reference?.deprecated ? " *(Deprecated)*" : ""
|
|
637
|
+
markdown += `- [${title}](${url})${deprecatedLabel}`
|
|
598
638
|
if (abstract) {
|
|
599
639
|
markdown += ` ${abstract}`
|
|
600
640
|
}
|
|
@@ -694,6 +734,102 @@ function renderSeeAlso(
|
|
|
694
734
|
return markdown
|
|
695
735
|
}
|
|
696
736
|
|
|
737
|
+
/**
|
|
738
|
+
* Whether the symbol page represents a deprecated API.
|
|
739
|
+
*/
|
|
740
|
+
function isSymbolDeprecated(jsonData: AppleDocJSON): boolean {
|
|
741
|
+
return getDeprecationNoticeBody(jsonData, jsonData.references) !== null
|
|
742
|
+
}
|
|
743
|
+
|
|
744
|
+
/**
|
|
745
|
+
* Collect a deprecation message from platform availability metadata.
|
|
746
|
+
*/
|
|
747
|
+
function getDeprecationMessageFromPlatforms(platforms?: Platform[]): string | null {
|
|
748
|
+
if (!platforms?.length) {
|
|
749
|
+
return null
|
|
750
|
+
}
|
|
751
|
+
|
|
752
|
+
const deprecatedPlatforms = platforms.filter(
|
|
753
|
+
(platform) => platform.deprecated === true || platform.deprecatedAt,
|
|
754
|
+
)
|
|
755
|
+
if (deprecatedPlatforms.length === 0) {
|
|
756
|
+
return null
|
|
757
|
+
}
|
|
758
|
+
|
|
759
|
+
const uniqueMessages = [
|
|
760
|
+
...new Set(
|
|
761
|
+
deprecatedPlatforms
|
|
762
|
+
.map((platform) => platform.message?.trim())
|
|
763
|
+
.filter((message): message is string => Boolean(message)),
|
|
764
|
+
),
|
|
765
|
+
]
|
|
766
|
+
|
|
767
|
+
if (uniqueMessages.length === 1) {
|
|
768
|
+
return uniqueMessages[0]
|
|
769
|
+
}
|
|
770
|
+
|
|
771
|
+
if (uniqueMessages.length > 1) {
|
|
772
|
+
return deprecatedPlatforms
|
|
773
|
+
.filter((platform) => platform.message)
|
|
774
|
+
.map((platform) => `**${platform.name}:** ${platform.message}`)
|
|
775
|
+
.join("\n")
|
|
776
|
+
}
|
|
777
|
+
|
|
778
|
+
return DEFAULT_DEPRECATION_MESSAGE
|
|
779
|
+
}
|
|
780
|
+
|
|
781
|
+
const DEFAULT_DEPRECATION_MESSAGE = "This symbol is deprecated."
|
|
782
|
+
|
|
783
|
+
/**
|
|
784
|
+
* Resolve deprecation notice text from DocC JSON (without rendering the callout).
|
|
785
|
+
*/
|
|
786
|
+
function getDeprecationNoticeBody(
|
|
787
|
+
jsonData: AppleDocJSON,
|
|
788
|
+
references?: Record<string, ContentItem>,
|
|
789
|
+
externalOrigin?: string,
|
|
790
|
+
): string | null {
|
|
791
|
+
if (jsonData.deprecationSummary?.length) {
|
|
792
|
+
const summary = renderContentArray(
|
|
793
|
+
jsonData.deprecationSummary,
|
|
794
|
+
references,
|
|
795
|
+
0,
|
|
796
|
+
externalOrigin,
|
|
797
|
+
).trim()
|
|
798
|
+
if (summary) {
|
|
799
|
+
return summary
|
|
800
|
+
}
|
|
801
|
+
}
|
|
802
|
+
|
|
803
|
+
const platformMessage = getDeprecationMessageFromPlatforms(jsonData.metadata?.platforms)
|
|
804
|
+
if (platformMessage) {
|
|
805
|
+
return platformMessage
|
|
806
|
+
}
|
|
807
|
+
|
|
808
|
+
const identifier = jsonData.identifier?.url
|
|
809
|
+
if (identifier && references?.[identifier]?.deprecated === true) {
|
|
810
|
+
return DEFAULT_DEPRECATION_MESSAGE
|
|
811
|
+
}
|
|
812
|
+
|
|
813
|
+
return null
|
|
814
|
+
}
|
|
815
|
+
|
|
816
|
+
/**
|
|
817
|
+
* Render a deprecation callout for deprecated symbol pages.
|
|
818
|
+
*/
|
|
819
|
+
function renderDeprecationNotice(
|
|
820
|
+
jsonData: AppleDocJSON,
|
|
821
|
+
references?: Record<string, ContentItem>,
|
|
822
|
+
externalOrigin?: string,
|
|
823
|
+
): string {
|
|
824
|
+
const body = getDeprecationNoticeBody(jsonData, references, externalOrigin)
|
|
825
|
+
if (!body) {
|
|
826
|
+
return ""
|
|
827
|
+
}
|
|
828
|
+
|
|
829
|
+
const quotedBody = body.replace(/\n/g, "\n> ")
|
|
830
|
+
return `> [!WARNING]\n> **Deprecated**\n>\n> ${quotedBody}\n\n`
|
|
831
|
+
}
|
|
832
|
+
|
|
697
833
|
/**
|
|
698
834
|
* Map aside style to GitHub-style callout
|
|
699
835
|
*/
|
package/src/lib/types.ts
CHANGED
|
@@ -75,6 +75,9 @@ export interface ContentItem {
|
|
|
75
75
|
|
|
76
76
|
// Abstract content
|
|
77
77
|
abstract?: TextFragment[]
|
|
78
|
+
|
|
79
|
+
/** Present on reference entries for deprecated symbols. */
|
|
80
|
+
deprecated?: boolean
|
|
78
81
|
}
|
|
79
82
|
|
|
80
83
|
// ============================================================================
|
|
@@ -86,6 +89,7 @@ export interface ContentItem {
|
|
|
86
89
|
*/
|
|
87
90
|
export interface Declaration {
|
|
88
91
|
tokens?: Token[]
|
|
92
|
+
languages?: string[]
|
|
89
93
|
}
|
|
90
94
|
|
|
91
95
|
/**
|
|
@@ -260,6 +264,10 @@ export interface Platform {
|
|
|
260
264
|
name: string
|
|
261
265
|
introducedAt: string
|
|
262
266
|
beta?: boolean
|
|
267
|
+
deprecated?: boolean
|
|
268
|
+
deprecatedAt?: string
|
|
269
|
+
message?: string
|
|
270
|
+
unavailable?: boolean
|
|
263
271
|
}
|
|
264
272
|
|
|
265
273
|
/**
|
|
@@ -296,6 +304,8 @@ export interface AppleDocJSON {
|
|
|
296
304
|
|
|
297
305
|
// Content
|
|
298
306
|
abstract?: Array<{ text: string; type: string }>
|
|
307
|
+
/** DocC deprecation notice shown at the top of deprecated symbol pages. */
|
|
308
|
+
deprecationSummary?: ContentItem[]
|
|
299
309
|
sections?: ContentItem[]
|
|
300
310
|
|
|
301
311
|
// Primary content sections
|