asset_mapper 0.0.1 → 1.0.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.
@@ -0,0 +1,74 @@
1
+ require 'dry-initializer'
2
+ require 'dry-files'
3
+
4
+ module AssetMapper
5
+ # Manifest reads a given sets of files and reads them into memory via a Hash
6
+ class Manifest
7
+ extend Dry::Initializer
8
+
9
+ # @return [AssetMapper::Configuration]
10
+ param :config
11
+
12
+ class FileNotFoundError < StandardError; end
13
+
14
+ # Attempt to find the +file_name+ inside of the manifest, fallback to given filename.
15
+ # @param {String} file_name - The filename to find in the manifest.
16
+ # @param {Boolean} prepend_asset_host - Whether or not to add the asset_host. Usually "/"
17
+ # @return {String}
18
+ def find(file_name, prepend_asset_host: true)
19
+ file = manifest_files[file_name]
20
+
21
+ if file.nil?
22
+ raise FileNotFoundError("Unable to find #{filename} in your manifest[s].") if config.raise_on_missing_file
23
+
24
+ # Fall back to the default filename, perhaps it exists....
25
+ file = file_name
26
+ end
27
+
28
+ file = file["asset_path"]
29
+
30
+ return with_asset_host(asset_host: config.asset_host, file: file) if prepend_asset_host
31
+
32
+ file
33
+ end
34
+
35
+ # Returns a cached copy of the manifest only if cache_manifest is true.
36
+ def manifest_files
37
+ # Always reload the manifest. Useful for development / testing.
38
+ return load_manifest_files if config.cache_manifest == false
39
+
40
+ @manifest_files ||= load_manifest_files
41
+ end
42
+
43
+ # Refreshes the cached mappings by reading the updated manifest files.
44
+ # Usually used for things like auto-building.
45
+ def refresh_files
46
+ @manifest_files = load_manifest_files
47
+ end
48
+
49
+ private
50
+
51
+ def with_asset_host(asset_host:, file:)
52
+ # strip leading "/"
53
+ file = file[(1..-1)] if file.start_with?("/")
54
+
55
+ asset_host += "/" unless asset_host.end_with?("/")
56
+
57
+ asset_host + file
58
+ end
59
+
60
+ def load_manifest_files
61
+ generate_manifest
62
+
63
+ hash = {}
64
+ config.manifest_files.each { |path| hash.merge!(JSON.parse(Dry::Files.new.read(path))["files"]) }
65
+ hash
66
+ end
67
+
68
+ def generate_manifest
69
+ @manifest_generator ||= ManifestGenerator.new(config)
70
+
71
+ @manifest_generator.generate
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,65 @@
1
+ require 'dry-initializer'
2
+ require "rake"
3
+
4
+ module AssetMapper
5
+ class ManifestGenerator
6
+ extend Dry::Initializer
7
+
8
+ FILES = Dry::Files.new
9
+
10
+ # @return [AssetMapper::Configuration]
11
+ param :config
12
+
13
+ def generate
14
+ return if config.asset_files.nil?
15
+ return if config.asset_files.size.zero?
16
+
17
+ map = {
18
+ "files" => {}
19
+ }
20
+
21
+ config.asset_files.each do |file|
22
+ hash = handle_file(file)
23
+
24
+ map["files"][hash[:relative_path]] = {
25
+ file_path: hash[:file_path],
26
+ asset_path: hash[:asset_path]
27
+ }
28
+ end
29
+
30
+ FILES.write(config.manifest_output_path, JSON.pretty_generate(map))
31
+ end
32
+
33
+ private
34
+
35
+ def handle_file(file)
36
+ relative_path = Pathname.new(file).relative_path_from(config.assets_root).to_s
37
+
38
+ content = FILES.read(file)
39
+ asset_path = (find_relative_hashed_path(file, content) || relative_path).to_s
40
+
41
+ dir = File.dirname(file)
42
+ FILES.mkdir_p(FILES.join(config.assets_output_path, dir))
43
+ FILES.write(FILES.join(config.assets_output_path, asset_path), content)
44
+
45
+ {
46
+ relative_path: relative_path,
47
+ file_path: FILES.join(config.assets_output_path, asset_path),
48
+ asset_path: asset_path
49
+ }
50
+ end
51
+
52
+ def find_relative_hashed_path(file, content)
53
+ return nil if config.fingerprint == false
54
+
55
+ content_hash = config.fingerprint_method.call(content)
56
+
57
+ dir = File.dirname(file)
58
+
59
+ base_name_ary = File.basename(file).split(".")
60
+ base_name = FILES.join(dir, base_name_ary[0])
61
+ hashed_path = base_name + "-#{content_hash}." + base_name_ary[1]
62
+ Pathname.new(hashed_path).relative_path_from(config.assets_root)
63
+ end
64
+ end
65
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module AssetMapper
4
- VERSION = "0.0.1"
4
+ VERSION = "1.0.0"
5
5
  end
data/lib/asset_mapper.rb CHANGED
@@ -4,29 +4,19 @@ require "zeitwerk"
4
4
  loader = Zeitwerk::Loader.for_gem
