Skip to content

Commit

Permalink
Format everything with Prettier
Browse files Browse the repository at this point in the history
  • Loading branch information
timriley committed Oct 10, 2023
1 parent 67376bd commit 510cbf3
Show file tree
Hide file tree
Showing 15 changed files with 225 additions and 220 deletions.
2 changes: 2 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Ignore artifacts
dist
1 change: 1 addition & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{ "printWidth": 100 }
13 changes: 6 additions & 7 deletions jest.config.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,21 @@
import type { JestConfigWithTsJest } from "ts-jest"
import type { JestConfigWithTsJest } from "ts-jest";

const config: JestConfigWithTsJest = {
testEnvironment: "node",
testMatch: [
"**/test/**/*.test.ts",
],
testMatch: ["**/test/**/*.test.ts"],
// See https://kulshekhar.github.io/ts-jest/docs/guides/esm-support#esm-presets for below
preset: "ts-jest/presets/default-esm",
moduleNameMapper: {
"^(\\.{1,2}/.*)\\.js$": "$1",
},
transform: {
"^.+\\.tsx?$": [
"ts-jest", {
"ts-jest",
{
useESM: true,
},
],
},
}
};

export default config
export default config;
4 changes: 2 additions & 2 deletions src/args.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,6 @@ export const parseArgs = (args: string[]): Args => {

return {
watch: result.hasOwnProperty("watch"),
sri: result["sri"]?.split(",")
sri: result["sri"]?.split(","),
};
}
};
69 changes: 34 additions & 35 deletions src/esbuild.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,29 +2,29 @@ import path from "path";
import { globSync } from "glob";
import { BuildOptions, Loader } from "esbuild";
import { Args } from "./args.js";
import hanamiEsbuild, { HanamiEsbuildPluginOptions, defaults } from './hanami-esbuild-plugin.js';
import hanamiEsbuild, { HanamiEsbuildPluginOptions, defaults } from "./hanami-esbuild-plugin.js";

const loader: { [ext: string]: Loader } = {
'.tsx': 'tsx',
'.ts': 'ts',
'.js': 'js',
'.jsx': 'jsx',
'.json': 'json',
'.png': 'file',
'.jpg': 'file',
'.jpeg': 'file',
'.gif': 'file',
'.svg': 'file',
'.woff': 'file',
'.woff2': 'file',
'.otf': 'file',
'.eot': 'file',
'.ttf': 'file',
".tsx": "tsx",
".ts": "ts",
".js": "js",
".jsx": "jsx",
".json": "json",
".png": "file",
".jpg": "file",
".jpeg": "file",
".gif": "file",
".svg": "file",
".woff": "file",
".woff2": "file",
".otf": "file",
".eot": "file",
".ttf": "file",
};

const entryPointExtensions = "app.{js,ts,mjs,mts,tsx,jsx}";
// FIXME: make cross platform
const entryPointsMatcher = /(app\/assets\/js\/|slices\/(.*\/)assets\/js\/)/
const entryPointsMatcher = /(app\/assets\/js\/|slices\/(.*\/)assets\/js\/)/;

const findEntryPoints = (root: string): Record<string, string> => {
const result: Record<string, string> = {};
Expand All @@ -36,31 +36,31 @@ const findEntryPoints = (root: string): Record<string, string> => {
]);

entryPoints.forEach((entryPoint) => {
let modifiedPath = entryPoint.replace(entryPointsMatcher, "$2")
const relativePath = path.relative(root, modifiedPath)
let modifiedPath = entryPoint.replace(entryPointsMatcher, "$2");
const relativePath = path.relative(root, modifiedPath);

const { dir, name } = path.parse(relativePath)
const { dir, name } = path.parse(relativePath);

if (dir) {
modifiedPath = path.join(dir, name)
modifiedPath = path.join(dir, name);
} else {
modifiedPath = name
modifiedPath = name;
}

result[modifiedPath] = entryPoint
result[modifiedPath] = entryPoint;
});

return result;
}
};

// TODO: feels like this really should be passed a root too, to become the cwd for globSync
const externalDirectories = (): string[] => {
const assetDirsPattern = [
path.join("app", "assets", "*"),
path.join("slices", "*", "assets", "*"),
]
];

const excludeDirs = ['js', 'css'];
const excludeDirs = ["js", "css"];

