froxy 0.1.2 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
 - data/.gitignore +2 -1
 - data/Gemfile.lock +1 -1
 - data/README.md +29 -5
 - data/bin/froxy +15 -15
 - data/lib/froxy/esbuild/plugins/alias.js +4 -4
 - data/lib/froxy/esbuild/plugins/css.js +52 -27
 - data/lib/froxy/esbuild/plugins/ignore.js +14 -0
 - data/lib/froxy/esbuild/plugins/images.js +7 -5
 - data/lib/froxy/esbuild/plugins/root.js +5 -3
 - data/lib/froxy/esbuild/utils.js +34 -33
 - data/lib/froxy/proxy.rb +17 -4
 - data/lib/froxy/version.rb +1 -1
 - data/package.json +1 -3
 - data/yarn.lock +0 -4
 - metadata +3 -2
 
    
        checksums.yaml
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            ---
         
     | 
| 
       2 
2 
     | 
    
         
             
            SHA256:
         
     | 
| 
       3 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       4 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 3 
     | 
    
         
            +
              metadata.gz: 926d7b56d53ab4dc548a73b3d8f06c231d0bff8a3ea6ade601b6b4625582c529
         
     | 
| 
      
 4 
     | 
    
         
            +
              data.tar.gz: 50e66435e3858795c88af5f20609e286336fa627e15f2f430ea66a617faf719f
         
     | 
| 
       5 
5 
     | 
    
         
             
            SHA512:
         
     | 
| 
       6 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       7 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 6 
     | 
    
         
            +
              metadata.gz: 65623c88771f9a1654d2612fa31954adc8f35ee7152575e8c9b14aef146a77acb63715b2f4ae37ee807ec13faea7ad02a3a6c9941ea06b7cfb39268e5d7e3990
         
     | 
| 
      
 7 
     | 
    
         
            +
              data.tar.gz: f2a78301922e4dd6fbf505dc3c0a83bf94a7a6878bfc2c8d7109b0111e813367bc6425fd661b3bd1ad9b927188aeaf5c1f5130010ddcb2631a0827aaac7cbfdb
         
     | 
    
        data/.gitignore
    CHANGED
    
    
    
        data/Gemfile.lock
    CHANGED
    
    
    
        data/README.md
    CHANGED
    
    | 
         @@ -24,6 +24,7 @@ production mode will likely include pre-built cachable assets. 
     | 
|
| 
       24 
24 
     | 
    
         
             
            - Code Splitting.
         
     | 
| 
       25 
25 
     | 
    
         
             
            - Source Maps.
         
     | 
| 
       26 
26 
     | 
    
         
             
            - Minification.
         
     | 
| 
      
 27 
     | 
    
         
            +
            - PostCSS support.
         
     | 
| 
       27 
28 
     | 
    
         | 
| 
       28 
29 
     | 
    
         
             
            ## Roadmap
         
     | 
| 
       29 
30 
     | 
    
         | 
| 
         @@ -32,7 +33,6 @@ In no particular order: 
     | 
|
| 
       32 
33 
     | 
    
         
             
            - Pre-bundling / cached assets.
         
     | 
| 
       33 
34 
     | 
    
         
             
            - Typescript.
         
     | 
| 
       34 
35 
     | 
    
         
             
            - CSS Modules.
         
     | 
| 
       35 
     | 
    
         
            -
            - PostCSS support.
         
     | 
| 
       36 
36 
     | 
    
         | 
| 
       37 
37 
     | 
    
         
             
            ## Installation
         
     | 
| 
       38 
38 
     | 
    
         | 
| 
         @@ -82,6 +82,12 @@ imported from JS will result in the requested CSS injected into an HTML `link` t 
     | 
|
| 
       82 
82 
     | 
    
         
             
            import '/my/styles.css'
         
     | 
| 
       83 
83 
     | 
    
         
             
            ```
         
     | 
| 
       84 
84 
     | 
    
         | 
| 
      
 85 
     | 
    
         
            +
            ### PostCSS
         
     | 
| 
      
 86 
     | 
    
         
            +
             
     | 
| 
      
 87 
     | 
    
         
            +
            [PostCSS](https://postcss.org/) is supported out of the box. If any
         
     | 
| 
      
 88 
     | 
    
         
            +
            [PostCSS config](https://github.com/postcss/postcss-load-config) is found in your project, then any
         
     | 
| 
      
 89 
     | 
    
         
            +
            local CSS (not from node modules) will be parsed with PostCSS.
         
     | 
| 
      
 90 
     | 
    
         
            +
             
     | 
| 
       85 
91 
     | 
    
         
             
            ### Images/Fonts, etc.
         
     | 
| 
       86 
92 
     | 
    
         | 
| 
       87 
93 
     | 
    
         
             
            When called directly, images are served directly - avoiding a call to esbuild. But when an image is
         
     | 
| 
         @@ -153,10 +159,12 @@ There are a few options that you can customise, and they are all defined in your 
     | 
|
| 
       153 
159 
     | 
    
         
             
            example:
         
     | 
| 
       154 
160 
     | 
    
         | 
| 
       155 
161 
     | 
    
         
             
            ```json
         
     | 
| 
       156 
     | 
    
         
            -
             
     | 
| 
       157 
     | 
    
         
            -
              " 
     | 
| 
       158 
     | 
    
         
            -
             
     | 
| 
       159 
     | 
    
         
            -
                " 
     | 
| 
      
 162 
     | 
    
         
            +
            {
         
     | 
| 
      
 163 
     | 
    
         
            +
              "froxy": {
         
     | 
| 
      
 164 
     | 
    
         
            +
                "target": [],
         
     | 
| 
      
 165 
     | 
    
         
            +
                "aliases": {
         
     | 
| 
      
 166 
     | 
    
         
            +
                  "_": "lodash"
         
     | 
| 
      
 167 
     | 
    
         
            +
                }
         
     | 
| 
       160 
168 
     | 
    
         
             
              }
         
     | 
| 
       161 
169 
     | 
    
         
             
            }
         
     | 
