@procore/hammer-lib-tsup 0.5.2 → 0.7.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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,41 @@
1
1
  # @procore/hammer-lib-tsup
2
2
 
3
+ ## 0.7.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 59a4b08: Upgrades tsup, esbuild, and other dependencies.
8
+ - 32ad5d2: Add validate command to libs-tsup
9
+
10
+ ### Patch Changes
11
+
12
+ - 59a4b08: Upgrades `picocolors` to 1.1.1.
13
+ - 5dd6e18: Fixes interface for `lib:validate` command.
14
+ - Updated dependencies [59a4b08]
15
+ - Updated dependencies [59a4b08]
16
+ - Updated dependencies [5dd6e18]
17
+ - Updated dependencies [32ad5d2]
18
+ - @procore/hammer-utils@0.2.0
19
+ - @procore/hammer-types@0.5.1
20
+
21
+ ## 0.6.0
22
+
23
+ ### Minor Changes
24
+
25
+ - 9407067: Add new general command `init` for hammer and all plugins
26
+ - a3dadc6: Update engine.node version with actual supported node versions
27
+ - f4d2605: Implemented init function for lib-tsup plugin to successfully initialize the project
28
+ - bdf3901: Upgrades dependencies.
29
+
30
+ ### Patch Changes
31
+
32
+ - Updated dependencies [2aa7e7b]
33
+ - Updated dependencies [9407067]
34
+ - Updated dependencies [f4d2605]
35
+ - Updated dependencies [1f1d590]
36
+ - @procore/hammer-types@0.5.0
37
+ - @procore/hammer-utils@0.1.0
38
+
3
39
  ## 0.5.2
4
40
 
5
41
  ### Patch Changes
package/README.md CHANGED
@@ -46,9 +46,25 @@ This project uses [`yarn`][yarn], and supports the following commands:
46
46
  - `lint:types`: uses [`TypeScript`][typescript] to validate types.
47
47
  - `test`: runs the unit test suite.
48
48
  - `test:ci`: run the unit test suite, reporting coverage.
49
+ - `lib:build --analyze`: builds the library and generates metadata for bundle analysis.
49
50
 
51
+ ### Using `lib:build --analyze`
52
+
53
+ When you run `hammer lib:build --analyze`, it generates the following output files:
54
+
55
+ - `metafile-esm.json`: Metadata for the ESM (ECMAScript Module) output.
56
+ - `metafile-cjs.json`: Metadata for the CJS (CommonJS) output.
57
+
58
+ These files can be used to analyze the bundle, understand the size of individual modules, and identify optimizations.
59
+
60
+ For more detailed information on how the metadata works, refer to the [Tsup Metafile Documentation][tsup-metafile].
61
+
62
+ Additionally, you can use tools like [Bundle Buddy][bundle-buddy] to visualize the output and track down duplicate dependencies or optimize your bundle for better performance.
63
+
64
+ [bundle-buddy]: https://www.bundle-buddy.com/esbuild
50
65
  [eslint]: https://eslint.org/
51
66
  [prettier]: https://prettier.io/
52
67
  [tsup]: https://tsup.egoist.dev/
68
+ [tsup-metafile]: https://tsup.egoist.dev/#metafile
53
69
  [typescript]: https://www.typescriptlang.org/
54
70
  [yarn]: https://classic.yarnpkg.com/
package/dist/index.d.mts CHANGED
@@ -1,5 +1,8 @@
1
1
  import * as _procore_hammer_types from '@procore/hammer-types';
2
2
 
3
+ declare const init: (rootDir: string, config: _procore_hammer_types.HammerConfig, options: {
4
+ force?: boolean;
5
+ }) => Promise<void>;
3
6
  declare const build: (rootDir: string, config: _procore_hammer_types.HammerConfig, options: {
4
7
  analyze: boolean;
5
8
  }) => Promise<void>;
