11#!/usr/bin/env node
2- /* eslint-disable @typescript-eslint/no-unused-vars */
2+
3+ /**
4+ * This script is ran with `npx copy-dsfr-to-public`
5+ * It takes two optional arguments:
6+ * - `--projectDir <path>` to specify the project directory. Default to the current working directory.
7+ * 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.
12+ */
313
414import {
515 join as pathJoin ,
@@ -9,101 +19,55 @@ import {
919} from "path" ;
1020import * as fs from "fs" ;
1121import { getProjectRoot } from "./tools/getProjectRoot" ;
12- import { assert } from "tsafe/assert" ;
13- import type { Equals } from "tsafe" ;
22+ import yargsParser from "yargs-parser" ;
23+ import { getAbsoluteAndInOsFormatPath } from "./tools/getAbsoluteAndInOsFormatPath" ;
24+ import { readPublicDirPath } from "./readPublicDirPath" ;
1425
1526( async ( ) => {
16- const projectDirPath = process . cwd ( ) ;
27+ const argv = yargsParser ( process . argv . slice ( 2 ) ) ;
1728
18- const viteConfigFilePath = ( ( ) => {
19- for ( const ext of [ ".js" , ".ts" ] ) {
20- const candidateFilePath = pathJoin ( projectDirPath , `vite.config ${ ext } ` ) ;
29+ const projectDirPath : string = ( ( ) => {
30+ read_from_argv: {
31+ const arg = argv [ "projectDir" ] ;
2132
22- if ( ! fs . existsSync ( candidateFilePath ) ) {
23- continue ;
33+ if ( arg === undefined ) {
34+ break read_from_argv ;
2435 }
2536
26- return candidateFilePath ;
37+ return getAbsoluteAndInOsFormatPath ( { "pathIsh" : arg , "cwd" : process . cwd ( ) } ) ;
2738 }
2839
29- return undefined ;
40+ return process . cwd ( ) ;
3041 } ) ( ) ;
3142
3243 const publicDirPath = await ( async ( ) => {
33- command_line_argument : {
34- const arg = process . argv [ 2 ] ;
44+ read_from_argv : {
45+ const arg = argv [ "publicDir" ] ;
3546
3647 if ( arg === undefined ) {
37- break command_line_argument ;
48+ break read_from_argv ;
3849 }
3950
40- return arg ;
41- }
51+ const publicDirPath = getAbsoluteAndInOsFormatPath ( {
52+ "pathIsh" : arg ,
53+ "cwd" : projectDirPath
54+ } ) ;
4255
43- read_from_vite_config: {
44- if ( viteConfigFilePath === undefined ) {
45- break read_from_vite_config;
56+ if ( ! fs . existsSync ( publicDirPath ) ) {
57+ fs . mkdirSync ( publicDirPath , { "recursive" : true } ) ;
4658 }
4759
48- const viteConfig = fs . readFileSync ( viteConfigFilePath ) . toString ( "utf8" ) ;
49-
50- if ( ! viteConfig . includes ( "publicDir" ) ) {
51- return pathJoin ( projectDirPath , "public" ) ;
52- }
53-
54- const [ , afterPublicDir ] = viteConfig . split ( / \s [ " ' ] ? p u b l i c D i r [ " ' ] ? \s * : / ) ;
55-
56- for ( let indexEnd = 0 ; indexEnd < afterPublicDir . length ; indexEnd ++ ) {
57- const {
58- default : path ,
59- basename,
60- dirname,
61- delimiter,
62- extname,
63- format,
64- isAbsolute,
65- join,
66- normalize,
67- parse,
68- posix,
69- relative,
70- resolve,
71- sep,
72- toNamespacedPath,
73- win32,
74- ...rest
75- } = await import ( "path" ) ;
76- assert < Equals < keyof typeof rest , never >> ( ) ;
77-
78- const part = afterPublicDir
79- . substring ( 0 , indexEnd )
80- . replace ( / _ _ d i r n a m e / g, `"${ projectDirPath } "` ) ;
81-
82- let candidate : string ;
83-
84- try {
85- candidate = eval ( part ) ;
86- } catch {
87- continue ;
88- }
89-
90- if ( typeof candidate !== "string" ) {
91- continue ;
92- }
93-
94- return candidate ;
95- }
96-
97- console . error (
98- `Can't parse the vite configuration please open an issue about it ${ getRepoIssueUrl ( ) } `
99- ) ;
100-
101- process . exit ( - 1 ) ;
60+ return publicDirPath ;
10261 }
10362
104- return pathJoin ( projectDirPath , "public" ) ;
63+ return await readPublicDirPath ( { projectDirPath } ) ;
10564 } ) ( ) ;
10665
66+ if ( ! fs . existsSync ( publicDirPath ) ) {
67+ console . error ( `Can't locate your public directory, use the --public option to specify it.` ) ;
68+ process . exit ( - 1 ) ;
69+ }
70+
10771 edit_gitignore: {
10872 const gitignoreFilePath = pathJoin ( projectDirPath , ".gitignore" ) ;
10973
@@ -128,22 +92,6 @@ import type { Equals } from "tsafe";
12892 ) ;
12993 }
13094
131- if ( ! fs . existsSync ( publicDirPath ) ) {
132- if ( viteConfigFilePath === undefined ) {
133- console . error (
134- [
135- "There is no public/ directory in the current working directory, we don't know your framework" ,
136- "you are not calling this script at the right location or we don't know your React framework" ,
137- `please submit an issue about it here ${ getRepoIssueUrl ( ) } `
138- ] . join ( " " )
139- ) ;
140-
141- process . exit ( - 1 ) ;
142- }
143-
144- fs . mkdirSync ( publicDirPath , { "recursive" : true } ) ;
145- }
146-
14795 const dsfrDirPath = pathJoin ( publicDirPath , "dsfr" ) ;
14896
14997 if ( fs . existsSync ( dsfrDirPath ) ) {
0 commit comments