| 
       162 
170 
     | 
    
         
             
            ```
         
     | 
| 
         @@ -185,6 +193,22 @@ See esbuild's documentation on [minification](https://esbuild.github.io/api/#min 
     | 
|
| 
       185 
193 
     | 
    
         | 
| 
       186 
194 
     | 
    
         
             
            See esbuild's documentation on [sourcemap](https://esbuild.github.io/api/#sourcemap).
         
     | 
| 
       187 
195 
     | 
    
         | 
| 
      
 196 
     | 
    
         
            +
            #### `ignore`
         
     | 
| 
      
 197 
     | 
    
         
            +
             
     | 
| 
      
 198 
     | 
    
         
            +
            A regular expression matching paths that should be ignored and not built or bundled.
         
     | 
| 
      
 199 
     | 
    
         
            +
             
     | 
| 
      
 200 
     | 
    
         
            +
            Example:
         
     | 
| 
      
 201 
     | 
    
         
            +
             
     | 
| 
      
 202 
     | 
    
         
            +
            Ignore all paths starting with "/fonts/":
         
     | 
| 
      
 203 
     | 
    
         
            +
             
     | 
| 
      
 204 
     | 
    
         
            +
            ```json
         
     | 
| 
      
 205 
     | 
    
         
            +
            {
         
     | 
| 
      
 206 
     | 
    
         
            +
              "froxy": {
         
     | 
| 
      
 207 
     | 
    
         
            +
                "ignore": "^\\/fonts\\/"
         
     | 
| 
      
 208 
     | 
    
         
            +
              }
         
     | 
| 
      
 209 
     | 
    
         
            +
            }
         
     | 