@@ -10,5 +13,6 @@ declare const inspect: (rootDir: string, config: _procore_hammer_types.HammerCon
10
13
  declare const start: (rootDir: string, config: _procore_hammer_types.HammerConfig, options: {
11
14
  analyze: boolean;
12
15
  }) => Promise<void>;
16
+ declare const validate: (rootDir: string, config: _procore_hammer_types.HammerConfig) => Promise<void>;
13
17
 
14
- export { build, clean, inspect, start };
18
+ export { build, clean, init, inspect, start, validate };
package/dist/index.d.ts CHANGED
@@ -1,5 +1,8 @@
1
1
  import * as _procore_hammer_types from '@procore/hammer-types';
2
2
 
3
+ declare const init: (rootDir: string, config: _procore_hammer_types.HammerConfig, options: {
4
+ force?: boolean;
5
+ }) => Promise<void>;
3
6
  declare const build: (rootDir: string, config: _procore_hammer_types.HammerConfig, options: {
4
7
  analyze: boolean;
5
8
  }) => Promise<void>;
@@ -10,5 +13,6 @@ declare const inspect: (rootDir: string, config: _procore_hammer_types.HammerCon
10
13
  declare const start: (rootDir: string, config: _procore_hammer_types.HammerConfig, options: {
11
14
  analyze: boolean;
12
15
  }) => Promise<void>;
16
+ declare const validate: (rootDir: string, config: _procore_hammer_types.HammerConfig) => Promise<void>;
13
17
 
14
- export { build, clean, inspect, start };
18
+ export { build, clean, init, inspect, start, validate };
package/dist/index.js CHANGED
@@ -32,8 +32,10 @@ var src_exports = {};
32
32
  __export(src_exports, {
33
33
  build: () => build,
34
34
  clean: () => clean,
35
+ init: () => init,
35
36
  inspect: () => inspect,
36
- start: () => start
37
+ start: () => start,
38
+ validate: () => validate
37
39
  });
38
40
  module.exports = __toCommonJS(src_exports);
39
41
  var import_node_process = __toESM(require("process"));
@@ -146,7 +148,139 @@ async function performBuild(buildOptions) {
146
148
  }
147
149
 
148
150
  // src/index.ts
149
- var { build, clean, inspect, start } = {
151
+ var import_hammer_utils2 = require("@procore/hammer-utils");
152
+
153
+ // src/validate-package.ts
154
+ var import_hammer_utils = require("@procore/hammer-utils");
155
+ var import_picocolors3 = __toESM(require("picocolors"));
156
+ var import_node_fs = __toESM(require("fs"));
157
+ var errorIsNotExisted = (name) => `The property ${import_picocolors3.default.yellow(name)} doesn't exist in the package.json.`;
158
+ var errorFileIsNotExisted = (name) => `The file from ${import_picocolors3.default.yellow(name)} property doesn't exist in the dist folder.
159
+ `;
160
+ var areDeepFileExist = (value) => {
161
+ let isValid = true;
162
+ if (Array.isArray(value) && isValid) {
163
+ isValid = value.every(import_node_fs.default.existsSync);
164
+ }
165
+ if (typeof value === "object" && !Array.isArray(value) && value !== null && isValid) {
166
+ isValid = Object.values(value).every(
167
+ (file) => areDeepFileExist(file)
168
+ );
169
+ }
170
+ if (typeof value === "string" && isValid) {
171
+ isValid = import_node_fs.default.existsSync(value);
172
+ }
173
+ return isValid;
174
+ };
175
+ var validatePackage = async (rootDir) => {
176
+ const pkg = await (0, import_hammer_utils.readRootPackageJson)(rootDir);
177
+ let isValid = true;
178
+ if (!pkg.type) {
179
+ const docUrl = "https://nodejs.org/docs/latest/api/packages.html#type";
180
+ process.stderr.write(errorIsNotExisted("type"));
181
+ process.stdout.write(
182
+ `Please specify it as ${import_picocolors3.default.bold('"module" (recommended)')} or read ${import_picocolors3.default.bold(docUrl)}.
183
+ `
184
+ );
185
+ isValid = false;
186
+ }
187
+ if (!pkg.exports) {
188
+ const docUrl = "https://nodejs.org/docs/latest/api/packages.html#exports";
189
+ const exampleStructure = {
190
+ exports: {
191
+ ".": {
192
+ import: {
193
+ types: "./dist/modern/index.d.ts",
194
+ default: "./dist/modern/index.js"
195
+ },
196
+ require: {
197
+ types: "./dist/modern/index.d.cts",
198
+ default: "./dist/modern/index.cjs"
199
+ }
200
+ },
201
+ "./package.json": "./package.json"
202
+ }
203
+ };
204
+ process.stderr.write(errorIsNotExisted("exports"));
205
+ process.stdout.write(
206
+ `Please specify it as ${import_picocolors3.default.bold(JSON.stringify(exampleStructure, null, 2))} or read ${import_picocolors3.default.bold(docUrl)}.
207
+ `
208
+ );
209
+ isValid = false;
210
+ }
211
+ if (pkg.exports && !areDeepFileExist(pkg.exports)) {
212
+ process.stderr.write(errorFileIsNotExisted("exports"));
213
+ isValid = false;
214
+ }
215
+ if (!pkg.main) {
216
+ const docUrl = "https://nodejs.org/docs/latest/api/packages.html#main";
217
+ process.stderr.write(errorIsNotExisted("main"));
218
+ process.stdout.write(
219
+ `Please point it on your main file. You can read more in ${import_picocolors3.default.bold(docUrl)}.
220
+ `
221
+ );
222
+ isValid = false;
223
+ }
224
+ if (pkg.main && !import_node_fs.default.existsSync(pkg.main)) {
225
+ process.stderr.write(errorFileIsNotExisted("main"));
226
+ isValid = false;
227
+ }
228
+ if (!pkg.module) {
229
+ const docUrl = "https://nodejs.org/docs/latest/api/packages.html#package-entry-points";
230
+ process.stderr.write(errorIsNotExisted("module"));
231
+ process.stdout.write(`You can read more in ${import_picocolors3.default.bold(docUrl)}.
232
+ `);
233
+ isValid = false;
234
+ }
235
+ if (pkg.module && !import_node_fs.default.existsSync(pkg.module)) {
236
+ process.stderr.write(errorFileIsNotExisted("module"));
237
+ isValid = false;
238
+ }
239
+ if (!pkg.types) {
240
+ const docUrl = "https://nodejs.org/docs/latest/api/packages.html#community-conditions-definitions";
241
+ process.stderr.write(errorIsNotExisted("types"));
242
+ process.stdout.write(`You can read more in ${import_picocolors3.default.bold(docUrl)}.
243
+ `);
244
+ isValid = false;
245
+ }
246
+ if (pkg.types && !areDeepFileExist(pkg.types)) {
247
+ process.stderr.write(errorFileIsNotExisted("types"));
248
+ isValid = false;
249
+ }
250
+ if (!pkg.files) {
251
+ const docUrl = "https://classic.yarnpkg.com/lang/en/docs/package-json/#toc-files";
252
+ process.stderr.write(
253
+ `${errorIsNotExisted("files")}
254
+ The optional ${import_picocolors3.default.yellow("files")} field is an array of file patterns that describes the entries to be included when your package is installed as a dependency.
255
+ `
256
+ );
257
+ process.stdout.write(`You can read more in ${import_picocolors3.default.bold(docUrl)}.
258
+ `);
259
+ isValid = false;
260
+ }
261
+ if (pkg.files && !areDeepFileExist(pkg.files)) {
262
+ process.stderr.write(errorFileIsNotExisted("files"));
263
+ isValid = false;
264
+ }
265
+ if (!pkg.sideEffects) {
266
+ process.stderr.write(
267
+ `${errorIsNotExisted("sideEffects")}
268
+ This field helps bundlers make assumptions about packages that improve tree shaking, or pruning files that aren't used and don't have any global side effects.
269
+ `
270
+ );
271
+ isValid = false;
272
+ }
273
+ if (isValid) {
274
+ process.stdout.write(import_picocolors3.default.green(`Validation finished succesfully.
275
+ `));
276
+ }
277
+ };
278
+
279
+ // src/index.ts
280
+ var { init, build, clean, inspect, start, validate } = {
281
+ init: async function init2(rootDir, config, options) {
282
+ await (0, import_hammer_utils2.updatePackageJsonFromTemplate)(rootDir, options.force);
283
+ },
150
284
  build: async function build2(rootDir, config, options) {
151
285
  const pluginOptions = { ...options, config };
152
286
  const buildOptions = await createBuildOptions(base_configs_default, pluginOptions);
@@ -169,12 +303,18 @@ ${highlightedConfig}
169
303
  const pluginOptions = { ...options, config, watch: true };
170
304
  const buildOptions = await createBuildOptions(base_configs_default, pluginOptions);
171
305
  await performBuild(buildOptions);
306
+ },
307
+ validate: async function validate2(rootDir, config) {
308
+ await this.build(rootDir, config, { analyze: false });
309
+ await validatePackage(rootDir);
172
310
  }
173
311
  };
174
312
  // Annotate the CommonJS export names for ESM import in node:
175
313
  0 && (module.exports = {
176
314
  build,
177
315
  clean,
316
+ init,
178
317
  inspect,
179
- start
318
+ start,
319
+ validate
180
320
  });
package/dist/index.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  // src/index.ts
2
- import process2 from "process";
2
+ import process2 from "node:process";
3
3
 
4
4
  // src/base-configs.ts
5
5
  import { postcssModules, sassPlugin } from "esbuild-sass-plugin";
@@ -68,7 +68,7 @@ function toHighlightedString(input) {
68
68
 
69
69
  // src/clean-output.ts
70
70
  import { resolve } from "pathe";
71
- import { rm } from "fs/promises";
71
+ import { rm } from "node:fs/promises";
72
72
  import c from "picocolors";
73
73
  async function cleanOutput(rootDir, buildOptions) {
74
74
  for (const buildOption of buildOptions) {
@@ -109,7 +109,139 @@ async function performBuild(buildOptions) {
109
109
  }
110
110
 
111
111
  // src/index.ts
112
- var { build, clean, inspect, start } = {
112
+ import { updatePackageJsonFromTemplate } from "@procore/hammer-utils";
113
+
114
+ // src/validate-package.ts
115
+ import { readRootPackageJson } from "@procore/hammer-utils";
116
+ import c3 from "picocolors";
117
+ import fs from "node:fs";
118
+ var errorIsNotExisted = (name) => `The property ${c3.yellow(name)} doesn't exist in the package.json.`;
119
+ var errorFileIsNotExisted = (name) => `The file from ${c3.yellow(name)} property doesn't exist in the dist folder.
120
+ `;
121
+ var areDeepFileExist = (value) => {
122
+ let isValid = true;
123
+ if (Array.isArray(value) && isValid) {
124
+ isValid = value.every(fs.existsSync);
125
+ }
126
+ if (typeof value === "object" && !Array.isArray(value) && value !== null && isValid) {
127
+ isValid = Object.values(value).every(
128
+ (file) => areDeepFileExist(file)
129
+ );
130
+ }
131
+ if (typeof value === "string" && isValid) {
132
+ isValid = fs.existsSync(value);
133
+ }
134
+ return isValid;
135
+ };
136
+ var validatePackage = async (rootDir) => {
137
+ const pkg = await readRootPackageJson(rootDir);
138
+ let isValid = true;
139
+ if (!pkg.type) {
140
+ const docUrl = "https://nodejs.org/docs/latest/api/packages.html#type";
141
+ process.stderr.write(errorIsNotExisted("type"));
142
+ process.stdout.write(
143
+ `Please specify it as ${c3.bold('"module" (recommended)')} or read ${c3.bold(docUrl)}.
144
+ `
145
+ );
146
+ isValid = false;
147
+ }
148
+ if (!pkg.exports) {
149
+ const docUrl = "https://nodejs.org/docs/latest/api/packages.html#exports";
150
+ const exampleStructure = {
151
+ exports: {
152
+ ".": {
153
+ import: {
154
+ types: "./dist/modern/index.d.ts",
155
+ default: "./dist/modern/index.js"
156
+ },
157
+ require: {
158
+ types: "./dist/modern/index.d.cts",
159
+ default: "./dist/modern/index.cjs"
160
+ }
161
+ },
162
+ "./package.json": "./package.json"
163
+ }
164
+ };
165
+ process.stderr.write(errorIsNotExisted("exports"));
166
+ process.stdout.write(
167
+ `Please specify it as ${c3.bold(JSON.stringify(exampleStructure, null, 2))} or read ${c3.bold(docUrl)}.
168
+ `
169
+ );
170
+ isValid = false;
171
+ }
172
+ if (pkg.exports && !areDeepFileExist(pkg.exports)) {
173
+ process.stderr.write(errorFileIsNotExisted("exports"));
174
+ isValid = false;
175
+ }
176
+ if (!pkg.main) {
177
+ const docUrl = "https://nodejs.org/docs/latest/api/packages.html#main";
178
+ process.stderr.write(errorIsNotExisted("main"));
179
+ process.stdout.write(
180
+ `Please point it on your main file. You can read more in ${c3.bold(docUrl)}.
181
+ `
182
+ );
183
+ isValid = false;
184
+ }
185
+ if (pkg.main && !fs.existsSync(pkg.main)) {
186
+ process.stderr.write(errorFileIsNotExisted("main"));
187
+ isValid = false;
188
+ }
189
+ if (!pkg.module) {
190
+ const docUrl = "https://nodejs.org/docs/latest/api/packages.html#package-entry-points";
191
+ process.stderr.write(errorIsNotExisted("module"));
192
+ process.stdout.write(`You can read more in ${c3.bold(docUrl)}.
193
+ `);
194
+ isValid = false;
195
+ }
196
+ if (pkg.module && !fs.existsSync(pkg.module)) {
197
+ process.stderr.write(errorFileIsNotExisted("module"));
198
+ isValid = false;
199
+ }
200
+ if (!pkg.types) {
201
+ const docUrl = "https://nodejs.org/docs/latest/api/packages.html#community-conditions-definitions";
202
+ process.stderr.write(errorIsNotExisted("types"));
203
+ process.stdout.write(`You can read more in ${c3.bold(docUrl)}.
204
+ `);
205
+ isValid = false;
206
+ }
207
+ if (pkg.types && !areDeepFileExist(pkg.types)) {
208
+ process.stderr.write(errorFileIsNotExisted("types"));
209
+ isValid = false;
210
+ }
211
+ if (!pkg.files) {
212
+ const docUrl = "https://classic.yarnpkg.com/lang/en/docs/package-json/#toc-files";
213
+ process.stderr.write(
214
+ `${errorIsNotExisted("files")}
215
+ The optional ${c3.yellow("files")} field is an array of file patterns that describes the entries to be included when your package is installed as a dependency.
216
+ `
217
+ );
218
+ process.stdout.write(`You can read more in ${c3.bold(docUrl)}.
219
+ `);
220
+ isValid = false;
221
+ }
222
+ if (pkg.files && !areDeepFileExist(pkg.files)) {
223
+ process.stderr.write(errorFileIsNotExisted("files"));
224
+ isValid = false;
225
+ }
226
+ if (!pkg.sideEffects) {
227
+ process.stderr.write(
228
+ `${errorIsNotExisted("sideEffects")}
229
+ This field helps bundlers make assumptions about packages that improve tree shaking, or pruning files that aren't used and don't have any global side effects.
230
+ `
231
+ );
232
+ isValid = false;
233
+ }
234
+ if (isValid) {
235
+ process.stdout.write(c3.green(`Validation finished succesfully.
236
+ `));
237
+ }
238
+ };
239
+
240
+ // src/index.ts
241
+ var { init, build, clean, inspect, start, validate } = {
242
+ init: async function init2(rootDir, config, options) {
243
+ await updatePackageJsonFromTemplate(rootDir, options.force);
244
+ },
113
245
  build: async function build2(rootDir, config, options) {
114
246
  const pluginOptions = { ...options, config };
115
247
  const buildOptions = await createBuildOptions(base_configs_default, pluginOptions);
@@ -132,11 +264,17 @@ ${highlightedConfig}
132
264
  const pluginOptions = { ...options, config, watch: true };
133
265
  const buildOptions = await createBuildOptions(base_configs_default, pluginOptions);
134
266
  await performBuild(buildOptions);
267
+ },
268
+ validate: async function validate2(rootDir, config) {
269
+ await this.build(rootDir, config, { analyze: false });
270
+ await validatePackage(rootDir);
135
271
  }
136
272
  };
137
273
  export {
138
274
  build,
139
275
  clean,
276
+ init,
140
277
  inspect,
141
- start
278
+ start,
279
+ validate
142
280
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@procore/hammer-lib-tsup",
3
- "version": "0.5.2",
3
+ "version": "0.7.0",
4
4
  "description": "Hammer library builder, tsup-style",
5
5
  "author": "Procore Technologies, Inc",
6
6
  "homepage": "https://github.com/procore/hammer/packages/lib-tsup",
@@ -27,12 +27,12 @@
27
27
  "dist"
28
28
  ],
29
29
  "engines": {
30
- "node": "^18.0.0 || >=20.0.0"
30
+ "node": "^18.18.0 || ^20.9.0 || ^22.0.0"
31
31
  },
32
32
  "scripts": {
33
33
  "build": "tsup",
34
- "clean": "rimraf dist",
35
- "exec": "exec",
34
+ "clean": "del dist coverage .eslintcache .turbo",
35
+ "exec": "yarn exec",
36
36
  "format": "prettier --ignore-unknown --write --cache .",
37
37
  "format:check": "prettier --ignore-unknown --check --cache .",
38
38
  "lint:code": "eslint . --cache",
@@ -51,29 +51,29 @@
51
51
  }
52
52
  },
53
53
  "dependencies": {
54
- "@procore/hammer-types": "^0.4.0",
54
+ "@procore/hammer-types": "^0.5.1",
55
+ "@procore/hammer-utils": "^0.2.0",
55
56
  "cli-highlight": "^2.1.11",
56
- "esbuild": "^0.21.5",
57
+ "esbuild": "^0.24.0",
57
58
  "esbuild-sass-plugin": "^3.3.1",
58
59
  "pathe": "^1.1.2",
59
- "picocolors": "^1.0.1",
60
- "sass-embedded": "^1.77.5",
61
- "tsup": "^8.1.0"
60
+ "picocolors": "^1.1.1",
61
+ "sass-embedded": "^1.81.0",
62
+ "tsup": "^8.3.5"
62
63
  },
63
64
  "devDependencies": {
64
65
  "@procore/eslint-config": "^15.2.1",
66
+ "@procore/hammer-test-utils": "^0.0.1",
65
67
  "@procore/prettier-config": "^1.1.1",
66
68
  "@procore/typescript-config": "^2.0.0",
67
- "@types/node": "^20.14.10",
68
- "@vitest/coverage-v8": "^1.6.0",
69
- "eslint": "^8.57.0",
70
- "lint-staged": "^15.2.7",
71
- "postcss": "^8.4.39",
72
- "prettier": "^3.3.2",
73
- "rimraf": "^6.0.0",
69
+ "@types/node": "^20.17.6",
70
+ "@vitest/coverage-v8": "^2.1.5",
71
+ "del-cli": "^6.0.0",
72
+ "eslint": "^9.15.0",
73
+ "postcss": "^8.4.49",
74
+ "prettier": "^3.3.3",
74
75
  "strip-ansi": "^7.1.0",
75
- "typescript": "^5.5.3",
76
- "vitest": "^1.6.0",
77
- "vitest-mock-process": "^1.0.4"
76
+ "typescript": "~5.5.4",
77
+ "vitest": "^2.1.5"
78
78
  }
79
79
  }