@lipemat/js-boilerplate 10.8.0-beta.2 → 10.8.0-beta.4

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/bin/build.ts ADDED
@@ -0,0 +1,8 @@
1
+ import {execSync} from 'node:child_process';
2
+ import chalk from 'chalk';
3
+
4
+ console.log( chalk.blue( '[TS] ' ) + ' Compiling the files using the tsconfig.json in the src directory.' );
5
+
6
+ execSync( 'tsc -p src', {stdio: 'inherit'} );
7
+
8
+ console.log( chalk.blueBright( '[TS] ' ) + ' Finished compiling the files.' );
package/bin/watch.ts ADDED
@@ -0,0 +1,26 @@
1
+ import chokidar from 'chokidar';
2
+ import {exec} from 'child_process';
3
+ import chalk, {red} from 'chalk';
4
+
5
+ const toWatch = [
6
+ 'config/*.ts',
7
+ 'helpers/*.ts',
8
+ ];
9
+
10
+ /**
11
+ * Watch for changes in the config or helpers directory and run the build script when a change is detected.
12
+ */
13
+ chokidar.watch( toWatch, {ignored: /(^|[\/\\])\../} )
14
+ .on( 'change', path => {
15
+ console.log( chalk.yellowBright( '[watch]' ), `${path} changed` );
16
+ exec( 'yarn run build', ( err, stdout ) => {
17
+ if ( err ) {
18
+ console.error( red( stdout ) );
19
+ } else {
20
+ console.log( stdout );
21
+ }
22
+ } );
23
+ } )
24
+ .once( 'ready', () => {
25
+ console.log( chalk.greenBright( '[watch]' ), 'Watching for changes…' );
26
+ } )
@@ -1,12 +1,6 @@
1
- 'use strict';
2
- Object.defineProperty( exports, '__esModule', {value: true} );
3
- /**
4
- * Generated from the `src` directory to compile TS to JS because JEST
5
- * does not support using TS files as part of the JEST configuration when
6
- * located in a `node_modules directory.
7
- *
8
- */
9
- const config_1 = require( '../helpers/config' );
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const config_1 = require("../helpers/config");
10
4
  /**
11
5
  * Use Babel's preset-env to add support for target browsers.
12
6
  *
@@ -15,35 +9,35 @@ const config_1 = require( '../helpers/config' );
15
9
  * @see https://babeljs.io/docs/en/babel-preset-env
16
10
  */
17
11
  const presetEnv = {
18
- bugfixes: true,
19
- corejs: {
20
- // Use the core-js version currently installed in the project.
21
- version: require( 'core-js/package.json' ).version,
22
- proposals: false,
23
- },
24
- // Enable the `debug` option to debug the included polyfills and plugins.
25
- debug: false,
26
- // Ignore any external browserslist in favor of `getBrowsersList()`.
27
- ignoreBrowserslistConfig: true,
28
- shippedProposals: false,
29
- targets: {
30
- browsers: ( 0, config_1.getBrowsersList )(),
31
- },
32
- useBuiltIns: 'usage',
12
+ bugfixes: true,
13
+ corejs: {
14
+ // Use the core-js version currently installed in the project.
15
+ version: require('core-js/package.json').version,
16
+ proposals: false,
17
+ },
18
+ // Enable the `debug` option to debug the included polyfills and plugins.
19
+ debug: false,
20
+ // Ignore any external browserslist in favor of `getBrowsersList()`.
21
+ ignoreBrowserslistConfig: true,
22
+ shippedProposals: false,
23
+ targets: {
24
+ browsers: (0, config_1.getBrowsersList)(),
25
+ },
26
+ useBuiltIns: 'usage',
33
27
  };
34
28
  const babelConfig = {
35
- cacheDirectory: true,
36
- presets: [
37
- [ '@babel/preset-env', presetEnv ],
38
- [ '@babel/preset-react', {
39
- development: 'production' !== process.env.NODE_ENV,
40
- runtime: 'automatic',
41
- } ],
42
- '@babel/preset-typescript',
43
- ],
44
- plugins: [
45
- '@babel/plugin-syntax-dynamic-import',
46
- ],
29
+ cacheDirectory: true,
30
+ presets: [
31
+ ['@babel/preset-env', presetEnv],
32
+ ['@babel/preset-react', {
33
+ development: 'production' !== process.env.NODE_ENV,
34
+ runtime: 'automatic',
35
+ }],
36
+ '@babel/preset-typescript',
37
+ ],
38
+ plugins: [
39
+ '@babel/plugin-syntax-dynamic-import',
40
+ ],
47
41
  };
48
42
  exports.default = babelConfig;
49
43
  module.exports = babelConfig;
@@ -0,0 +1,61 @@
1
+ import {getBrowsersList} from '../helpers/config';
2
+ import type {TransformOptions} from '@babel/core';
3
+ import type {Options} from '@babel/preset-env';
4
+
5
+ export type BabelConfig = Pick<BabelFull, 'presets' | 'plugins' | 'cacheDirectory'>;
6
+ export type BabelFull = Partial<TransformOptions> & BabelLoader;
7
+
8
+ /**
9
+ * @link https://webpack.js.org/loaders/babel-loader/#options
10
+ */
11
+ export type BabelLoader = {
12
+ cacheDirectory?: boolean | string;
13
+ cacheIdentifier?: string;
14
+ cacheCompression?: boolean;
15
+ customize?: string;
16
+ metadataSubscribers?: string[];
17
+ }
18
+
19
+ /**
20
+ * Use Babel's preset-env to add support for target browsers.
21
+ *
22
+ * @note Set the `debug` option to `true` to debug the included polyfills and plugins.
23
+ *
24
+ * @see https://babeljs.io/docs/en/babel-preset-env
25
+ */
26
+ const presetEnv: Options = {
27
+ bugfixes: true,
28
+ corejs: {
29
+ // Use the core-js version currently installed in the project.
30
+ version: require( 'core-js/package.json' ).version,
31
+ proposals: false,
32
+ },
33
+ // Enable the `debug` option to debug the included polyfills and plugins.
34
+ debug: false,
35
+ // Ignore any external browserslist in favor of `getBrowsersList()`.
36
+ ignoreBrowserslistConfig: true,
37
+ shippedProposals: false,
38
+ targets: {
39
+ browsers: getBrowsersList(),
40
+ },
41
+ useBuiltIns: 'usage',
42
+ };
43
+
44
+
45
+ const babelConfig: BabelConfig = {
46
+ cacheDirectory: true,
47
+ presets: [
48
+ [ '@babel/preset-env', presetEnv ],
49
+ [ '@babel/preset-react', {
50
+ development: 'production' !== process.env.NODE_ENV,
51
+ runtime: 'automatic',
52
+ } ],
53
+ '@babel/preset-typescript',
54
+ ],
55
+ plugins: [
56
+ '@babel/plugin-syntax-dynamic-import',
57
+ ],
58
+ };
59
+
60
+ export default babelConfig;
61
+ module.exports = babelConfig;
@@ -1,3 +1,4 @@
1
+ "use strict";
1
2
  /**
2
3
  * Entry points to be loaded by Webpack.
3
4
  *
@@ -6,15 +7,17 @@
6
7
  *
7
8
  * @see getEntries
8
9
  */