| 
      
 210 
     | 
    
         
            +
            ```
         
     | 
| 
      
 211 
     | 
    
         
            +
             
     | 
| 
       188 
212 
     | 
    
         
             
            ## Development
         
     | 
| 
       189 
213 
     | 
    
         | 
| 
       190 
214 
     | 
    
         
             
            After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
         
     | 
    
        data/bin/froxy
    CHANGED
    
    | 
         @@ -1,27 +1,25 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            #!/usr/bin/env node
         
     | 
| 
       2 
2 
     | 
    
         | 
| 
       3 
     | 
    
         
            -
            const  
     | 
| 
      
 3 
     | 
    
         
            +
            const [, , cwd, entryPoint] = process.argv
         
     | 
| 
       4 
4 
     | 
    
         | 
| 
       5 
     | 
    
         
            -
            const  
     | 
| 
      
 5 
     | 
    
         
            +
            const esbuild = require(require.resolve('esbuild', { paths: [cwd] }))
         
     | 
| 
       6 
6 
     | 
    
         | 
| 
       7 
7 
     | 
    
         
             
            const { resolve, config } = require('../lib/froxy/esbuild/utils')
         
     | 
| 
       8 
8 
     | 
    
         
             
            const loadStylePlugin = require('../lib/froxy/esbuild/plugins/load_style')
         
     | 
| 
       9 
     | 
    
         
            -
            const  
     | 
| 
       10 
     | 
    
         
            -
            const aliasPlugin = require('../lib/froxy/esbuild/plugins/alias') 
     | 
| 
       11 
     | 
    
         
            -
            const cssPlugin = require('../lib/froxy/esbuild/plugins/css') 
     | 
| 
       12 
     | 
    
         
            -
            const imagesPlugin = require('../lib/froxy/esbuild/plugins/images') 
     | 
| 
       13 
     | 
    
         
            -
            const rootPlugin = require('../lib/froxy/esbuild/plugins/root') 
     | 
| 
       14 
     | 
    
         
            -
             
     | 
| 
       15 
     | 
    
         
            -
            const conf = config(absWorkingDir)
         
     | 
| 
      
 9 
     | 
    
         
            +
            const ignorePlugin = require('../lib/froxy/esbuild/plugins/ignore')
         
     | 
| 
      
 10 
     | 
    
         
            +
            const aliasPlugin = require('../lib/froxy/esbuild/plugins/alias')
         
     | 
| 
      
 11 
     | 
    
         
            +
            const cssPlugin = require('../lib/froxy/esbuild/plugins/css')
         
     | 
| 
      
 12 
     | 
    
         
            +
            const imagesPlugin = require('../lib/froxy/esbuild/plugins/images')
         
     | 
| 
      
 13 
     | 
    
         
            +
            const rootPlugin = require('../lib/froxy/esbuild/plugins/root')
         
     | 
| 
       16 
14 
     | 
    
         | 
| 
       17 
15 
     | 
    
         
             
            const buildOptions = {
         
     | 
| 
       18 
     | 
    
         
            -
              absWorkingDir,
         
     | 
| 
      
 16 
     | 
    
         
            +
              absWorkingDir: cwd,
         
     | 
| 
       19 
17 
     | 
    
         
             
              entryPoints: [entryPoint],
         
     | 
| 
       20 
18 
     | 
    
         
             
              bundle: true,
         
     | 
| 
       21 
     | 
    
         
            -
              target:  
     | 
| 
       22 
     | 
    
         
            -
              minify:  
     | 
| 
       23 
     | 
    
         
            -
              inject:  
     | 
| 
       24 
     | 
    
         
            -
              sourcemap:  
     | 
| 
      
 19 
     | 
    
         
            +
              target: config.target,
         
     | 
| 
      
 20 
     | 
    
         
            +
              minify: config.minify,
         
     | 
| 
      
 21 
     | 
    
         
            +
              inject: config.inject,
         
     | 
| 
      
 22 
     | 
    
         
            +
              sourcemap: config.sourcemap,
         
     | 
| 
       25 
23 
     | 
    
         
             
              format: 'esm',
         
     | 
| 
       26 
24 
     | 
    
         
             
              splitting: true,
         
     | 
| 
       27 
25 
     | 
    
         
             
              outdir: 'public/froxy/build',
         
     | 
| 
         @@ -32,9 +30,11 @@ const buildOptions = { 
     | 
|
| 
       32 
30 
     | 
    
         
             
                'process.env.NODE_ENV': `"${process.env.NODE_ENV || 'development'}"`,
         
     | 
| 
       33 
31 
     | 
    
         
             
                'process.env.RAILS_ENV': `"${process.env.RAILS_ENV || 'development'}"`
         
     | 
| 
       34 
32 
     | 
    
         
             
              },
         
     | 
| 
       35 
     | 
    
         
            -
              plugins: [aliasPlugin,  
     | 
| 
      
 33 
     | 
    
         
            +
              plugins: [aliasPlugin, loadStylePlugin, cssPlugin, imagesPlugin, rootPlugin]
         
     | 
| 
       36 
34 
     | 
    
         
             
            }
         
     | 
| 
       37 
35 
     | 
    
         | 
| 
      
 36 
     | 
    
         
            +
            config.ignore && buildOptions.plugins.unshift(ignorePlugin)
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
       38 
38 
     | 
    
         
             
            esbuild.build(buildOptions).catch(() => {
         
     | 
| 
       39 
39 
     | 
    
         
             
              process.exit(1)
         
     | 
| 
       40 
40 
     | 
    
         
             
            })
         
     | 
| 
         @@ -17,14 +17,14 @@ const { resolve, config } = require('../utils') 
     | 
|
| 
       17 
17 
     | 
    
         
             
            //  import { map } from '_'
         
     | 
| 
       18 
18 
     | 
    
         
             
            //  import axios from 'myaxios'
         
     | 
| 
       19 
19 
     | 
    
         
             
            //
         
     | 
| 
       20 
     | 
    
         
            -
            module.exports =  
     | 
| 
      
 20 
     | 
    
         
            +
            module.exports = {
         
     | 
| 
       21 
21 
     | 
    
         
             
              name: 'froxy.alias',
         
     | 
| 
       22 
22 
     | 
    
         
             
              setup(build) {
         
     | 
| 
       23 
23 
     | 
    
         
             
                let map = []
         
     | 
| 
       24 
24 
     | 
    
         
             
                let aliases = {}
         
     | 
| 
       25 
25 
     | 
    
         | 
| 
       26 
26 
     | 
    
         
             
                try {
         
     | 
| 
       27 
     | 
    
         
            -
                  map = config 
     | 
| 
      
 27 
     | 
    
         
            +
                  map = config.aliases
         
     | 
| 
       28 
28 
     | 
    
         
             
                  aliases = Object.keys(map)
         
     | 
| 
       29 
29 
     | 
    
         
             
                } catch {
         
     | 
| 
       30 
30 
     | 
    
         
             
                  // Fail silently, as there is no package.json.
         
     | 
| 
         @@ -35,11 +35,11 @@ module.exports = absWorkingDir => ({ 
     | 
|
| 
       35 
35 
     | 
    
         
             
                  const re = new RegExp(`^${aliases.map(x => escapeRegExp(x)).join('|')}$`)
         
     | 
| 
       36 
36 
     | 
    
         | 
| 
       37 
37 
     | 
    
         
             
                  build.onResolve({ filter: re }, async ({ resolveDir, path }) => ({
         
     | 
| 
       38 
     | 
    
         
            -
                    path: await resolve( 
     | 
| 
      
 38 
     | 
    
         
            +
                    path: await resolve(resolveDir, map[path], { fallbackToEsbuild: true })
         
     | 
| 
       39 
39 
     | 
    
         
             
                  }))
         
     | 
| 
       40 
40 
     | 
    
         
             
                }
         
     | 
| 
       41 
41 
     | 
    
         
             
              }
         
     | 
| 
       42 
     | 
    
         
            -
            } 
     | 
| 
      
 42 
     | 
    
         
            +
            }
         
     | 
| 
       43 
43 
     | 
    
         | 
| 
       44 
44 
     | 
    
         
             
            function escapeRegExp(string) {
         
     | 
| 
       45 
45 
     | 
    
         
             
              // $& means the whole matched string
         
     | 
| 
         @@ -3,21 +3,24 @@ const fs = require('fs') 
     | 
|
| 
       3 
3 
     | 
    
         | 
| 
       4 
4 
     | 
    
         
             
            const { resolve } = require('../utils')
         
     | 
| 
       5 
5 
     | 
    
         | 
| 
       6 
     | 
    
         
            -
             
     | 
| 
      
 6 
     | 
    
         
            +
            const [, , cwd] = process.argv
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
            module.exports = {
         
     | 
| 
       7 
9 
     | 
    
         
             
              name: 'froxy.css',
         
     | 
| 
       8 
10 
     | 
    
         
             
              setup(build) {
         
     | 
| 
       9 
     | 
    
         
            -
                 
     | 
| 
       10 
     | 
    
         
            -
             
     | 
| 
       11 
     | 
    
         
            -
                  let resolvedPath = resolve(absWorkingDir, args.resolveDir, args.path)
         
     | 
| 
      
 11 
     | 
    
         
            +
                build.onResolve({ filter: /\.css$/ }, async args => {
         
     | 
| 
      
 12 
     | 
    
         
            +
                  let resolvedPath = resolve(args.resolveDir, args.path)
         
     | 
| 
       12 
13 
     | 
    
         | 
| 
      
 14 
     | 
    
         
            +
                  // Resolved path is not relative or absolute, so we assume it's a node module, and attempt to
         
     | 
| 
      
 15 
     | 
    
         
            +
                  // resolve it from node_modules.
         
     | 
| 
       13 
16 
     | 
    
         
             
                  if (resolvedPath === args.path) {
         
     | 
| 
       14 
     | 
    
         
            -
                    const nodeModulesDir = path.join( 
     | 
| 
      
 17 
     | 
    
         
            +
                    const nodeModulesDir = path.join(cwd, 'node_modules')
         
     | 
| 
       15 
18 
     | 
    
         | 
| 
       16 
19 
     | 
    
         
             
                    try {
         
     | 
| 
       17 
     | 
    
         
            -
                      fs. 
     | 
| 
      
 20 
     | 
    
         
            +
                      await fs.promises.access(nodeModulesDir, fs.constants.R_OK)
         
     | 
| 
       18 
21 
     | 
    
         
             
                      resolvedPath = path.join(nodeModulesDir, args.path)
         
     | 
| 
       19 
22 
     | 
    
         
             
                    } catch {
         
     | 
| 
       20 
     | 
    
         
            -
                      //  
     | 
| 
      
 23 
     | 
    
         
            +
                      // Fail siently
         
     | 
| 
       21 
24 
     | 
    
         
             
                    }
         
     | 
| 
       22 
25 
     | 
    
         
             
                  }
         
     | 
| 
       23 
26 
     | 
    
         | 
| 
         @@ -27,24 +30,46 @@ module.exports = absWorkingDir => ({ 
     | 
|
| 
       27 
30 
     | 
    
         
             
                  }
         
     | 
| 
       28 
31 
     | 
    
         
             
                })
         
     | 
| 
       29 
32 
     | 
    
         | 
| 
       30 
     | 
    
         
            -
                //  
     | 
| 
       31 
     | 
    
         
            -
                 
     | 
| 
       32 
     | 
    
         
            -
             
     | 
| 
       33 
     | 
    
         
            -
             
     | 
| 
       34 
     | 
    
         
            -
             
     | 
| 
       35 
     | 
    
         
            -
             
     | 
| 
       36 
     | 
    
         
            -
             
     | 
| 
       37 
     | 
    
         
            -
             
     | 
| 
       38 
     | 
    
         
            -
             
     | 
| 
       39 
     | 
    
         
            -
             
     | 
| 
       40 
     | 
    
         
            -
             
     | 
| 
       41 
     | 
    
         
            -
             
     | 
| 
       42 
     | 
    
         
            -
             
     | 
| 
       43 
     | 
    
         
            -
             
     | 
| 
       44 
     | 
    
         
            -
             
     | 
| 
       45 
     | 
    
         
            -
                     
     | 
| 
       46 
     | 
    
         
            -
             
     | 
| 
       47 
     | 
    
         
            -
             
     | 
| 
       48 
     | 
    
         
            -
             
     | 
| 
      
 33 
     | 
    
         
            +
                // When CSS is requested directly - and not imported from JS.
         
     | 
| 
      
 34 
     | 
    
         
            +
                build.onLoad({ filter: /\.css$/, namespace: 'file' }, async args => {
         
     | 
| 
      
 35 
     | 
    
         
            +
                  // Don't parse node modules with postcss.
         
     | 
| 
      
 36 
     | 
    
         
            +
                  if (args.path.includes('node_modules')) return
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
      
 38 
     | 
    
         
            +
                  const postcssrc = require(require.resolve('postcss-load-config', { paths: [cwd] }))
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
                  let postcssConfig
         
     | 
| 
      
 41 
     | 
    
         
            +
                  try {
         
     | 
| 
      
 42 
     | 
    
         
            +
                    postcssConfig = await postcssrc({ cwd: cwd }, cwd)
         
     | 
| 
      
 43 
     | 
    
         
            +
                  } catch {
         
     | 
| 
      
 44 
     | 
    
         
            +
                    // Fail siently
         
     | 
| 
      
 45 
     | 
    
         
            +
                  }
         
     | 
| 
      
 46 
     | 
    
         
            +
             
     | 
| 
      
 47 
     | 
    
         
            +
                  if (postcssConfig) {
         
     | 
| 
      
 48 
     | 
    
         
            +
                    const postcss = require(require.resolve('postcss', { paths: [cwd] }))
         
     | 
| 
      
 49 
     | 
    
         
            +
                    const css = await fs.promises.readFile(args.path, 'utf8')
         
     | 
| 
      
 50 
     | 
    
         
            +
             
     | 
| 
      
 51 
     | 
    
         
            +
                    const result = await postcss(postcssConfig.plugins).process(css, {
         
     | 
| 
      
 52 
     | 
    
         
            +
                      ...postcssConfig.options,
         
     | 
| 
      
 53 
     | 
    
         
            +
                      from: args.path
         
     | 
| 
      
 54 
     | 
    
         
            +
                    })
         
     | 
| 
      
 55 
     | 
    
         
            +
             
     | 
| 
      
 56 
     | 
    
         
            +
                    return {
         
     | 
| 
      
 57 
     | 
    
         
            +
                      contents: result.css,
         
     | 
| 
      
 58 
     | 
    
         
            +
                      loader: 'css'
         
     | 
| 
      
 59 
     | 
    
         
            +
                    }
         
     | 
| 
      
 60 
     | 
    
         
            +
                  }
         
     | 
| 
      
 61 
     | 
    
         
            +
                })
         
     | 
| 
      
 62 
     | 
    
         
            +
             
     | 
| 
      
 63 
     | 
    
         
            +
                // When CSS is imported from JS, the CSS is injected into the DOM as a <link> tag. The browser
         
     | 
| 
      
 64 
     | 
    
         
            +
                // then loads the CSS file as it usually would.
         
     | 
| 
      
 65 
     | 
    
         
            +
                build.onLoad({ filter: /\.css$/, namespace: 'cssFromJs' }, args => {
         
     | 
| 
      
 66 
     | 
    
         
            +
                  return {
         
     | 
| 
      
 67 
     | 
    
         
            +
                    contents: `
         
     | 
