@@ -29,12 +29,13 @@ const mapComponentDetails = (component: Component): ParsedComponent =>
2929const isHtmlRequest = ( headers : IncomingHttpHeaders ) =>
3030 ! ! headers . accept && headers . accept . indexOf ( 'text/html' ) >= 0 ;
3131
32+ const excludedMeta = [ 'dependencies' , 'devDependencies' ] ;
33+
3234export default function ( repository : Repository ) {
3335 return async ( req : Request , res : Response ) : Promise < void > => {
34- let components : string [ ] ;
35-
36+ let componentNames : string [ ] ;
3637 try {
37- components = await repository . getComponents ( ) ;
38+ componentNames = await repository . getComponents ( ) ;
3839 } catch {
3940 res . errorDetails = 'cdn not available' ;
4041 res . status ( 404 ) . json ( { error : res . errorDetails } ) ;
@@ -46,48 +47,49 @@ export default function (repository: Repository) {
4647 ocVersion : packageInfo . version ,
4748 type : res . conf . local ? 'oc-registry-local' : 'oc-registry'
4849 } ;
49- const componentResults = await Promise . all (
50- components . map ( ( component ) =>
51- repository . getComponent ( component , undefined )
50+
51+ const componentDetails = await Promise . all (
52+ componentNames . map ( ( componentName ) =>
53+ repository . getComponent ( componentName , undefined )
5254 )
5355 ) ;
5456
5557 if ( isHtmlRequest ( req . headers ) && ! ! res . conf . discovery . ui ) {
56- const componentsInfo : ParsedComponent [ ] = componentResults . map (
57- ( result ) => {
58- if ( result . oc ?. date ) {
59- result . oc . stringifiedDate = dateStringified (
60- new Date ( result . oc . date )
58+ const processedComponents : ParsedComponent [ ] = componentDetails . map (
59+ ( component ) => {
60+ if ( component . oc ?. date ) {
61+ component . oc . stringifiedDate = dateStringified (
62+ new Date ( component . oc . date )
6163 ) ;
6264 }
63- return mapComponentDetails ( result ) ;
65+ return mapComponentDetails ( component ) ;
6466 }
6567 ) ;
6668
67- const componentsReleases = componentResults . reduce (
68- ( sum , result ) => sum + result . allVersions . length ,
69+ const totalReleases = componentDetails . reduce (
70+ ( sum , component ) => sum + component . allVersions . length ,
6971 0
7072 ) ;
7173
7274 const stateCounts : { deprecated ?: number ; experimental ?: number } = { } ;
73-
74- const componentsList = componentsInfo . map ( ( component ) => {
75- const state : 'deprecated' | 'experimental' | '' =
75+ const componentsList = processedComponents . map ( ( component ) => {
76+ const componentState : 'deprecated' | 'experimental' | '' =
7677 ( component ?. oc ?. state as 'deprecated' | 'experimental' | '' ) || '' ;
77- if ( state ) {
78- stateCounts [ state ] = ( stateCounts [ state ] || 0 ) + 1 ;
78+
79+ if ( componentState ) {
80+ stateCounts [ componentState ] = ( stateCounts [ componentState ] || 0 ) + 1 ;
7981 }
82+
8083 return {
8184 name : component . name ,
8285 author : component . author ,
83- state
86+ state : componentState
8487 } ;
8588 } ) ;
8689
87- componentsInfo . sort ( ( a , b ) => a . name . localeCompare ( b . name ) ) ;
90+ processedComponents . sort ( ( a , b ) => a . name . localeCompare ( b . name ) ) ;
8891
89- // Get theme from cookie or default to dark
90- const theme = req . cookies ?. [ 'oc-theme' ] || 'dark' ;
92+ const userTheme = req . cookies ?. [ 'oc-theme' ] || 'dark' ;
9193
9294 res . send (
9395 indexView (
@@ -97,50 +99,84 @@ export default function (repository: Repository) {
9799 res . conf . dependencies
98100 ) ,
99101 availablePlugins : res . conf . plugins ,
100- components : componentsInfo ,
101- componentsReleases,
102+ components : processedComponents ,
103+ componentsReleases : totalReleases ,
102104 componentsList,
103105 q : req . query [ 'q' ] || '' ,
104106 stateCounts,
105107 templates : repository . getTemplatesInfo ( ) ,
106108 title : 'OpenComponents Registry' ,
107- theme
109+ theme : userTheme
108110 } )
109111 )
110112 ) ;
111113 } else {
112- const state = req . query [ 'state' ] || '' ;
113- const meta = req . query [ 'meta' ] === 'true' && res . conf . discovery . api ;
114- let list = componentResults ;
114+ const requestedState = ( req . query [ 'state' ] as string ) || '' ;
115+ const includeMetadata =
116+ req . query [ 'meta' ] &&
117+ req . query [ 'meta' ] !== 'false' &&
118+ res . conf . discovery . api ;
119+
120+ let filteredComponents = componentDetails ;
121+
115122 if ( ! res . conf . discovery . experimental ) {
116- list = list . filter (
123+ filteredComponents = filteredComponents . filter (
117124 ( component ) => component . oc ?. state !== 'experimental'
118125 ) ;
119126 }
120- if ( state ) {
121- list = list . filter ( ( component ) => component . oc ?. state === state ) ;
127+
128+ if ( requestedState ) {
129+ filteredComponents = filteredComponents . filter (
130+ ( component ) => component . oc ?. state === requestedState
131+ ) ;
122132 }
123133
124- res . status ( 200 ) . json (
125- Object . assign ( baseResponse , {
126- components : list . map ( ( component ) => {
127- const href = urlBuilder . component ( component . name , res . conf . baseUrl ) ;
128-
129- return meta
130- ? {
131- href,
132- name : component . name ,
133- version : component . version ,
134- author : component . author ,
135- description : component . description ,
136- state : component . oc . state ,
137- keywords : component . keywords || [ ] ,
138- publishDate : new Date ( component . oc . date ) . toISOString ( )
139- }
140- : href ;
141- } )
142- } )
143- ) ;
134+ // Build component responses
135+ const componentResponses = filteredComponents . map ( ( component ) => {
136+ const componentUrl = urlBuilder . component (
137+ component . name ,
138+ res . conf . baseUrl
139+ ) ;
140+
141+ if ( includeMetadata ) {
142+ const metaQuery = req . query [ 'meta' ] as string ;
143+
144+ // Return all metadata fields
145+ if ( metaQuery === 'true' ) {
146+ return {
147+ href : componentUrl ,
148+ name : component . name ,
149+ version : component . version ,
150+ author : component . author ,
151+ description : component . description ,
152+ state : component . oc . state ,
153+ keywords : component . keywords || [ ] ,
154+ publishDate : new Date ( component . oc . date ) . toISOString ( )
155+ } ;
156+ }
157+
158+ const requestedFields = metaQuery
159+ . split ( ',' )
160+ . filter ( ( field ) => ! excludedMeta . includes ( field ) ) ;
161+ const responseData = requestedFields . reduce (
162+ ( acc , field ) => {
163+ acc [ field ] = component [ field as keyof Component ] ;
164+ return acc ;
165+ } ,
166+ { } as Record < string , any >
167+ ) ;
168+ responseData [ 'href' ] = componentUrl ;
169+
170+ return responseData ;
171+ }
172+
173+ return componentUrl ;
174+ } ) ;
175+
176+ res . status ( 200 ) . json ( {
177+ ...baseResponse ,
178+ components : componentResponses
179+ } ) ;
144180 }
145181 } ;
146182}
0 commit comments