-
Notifications
You must be signed in to change notification settings - Fork 66.8k
Expand file tree
/
Copy pathall-versions.ts
More file actions
157 lines (140 loc) · 5.72 KB
/
all-versions.ts
File metadata and controls
157 lines (140 loc) · 5.72 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
import fs from 'fs'
import type { AllVersions, Version } from '@/types'
import enterpriseServerReleases from './enterprise-server-releases'
// version = "plan"@"release"
// example: enterprise-server@2.21
// where "enterprise-server" is the plan and "2.21" is the release
const versionDelimiter = '@'
const latestNonNumberedRelease = 'latest'
const REST_DATA_META_FILE = 'src/rest/lib/config.json'
// Type for the plan configuration
interface PlanConfig {
plan: string
planTitle: string
shortName: string
releases: string[]
latestRelease: string
nonEnterpriseDefault?: boolean
hasNumberedReleases: boolean
openApiBaseName: string
miscBaseName: string
}
// Type for the REST API config file
interface RestApiConfig {
'api-versions': {
[key: string]: string[]
}
}
// !Explanation of versionless redirect fallbacks!
// This array is **in order** of the versions the site should try to fall back to if
// no version is provided in a URL. For example, if /foo refers to a page that is available
// in all versions, we should not redirect it (because /foo is the correct FPT versioned URL).
// But if /foo refers to a page that is only available in GHEC and GHES, we should redirect it
// to /enterprise-cloud@latest/foo (since GHEC comes first in the hierarchy of version fallbacks).
// The implementation lives in lib/redirects/permalinks.ts.
const plans: PlanConfig[] = [
{
// free-pro-team is **not** a user-facing version and is stripped from URLs.
// See lib/remove-fpt-from-path.ts for details.
plan: 'free-pro-team',
planTitle: 'Free, Pro, & Team',
shortName: 'fpt',
releases: [latestNonNumberedRelease],
latestRelease: latestNonNumberedRelease,
nonEnterpriseDefault: true, // permanent way to refer to this plan if the name changes
hasNumberedReleases: false,
openApiBaseName: 'fpt', // used for REST
miscBaseName: 'dotcom', // used for GraphQL and webhooks
},
{
plan: 'enterprise-cloud',
planTitle: 'Enterprise Cloud',
shortName: 'ghec',
releases: [latestNonNumberedRelease],
latestRelease: latestNonNumberedRelease,
hasNumberedReleases: false,
openApiBaseName: 'ghec',
miscBaseName: 'ghec',
},
{
plan: 'enterprise-server',
planTitle: 'Enterprise Server',
shortName: 'ghes',
releases: enterpriseServerReleases.supported,
latestRelease: enterpriseServerReleases.latest,
hasNumberedReleases: true,
openApiBaseName: 'ghes-',
miscBaseName: 'ghes-',
},
]
const allVersions: AllVersions = {}
// combine the plans and releases to get allVersions object
// e.g. free-pro-team@latest, enterprise-server@2.21, enterprise-server@2.20, etc.
for (const planObj of plans) {
for (const release of planObj.releases) {
const version = `${planObj.plan}${versionDelimiter}${release}`
const versionObj: Version = {
version,
versionTitle: planObj.hasNumberedReleases
? `${planObj.planTitle} ${release}`
: planObj.planTitle,
latestVersion: `${planObj.plan}${versionDelimiter}${planObj.latestRelease}`,
currentRelease: release,
openApiVersionName: planObj.hasNumberedReleases
? `${planObj.openApiBaseName}${release}`
: planObj.openApiBaseName,
miscVersionName: planObj.hasNumberedReleases
? `${planObj.miscBaseName}${release}`
: planObj.miscBaseName,
apiVersions: [], // REST Calendar Date Versions, this may be empty for non calendar date versioned products
latestApiVersion: '', // Latest REST Calendar Date Version, this may be empty for non calendar date versioned products
plan: planObj.plan,
planTitle: planObj.planTitle,
shortName: planObj.shortName,
releases: planObj.releases,
latestRelease: planObj.latestRelease,
hasNumberedReleases: planObj.hasNumberedReleases,
openApiBaseName: planObj.openApiBaseName,
miscBaseName: planObj.miscBaseName,
...(planObj.nonEnterpriseDefault && { nonEnterpriseDefault: planObj.nonEnterpriseDefault }),
}
allVersions[version] = versionObj
}
}
// Adds the calendar date (or api versions) to the allVersions object
const apiVersions: RestApiConfig['api-versions'] = JSON.parse(
fs.readFileSync(REST_DATA_META_FILE, 'utf8'),
)['api-versions']
for (const key of Object.keys(apiVersions)) {
const docsVersion = getDocsVersion(key)
allVersions[docsVersion].apiVersions.push(...apiVersions[key].sort().reverse())
// Create a copy of the array to avoid mutating the original when using pop()
const sortedVersions = [...apiVersions[key].sort()]
allVersions[docsVersion].latestApiVersion = sortedVersions.pop() || ''
}
export const allVersionKeys: string[] = Object.keys(allVersions)
export const allVersionShortnames: Record<string, string> = Object.fromEntries(
Object.values(allVersions).map((v) => [v.shortName, v.plan]),
)
export function isApiVersioned(version: string): boolean {
return allVersions[version] && allVersions[version].apiVersions.length > 0
}
// Currently the versions from the OpenAPI do not match the versions on Docs.
// There is a mapping between the version names. This gets the Docs version from
// the OpenAPI version name (the filename )
export function getDocsVersion(openApiVersion: string): string {
const matchingVersion = Object.values(allVersions).find((version) =>
openApiVersion.startsWith(version.openApiVersionName),
)
if (!matchingVersion) {
throw new Error(`Error: Could not find a matching version for ${openApiVersion}.`)
}
return matchingVersion.version
}
export function getOpenApiVersion(version: string): string {
if (!(version in allVersions)) {
throw new Error(`Unrecognized version '${version}'. Not found in ${Object.keys(allVersions)}`)
}
return allVersions[version].openApiVersionName
}
export { allVersions }