| 
      
 68 
     | 
    
         
            +
                      import loadStyle from 'loadStyle'
         
     | 
| 
      
 69 
     | 
    
         
            +
                      loadStyle("${args.path.slice(cwd.length)}")
         
     | 
| 
      
 70 
     | 
    
         
            +
                    `,
         
     | 
| 
      
 71 
     | 
    
         
            +
                    loader: 'js'
         
     | 
| 
      
 72 
     | 
    
         
            +
                  }
         
     | 
| 
      
 73 
     | 
    
         
            +
                })
         
     | 
| 
       49 
74 
     | 
    
         
             
              }
         
     | 
| 
       50 
     | 
    
         
            -
            } 
     | 
| 
      
 75 
     | 
    
         
            +
            }
         
     | 
| 
         @@ -0,0 +1,14 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            const path = require('path')
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            const { config } = require('../utils')
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            if (!config.ignore) return
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
            module.exports = {
         
     | 
| 
      
 8 
     | 
    
         
            +
              name: 'froxy.ignore',
         
     | 
| 
      
 9 
     | 
    
         
            +
              setup(build) {
         
     | 
| 
      
 10 
     | 
    
         
            +
                build.onResolve({ filter: new RegExp(config.ignore) }, args => ({
         
     | 
| 
      
 11 
     | 
    
         
            +
                  external: true
         
     | 
| 
      
 12 
     | 
    
         
            +
                }))
         
     | 
| 
      
 13 
     | 
    
         
            +
              }
         
     | 
| 
      
 14 
     | 
    
         
            +
            }
         
     | 
| 
         @@ -1,6 +1,8 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            const { resolve } = require('../utils')
         
     | 
| 
       2 
2 
     | 
    
         | 
| 
       3 
     | 
    
         
            -
             
     | 
| 
      
 3 
     | 
    
         
            +
            const [, , cwd] = process.argv
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            module.exports = {
         
     | 
| 
       4 
6 
     | 
    
         
             
              name: 'froxy.images',
         
     | 
| 
       5 
7 
     | 
    
         
             
              setup(build) {
         
     | 
| 
       6 
8 
     | 
    
         
             
                const IMAGE_TYPES = /\.(png|gif|jpe?g|svg|ico|webp|avif)$/
         
     | 
| 
         @@ -10,11 +12,11 @@ module.exports = absWorkingDir => ({ 
     | 
|
| 
       10 
12 
     | 
    
         
             
                // exported using the default export. Including an image in CSS using `url()`, will simply
         
     | 
| 
       11 
13 
     | 
    
         
             
                // return the relative URL of the image.
         
     | 
| 
       12 
14 
     | 
    
         
             
                build.onResolve({ filter: IMAGE_TYPES }, args => {
         
     | 
| 
       13 
     | 
    
         
            -
                  const resolvedPath = resolve( 
     | 
| 
      
 15 
     | 
    
         
            +
                  const resolvedPath = resolve(args.resolveDir, args.path)
         
     | 
| 
       14 
16 
     | 
    
         | 
| 
       15 
17 
     | 
    
         
             
                  if (args.importer.endsWith('.css')) {
         
     | 
| 
       16 
18 
     | 
    
         
             
                    return {
         
     | 
| 
       17 
     | 
    
         
            -
                      path: resolvedPath.slice( 
     | 
| 
      
 19 
     | 
    
         
            +
                      path: resolvedPath.slice(cwd.length),
         
     | 
| 
       18 
20 
     | 
    
         
             
                      external: true
         
     | 
| 
       19 
21 
     | 
    
         
             
                    }
         
     | 
| 
       20 
22 
     | 
    
         
             
                  } else {
         
     | 
| 
         @@ -24,9 +26,9 @@ module.exports = absWorkingDir => ({ 
     | 
|
| 
       24 
26 
     | 
    
         | 
| 
       25 
27 
     | 
    
         
             
                build.onLoad({ filter: IMAGE_TYPES }, args => {
         
     | 
| 
       26 
28 
     | 
    
         
             
                  return {
         
     | 
| 
       27 
     | 
    
         
            -
                    contents: `export default '${args.path.slice( 
     | 