5
5
  loader.setup # ready!
6
6
 
7
- require "dry/configurable"
8
7
 
8
+ # @example
9
+ #
10
+ # asset_mapper = AssetMapper.new.configure do |config|
11
+ # config.asset_host = "/builds"
12
+ # config.manifest_files = "public/builds/asset_manifest.json"
13
+ # config.cache_manifest = Rails.env.development? || Rails.env.test?
14
+ # config.raise_on_missing_file = Rails.env.development? || Rails.env.test?
15
+ # end
9
16
  module AssetMapper
10
- # Your code goes here...
11
- extend ::Dry::Configurable
12
- extend self
13
-
14
- setting :files, reader: true
15
- setting :output_path, reader: true
16
-
17
- # For file.1234.ext
18
- # if using file-1234.ext change to: /\.[\d\w]+\./
19
- setting :fingerprint_regexp, default: /\-[\d\w]+\./, reader: true
20
- setting :fingerprint_replacer, default: ".", reader: true
21
-
22
- def generate_mapping
23
- hash = {}
24
-
25
- files.map do |file|
26
- file_without_fingerprint = file.gsub(fingerprint_regexp, fingerprint_replacer)
27
- hash[file_without_fingerprint] = file
28
- end
29
-
30
- hash
17
+ # Returns an instance of AssetMapper configuration.
18
+ # @return [Configuration]
19
+ def self.new(*args, **kwargs, &block)
20
+ Configuration.new(*args, **kwargs, &block)
31
21
  end
32
22
  end
@@ -0,0 +1,12 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
4
+
5
+ ### [1.0.1](https://github.com/KonnorRogers/asset_mapper/compare/v1.0.0...v1.0.1) (2022-12-29)
6
+
7
+ ## [1.0.0](https://github.com/KonnorRogers/asset_mapper/compare/v0.0.1...v1.0.0) (2022-12-29)
8
+
9
+
10
+ ### Bug Fixes
11
+
12
+ * more fun fixes ([c3955ab](https://github.com/KonnorRogers/asset_mapper/commit/c3955ab79b522aa3dd2fea0cec1feaf2add3a8ec))
@@ -0,0 +1,37 @@
1
+ // @ts-check
2
+ const esbuild = require("esbuild")
3
+ const fs = require("fs")
4
+
5
+ const watch = process.argv.includes("--watch")
6
+
7
+ /** @type {import("esbuild").BuildOptions} */
8
+ const options = {
9
+ entryPoints: {
10
+ index: "src/index.js",
11
+ },
12
+ watch,
13
+ bundle: false,
14
+ sourcemap: true,
15
+ treeShaking: false
16
+ }
17
+
18
+ ;(async () => {
19
+ fs.rmSync("dist", { recursive: true, force: true });
20
+
21
+ try {
22
+ await Promise.allSettled([
23
+ esbuild.build({
24
+ ...options,
25
+ format: "esm",
26
+ outdir: "dist/esm"
27
+ }),
28
+ esbuild.build({
29
+ ...options,
30
+ format: "cjs",
31
+ outdir: "dist/cjs"
32
+ })
33
+ ])
34
+ } catch(e) { throw e }
35
+
36
+ console.log("Finished build")
37
+ })()
@@ -0,0 +1,41 @@
1
+ {
2
+ "name": "asset-mapper-esbuild",
3
+ "version": "1.0.1",
4
+ "description": "Manifest generator for ESBuild designed for use with AssetMapper.",
5
+ "main": "dist/cjs/index.js",
6
+ "module": "dist/esm/index.js",
7
+ "scripts": {
8
+ "build": "node esbuild.config.js && tsc && tsc -p ./tsconfig-cjs.json",
9
+ "deploy": "pnpm build && standard-version --release-as",
10
+ "deploy:beta": "pnpm build && standard-version --prerelease beta",
11
+ "deploy:patch": "pnpm build && standard-version --release-as patch",
12
+ "deploy:minor": "pnpm build && standard-version --release-as minor",
13
+ "deploy:major": "pnpm build && standard-version --release-as major",
14
+ "push": "git push --follow-tags origin main && pnpm publish",
15
+ "tsc": "tsc"
16
+ },
17
+ "keywords": [
18
+ "asset_mapper",
19
+ "esbuild"
20
+ ],
21
+ "author": "Konnor Rogers",
22
+ "bugs": {
23
+ "url": "https://github.com/konnorrogers/asset_mapper/issues",
24
+ "email": "konnor5456@gmail.com"
25
+ },
26
+ "homepage": "https://github.com/konnorrogers/asset_mapper#readme",
27
+ "files": [
28
+ "dist"
29
+ ],
30
+ "license": "MIT",
31
+ "devDependencies": {
32
+ "@types/node": "^18.11.12",
33
+ "esbuild": "^0.16.4",
34
+ "rimraf": "^3.0.2",
35
+ "standard-version": "^9.5.0",
36
+ "typescript": "^4.9.4"
37
+ },
38
+ "peerDependencies": {
39
+ "esbuild": ">= 0.14.0"
40
+ }
41
+ }