try {
const dirs = globSync(assetDirsPattern, { nodir: false });
Expand All @@ -71,7 +71,7 @@ const externalDirectories = (): string[] => {

return filteredDirs.map((dir) => path.join(dir, "*"));
} catch (err) {
console.error('Error listing external directories:', err);
console.error("Error listing external directories:", err);
return [];
}
};
Expand All @@ -80,9 +80,9 @@ const externalDirectories = (): string[] => {
export const buildOptions = (root: string, args: Args): Partial<BuildOptions> => {
const pluginOptions: HanamiEsbuildPluginOptions = {
...defaults,
sriAlgorithms: args.sri || []
sriAlgorithms: args.sri || [],
};
const plugin = hanamiEsbuild(pluginOptions)
const plugin = hanamiEsbuild(pluginOptions);

const options: Partial<BuildOptions> = {
bundle: true,
Expand All @@ -96,17 +96,17 @@ export const buildOptions = (root: string, args: Args): Partial<BuildOptions> =>
entryNames: "[dir]/[name]-[hash]",
entryPoints: findEntryPoints(root),
plugins: [plugin],
}
};

return options;
};

export const watchOptions = (root: string, args: Args): Partial<BuildOptions> => {
const pluginOptions: HanamiEsbuildPluginOptions = {
...defaults,
hash: false
hash: false,
};
const plugin = hanamiEsbuild(pluginOptions)
const plugin = hanamiEsbuild(pluginOptions);

const options: Partial<BuildOptions> = {
bundle: true,
Expand All @@ -120,8 +120,7 @@ export const watchOptions = (root: string, args: Args): Partial<BuildOptions> =>
entryNames: "[dir]/[name]",
entryPoints: findEntryPoints(root),
plugins: [plugin],
}
};

return options;
}

};
27 changes: 16 additions & 11 deletions src/hanami-assets.ts
Original file line number Diff line number Diff line change
@@ -1,34 +1,39 @@
#!/usr/bin/env node

import fs from 'fs-extra';
import path from 'path';
import fs from "fs-extra";
import path from "path";
import esbuild, { BuildOptions, BuildContext } from "esbuild";
import { Args, parseArgs } from "./args.js";
import { buildOptions, watchOptions } from './esbuild.js';
import { buildOptions, watchOptions } from "./esbuild.js";

type RunOptionsFunction = (args: Args, options: Partial<BuildOptions>) => Partial<BuildOptions>;

export const run = async function(root: string, argv: string[], optionsFunction?: RunOptionsFunction): Promise<BuildContext | void> {
export const run = async function (
root: string,
argv: string[],
optionsFunction?: RunOptionsFunction,
): Promise<BuildContext | void> {
const args = parseArgs(argv);

// TODO: make nicer
let esbuildOptions = args.watch ? watchOptions(root, args) : buildOptions(root, args);
if (optionsFunction) { esbuildOptions = optionsFunction(args, esbuildOptions); }
if (optionsFunction) {
esbuildOptions = optionsFunction(args, esbuildOptions);
}

const errorHandler = (err: any): void => {
console.log(err);
process.exit(1);
}
};

if (args.watch) {
touchManifest(root);

const ctx = await esbuild.context(esbuildOptions)
await ctx.watch().catch(errorHandler)
const ctx = await esbuild.context(esbuildOptions);
await ctx.watch().catch(errorHandler);

return ctx;
}
else {
} else {
await esbuild.build(esbuildOptions).catch(errorHandler);
}
};
Expand All @@ -40,4 +45,4 @@ const touchManifest = (root: string): void => {
fs.ensureDirSync(manifestDir);

fs.writeFileSync(manifestPath, JSON.stringify({}, null, 2));
}
};
69 changes: 39 additions & 30 deletions src/hanami-esbuild-plugin.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,9 @@
import {
BuildResult,
Plugin,
PluginBuild
} from 'esbuild';
import fs from 'fs-extra';
import path from 'path';
import crypto from 'node:crypto';
import { BuildResult, Plugin, PluginBuild } from "esbuild";
import fs from "fs-extra";
import path from "path";
import crypto from "node:crypto";

const URL_SEPARATOR = '/';
const URL_SEPARATOR = "/";

