22
33/**
44 * This script is ran with `npx copy-dsfr-to-public`
5- * It takes two optional arguments:
5+ * It takes one optional arguments (for NX monorepos) :
66 * - `--projectDir <path>` to specify the project directory. Default to the current working directory.
77 * This can be used in monorepos to specify the react project directory.
8- * - `--publicDir <path>` to specify the public directory.
9- * In Vite projects we will read the vite.config.ts (or .js) file to find the public directory.
10- * In other projects we will assume it's <project root>/public.
11- * This path is expressed relative to the project directory.
128 */
139
14- import { join as pathJoin , resolve as pathResolve } from "path" ;
10+ import { join as pathJoin , resolve as pathResolve , relative as pathRelative } from "path" ;
1511import * as fs from "fs" ;
1612import { getProjectRoot } from "./tools/getProjectRoot" ;
1713import yargsParser from "yargs-parser" ;
1814import { getAbsoluteAndInOsFormatPath } from "./tools/getAbsoluteAndInOsFormatPath" ;
1915import { readPublicDirPath } from "./readPublicDirPath" ;
2016import { transformCodebase } from "./tools/transformCodebase" ;
2117import { assert } from "tsafe/assert" ;
18+ import { modifyHtmlHrefs } from "./tools/modifyHtmlHrefs" ;
2219
2320( async ( ) => {
2421 const argv = yargsParser ( process . argv . slice ( 2 ) ) ;
@@ -37,38 +34,66 @@ import { assert } from "tsafe/assert";
3734 return process . cwd ( ) ;
3835 } ) ( ) ;
3936
40- const publicDirPath = await ( async ( ) => {
41- read_from_argv: {
42- const arg = argv [ "publicDir" ] ;
37+ const publicDirPath = await readPublicDirPath ( { projectDirPath } ) ;
4338
44- if ( arg === undefined ) {
45- break read_from_argv;
39+ const htmlFilePath = await ( async ( ) => {
40+ vite: {
41+ const filePath = pathJoin ( projectDirPath , "index.html" ) ;
42+
43+ if ( ! fs . existsSync ( filePath ) ) {
44+ break vite;
4645 }
4746
48- const publicDirPath = getAbsoluteAndInOsFormatPath ( {
49- "pathIsh" : arg ,
50- "cwd" : projectDirPath
51- } ) ;
47+ return filePath ;
48+ }
5249
53- if ( ! fs . existsSync ( publicDirPath ) ) {
54- fs . mkdirSync ( publicDirPath , { "recursive" : true } ) ;
50+ cra: {
51+ const filePath = pathJoin ( publicDirPath , "index.html" ) ;
52+
53+ if ( ! fs . existsSync ( filePath ) ) {
54+ break cra;
5555 }
5656
57- return publicDirPath ;
57+ return filePath ;
5858 }
5959
60- return await readPublicDirPath ( { projectDirPath } ) ;
60+ assert ( false , "Can't locate your index.html file." ) ;
6161 } ) ( ) ;
6262
6363 if ( ! fs . existsSync ( publicDirPath ) ) {
64- console . error ( `Can't locate your public directory, use the --public option to specify it .` ) ;
64+ console . error ( `Can't locate your public directory.` ) ;
6565 process . exit ( - 1 ) ;
6666 }
6767
6868 const dsfrDirPath = pathJoin ( publicDirPath , "dsfr" ) ;
6969
70- if ( fs . existsSync ( dsfrDirPath ) ) {
71- fs . rmSync ( dsfrDirPath , { "recursive" : true , "force" : true } ) ;
70+ const gouvFrDsfrVersion : string = JSON . parse (
71+ fs . readFileSync ( pathJoin ( getProjectRoot ( ) , "package.json" ) ) . toString ( "utf8" )
72+ ) [ "dependencies" ] [ "@gouvfr/dsfr" ] ;
73+
74+ const versionFilePath = pathJoin ( dsfrDirPath , "version.txt" ) ;
75+
76+ early_exit: {
77+ if ( ! fs . existsSync ( dsfrDirPath ) ) {
78+ break early_exit;
79+ }
80+
81+ if ( ! fs . existsSync ( versionFilePath ) ) {
82+ break early_exit;
83+ }
84+
85+ const currentVersion = fs . readFileSync ( versionFilePath ) . toString ( "utf8" ) ;
86+
87+ if ( currentVersion !== gouvFrDsfrVersion ) {
88+ fs . rmSync ( dsfrDirPath , { "recursive" : true , "force" : true } ) ;
89+ break early_exit;
90+ }
91+
92+ console . log (
93+ `DSFR distribution in ${ pathRelative ( process . cwd ( ) , dsfrDirPath ) } is up to date.`
94+ ) ;
95+
96+ return ;
7297 }
7398
7499 fs . mkdirSync ( dsfrDirPath , { "recursive" : true } ) ;
@@ -134,6 +159,33 @@ import { assert } from "tsafe/assert";
134159 }
135160 } ) ;
136161 }
162+
163+ fs . writeFileSync ( versionFilePath , Buffer . from ( gouvFrDsfrVersion , "utf8" ) ) ;
164+
165+ add_version_query_params_in_html_imports: {
166+ const { modifiedHtml } = modifyHtmlHrefs ( {
167+ "html" : fs . readFileSync ( htmlFilePath ) . toString ( "utf8" ) ,
168+ "getModifiedHref" : href => {
169+ if ( ! href . includes ( "/dsfr/" ) ) {
170+ return href ;
171+ }
172+
173+ if ( href . endsWith ( "icons.min.css" ) ) {
174+ return href ;
175+ }
176+
177+ const [ urlWithoutQuery ] = href . split ( "?" ) ;
178+
179+ return `${ urlWithoutQuery } ?v=${ gouvFrDsfrVersion } ` ;
180+ }
181+ } ) ;
182+
183+ if ( htmlFilePath === modifiedHtml ) {
184+ break add_version_query_params_in_html_imports;
185+ }
186+
187+ fs . writeFileSync ( htmlFilePath , Buffer . from ( modifiedHtml , "utf8" ) ) ;
188+ }
137189} ) ( ) ;
138190
139191function readAssetsImportFromDsfrCss ( params : { dsfrSourceCode : string } ) : string [ ] {
0 commit comments