9
- module.exports = {
10
- master: [
11
- 'index.js',
12
- 'index.ts',
13
- 'index.tsx',
14
- ],
15
- admin: [
16
- 'admin.js',
17
- 'admin.ts',
18
- 'admin.tsx',
19
- ],
10
+ Object.defineProperty(exports, "__esModule", { value: true });
11
+ const entries = {
12
+ master: [
13
+ 'index.js',
14
+ 'index.ts',
15
+ 'index.tsx',
16
+ ],
17
+ admin: [
18
+ 'admin.js',
19
+ 'admin.ts',
20
+ 'admin.tsx',
21
+ ],
20
22
  };
23
+ module.exports = entries;
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Entry points to be loaded by Webpack.
3
+ *
4
+ * Checks for sources in the order they are defined and creates a
5
+ * single entry per key if a source file exists.
6
+ *
7
+ * @see getEntries
8
+ */
9
+
10
+ export type EntriesConfig = {
11
+ [file: string]: string[];
12
+ };
13
+
14
+ const entries: EntriesConfig = {
15
+ master: [
16
+ 'index.js',
17
+ 'index.ts',
18
+ 'index.tsx',
19
+ ],
20
+ admin: [
21
+ 'admin.js',
22
+ 'admin.ts',
23
+ 'admin.tsx',
24
+ ],
25
+ };
26
+
27
+ module.exports = entries;
@@ -1,46 +1,41 @@
1
- 'use strict';
2
- Object.defineProperty( exports, '__esModule', {value: true} );
3
- /**
4
- * Generated from the `src` directory to compile TS to JS because JEST
5
- * does not support using TS files as part of the JEST configuration when
6
- * located in a `node_modules directory.
7
- *
8
- */
9
- const path_1 = require( 'path' );
10
- const {getPackageConfig} = require( '../helpers/package-config' );
11
- const fs_1 = require( 'fs' );
12
- const packageConfig = getPackageConfig();
13
- const babelConfig = require( '../helpers/config' ).getConfig( 'babel.config' );
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const path_1 = require("path");
4
+ const fs_1 = require("fs");
5
+ const package_config_1 = require("../helpers/package-config");
6
+ const config_1 = require("../helpers/config");
7
+ const { workingDirectory, url } = (0, package_config_1.getPackageConfig)();
8
+ const babelConfig = (0, config_1.getConfig)('babel.config');
14
9
  delete babelConfig.cacheDirectory;
15
10
  const jestConfig = {
16
- globals: {
17
- __TEST__: true,
18
- },
19
- moduleNameMapper: {
20
- '\\.(pcss|less|css)$': 'identity-obj-proxy',
21
- 'is-plain-obj': 'identity-obj-proxy',
22
- uuid: 'identity-obj-proxy',
23
- },
24
- roots: [
25
- './tests',
26
- ],
27
- testEnvironment: 'jsdom',
28
- testEnvironmentOptions: {
29
- url: packageConfig.url,
30
- },
31
- transform: {
32
- '^.+\\.[tj]sx?$': [ 'babel-jest', babelConfig ],
33
- },
34
- transformIgnorePatterns: [
35
- 'node_modules/(?!@lipemat)',
36
- ],
37
- setupFilesAfterEnv: [
38
- // @todo Remove old "tests" directory in version 11.
39
- ( 0, path_1.resolve )( packageConfig.workingDirectory, 'tests/setup.js' ),
40
- ( 0, path_1.resolve )( packageConfig.workingDirectory, 'tests/setup.ts' ),
41
- // New location.
42
- ( 0, path_1.resolve )( packageConfig.workingDirectory, 'jest/setup.ts' ),
43
- ].filter( fs_1.existsSync ),
11
+ globals: {
12
+ __TEST__: true,
13
+ },
14
+ moduleNameMapper: {
15
+ '\\.(pcss|less|css)$': 'identity-obj-proxy',
16
+ 'is-plain-obj': 'identity-obj-proxy',
17
+ uuid: 'identity-obj-proxy',
18
+ },
19
+ roots: [
20
+ './tests',
21
+ ],
22
+ testEnvironment: 'jsdom',
23
+ testEnvironmentOptions: {
24
+ url,
25
+ },
26
+ transform: {
27
+ '^.+\\.[tj]sx?$': ['babel-jest', babelConfig],
28
+ },
29
+ transformIgnorePatterns: [
30
+ 'node_modules/(?!@lipemat)',
31
+ ],
32
+ setupFilesAfterEnv: [
33
+ // @todo Remove old "tests" directory in version 11.
34
+ (0, path_1.resolve)(workingDirectory, 'tests/setup.js'),
35
+ (0, path_1.resolve)(workingDirectory, 'tests/setup.ts'),
36
+ // New location.
37
+ (0, path_1.resolve)(workingDirectory, 'jest/setup.ts'),
38
+ ].filter(fs_1.existsSync),
44
39
  };
45
40
  exports.default = jestConfig;
46
41
  module.exports = jestConfig;
@@ -0,0 +1,47 @@
1
+ import {resolve} from 'path';
2
+ import type {Config} from 'jest';
3
+ import {existsSync} from 'fs';
4
+ import {getPackageConfig} from '../helpers/package-config';
5
+ import {getConfig} from '../helpers/config';
6
+
7
+
8
+ export type JestConfig = Pick<Config, 'globals' | 'moduleNameMapper' | 'roots' | 'testEnvironment' | 'testEnvironmentOptions' | 'transform' | 'transformIgnorePatterns' | 'setupFilesAfterEnv'>;
9
+
10
+ const {workingDirectory, url} = getPackageConfig();
11
+ const babelConfig = getConfig( 'babel.config' );
12
+ delete babelConfig.cacheDirectory;
13
+
14
+
15
+ const jestConfig: Config = {
16
+ globals: {
17
+ __TEST__: true,
18
+ },
19
+ moduleNameMapper: {
20
+ '\\.(pcss|less|css)$': 'identity-obj-proxy',
21
+ 'is-plain-obj': 'identity-obj-proxy',
22
+ uuid: 'identity-obj-proxy',
23
+ },
24
+ roots: [
25
+ './tests',
26
+ ],
27
+ testEnvironment: 'jsdom',
28
+ testEnvironmentOptions: {
29
+ url,
30
+ },
31
+ transform: {
32
+ '^.+\\.[tj]sx?$': [ 'babel-jest', babelConfig ],
33
+ },
34
+ transformIgnorePatterns: [
35
+ 'node_modules/(?!@lipemat)',
36
+ ],
37
+ setupFilesAfterEnv: [
38
+ // @todo Remove old "tests" directory in version 11.
39
+ resolve( workingDirectory, 'tests/setup.js' ),
40
+ resolve( workingDirectory, 'tests/setup.ts' ),
41
+ // New location.
42
+ resolve( workingDirectory, 'jest/setup.ts' ),
43
+ ].filter( existsSync ),
44
+ };
45
+
46
+ export default jestConfig;
47
+ module.exports = jestConfig;
package/helpers/config.js CHANGED
@@ -1,14 +1,16 @@
1
- const packageConfig = require( './package-config' );
2
- const path = require( 'path' );
3
- const browserslist = require( 'browserslist' );
4
- const fs = require( 'fs' );
5
- const config = require( './package-config' );
6
-
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.adjustBrowserslist = exports.getDefaultBrowsersList = exports.getBrowsersList = exports.getTsConfigFile = exports.getExtensionsConfig = exports.getConfig = exports.hasLocalOverride = void 0;
4
+ const fs_1 = require("fs");
5
+ const path_1 = require("path");
6
+ const package_config_1 = require("./package-config");
7
+ // Must be required to avoid issues with browserslist.
8
+ const browserslist = require('browserslist');
9
+ const { dependencies, devDependencies, workingDirectory, packageDirectory } = (0, package_config_1.getPackageConfig)();
7
10
  const extensions = [
8
- ...Object.keys( packageConfig.dependencies ?? {} ).filter( name => name.includes( 'js-boilerplate-' ) ),
9
- ...Object.keys( packageConfig.devDependencies ?? {} ).filter( name => name.includes( 'js-boilerplate-' ) ),
11
+ ...Object.keys(dependencies ?? {}).filter(name => name.includes('js-boilerplate-')),
12
+ ...Object.keys(devDependencies ?? {}).filter(name => name.includes('js-boilerplate-')),
10
13
  ];
11
-
12
14
  /**
13
15
  * Check to see if a local config file exists.
14
16
  *
@@ -17,22 +19,23 @@ const extensions = [
17
19
  *
18
20
  * @return {boolean}
19
21
  */
20
- function hasLocalOverride( fileName, inWorkingDirectory = false, ) {
21
- let hasLocal = false;
22
- try {
23
- if ( inWorkingDirectory ) {
24
- require( path.resolve( packageConfig.workingDirectory, fileName ) );
25
- hasLocal = true;
26
- } else {
27
- require( path.resolve( packageConfig.packageDirectory + '/config', fileName ) );
28
- hasLocal = true;
29
- }
30
- } catch ( e ) {
31
- }
32
-
33
- return hasLocal;
22
+ function hasLocalOverride(fileName, inWorkingDirectory = false) {
23
+ let hasLocal = false;
24
+ try {
25
+ if (inWorkingDirectory) {
26
+ require((0, path_1.resolve)(workingDirectory, fileName));
27
+ hasLocal = true;
28
+ }
29
+ else {
30
+ require((0, path_1.resolve)(packageDirectory + '/config', fileName));
31
+ hasLocal = true;
32
+ }
33
+ }
34
+ catch (e) {
35
+ }
36
+ return hasLocal;
34
37
  }
35
-
38
+ exports.hasLocalOverride = hasLocalOverride;
36
39
  /**
37
40
  * Get a config from our /config directory merged with any
38
41
  * matching configuration from the project directory.
@@ -61,21 +64,23 @@ function hasLocalOverride( fileName, inWorkingDirectory = false, ) {
61
64
  *
62
65
  * @return {Object}
63
66
  */
64
- function getConfig( fileName ) {
65
- let mergedConfig = require( '../config/' + fileName );
66
- mergedConfig = {...mergedConfig, ...getExtensionsConfig( fileName, mergedConfig )};
67
- try {
68
- const localConfig = require( path.resolve( packageConfig.packageDirectory + '/config', fileName ) );
69
- if ( 'function' === typeof localConfig ) {
70
- mergedConfig = {...mergedConfig, ...localConfig( mergedConfig )};
71
- } else {
72
- mergedConfig = {...mergedConfig, ...localConfig};
73
- }
74
- } catch ( e ) {
75
- }
76
- return mergedConfig;
67
+ function getConfig(fileName) {
68
+ let mergedConfig = require('../config/' + fileName);
69
+ mergedConfig = { ...mergedConfig, ...getExtensionsConfig(fileName, mergedConfig) };
70
+ try {
71
+ const localConfig = require((0, path_1.resolve)(packageDirectory + '/config', fileName));
72
+ if ('function' === typeof localConfig) {
73
+ mergedConfig = { ...mergedConfig, ...localConfig(mergedConfig) };
74
+ }
75
+ else {
76
+ mergedConfig = { ...mergedConfig, ...localConfig };
77
+ }
78
+ }
79
+ catch (e) {
80
+ }
81
+ return mergedConfig;
77
82
  }
78
-
83
+ exports.getConfig = getConfig;
79
84
  /**
80
85
  * Get a config from any existing extension's /config directories
81
86
  * merged into one.
@@ -88,23 +93,24 @@ function getConfig( fileName ) {
88
93
  *
89
94
  * @return {Object}
90
95
  */
91
- function getExtensionsConfig( fileName, defaultConfig ) {
92
- let mergedConfig = {};
93
- extensions.forEach( extension => {
94
- try {
95
- const extensionConfig = require( extension + '/config/' + fileName );
96
- if ( 'function' === typeof extensionConfig ) {
97
- mergedConfig = {...mergedConfig, ...extensionConfig( {...defaultConfig, ...mergedConfig} )};
98
- } else {
99
- mergedConfig = {...mergedConfig, ...extensionConfig};
100
- }
101
- } catch ( e ) {
102
- }
103
- } );
104
-
105
- return mergedConfig;
96
+ function getExtensionsConfig(fileName, defaultConfig) {
97
+ let mergedConfig = {};
98
+ extensions.forEach(extension => {
99
+ try {
100
+ const extensionConfig = require(extension + '/config/' + fileName);
101
+ if ('function' === typeof extensionConfig) {
102
+ mergedConfig = { ...mergedConfig, ...extensionConfig({ ...defaultConfig, ...mergedConfig }) };
103
+ }
104
+ else {
105
+ mergedConfig = { ...mergedConfig, ...extensionConfig };
106
+ }
107
+ }
108
+ catch (e) {
109
+ }
110
+ });
111
+ return mergedConfig;
106
112
  }
107
-
113
+ exports.getExtensionsConfig = getExtensionsConfig;
108
114
  /**
109
115
  * Get the path to the "tsconfig.json" file if it exists.
110
116
  *
@@ -117,20 +123,18 @@ function getExtensionsConfig( fileName, defaultConfig ) {
117
123
  * @return {string}
118
124
  */
119
125
  function getTsConfigFile() {
120
- const possibles = [
121
- // Backward compatible for before @lipemat/eslint-config version 3.
122
- path.resolve( config.workingDirectory + '/tsconfig.json' ),
123
- path.resolve( config.packageDirectory + '/tsconfig.json' ),
124
- ];
125
- let tsConfig = '';
126
- possibles.forEach( filePath => {
127
- if ( fs.existsSync( filePath ) ) {
128
- tsConfig = filePath;
129
- }
130
- } );
131
- return tsConfig;
126
+ const possibles = [
127
+ // Backward compatible for before @lipemat/eslint-config version 3.
128
+ (0, path_1.resolve)(workingDirectory + '/tsconfig.json'),
129
+ (0, path_1.resolve)(packageDirectory + '/tsconfig.json'),
130
+ ].filter(fs_1.existsSync);
131
+ let tsConfig = '';
132
+ possibles.forEach(filePath => {
133
+ tsConfig = filePath;
134
+ });
135
+ return tsConfig;
132
136
  }
133
-
137
+ exports.getTsConfigFile = getTsConfigFile;
134
138
  /**
135
139
  * Get the browserslist from the current project.
136
140
  *
@@ -139,14 +143,14 @@ function getTsConfigFile() {
139
143
  * @link https://github.com/browserslist/browserslist#config-file
140
144
  */
141
145
  function getBrowsersList() {
142
- const projectBrowsersList = browserslist();
143
- if ( browserslist( browserslist.defaults ) === projectBrowsersList ) {
144
- const wp = [ ...require( '@wordpress/browserslist-config' ) ];
145
- return adjustBrowserslist( wp );
146
- }
147
- return projectBrowsersList;
146
+ const projectBrowsersList = browserslist();
147
+ if (browserslist(browserslist.defaults) === projectBrowsersList) {
148
+ const wp = [...require('@wordpress/browserslist-config')];
149
+ return adjustBrowserslist(wp);
150
+ }
151
+ return projectBrowsersList;
148
152
  }
149
-
153
+ exports.getBrowsersList = getBrowsersList;
150
154
  /**
151
155
  * If browserslist is not specified, we fall back to WordPress defaults.
152
156
  *
@@ -157,35 +161,26 @@ function getBrowsersList() {
157
161
  * has not specified one.
158
162
  *
159
163
  * @deprecated Use getBrowsersList instead.
164
+ *
160
165
  * @link https://github.com/browserslist/browserslist#config-file
161
166
  *
162
167
  * @return {boolean | string[]}
163
168
  */
164
169
  const getDefaultBrowsersList = () => {
165
- if ( browserslist( browserslist.defaults ) === browserslist() ) {
166
- const wp = [ ...require( '@wordpress/browserslist-config' ) ];
167
- return adjustBrowserslist( wp );
168
- }
169
- return false;
170
+ if (browserslist(browserslist.defaults) === browserslist()) {
171
+ const wp = [...require('@wordpress/browserslist-config')];
172
+ return adjustBrowserslist(wp);
173
+ }
174
+ return false;
170
175
  };
171
-
176
+ exports.getDefaultBrowsersList = getDefaultBrowsersList;
172
177
  /**
173
178
  * Adjust the browserslist to include our defaults.
174
179
  *
175
180
  * @todo Remove `not op_mini all` after 3/8/2024 if it does not creep back in to the defaults.
176
181
  */
177
- function adjustBrowserslist( browserRules ) {
178
- browserRules.push( 'not op_mini all' );
179
- return browserRules;
182
+ function adjustBrowserslist(browserRules) {
183
+ browserRules.push('not op_mini all');
184
+ return browserRules;
180
185
  }
181
-
182
-
183
- module.exports = {
184
- adjustBrowserslist,
185
- getBrowsersList,
186
- getConfig,
187
- getDefaultBrowsersList,
188
- getExtensionsConfig,
189
- getTsConfigFile,
190
- hasLocalOverride,
191
- };
186
+ exports.adjustBrowserslist = adjustBrowserslist;
@@ -0,0 +1,200 @@
1
+ import {existsSync} from 'fs';
2
+ import {resolve} from 'path';
3
+ import type {BabelConfig} from '../config/babel.config';
4
+ import type {JestConfig} from '../config/jest.config';
5
+ import {getPackageConfig} from './package-config';
6
+ import type {EntriesConfig} from '../config/entries.config';
7
+
8
+ // Must be required to avoid issues with browserslist.
9
+ const browserslist = require( 'browserslist' );
10
+
11
+
12
+ type Configs = {
13
+ 'babel.config': BabelConfig;
14
+ 'jest.config': JestConfig;
15
+ 'entries.config': EntriesConfig;
16
+ };
17
+
18
+ const {dependencies, devDependencies, workingDirectory, packageDirectory} = getPackageConfig();
19
+
20
+ const extensions = [
21
+ ...Object.keys( dependencies ?? {} ).filter( name => name.includes( 'js-boilerplate-' ) ),
22
+ ...Object.keys( devDependencies ?? {} ).filter( name => name.includes( 'js-boilerplate-' ) ),
23
+ ];
24
+
25
+
26
+ /**
27
+ * Check to see if a local config file exists.
28
+ *
29
+ * @param {string} fileName
30
+ * @param {boolean} inWorkingDirectory - Look in working directory instead of their /config directory
31
+ *
32
+ * @return {boolean}
33
+ */
34
+ export function hasLocalOverride( fileName: string, inWorkingDirectory: boolean = false ): boolean {
35
+ let hasLocal = false;
36
+ try {
37
+ if ( inWorkingDirectory ) {
38
+ require( resolve( workingDirectory, fileName ) );
39
+ hasLocal = true;
40
+ } else {
41
+ require( resolve( packageDirectory + '/config', fileName ) );
42
+ hasLocal = true;
43
+ }
44
+ } catch ( e ) {
45
+ }
46
+
47
+ return hasLocal;
48
+ }
49
+
50
+
51
+ /**
52
+ * Get a config from our /config directory merged with any
53
+ * matching configuration from the project directory.
54
+ *
55
+ * For instance if we have a file named config/babel.config.js in our project
56
+ * we will merge the contents with our config/babel.config.js in favor of whatever
57
+ * is specified with the project's file.
58
+ *
59
+ * If the `module.exports` are a function, the existing configuration will be passed
60
+ * as the only argument. Otherwise, standard `module.exports` are also supported.
61
+ *
62
+ * @example ```ts
63
+ * // standard
64
+ * module.export = {
65
+ * externals: {extra: 'Extra'}
66
+ * }
67
+ * // function
68
+ * module.exports = function( config ) {
69
+ * return {
70
+ * externals: {...config.externals, extra: 'Extra'}
71
+ * }
72
+ * }
73
+ * ```
74
+ *
75
+ * @param {string} fileName
76
+ *
77
+ * @return {Object}
78
+ */
79
+ export function getConfig<T extends keyof Configs>( fileName: T ): Configs[T] {
80
+ let mergedConfig = require( '../config/' + fileName ) as Configs[T];
81
+ mergedConfig = {...mergedConfig, ...getExtensionsConfig<Configs[T]>( fileName, mergedConfig )};
82
+ try {
83
+ const localConfig = require( resolve( packageDirectory + '/config', fileName ) );
84
+ if ( 'function' === typeof localConfig ) {
85
+ mergedConfig = {...mergedConfig, ...localConfig( mergedConfig )};
86
+ } else {
87
+ mergedConfig = {...mergedConfig, ...localConfig};
88
+ }
89
+ } catch ( e ) {
90
+ }
91
+ return mergedConfig;
92
+ }
93
+
94
+
95
+ /**
96
+ * Get a config from any existing extension's /config directories
97
+ * merged into one.
98
+ *
99
+ * @param {string} fileName
100
+ * @param {Object} defaultConfig - Default config from this package.
101
+ * Used for passing to an extension callback.
102
+ *
103
+ * @see getConfig
104
+ *
105
+ * @return {Object}
106
+ */
107
+ export function getExtensionsConfig<T extends object>( fileName: string, defaultConfig: T ): T {
108
+ let mergedConfig: T = {} as T;
109
+ extensions.forEach( extension => {
110
+ try {
111
+ const extensionConfig = require( extension + '/config/' + fileName );
112
+ if ( 'function' === typeof extensionConfig ) {
113
+ mergedConfig = {...mergedConfig, ...extensionConfig( {...defaultConfig, ...mergedConfig} )};
114
+ } else {
115
+ mergedConfig = {...mergedConfig, ...extensionConfig};
116
+ }
117
+ } catch ( e ) {
118
+ }
119
+ } );
120
+
121
+ return mergedConfig;
122
+ }
123
+
124
+
125
+ /**
126
+ * Get the path to the "tsconfig.json" file if it exists.
127
+ *
128
+ * 1. The working directory.
129
+ * 2. The package directory.
130
+ *
131
+ * The package directory takes priority over the working directory.
132
+ *
133
+ *
134
+ * @return {string}
135
+ */
136
+ export function getTsConfigFile(): string {
137
+ const possibles = [
138
+ // Backward compatible for before @lipemat/eslint-config version 3.
139
+ resolve( workingDirectory + '/tsconfig.json' ),
140
+ resolve( packageDirectory + '/tsconfig.json' ),
141
+ ].filter( existsSync );
142
+
143
+ let tsConfig = '';
144
+ possibles.forEach( filePath => {
145
+ tsConfig = filePath;
146
+ } );
147
+ return tsConfig;
148
+ }
149
+
150
+
151
+ /**
152
+ * Get the browserslist from the current project.
153
+ *
154
+ * - If specified using standard browserslist config, we will use that.
155
+ *
156
+ * @link https://github.com/browserslist/browserslist#config-file
157
+ */
158
+ export function getBrowsersList(): readonly string[] {
159
+ const projectBrowsersList = browserslist();
160
+ if ( browserslist( browserslist.defaults ) === projectBrowsersList ) {
161
+ const wp = [ ...require( '@wordpress/browserslist-config' ) ];
162
+ return adjustBrowserslist( wp );
163
+ }
164
+ return projectBrowsersList;
165
+ }
166
+
167
+
168
+ /**
169
+ * If browserslist is not specified, we fall back to WordPress defaults.
170
+ *
171
+ * - Return the default browserslist if the current project does not specify one.
172
+ * - Return false if a browserslist is specified.
173
+ *
174
+ * Used in cases where we can fall back to standard browserslist config if the project
175
+ * has not specified one.
176
+ *
177
+ * @deprecated Use getBrowsersList instead.
178
+ *
179
+ * @link https://github.com/browserslist/browserslist#config-file
180
+ *
181
+ * @return {boolean | string[]}
182
+ */
183
+ export const getDefaultBrowsersList = (): false | string[] => {
184
+ if ( browserslist( browserslist.defaults ) === browserslist() ) {
185
+ const wp = [ ...require( '@wordpress/browserslist-config' ) ];
186
+ return adjustBrowserslist( wp );
187
+ }
188
+ return false;
189
+ };
190
+
191
+
192
+ /**
193
+ * Adjust the browserslist to include our defaults.
194
+ *
195
+ * @todo Remove `not op_mini all` after 3/8/2024 if it does not creep back in to the defaults.
196
+ */
197
+ export function adjustBrowserslist( browserRules: string[] ): string[] {
198
+ browserRules.push( 'not op_mini all' );
199
+ return browserRules;
200
+ }
@@ -1,11 +1,11 @@
1
- const config = require( './package-config' );
2
- const fs = require( 'fs' );
3
- const path = require( 'path' );
4
- const {getConfig} = require( './config' );
5
-
6
- const entries = getConfig( 'entries.config' );
7
-
8
-
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getEntries = void 0;
4
+ const config_1 = require("./config");
5
+ const package_config_1 = require("./package-config");
6
+ const fs_1 = require("fs");
7
+ const path_1 = require("path");
8
+ const entries = (0, config_1.getConfig)('entries.config');
9
9
  /**
10
10
  * Entry points to be loaded by Webpack.
11
11
  *
@@ -15,20 +15,17 @@ const entries = getConfig( 'entries.config' );
15
15
  * @see entries.config.js
16
16
  */
17
17
  function getEntries() {
18
- const matches = {};
19
- Object.keys( entries ).forEach( name => {
20
- entries[ name ].some( possibleFile => {
21
- const filePath = config.workingDirectory + '/src/' + possibleFile;
22
- if ( fs.existsSync( path.resolve( filePath ) ) ) {
23
- matches[ name ] = path.resolve( filePath );
24
- return true;
25
- }
26
- return false;
27
- } );
28
- } );
29
- return matches;
18
+ const matches = {};
19
+ Object.keys(entries).forEach(name => {
20
+ entries[name].some(possibleFile => {
21
+ const filePath = (0, package_config_1.getPackageConfig)().workingDirectory + '/src/' + possibleFile;
22
+ if ((0, fs_1.existsSync)((0, path_1.resolve)(filePath))) {
23
+ matches[name] = (0, path_1.resolve)(filePath);
24
+ return true;
25
+ }
26
+ return false;
27
+ });
28
+ });
29
+ return matches;
30
30
  }
31
-
32
- module.exports = {
33
- getEntries,
34
- };
31
+ exports.getEntries = getEntries;
@@ -0,0 +1,30 @@
1
+ import {getConfig} from './config';
2
+ import {getPackageConfig} from './package-config';
3
+ import {existsSync} from 'fs';
4
+ import {resolve} from 'path';
5
+ import type {EntriesConfig} from '../config/entries.config';
6
+
7
+ const entries: EntriesConfig = getConfig( 'entries.config' );
8
+
9
+ /**
10
+ * Entry points to be loaded by Webpack.
11
+ *
12
+ * Checks for sources in the order they are defined and creates a
13
+ * single entry per key if a source file exists.
14
+ *
15
+ * @see entries.config.js
16
+ */
17
+ export function getEntries(): { [ name: string ]: string } {
18
+ const matches: {[name: string]: string} = {};
19
+ Object.keys( entries ).forEach( name => {
20
+ entries[ name ].some( possibleFile => {
21
+ const filePath = getPackageConfig().workingDirectory + '/src/' + possibleFile;
22
+ if ( existsSync( resolve( filePath ) ) ) {
23
+ matches[ name ] = resolve( filePath );
24
+ return true;
25
+ }
26
+ return false;
27
+ } );
28
+ } );
29
+ return matches;
30
+ }
@@ -1,7 +1,9 @@
1
- const areYouES5 = require( 'are-you-es5' );
2
- const regexBuilder = require( 'are-you-es5/dist/babel-loader-regex-builder' );
3
- const config = require( './package-config' );
4
-
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getBabelExcludeRegex = void 0;
4
+ const babel_loader_regex_builder_1 = require("are-you-es5/dist/babel-loader-regex-builder");
5
+ const package_config_1 = require("./package-config");
6
+ const are_you_es5_1 = require("are-you-es5");
5
7
  /**
6
8
  * Using `are-you-es5` generate a list of top level dependencies
7
9
  * which are not ES5 safe. Create a regular expression which excludes
@@ -14,14 +16,13 @@ const config = require( './package-config' );
14
16
  * @return {RegExp}
15
17
  */
16
18
  function getBabelExcludeRegex() {
17
- const nonES5 = areYouES5.checkModules( {} );
18
- // Support specifying additional es5Modules in package.json.
19
- const regex = regexBuilder.getBabelLoaderIgnoreRegex( [ ...nonES5.es6Modules, ...config.es6Modules ] );
20
-
21
- // We must strip off the leading and trailing '/'.
22
- return new RegExp( regex.replace( /^\/|\/$/g, '' ) );
19
+ const nonES5 = (0, are_you_es5_1.checkModules)({});
20
+ // Support specifying additional es5Modules in package.json.
21
+ const regex = (0, babel_loader_regex_builder_1.getBabelLoaderIgnoreRegex)([
22
+ ...nonES5.es6Modules,
23
+ ...(0, package_config_1.getPackageConfig)().es6Modules,
24
+ ]);
25
+ // We must strip off the leading and trailing '/'.
26
+ return new RegExp(regex.replace(/^\/|\/$/g, ''));
23
27
  }
24
-
25
- module.exports = {
26
- getBabelExcludeRegex,
27
- };
28
+ exports.getBabelExcludeRegex = getBabelExcludeRegex;
@@ -0,0 +1,26 @@
1
+ import {getBabelLoaderIgnoreRegex} from 'are-you-es5/dist/babel-loader-regex-builder';
2
+ import {getPackageConfig} from './package-config';
3
+ import {checkModules} from 'are-you-es5';
4
+
5
+ /**
6
+ * Using `are-you-es5` generate a list of top level dependencies
7
+ * which are not ES5 safe. Create a regular expression which excludes
8
+ * the `node_modules` directory except for any ES6 modules.
9
+ *
10
+ * Allows Babel to transpile any node_modules which are not available in ES5.
11
+ *
12
+ * @notice Only checks packages listed in package.json, not sub packages.
13
+ *
14
+ * @return {RegExp}
15
+ */
16
+ export function getBabelExcludeRegex(): RegExp {
17
+ const nonES5 = checkModules( {} );
18
+ // Support specifying additional es5Modules in package.json.
19
+ const regex = getBabelLoaderIgnoreRegex( [
20
+ ...nonES5.es6Modules,
21
+ ...getPackageConfig().es6Modules,
22
+ ] );
23
+
24
+ // We must strip off the leading and trailing '/'.
25
+ return new RegExp( regex.replace( /^\/|\/$/g, '' ) );
26
+ }
@@ -1,25 +1,27 @@
1
- const path = require( 'path' );
2
- const fs = require( 'fs' );
3
-
4
- const workingDirectory = fs.realpathSync( process.cwd() );
5
- let packageConfig = require( path.resolve( workingDirectory, 'package.json' ) );
6
- packageConfig.brotliFiles ||= false;
7
- packageConfig.es6Modules ||= [];
8
- packageConfig.jsPath ||= '';
9
- // Path of the package.json file (root).
10
- packageConfig.packageDirectory = workingDirectory;
11
- packageConfig.url ||= 'http://localhost';
12
- // Path of JS application files.
13
- packageConfig.workingDirectory = packageConfig.jsPath !== '' ? path.resolve( packageConfig.jsPath ) : workingDirectory;
14
- packageConfig.shortCssClasses ||= false;
15
- packageConfig.tsCssModules ||= false;
16
-
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getPackageConfig = void 0;
4
+ const path_1 = require("path");
5
+ const node_fs_1 = require("node:fs");
6
+ const workingDirectory = (0, node_fs_1.realpathSync)(process.cwd());
7
+ const defaults = {
8
+ brotliFiles: false,
9
+ cssTsFiles: false,
10
+ es6Modules: [],
11
+ jsPath: '',
12
+ packageDirectory: workingDirectory,
13
+ shortCssClasses: false,
14
+ url: 'http://localhost',
15
+ };
16
+ let packageConfig = require((0, path_1.resolve)(workingDirectory, 'package.json'));
17
+ packageConfig = { ...defaults, ...packageConfig };
18
+ packageConfig.workingDirectory = packageConfig.jsPath !== '' ? (0, path_1.resolve)(packageConfig.jsPath) : workingDirectory;
17
19
  try {
18
- const localConfig = require( path.resolve( workingDirectory, './local-config.json' ) );
19
- packageConfig = {...packageConfig, ...localConfig};
20
- } catch ( e ) {
20
+ const localConfig = require((0, path_1.resolve)(workingDirectory, './local-config.json'));
21
+ packageConfig = { ...packageConfig, ...localConfig };
22
+ }
23
+ catch (e) {
21
24
  }
22
-
23
25
  /**
24
26
  * Helper function to get the results of `packageConfig`.
25
27
  *
@@ -29,8 +31,9 @@ try {
29
31
  * @since 10.3.0
30
32
  */
31
33
  function getPackageConfig() {
32
- return packageConfig;
34
+ return packageConfig;
33
35
  }
36
+ exports.getPackageConfig = getPackageConfig;
34
37
  packageConfig.getPackageConfig = getPackageConfig;
35
-
38
+ packageConfig.default = packageConfig;
36
39
  module.exports = packageConfig;
@@ -0,0 +1,85 @@
1
+ import {resolve} from 'path';
2
+ import {realpathSync} from 'node:fs';
3
+
4
+ export interface PackageConfig {
5
+ author?: string;
6
+ brotliFiles: boolean;
7
+ certificates?: Certificates;
8
+ combinedJson: boolean;
9
+ cssTsFiles: boolean;
10
+ css_folder: string;
11
+ default: PackageConfig;
12
+ dependencies: Dependencies;
13
+ description?: string;
14
+ devDependencies: Dependencies;
15
+ es6Modules: string[];
16
+ getPackageConfig: () => PackageConfig;
17
+ jsPath: string;
18
+ license?: string;
19
+ name?: string;
20
+ packageDirectory: string;
21
+ packageManager?: string;
22
+ resolutions?: Dependencies;
23
+ scripts: Partial<Scripts>;
24
+ shortCssClasses: boolean;
25
+ url: string;
26
+ version?: string;
27
+ workingDirectory: string;
28
+ }
29
+
30
+ export interface Dependencies {
31
+ [ name: string ]: string;
32
+ }
33
+
34
+ export interface Certificates {
35
+ cert: string;
36
+ key: string;
37
+ }
38
+
39
+ export interface Scripts {
40
+ browserslist: string;
41
+ dist: string;
42
+ lint: string;
43
+ postinstall: string;
44
+ start: string;
45
+ test: string;
46
+ }
47
+
48
+
49
+ const workingDirectory = realpathSync( process.cwd() );
50
+
51
+ const defaults: Partial<PackageConfig> = {
52
+ brotliFiles: false,
53
+ cssTsFiles: false,
54
+ es6Modules: [],
55
+ jsPath: '',
56
+ packageDirectory: workingDirectory,
57
+ shortCssClasses: false,
58
+ url: 'http://localhost',
59
+ }
60
+
61
+ let packageConfig: PackageConfig = require( resolve( workingDirectory, 'package.json' ) );
62
+ packageConfig = {...defaults, ...packageConfig};
63
+ packageConfig.workingDirectory = packageConfig.jsPath !== '' ? resolve( packageConfig.jsPath ) : workingDirectory;
64
+
65
+ try {
66
+ const localConfig = require( resolve( workingDirectory, './local-config.json' ) );
67
+ packageConfig = {...packageConfig, ...localConfig};
68
+ } catch ( e ) {
69
+ }
70
+
71
+ /**
72
+ * Helper function to get the results of `packageConfig`.
73
+ *
74
+ * - Allows mocking the results of `packageConfig` for testing.
75
+ * - Allows getting the config through a callback instead of an import.
76
+ *
77
+ * @since 10.3.0
78
+ */
79
+ export function getPackageConfig() {
80
+ return packageConfig;
81
+ }
82
+ packageConfig.getPackageConfig = getPackageConfig;
83
+
84
+ packageConfig.default = packageConfig;
85
+ module.exports = packageConfig;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lipemat/js-boilerplate",
3
- "version": "10.8.0-beta.2",
3
+ "version": "10.8.0-beta.4",
4
4
  "description": "Dependencies and scripts for a no config JavaScript app",
5
5
  "author": "Mat Lipe",
6
6
  "license": "MIT",
@@ -34,9 +34,10 @@
34
34
  },
35
35
  "scripts": {
36
36
  "browserslist": "lipemat-js-boilerplate browserslist",
37
- "build": "cd src && tsc && cd .. && eslint 'config/*.config.*' --fix --rule 'camelcase: 0'",
37
+ "build": "ts-node ./bin/build.ts",
38
38
  "prepublishOnly": "yarn run build",
39
- "test": "lipemat-js-boilerplate test"
39
+ "test": "lipemat-js-boilerplate test",
40
+ "watch": "ts-node ./bin/watch.ts"
40
41
  },
41
42
  "dependencies": {
42
43
  "@babel/core": "^7.4.3",
@@ -98,6 +99,7 @@
98
99
  "devDependencies": {
99
100
  "@types/jest": "^29.5.3",
100
101
  "@types/minimist": "^1",
102
+ "chokidar": "^3.5.3",
101
103
  "eslint": "^8",
102
104
  "glob": "^10.3.3",
103
105
  "memfs": "^3.5.3",
package/scripts/lint.ts CHANGED
@@ -2,7 +2,7 @@ import {ESLint} from 'eslint';
2
2
  import minimist from 'minimist';
3
3
  import chalk from 'chalk';
4
4
 
5
- import packageConfig from '../helpers/package-config';
5
+ import {getPackageConfig} from '../helpers/package-config';
6
6
 
7
7
  // Command line arguments.
8
8
  const flags = minimist( process.argv.slice( 2 ) );
@@ -35,7 +35,7 @@ function errorOccurred( results: ESLint.LintResult[] ): boolean {
35
35
 
36
36
  // 2. Lint files. This doesn't modify target files.
37
37
  const results: ESLint.LintResult[] = await eslint.lintFiles( [
38
- packageConfig.workingDirectory + '/src/**/*.{js,jsx,ts,tsx}',
38
+ getPackageConfig().workingDirectory + '/src/**/*.{js,jsx,ts,tsx}',
39
39
  ] );
40
40
 
41
41
  // 3. Modify the files with the fixed code.
@@ -1,13 +0,0 @@
1
- import type {TransformOptions} from '@babel/core';
2
- /**
3
- * @link https://webpack.js.org/loaders/babel-loader/#options
4
- */
5
- export type BabelLoader = {
6
- cacheDirectory?: boolean | string;
7
- cacheIdentifier?: string;
8
- cacheCompression?: boolean;
9
- customize?: string;
10
- metadataSubscribers?: string[];
11
- };
12
- declare const babelConfig: TransformOptions & BabelLoader;
13
- export default babelConfig;
@@ -1,3 +0,0 @@
1
- import type {Config} from 'jest';
2
- declare const jestConfig: Config;
3
- export default jestConfig;
@@ -1,7 +0,0 @@
1
- /**
2
- * @todo convert the source to TS.
3
- */
4
-
5
- export function getBrowsersList(): readonly string[];
6
-
7
- export function getConfig<T extends object>( fileName: string ): T;
@@ -1,46 +0,0 @@
1
- export interface PackageConfig {
2
- author?: string;
3
- brotliFiles: boolean;
4
- certificates?: Certificates;
5
- combinedJson: boolean;
6
- css_folder: string;
7
- cssTsFiles: boolean;
8
- dependencies: Dependencies;
9
- description?: string;
10
- devDependencies: Dependencies;
11
- es6Modules?: string[];
12
- jsPath: string;
13
- license?: string;
14
- name?: string;
15
- packageDirectory: string;
16
- packageManager?: string;
17
- resolutions?: Dependencies;
18
- scripts: Partial<Scripts>;
19
- shortCssClasses: boolean;
20
- url: string;
21
- version?: string;
22
- workingDirectory: string;
23
- }
24
-
25
- export interface Dependencies {
26
- [ name: string ]: string;
27
- }
28
-
29
- export interface Certificates {
30
- cert: string;
31
- key: string;
32
- }
33
-
34
- export interface Scripts {
35
- browserslist: string;
36
- dist: string;
37
- lint: string;
38
- postinstall: string;
39
- start: string;
40
- test: string;
41
- }
42
-
43
- declare const packageConfig: PackageConfig & {
44
- getPackageConfig: () => PackageConfig;
45
- };
46
- export default packageConfig;