export interface HanamiEsbuildPluginOptions {
root: string;
Expand All @@ -18,11 +14,14 @@ export interface HanamiEsbuildPluginOptions {
hash: boolean;
}

export const defaults: Pick<HanamiEsbuildPluginOptions, 'root' | 'publicDir' | 'destDir' | 'manifestPath' | 'sriAlgorithms' | 'hash'> = {
root: '',
publicDir: 'public',
destDir: path.join('public', 'assets'),
manifestPath: path.join('public', 'assets.json'),
export const defaults: Pick<
HanamiEsbuildPluginOptions,
"root" | "publicDir" | "destDir" | "manifestPath" | "sriAlgorithms" | "hash"
> = {
root: "",
publicDir: "public",
destDir: path.join("public", "assets"),
manifestPath: path.join("public", "assets.json"),
sriAlgorithms: [],
hash: true,
};
Expand All @@ -34,7 +33,7 @@ interface Asset {

const hanamiEsbuild = (options: HanamiEsbuildPluginOptions = { ...defaults }): Plugin => {
return {
name: 'hanami-esbuild',
name: "hanami-esbuild",

setup(build: PluginBuild) {
build.initialOptions.metafile = true;
Expand All @@ -48,34 +47,36 @@ const hanamiEsbuild = (options: HanamiEsbuildPluginOptions = { ...defaults }): P
const assetsManifest: Record<string, Asset> = {};

const calulateSourceUrl = (str: string): string => {
return normalizeUrl(str).replace(/\/assets\//, '').replace(/-[A-Z0-9]{8}/, '');
}
return normalizeUrl(str)
.replace(/\/assets\//, "")
.replace(/-[A-Z0-9]{8}/, "");
};

const calulateDestinationUrl = (str: string): string => {
return normalizeUrl(str).replace(/public/, '');
}
return normalizeUrl(str).replace(/public/, "");
};

const normalizeUrl = (str: string): string => {
return str.replace(/[\\]+/, URL_SEPARATOR);
}
};

const calculateSubresourceIntegrity = (algorithm: string, path: string): string => {
const content = fs.readFileSync(path, 'utf8');
const hash = crypto.createHash(algorithm).update(content).digest('base64');
const content = fs.readFileSync(path, "utf8");
const hash = crypto.createHash(algorithm).update(content).digest("base64");

return `${algorithm}-${hash}`;
}
};

// Inspired by https://github.com/evanw/esbuild/blob/2f2b90a99d626921d25fe6d7d0ca50bd48caa427/internal/bundler/bundler.go#L1057
const calculateHash = (hashBytes: Uint8Array, hash: boolean): string | null => {
if (!hash) {
return null;
}

const result = crypto.createHash('sha256').update(hashBytes).digest('hex');
const result = crypto.createHash("sha256").update(hashBytes).digest("hex");

return result.slice(0, 8).toUpperCase();
}
};

function extractEsbuildInputs(inputData: Record<string, any>): Record<string, boolean> {
const inputs: Record<string, boolean> = {};
Expand Down Expand Up @@ -114,7 +115,11 @@ const hanamiEsbuild = (options: HanamiEsbuildPluginOptions = { ...defaults }): P
return;
};

const processAssetDirectory = (pattern: string, inputs: Record<string, boolean>, options: HanamiEsbuildPluginOptions): string[] => {
const processAssetDirectory = (
pattern: string,
inputs: Record<string, boolean>,
options: HanamiEsbuildPluginOptions,
): string[] => {
const dirPath = path.dirname(pattern);
const files = fs.readdirSync(dirPath);
const assets: string[] = [];
Expand All @@ -130,8 +135,12 @@ const hanamiEsbuild = (options: HanamiEsbuildPluginOptions = { ...defaults }): P
const fileHash = calculateHash(fs.readFileSync(srcPath), options.hash);
const fileExtension = path.extname(srcPath);
const baseName = path.basename(srcPath, fileExtension);
const destFileName = [baseName, fileHash].filter(item => item !== null).join("-") + fileExtension;
const destPath = path.join(options.destDir, path.relative(dirPath, srcPath).replace(file, destFileName));
const destFileName =
[baseName, fileHash].filter((item) => item !== null).join("-") + fileExtension;
const destPath = path.join(
options.destDir,
path.relative(dirPath, srcPath).replace(file, destFileName),
);

if (fs.lstatSync(srcPath).isDirectory()) {
assets.push(...processAssetDirectory(destPath, inputs, options));
Expand All @@ -144,7 +153,7 @@ const hanamiEsbuild = (options: HanamiEsbuildPluginOptions = { ...defaults }): P
return assets;
};

if (typeof outputs === 'undefined') {
if (typeof outputs === "undefined") {
return;
}

Expand All @@ -157,7 +166,7 @@ const hanamiEsbuild = (options: HanamiEsbuildPluginOptions = { ...defaults }): P
const assetsToProcess = Object.keys(outputs).concat(copiedAssets);

for (const assetToProcess of assetsToProcess) {
if (assetToProcess.endsWith('.map')) {
if (assetToProcess.endsWith(".map")) {
continue;
}

Expand Down
Loading

0 comments on commit 510cbf3

Please sign in to comment.