1
+ #! /usr/bin/env node
2
+ import path from 'path' ;
3
+ import fs from 'fs' ;
4
+ import { Command } from "commander" ;
5
+ import fastGlob from 'fast-glob' ;
6
+ import TOML from '@ltd/j-toml' ;
7
+ import normalizePath from "normalize-path" ;
8
+ import Structures from "@bookshop/cloudcannon-structures" ;
9
+ import Narrator from "@bookshop/toml-narrator" ;
10
+
11
+ const cwd = process . cwd ( ) ;
12
+ const program = new Command ( ) ;
13
+
14
+ const plur = ( num , str , pluralStr ) => {
15
+ const pluralized = num === 1 ? str : ( pluralStr ?? `${ str } s` ) ;
16
+ return `${ num } ${ pluralized } ` ;
17
+ }
18
+
19
+ const addComponentTo = ( obj , component ) => {
20
+ const { structures, ...fields } = component ;
21
+ structures ?. forEach ( structure => {
22
+ obj [ structure ] = obj [ structure ] || { } ;
23
+ obj [ structure ] [ "id_key" ] = "_bookshop_name"
24
+ obj [ structure ] [ "values" ] = obj [ structure ] [ "values" ] || [ ] ;
25
+ obj [ structure ] [ "values" ] . push ( fields ) ;
26
+ } ) ;
27
+ }
28
+
29
+ async function run ( ) {
30
+ program . option ( "-d, --dot" , "Look for Bookshops inside . directories" ) ;
31
+ program . parse ( process . argv ) ;
32
+ const options = program . opts ( ) ;
33
+
34
+ const bookshopConfigFiles = await fastGlob ( `./**/bookshop.config.js` , {
35
+ cwd,
36
+ dot : ! ! options . dot
37
+ } ) ;
38
+
39
+ const tomlFiles = [ ] ;
40
+
41
+ for ( const bookshopConfig of bookshopConfigFiles ) {
42
+ const bookshopRoot = path . dirname ( path . dirname ( bookshopConfig ) ) ;
43
+ console . log ( `📚 Reading Bookshop ./${ bookshopRoot } ` ) ;
44
+ const bookshopPath = normalizePath ( `${ bookshopRoot } /**/*.bookshop.toml` ) ;
45
+ tomlFiles . push ( ...await fastGlob ( bookshopPath , {
46
+ cwd
47
+ } ) ) ;
48
+ }
49
+
50
+ const files = Array . from ( new Set ( tomlFiles . sort ( ) ) ) . map ( file => { return { path : file } } ) ;
51
+ let structureCount = 0 ;
52
+
53
+ files ?. forEach ( file => {
54
+ let contents = fs . readFileSync ( file . path , "utf8" ) ;
55
+ contents = Narrator . RewriteTOML ( contents ) ;
56
+ file . contents = TOML . parse ( contents , 1.0 , '\n' , false ) ;
57
+ file . components = Structures . TransformComponent ( file . path , file . contents ) ;
58
+ structureCount += file . components . length ;
59
+ } ) ;
60
+
61
+ const infoJsonFiles = await fastGlob ( `./**/_cloudcannon/info.json` , {
62
+ cwd,
63
+ dot : ! ! options . dot
64
+ } ) ;
65
+
66
+ for ( const infoJsonFile of infoJsonFiles ) {
67
+ const siteRoot = path . dirname ( path . dirname ( infoJsonFile ) ) ;
68
+ console . log ( `📚 Modifying built site at ./${ siteRoot } ` ) ;
69
+ const contents = fs . readFileSync ( infoJsonFile , "utf8" ) ;
70
+ const info_json = JSON . parse ( contents ) ;
71
+ info_json [ "_structures" ] = info_json [ "_structures" ] || { } ;
72
+
73
+ files ?. forEach ( file => {
74
+ file . components ?. forEach ( component => {
75
+ addComponentTo ( info_json [ "_structures" ] , component ) ;
76
+ if ( typeof info_json [ "_array_structures" ] === 'object' ) {
77
+ addComponentTo ( info_json [ "_array_structures" ] , component ) ;
78
+ }
79
+ } ) ;
80
+ } ) ;
81
+
82
+ fs . writeFileSync ( infoJsonFile , JSON . stringify ( info_json , null , 2 ) ) ;
83
+ }
84
+
85
+ console . log ( `📚 Added ${ plur ( structureCount , "structure" ) } from ${ plur ( bookshopConfigFiles . length , "Bookshop" ) } to ${ plur ( infoJsonFiles . length , "site" ) } .` ) ;
86
+ }
87
+
88
+ run ( ) ;
0 commit comments