Skip to content

Commit 387932e

Browse files
committed
feat: queue.xml improvements
1 parent de84ba2 commit 387932e

4 files changed

Lines changed: 99 additions & 62 deletions

File tree

precomputer/src/tasks/queue-xml.ts

Lines changed: 38 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
import path from 'node:path'
22
import fsPromises from 'node:fs/promises'
3+
import { JSDOM } from 'jsdom'
34
import { DateTime } from 'luxon'
45
import { groupBy } from 'es-toolkit'
56
import { PurpleApi } from '../../generated/purple_client/index.ts'
67
import { getDOMParser, validateXml } from '../utils/dom.ts'
78
import { getQueueCommon } from '../utils/queue.ts'
89
import { type QueueCommon } from '../../../website/app/utils/validators.ts'
9-
import { JSDOM } from 'jsdom'
1010

1111
type Props = {
1212
api: PurpleApi
@@ -27,23 +27,37 @@ const XML_DECLARATION = '<?xml version="1.0" encoding="utf-8"?>'
2727
* Generates a queue.xml file aNd validate against the XSD
2828
*/
2929
export const renderQueueXML = async (queue: QueueCommon): Promise<string> => {
30-
// console.log("========")
31-
// console.log(JSON.stringify(queue, null, 2))
32-
// console.log("========")
30+
console.log("========")
31+
console.log(JSON.stringify(queue, null, 2))
32+
console.log("========")
3333

3434
const dom = await getDOMParser()
3535

3636
const doc = dom.parseFromString(`<rfc-editor-queue xmlns="${NAMESPACE}"></rfc-editor-queue>`, 'text/xml')
3737

38-
const itemsbyGroup = groupBy(queue.items, (item) => item.stream ?? 'NO STREAM')
38+
const itemsbyGroup = groupBy(queue.items, (item) => {
39+
// eg "IETF STREAM: WORKING GROUP STANDARDS TRACK"
40+
// or "IETF STREAM: NON-WORKING GROUP STANDARDS TRACK"
41+
const sectionNameParts = [
42+
item.stream?.toUpperCase(),
43+
item.groupName?.toUpperCase()
44+
].filter(val => Boolean(val))
45+
46+
if (sectionNameParts.length > 0) {
47+
const COLON_AND_SPACE = ': '
48+
const sectionName = sectionNameParts.join(COLON_AND_SPACE)
49+
return sectionName
50+
}
51+
return 'UNKNOWN'
52+
})
3953
const sections = Object.keys(itemsbyGroup)
4054

4155
sections.forEach(section => {
4256
// eg <section name="IETF STREAM: WORKING GROUP STANDARDS TRACK">
4357
// or <section name="IETF STREAM: NON-WORKING GROUP STANDARDS TRACK">
4458
const sectionEl = doc.createElementNS(NAMESPACE, 'section')
4559
doc.documentElement.append(sectionEl)
46-
sectionEl.setAttribute('name', section.toUpperCase())
60+
sectionEl.setAttribute('name', section)
4761

4862
const items = itemsbyGroup[section]
4963
items.forEach(item => {
@@ -77,9 +91,19 @@ export const renderQueueXML = async (queue: QueueCommon): Promise<string> => {
7791
})
7892
}
7993

80-
// TODO
8194
// eg <normRef><ref-name>draft-ietf-ecrit-lost-planned-changes</ref-name><ref-state>NOT-RECEIVED</ref-state></normRef>
82-
// TODO
95+
item.references?.forEach(reference => {
96+
const normRefEl = doc.createElementNS(NAMESPACE, 'normRef')
97+
entryEl.append(normRefEl)
98+
99+
const refNameEl = doc.createElementNS(NAMESPACE, 'ref-name')
100+
normRefEl.append(refNameEl)
101+
refNameEl.textContent = reference.targetDraftName
102+
103+
const refStateEl = doc.createElementNS(NAMESPACE, 'ref-state')
104+
normRefEl.append(refStateEl)
105+
refStateEl.textContent = reference.relationship.toUpperCase()
106+
})
83107

84108
// eg <authors>B. Rosen, R. Marshall, J. Martin</authors>
85109
const authorsEl = doc.createElementNS(NAMESPACE, 'authors')
@@ -94,12 +118,12 @@ export const renderQueueXML = async (queue: QueueCommon): Promise<string> => {
94118
entryEl.append(titleEl)
95119
titleEl.textContent = item.title
96120

97-
// TODO
98-
// eg <source>Emergency Context Resolution with Internet Technologies</source>
99-
// const sourceEl = doc.createElementNS(NS, 'source')
100-
// entryEl.append(sourceEl)
101-
// titleEl.textContent = item.source
102-
// TODO
121+
if (item.groupName) {
122+
// eg <source>Emergency Context Resolution with Internet Technologies</source>
123+
const sourceEl = doc.createElementNS(NAMESPACE, 'source')
124+
entryEl.append(sourceEl)
125+
sourceEl.textContent = item.groupName
126+
}
103127

104128
// eg <consensus>yes</consensus>
105129
const consensusEl = doc.createElementNS(NAMESPACE, 'consensus')

precomputer/src/utils/converters.ts

Lines changed: 28 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { DateTime } from 'luxon'
2-
import { type Cluster, type QueueItem, type ApprovalLogMessage } from "../../generated/purple_client/index.ts";
3-
import { type ClusterDocumentCommon, type ClusterDocumentReferenceCommon, type QueueCommonItem, type ApprovalLogMessageCommon } from "../../../website/app/utils/validators.ts";
2+
import { type Cluster, type QueueItem, type ApprovalLogMessage, RpcRelatedDocument } from "../../generated/purple_client/index.ts";
3+
import { type ClusterDocumentCommon, type DocumentReferenceCommon, type QueueCommonItem, type ApprovalLogMessageCommon } from "../../../website/app/utils/validators.ts";
44
import { assertIsString, assertNever } from "./typescript.ts";
55

66
export const parseDisposition = (disposition: string): QueueCommonItem["disposition"] => {
@@ -99,38 +99,40 @@ type ClusterMember = ClusterDocuments[number]
9999
export const clusterMemberToClusterDocumentCommon = (clusterNumber: number, clusterMember: ClusterMember): ClusterDocumentCommon => {
100100
const { name, rfcNumber, disposition, references, isReceived } = clusterMember
101101

102-
// console.log(`[cluster ${clusterNumber}]`, `[${name}]`, references?.length ? `${references.length} reference(s)` : 'no references')
103-
104102
return {
105103
name,
106104
disposition: disposition ? parseDisposition(disposition) : undefined,
107105
isReceived: Boolean(isReceived),
108106
rfcNumber: rfcNumber ?? undefined,
109-
references: references?.map((reference): ClusterDocumentReferenceCommon => {
110-
const {
111-
relationship,
112-
draftName,
113-
targetDraftName,
114-
targetRfcNumber,
115-
sourceRfcNumber,
116-
targetDisposition,
117-
} = reference
118-
119-
assertIsString(draftName)
120-
assertIsString(targetDraftName)
121-
122-
return {
123-
relationship: parseRelationship(relationship),
124-
draftName,
125-
targetDraftName,
126-
targetRfcNumber,
127-
sourceRfcNumber,
128-
targetDisposition: targetDisposition ? parseDisposition(targetDisposition) : undefined
129-
}
130-
}) ?? []
107+
references: parseReferences(references)
131108
}
132109
}
133110

111+
export const parseReferences = (references?: RpcRelatedDocument[]): DocumentReferenceCommon[] => {
112+
return references?.map((reference): DocumentReferenceCommon => {
113+
const {
114+
relationship,
115+
draftName,
116+
targetDraftName,
117+
targetRfcNumber,
118+
sourceRfcNumber,
119+
targetDisposition,
120+
} = reference
121+
122+
assertIsString(draftName)
123+
assertIsString(targetDraftName)
124+
125+
return {
126+
relationship: parseRelationship(relationship),
127+
draftName,
128+
targetDraftName,
129+
targetRfcNumber,
130+
sourceRfcNumber,
131+
targetDisposition: targetDisposition ? parseDisposition(targetDisposition) : undefined
132+
}
133+
}) ?? []
134+
}
135+
134136
export const parseApprovalLogMessages = (approvalLogMessages?: ApprovalLogMessage[]): undefined | ApprovalLogMessageCommon[] => {
135137
if (!approvalLogMessages) {
136138
return undefined

precomputer/src/utils/queue.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { DateTime } from 'luxon'
22
import { PurpleApi, type ApiPubqQueueListRequest } from "../../generated/purple_client/index.ts";
33
import { type QueueCommon, type QueueCommonItem, QueueCommonSchema, type BlockingReason } from '../../../website/app/utils/validators.ts'
44
import { assertIsString } from "../utils/typescript.ts";
5-
import { parseApprovalLogMessages, parseDisposition, parseIanaStatus, parseLabels } from "../utils/converters.ts";
5+
import { parseApprovalLogMessages, parseDisposition, parseIanaStatus, parseLabels, parseReferences } from "../utils/converters.ts";
66
import { groupBy } from "es-toolkit";
77

88
type Props = {
@@ -32,6 +32,10 @@ export const getQueueCommon = async ({ api, params }: Props): Promise<QueueCommo
3232
ianaStatus,
3333
stream,
3434
authors,
35+
group,
36+
groupName,
37+
stdLevel,
38+
references,
3539
finalApproval: finalApprovals,
3640
approvalLogMessage: approvalLogMessages,
3741
} = queueItem
@@ -52,6 +56,10 @@ export const getQueueCommon = async ({ api, params }: Props): Promise<QueueCommo
5256
title,
5357
pages,
5458
stream,
59+
group,
60+
groupName: groupName ?? undefined,
61+
stdLevel,
62+
references: parseReferences(references),
5563
authors: authors.map(author => {
5664
const { titlepageName, isEditor } = author
5765
return {

website/app/utils/validators.ts

Lines changed: 24 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,23 @@ const FinalApprovalSchema = z.object({
9696
approvedAtIso: z.string().optional(),
9797
})
9898

99+
const ClusterDocumentRelationshipCommonSchema = z.union([
100+
z.literal('refqueue'),
101+
z.literal('not-received'),
102+
z.literal('not-received-2g'),
103+
z.literal('not-received-3g'),
104+
z.literal('withdrawnref')
105+
])
106+
107+
const DocumentReferenceCommonSchema = z.object({
108+
relationship: ClusterDocumentRelationshipCommonSchema,
109+
draftName: z.string(),
110+
sourceRfcNumber: z.number().optional(),
111+
targetDraftName: z.string(),
112+
targetRfcNumber: z.number().optional(),
113+
targetDisposition: DispositionCommonSchema.optional(),
114+
})
115+
99116
export const QueueCommonItemSchema = z.object({
100117
name: z.string(),
101118
title: z.string(),
@@ -111,7 +128,11 @@ export const QueueCommonItemSchema = z.object({
111128
pages: z.number().optional(),
112129
enqueuedAtIso: z.string().optional(), // ISO date
113130
ianaStatus: IanaStatusCommonSchema.optional(),
114-
approvalLogMessages: ApprovalLogMessageCommonSchema.array().optional()
131+
approvalLogMessages: ApprovalLogMessageCommonSchema.array().optional(),
132+
group: z.string().optional(),
133+
groupName: z.string().optional(),
134+
stdLevel: z.string().optional(),
135+
references: DocumentReferenceCommonSchema.array().optional(),
115136
})
116137

117138
export type QueueCommonItem = z.infer<typeof QueueCommonItemSchema>
@@ -123,31 +144,13 @@ export const QueueCommonSchema = z.object({
123144

124145
export type QueueCommon = z.infer<typeof QueueCommonSchema>
125146

126-
127-
const ClusterDocumentRelationshipCommonSchema = z.union([
128-
z.literal('refqueue'),
129-
z.literal('not-received'),
130-
z.literal('not-received-2g'),
131-
z.literal('not-received-3g'),
132-
z.literal('withdrawnref')
133-
])
134-
135-
const ClusterDocumentReferenceCommonSchema = z.object({
136-
relationship: ClusterDocumentRelationshipCommonSchema,
137-
draftName: z.string(),
138-
sourceRfcNumber: z.number().optional(),
139-
targetDraftName: z.string(),
140-
targetRfcNumber: z.number().optional(),
141-
targetDisposition: DispositionCommonSchema.optional(),
142-
})
143-
144-
export type ClusterDocumentReferenceCommon = z.infer<typeof ClusterDocumentReferenceCommonSchema>
147+
export type DocumentReferenceCommon = z.infer<typeof DocumentReferenceCommonSchema>
145148

146149
export const ClusterDocumentCommonSchema = z.object({
147150
name: z.string(),
148151
rfcNumber: z.number().optional(),
149152
disposition: DispositionCommonSchema.optional(),
150-
references: ClusterDocumentReferenceCommonSchema.array(),
153+
references: DocumentReferenceCommonSchema.array(),
151154
isReceived: z.boolean()
152155
})
153156

0 commit comments

Comments
 (0)