| 
      
 29 
     | 
    
         
            +
                    contents: `export default '${args.path.slice(cwd.length)}';`,
         
     | 
| 
       28 
30 
     | 
    
         
             
                    loader: 'js'
         
     | 
| 
       29 
31 
     | 
    
         
             
                  }
         
     | 
| 
       30 
32 
     | 
    
         
             
                })
         
     | 
| 
       31 
33 
     | 
    
         
             
              }
         
     | 
| 
       32 
     | 
    
         
            -
            } 
     | 
| 
      
 34 
     | 
    
         
            +
            }
         
     | 
| 
         @@ -1,6 +1,8 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            const path = require('path')
         
     | 
| 
       2 
2 
     | 
    
         | 
| 
       3 
     | 
    
         
            -
             
     | 
| 
      
 3 
     | 
    
         
            +
            const [, , cwd] = process.argv
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            module.exports = {
         
     | 
| 
       4 
6 
     | 
    
         
             
              name: 'froxy.root',
         
     | 
| 
       5 
7 
     | 
    
         
             
              setup(build) {
         
     | 
| 
       6 
8 
     | 
    
         
             
                // Resolves paths starting with a `/` to the Rails root.
         
     | 
| 
         @@ -8,7 +10,7 @@ module.exports = absWorkingDir => ({ 
     | 
|
| 
       8 
10 
     | 
    
         
             
                // Example:
         
     | 
| 
       9 
11 
     | 
    
         
             
                //  import '/my/lib.js' //-> import '{Rails.root}/my/lib.js'
         
     | 
| 
       10 
12 
     | 
    
         
             
                build.onResolve({ filter: /^\// }, args => ({
         
     | 
| 
       11 
     | 
    
         
            -
                  path: path.join( 
     | 
| 
      
 13 
     | 
    
         
            +
                  path: path.join(cwd, args.path)
         
     | 
| 
       12 
14 
     | 
    
         
             
                }))
         
     | 
| 
       13 
15 
     | 
    
         
             
              }
         
     | 
| 
       14 
     | 
    
         
            -
            } 
     | 
| 
      
 16 
     | 
    
         
            +
            }
         
     | 
    
        data/lib/froxy/esbuild/utils.js
    CHANGED
    
    | 
         @@ -1,39 +1,42 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            const path = require('path')
         
     | 
| 
       2 
2 
     | 
    
         
             
            const fs = require('fs')
         
     | 
| 
       3 
     | 
    
         
            -
            const esbuild = require(require.resolve('esbuild', { paths: [process.cwd()] }))
         
     | 
| 
       4 
3 
     | 
    
         | 
| 
       5 
     | 
    
         
            -
             
     | 
| 
       6 
     | 
    
         
            -
            const resolve = (absWorkingDir, b, p, options = {}) => {
         
     | 
| 
       7 
     | 
    
         
            -
              options = {
         
     | 
| 
       8 
     | 
    
         
            -
                fallbackToEsbuild: false,
         
     | 
| 
       9 
     | 
    
         
            -
                ...options
         
     | 
| 
       10 
     | 
    
         
            -
              }
         
     | 
| 
      
 4 
     | 
    
         
            +
            const [, , cwd] = process.argv
         
     | 
| 
       11 
5 
     | 
    
         | 
| 
       12 
     | 
    
         
            -
             
     | 
| 
       13 
     | 
    
         
            -
               
     | 
| 
      
 6 
     | 
    
         
            +
            module.exports = {
         
     | 
| 
      
 7 
     | 
    
         
            +
              // Resolve the given path (`p`) to an absolute path.
         
     | 
| 
      
 8 
     | 
    
         
            +
              resolve: (b, p, options = {}) => {
         
     | 
| 
      
 9 
     | 
    
         
            +
                options = {
         
     | 
| 
      
 10 
     | 
    
         
            +
                  fallbackToEsbuild: false,
         
     | 
| 
      
 11 
     | 
    
         
            +
                  ...options
         
     | 
| 
      
 12 
     | 
    
         
            +
                }
         
     | 
| 
       14 
13 
     | 
    
         | 
| 
       15 
     | 
    
         
            -
             
     | 
| 
       16 
     | 
    
         
            -
                 
     | 
| 
       17 
     | 
    
         
            -
              }
         
     | 
| 
      
 14 
     | 
    
         
            +
                if (p.startsWith('/')) return path.resolve(cwd, p.slice(1))
         
     | 
| 
      
 15 
     | 
    
         
            +
                if (p.startsWith('.')) return path.resolve(b, p)
         
     | 
| 
       18 
16 
     | 
    
         | 
| 
       19 
     | 
    
         
            -
             
     | 
| 
       20 
     | 
    
         
            -
             
     | 
| 
      
 17 
     | 
    
         
            +
                if (options.fallbackToEsbuild) {
         
     | 
| 
      
 18 
     | 
    
         
            +
                  return (async () => await esbuildResolve(p, b))()
         
     | 
| 
      
 19 
     | 
    
         
            +
                }
         
     | 
| 
       21 
20 
     | 
    
         | 
| 
       22 
     | 
    
         
            -
             
     | 
| 
       23 
     | 
    
         
            -
               
     | 
| 
       24 
     | 
    
         
            -
              const defaultConfig = {
         
     | 
| 
       25 
     | 
    
         
            -
                minify: false,
         
     | 
| 
       26 
     | 
    
         
            -
                sourcemap: true
         
     | 
| 
       27 
     | 
    
         
            -
              }
         
     | 
| 
      
 21 
     | 
    
         
            +
                return p
         
     | 
| 
      
 22 
     | 
    
         
            +
              },
         
     | 
| 
       28 
23 
     | 
    
         | 
| 
       29 
     | 
    
         
            -
               
     | 
| 
       30 
     | 
    
         
            -
                 
     | 
| 
       31 
     | 
    
         
            -
                 
     | 
| 
       32 
     | 
    
         
            -
             
     | 
| 
       33 
     | 
    
         
            -
             
     | 
| 
       34 
     | 
    
         
            -
             
     | 
| 
      
 24 
     | 
    
         
            +
              get config() {
         
     | 
| 
      
 25 
     | 
    
         
            +
                let packageConfig = {}
         
     | 
| 
      
 26 
     | 
    
         
            +
                const defaultConfig = {
         
     | 
| 
      
 27 
     | 
    
         
            +
                  minify: false,
         
     | 
| 
      
 28 
     | 
    
         
            +
                  sourcemap: true
         
     | 
| 
      
 29 
     | 
    
         
            +
                }
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
                try {
         
     | 
| 
      
 32 
     | 
    
         
            +
                  const pkg = fs.readFileSync(path.join(cwd, 'package.json'))
         
     | 
| 
      
 33 
     | 
    
         
            +
                  packageConfig = JSON.parse(pkg).froxy
         
     | 
| 
      
 34 
     | 
    
         
            +
                } catch {
         
     | 
| 
      
 35 
     | 
    
         
            +
                  // Fail silently, as there is no package.json.
         
     | 
| 
      
 36 
     | 
    
         
            +
                }
         
     | 
| 
       35 
37 
     | 
    
         | 
| 
       36 
     | 
    
         
            -
             
     | 
| 
      
 38 
     | 
    
         
            +
                return { ...defaultConfig, ...packageConfig }
         
     | 
| 
      
 39 
     | 
    
         
            +
              }
         
     | 
| 
       37 
40 
     | 
    
         
             
            }
         
     | 
| 
       38 
41 
     | 
    
         | 
| 
       39 
42 
     | 
    
         
             
            // Resolves a module using esbuild module resolution.
         
     | 
| 
         @@ -41,9 +44,12 @@ const config = absWorkingDir => { 
     | 
|
| 
       41 
44 
     | 
    
         
             
            // @param {string} id Module to resolve
         
     | 
| 
       42 
45 
     | 
    
         
             
            // @param {string} [resolveDir] The directory to resolve from
         
     | 
| 
       43 
46 
     | 
    
         
             
            // @returns {string} The resolved module
         
     | 
| 
       44 
     | 
    
         
            -
            async function esbuildResolve(id, resolveDir 
     | 
| 
      
 47 
     | 
    
         
            +
            async function esbuildResolve(id, resolveDir) {
         
     | 
| 
      
 48 
     | 
    
         
            +
              const esbuild = require(require.resolve('esbuild', { paths: [cwd] }))
         
     | 
| 
      
 49 
     | 
    
         
            +
             
     | 
| 
       45 
50 
     | 
    
         
             
              let _resolve
         
     | 
| 
       46 
51 
     | 
    
         
             
              const resolvedPromise = new Promise(resolve => (_resolve = resolve))
         
     | 
| 
      
 52 
     | 
    
         
            +
             
     | 
| 
       47 
53 
     | 
    
         
             
              return Promise.race([
         
     | 
| 
       48 
54 
     | 
    
         
             
                resolvedPromise,
         
     | 
| 
       49 
55 
     | 
    
         
             
                esbuild
         
     | 
| 
         @@ -76,8 +82,3 @@ async function esbuildResolve(id, resolveDir = process.cwd()) { 
     | 
|
| 
       76 
82 
     | 
    
         
             
                  .then(() => id)
         
     | 
| 
       77 
83 
     | 
    
         
             
              ])
         
     | 
| 
       78 
84 
     | 
    
         
             
            }
         
     | 
| 
       79 
     | 
    
         
            -
             
     | 
| 
       80 
     | 
    
         
            -
            module.exports = {
         
     | 
| 
       81 
     | 
    
         
            -
              resolve,
         
     | 
| 
       82 
     | 
    
         
            -
              config
         
     | 
| 
       83 
     | 
    
         
            -
            }
         
     | 
    
        data/lib/froxy/proxy.rb
    CHANGED
    
    | 
         @@ -2,13 +2,16 @@ 
     | 
|
| 
       2 
2 
     | 
    
         | 
| 
       3 
3 
     | 
    
         
             
            require 'open3'
         
     | 
| 
       4 
4 
     | 
    
         
             
            require 'rack/utils'
         
     | 
| 
      
 5 
     | 
    
         
            +
            require 'active_support/benchmarkable'
         
     | 
| 
       5 
6 
     | 
    
         | 
| 
       6 
7 
     | 
    
         
             
            # Proxies files to esbuild.
         
     | 
| 
       7 
8 
     | 
    
         
             
            module Froxy
         
     | 
| 
       8 
9 
     | 
    
         
             
              class Proxy
         
     | 
| 
      
 10 
     | 
    
         
            +
                include ActiveSupport::Benchmarkable
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
       9 
12 
     | 
    
         
             
                BUILD_PATH = 'public/froxy/build'
         
     | 
| 
       10 
13 
     | 
    
         
             
                CLI = File.expand_path('../../bin/froxy', __dir__)
         
     | 
| 
       11 
     | 
    
         
            -
                 
     | 
| 
      
 14 
     | 
    
         
            +
                FALLTHRU_TYPES = /\.(png|gif|jpeg|jpg|svg|ico|webp|avif)$/i.freeze
         
     | 
| 
       12 
15 
     | 
    
         
             
                FILE_EXT_MAP = {
         
     | 
| 
       13 
16 
     | 
    
         
             
                  '.jsx' => '.js'
         
     | 
| 
       14 
17 
     | 
    
         
             
                }.freeze
         
     | 
| 
         @@ -25,7 +28,7 @@ module Froxy 
     | 
|
| 
       25 
28 
     | 
    
         | 
| 
       26 
29 
     | 
    
         
             
                  if req.get? || req.head?
         
     | 
| 
       27 
30 
     | 
    
         
             
                    # Let images through.
         
     | 
| 
       28 
     | 
    
         
            -
                    return @file_server.call(env) if  
     | 
| 
      
 31 
     | 
    
         
            +
                    return @file_server.call(env) if FALLTHRU_TYPES.match?(path_info)
         
     | 
| 
       29 
32 
     | 
    
         | 
| 
       30 
33 
     | 
    
         
             
                    # Let JS sourcemaps through.
         
     | 
| 
       31 
34 
     | 
    
         
             
                    return @build_file_server.call(env) if /\.js\.map$/i.match?(path_info)
         
     | 
| 
         @@ -34,9 +37,12 @@ module Froxy 
     | 
|
| 
       34 
37 
     | 
    
         
             
                    if /\.(js|jsx|css)$/i.match?(path_info)
         
     | 
| 
       35 
38 
     | 
    
         
             
                      return unless (path = clean_path(path_info))
         
     | 
| 
       36 
39 
     | 
    
         
             
                      return [404, {}, []] unless file_readable?(path)
         
     | 
| 
      
 40 
     | 
    
         
            +
             
     | 
| 
       37 
41 
     | 
    
         
             
                      return @file_server.call(env) unless Rails.application.config.froxy.use_esbuild
         
     | 
| 
       38 
42 
     | 
    
         | 
| 
       39 
     | 
    
         
            -
                      return  
     | 
| 
      
 43 
     | 
    
         
            +
                      return benchmark logging_message(req) do
         
     | 
| 
      
 44 
     | 
    
         
            +
                        build env, req, path
         
     | 
| 
      
 45 
     | 
    
         
            +
                      end
         
     | 
| 
       40 
46 
     | 
    
         
             
                    end
         
     | 
| 
       41 
47 
     | 
    
         
             
                  end
         
     | 
| 
       42 
48 
     | 
    
         | 
| 
         @@ -45,6 +51,10 @@ module Froxy 
     | 
|
| 
       45 
51 
     | 
    
         | 
| 
       46 
52 
     | 
    
         
             
                private
         
     | 
| 
       47 
53 
     | 
    
         | 
| 
      
 54 
     | 
    
         
            +
                def logging_message(request)
         
     | 
| 
      
 55 
     | 
    
         
            +
                  format '[froxy] "%s" for %s at %s', request.path_info, request.ip, Time.now.to_default_s
         
     | 
| 
      
 56 
     | 
    
         
            +
                end
         
     | 
| 
      
 57 
     | 
    
         
            +
             
     | 
| 
       48 
58 
     | 
    
         
             
                def path_to_file(env, request, path)
         
     | 
| 
       49 
59 
     | 
    
         
             
                  ext = Pathname.new(path).extname
         
     | 
| 
       50 
60 
     | 
    
         
             
                  request.path_info = path.sub(/#{ext}$/, FILE_EXT_MAP[ext]) if FILE_EXT_MAP.key?(ext)
         
     | 
| 
         @@ -57,7 +67,6 @@ module Froxy 
     | 
|
| 
       57 
67 
     | 
    
         
             
                  stdout, stderr, status = Open3.capture3(CLI, Rails.root.to_s, path)
         
     | 
| 
       58 
68 
     | 
    
         | 
| 
       59 
69 
     | 
    
         
             
                  if status.success?
         
     | 
| 
       60 
     | 
    
         
            -
                    Rails.logger.info "[froxy] built #{path}"
         
     | 
| 
       61 
70 
     | 
    
         
             
                    raise "[froxy] build failed: #{stderr}" unless stderr.empty?
         
     | 
| 
       62 
71 
     | 
    
         
             
                  else
         
     | 
| 
       63 
72 
     | 
    
         
             
                    non_empty_streams = [stdout, stderr].delete_if(&:empty?)
         
     | 
| 
         @@ -79,5 +88,9 @@ module Froxy 
     | 
|
| 
       79 
88 
     | 
    
         
             
                  path = Rack::Utils.unescape_path path_info.chomp('/').delete_prefix('/')
         
     | 
| 
       80 
89 
     | 
    
         
             
                  Rack::Utils.clean_path_info path if Rack::Utils.valid_path? path
         
     | 
| 
       81 
90 
     | 
    
         
             
                end
         
     | 
| 
      
 91 
     | 
    
         
            +
             
     | 
| 
      
 92 
     | 
    
         
            +
                def logger
         
     | 
| 
      
 93 
     | 
    
         
            +
                  Rails.logger
         
     | 
| 
      
 94 
     | 
    
         
            +
                end
         
     | 
| 
       82 
95 
     | 
    
         
             
              end
         
     | 
| 
       83 
96 
     | 
    
         
             
            end
         
     | 
    
        data/lib/froxy/version.rb
    CHANGED
    
    
    
        data/package.json
    CHANGED
    
    
    
        data/yarn.lock
    CHANGED
    
    | 
         @@ -2,7 +2,3 @@ 
     | 
|
| 
       2 
2 
     | 
    
         
             
            # yarn lockfile v1
         
     | 
| 
       3 
3 
     | 
    
         | 
| 
       4 
4 
     | 
    
         | 
| 
       5 
     | 
    
         
            -
            esbuild@0.8.50:
         
     | 
| 
       6 
     | 
    
         
            -
              version "0.8.50"
         
     | 
| 
       7 
     | 
    
         
            -
              resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.8.50.tgz#ebf24fde0cdad1a369789dd6fd7a820b0a01e46c"
         
     | 
| 
       8 
     | 
    
         
            -
              integrity sha512-oidFLXssA7IccYzkqLVZSqNJDwDq8Mh/vqvrW+3fPWM7iUiC5O2bCllhnO8+K9LlyL/2Z6n+WwRJAz9fqSIVRg==
         
     | 
    
        metadata
    CHANGED
    
    | 
         @@ -1,14 +1,14 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            --- !ruby/object:Gem::Specification
         
     | 
| 
       2 
2 
     | 
    
         
             
            name: froxy
         
     | 
| 
       3 
3 
     | 
    
         
             
            version: !ruby/object:Gem::Version
         
     | 
| 
       4 
     | 
    
         
            -
              version: 0. 
     | 
| 
      
 4 
     | 
    
         
            +
              version: 0.2.0
         
     | 
| 
       5 
5 
     | 
    
         
             
            platform: ruby
         
     | 
| 
       6 
6 
     | 
    
         
             
            authors:
         
     | 
| 
       7 
7 
     | 
    
         
             
            - Joel Moss
         
     | 
| 
       8 
8 
     | 
    
         
             
            autorequire:
         
     | 
| 
       9 
9 
     | 
    
         
             
            bindir: exe
         
     | 
| 
       10 
10 
     | 
    
         
             
            cert_chain: []
         
     | 
| 
       11 
     | 
    
         
            -
            date: 2021-02- 
     | 
| 
      
 11 
     | 
    
         
            +
            date: 2021-02-24 00:00:00.000000000 Z
         
     | 
| 
       12 
12 
     | 
    
         
             
            dependencies:
         
     | 
| 
       13 
13 
     | 
    
         
             
            - !ruby/object:Gem::Dependency
         
     | 
| 
       14 
14 
     | 
    
         
             
              name: activesupport
         
     | 
| 
         @@ -55,6 +55,7 @@ files: 
     | 
|
| 
       55 
55 
     | 
    
         
             
            - lib/froxy/esbuild/plugins/css.js
         
     | 
| 
       56 
56 
     | 
    
         
             
            - lib/froxy/esbuild/plugins/debug.js
         
     | 
| 
       57 
57 
     | 
    
         
             
            - lib/froxy/esbuild/plugins/env.js
         
     | 
| 
      
 58 
     | 
    
         
            +
            - lib/froxy/esbuild/plugins/ignore.js
         
     | 
| 
       58 
59 
     | 
    
         
             
            - lib/froxy/esbuild/plugins/images.js
         
     | 
| 
       59 
60 
     | 
    
         
             
            - lib/froxy/esbuild/plugins/load_style.js
         
     | 
| 
       60 
61 
     | 
    
         
             
            - lib/froxy/esbuild/plugins/root.js
         
     |