itee-validators 5.5.0 → 5.6.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.
Files changed (36) hide show
  1. package/.github/workflows/node.js.yml +1 -1
  2. package/.tasks/_utils.mjs +66 -0
  3. package/.tasks/builds/build.mjs +65 -0
  4. package/.tasks/cleans/clean.mjs +20 -0
  5. package/.tasks/docs/doc.mjs +37 -0
  6. package/.tasks/helps/help.mjs +195 -0
  7. package/.tasks/lints/lint.mjs +33 -0
  8. package/.tasks/patches/patch.mjs +9 -0
  9. package/.tasks/tests/benchmarks/bundle-benchmarks.mjs +33 -0
  10. package/.tasks/tests/benchmarks/compute-benchmarks.mjs +215 -0
  11. package/.tasks/tests/benchmarks/run-benchmarks-for-backend.mjs +24 -0
  12. package/.tasks/tests/benchmarks/run-benchmarks-for-frontend.mjs +38 -0
  13. package/.tasks/tests/bundling/check-bundling-from-esm-build-import.mjs +167 -0
  14. package/.tasks/tests/bundling/check-bundling-from-esm-files-direct.mjs +129 -0
  15. package/.tasks/tests/bundling/check-bundling-from-esm-files-import.mjs +149 -0
  16. package/.tasks/tests/unit-tests/bundle-unit-tests.mjs +33 -0
  17. package/.tasks/tests/unit-tests/compute-unit-tests.mjs +578 -0
  18. package/.tasks/tests/unit-tests/run-unit-tests-for-backend.mjs +25 -0
  19. package/.tasks/tests/unit-tests/run-unit-tests-for-frontend.mjs +41 -0
  20. package/CHANGELOG.md +10 -0
  21. package/builds/itee-validators.cjs.js +18 -10
  22. package/builds/itee-validators.cjs.js.map +1 -1
  23. package/builds/itee-validators.cjs.min.js +62 -62
  24. package/builds/itee-validators.esm.js +2 -2
  25. package/builds/itee-validators.iife.js +4 -3
  26. package/builds/itee-validators.iife.js.map +1 -1
  27. package/builds/itee-validators.iife.min.js +17 -17
  28. package/package.json +1 -1
  29. package/sources/file-system/block-devices/isBlockDevicePath.js +2 -1
  30. package/sources/file-system/character-devices/isCharacterDevicePath.js +2 -1
  31. package/sources/file-system/directories/isDirectoryPath.js +2 -1
  32. package/sources/file-system/fifo-pipes/isFIFOPath.js +2 -1
  33. package/sources/file-system/files/isEmptyFile.js +2 -1
  34. package/sources/file-system/files/isFilePath.js +2 -1
  35. package/sources/file-system/sockets/isSocketPath.js +2 -1
  36. package/sources/file-system/symbolic-links/isSymbolicLinkPath.js +2 -1
@@ -0,0 +1,24 @@
1
+ import path from 'path'
2
+ import childProcess from 'child_process'
3
+ import {
4
+ getDirname,
5
+ packageInfos
6
+ } from '../../_utils.mjs'
7
+
8
+
9
+ function runBenchmarksForBackend( done ) {
10
+
11
+ const projectDir = getDirname()
12
+ const benchsPath = path.join( projectDir, `tests/benchmarks/builds/${ packageInfos.name }.benchs.cjs.js` )
13
+ const benchmark = childProcess.spawn( 'node', [ benchsPath ], { stdio: 'inherit' } )
14
+ benchmark.on( 'close', ( code ) => {
15
+
16
+ ( code === 0 )
17
+ ? done()
18
+ : done( `benchmark exited with code ${ code }` )
19
+
20
+ } )
21
+
22
+ }
23
+
24
+ export { runBenchmarksForBackend }
@@ -0,0 +1,38 @@
1
+ import path from 'path'
2
+ import karma from 'karma'
3
+ import log from 'fancy-log'
4
+ import colors from 'ansi-colors'
5
+ import { getDirname } from '../../_utils.mjs'
6
+
7
+ const {
8
+ red,
9
+ green,
10
+ blue,
11
+ cyan,
12
+ yellow,
13
+ magenta
14
+ } = colors
15
+
16
+
17
+ async function runBenchmarksForFrontend( done ) {
18
+
19
+ const projectDir = getDirname()
20
+ const configFile = path.normalize( `${ projectDir }/configs/karma.benchs.conf.js` )
21
+ const karmaConfig = karma.config.parseConfig( configFile )
22
+ const karmaServer = new karma.Server( karmaConfig, ( exitCode ) => {
23
+ if ( exitCode === 0 ) {
24
+ log( `Karma server exit with code ${ exitCode }` )
25
+ done()
26
+ } else {
27
+ done( `Karma server exit with code ${ exitCode }` )
28
+ }
29
+ } )
30
+ karmaServer.on( 'browser_error', ( browser, error ) => {
31
+ log( red( error.message ) )
32
+ } )
33
+
34
+ await karmaServer.start()
35
+
36
+ }
37
+
38
+ export { runBenchmarksForFrontend }
@@ -0,0 +1,167 @@
1
+ import {
2
+ join,
3
+ normalize,
4
+ basename,
5
+ parse,
6
+ dirname,
7
+ relative
8
+ } from 'path'
9
+ import {
10
+ existsSync,
11
+ rmSync,
12
+ mkdirSync,
13
+ writeFileSync,
14
+ readFileSync
15
+ } from 'fs'
16
+ import log from 'fancy-log'
17
+ import { nodeResolve } from '@rollup/plugin-node-resolve'
18
+ import cleanup from 'rollup-plugin-cleanup'
19
+ import { rollup } from 'rollup'
20
+ import colors from 'ansi-colors'
21
+ import { getDirname } from '../../_utils.mjs'
22
+ import { packageInfos } from '../../_utils.mjs'
23
+
24
+
25
+ const {
26
+ red,
27
+ green,
28
+ magenta
29
+ } = colors
30
+
31
+ async function checkBundlingFromEsmBuildImport( done ) {
32
+
33
+ const baseDir = getDirname()
34
+ const buildsDir = join( baseDir, 'builds' )
35
+ const buildFilePath = join( buildsDir, `${ packageInfos.name }.esm.js` )
36
+ const testsDir = join( baseDir, 'tests' )
37
+ const bundlesDir = join( testsDir, 'bundles' )
38
+ const outputDir = join( bundlesDir, 'from_build_import' )
39
+ const temporaryDir = join( bundlesDir, 'from_build_import', '.tmp' )
40
+ const importDir = relative( temporaryDir, buildsDir )
41
+ const importFilePath = join( importDir, `${ packageInfos.name }.esm.js` )
42
+
43
+ if ( !existsSync( buildFilePath ) ) {
44
+ done( red( buildFilePath + ' does not exist' ) )
45
+ }
46
+
47
+ if ( existsSync( outputDir ) ) {
48
+ log( 'Clean up', magenta( outputDir ) )
49
+ rmSync( outputDir, { recursive: true } )
50
+ }
51
+
52
+ try {
53
+
54
+ // Get build exports list
55
+ const data = readFileSync( buildFilePath, 'utf8' )
56
+ const regex = /export\s{\s(.*)\s}/
57
+ const found = data.match( regex )
58
+ if ( found === null ) {
59
+ log( red( `Unable to find exports in ${ buildFilePath }` ) )
60
+ return
61
+ }
62
+
63
+ const exports = found[ 1 ].split( ',' )
64
+ .map( item => item.trim() )
65
+
66
+ // Create temporary imports files for each build export
67
+ // And then bundle it
68
+ let temporaryFilePaths = []
69
+ for ( let namedExport of exports ) {
70
+ if ( namedExport.includes( ' as ' ) ) {
71
+ namedExport = namedExport.split( ' as ' )[ 1 ]
72
+ }
73
+
74
+ const temporaryFileName = `${ namedExport }.import.js`
75
+ const temporaryFilePath = join( temporaryDir, temporaryFileName )
76
+ const temporaryFileData = `import { ${ namedExport } } from '${ importFilePath.replace( /\\/g, '/' ) }'`
77
+
78
+ mkdirSync( temporaryDir, { recursive: true } )
79
+ writeFileSync( temporaryFilePath, temporaryFileData )
80
+
81
+ temporaryFilePaths.push( temporaryFilePath )
82
+ }
83
+
84
+ // Bundle each temporary files and check side-effects
85
+ const config = {
86
+ input: null,
87
+ external: [ '' ],
88
+ plugins: [
89
+ nodeResolve( {
90
+ preferBuiltins: true
91
+ } ),
92
+ cleanup( {
93
+ comments: 'all' // else remove __PURE__ declaration... -_-'
94
+ } )
95
+ ],
96
+ onwarn: ( {
97
+ loc,
98
+ frame,
99
+ message
100
+ } ) => {
101
+
102
+ // Ignore some errors
103
+ if ( message.includes( 'Circular dependency' ) ) { return }
104
+ if ( message.includes( 'Generated an empty chunk' ) ) { return }
105
+
106
+ if ( loc ) {
107
+ process.stderr.write( `/!\\ ${ loc.file } (${ loc.line }:${ loc.column }) ${ frame } ${ message }\n` )
108
+ } else {
109
+ process.stderr.write( `/!\\ ${ message }\n` )
110
+ }
111
+
112
+ },
113
+ treeshake: {
114
+ moduleSideEffects: true,
115
+ annotations: true,
116
+ correctVarValueBeforeDeclaration: true,
117
+ propertyReadSideEffects: true,
118
+ tryCatchDeoptimization: true,
119
+ unknownGlobalSideEffects: true
120
+ },
121
+ output: {
122
+ indent: '\t',
123
+ format: 'esm',
124
+ file: null
125
+ }
126
+ }
127
+ let fileName, bundleFileName, bundleFilePath
128
+ for ( const temporaryFilePath of temporaryFilePaths ) {
129
+
130
+ fileName = basename( temporaryFilePath )
131
+ bundleFileName = fileName.replace( '.tmp.', '.bundle.' )
132
+ bundleFilePath = join( outputDir, bundleFileName )
133
+
134
+ try {
135
+
136
+ config.input = temporaryFilePath
137
+ config.output.file = bundleFilePath
138
+
139
+ const bundle = await rollup( config )
140
+ const { output } = await bundle.generate( config.output )
141
+
142
+ let code = output[ 0 ].code
143
+ if ( code.length > 1 ) {
144
+ log( red( `[${ bundleFileName }] contain side-effects !` ) )
145
+ await bundle.write( config.output )
146
+ } else {
147
+ log( green( `[${ bundleFileName }] is side-effect free.` ) )
148
+ }
149
+
150
+ } catch ( error ) {
151
+
152
+ log( red( error.message ) )
153
+
154
+ }
155
+ }
156
+
157
+ } catch ( err ) {
158
+ log( red( error.message ) )
159
+ } finally {
160
+
161
+ done()
162
+
163
+ }
164
+
165
+ }
166
+
167
+ export { checkBundlingFromEsmBuildImport }
@@ -0,0 +1,129 @@
1
+ import {
2
+ join,
3
+ normalize,
4
+ basename,
5
+ extname,
6
+ dirname,
7
+ relative
8
+ } from 'path'
9
+ import {
10
+ existsSync,
11
+ rmSync,
12
+ mkdirSync,
13
+ writeFileSync
14
+ } from 'fs'
15
+ import glob from 'glob'
16
+ import { nodeResolve } from '@rollup/plugin-node-resolve'
17
+ import cleanup from 'rollup-plugin-cleanup'
18
+ import { rollup } from 'rollup'
19
+ import { getGulpConfigForTask } from '../../../configs/gulp.conf.mjs'
20
+ import { getDirname } from '../../_utils.mjs'
21
+ import log from 'fancy-log'
22
+ import colors from 'ansi-colors'
23
+
24
+ const {
25
+ red,
26
+ green,
27
+ blue,
28
+ cyan,
29
+ yellow,
30
+ magenta
31
+ } = colors
32
+
33
+ async function checkBundlingFromEsmFilesDirect( done ) {
34
+
35
+ const baseDir = getDirname()
36
+ const sourcesDir = join( baseDir, 'sources' )
37
+ const testsDir = join( baseDir, 'tests' )
38
+ const bundlesDir = join( testsDir, 'bundles' )
39
+ const outputDir = join( bundlesDir, 'from_files_direct' )
40
+ const filePathsToIgnore = getGulpConfigForTask( 'check-bundling' )
41
+
42
+ if ( existsSync( outputDir ) ) {
43
+ log( 'Clean up', magenta( outputDir ) )
44
+ rmSync( outputDir, { recursive: true } )
45
+ }
46
+
47
+ const sourcesFiles = glob.sync( join( sourcesDir, '**' ) )
48
+ .map( filePath => normalize( filePath ) )
49
+ .filter( filePath => {
50
+ const fileName = basename( filePath )
51
+ const isJsFile = fileName.endsWith( '.js' )
52
+ const isNotPrivateFile = !fileName.startsWith( '_' )
53
+ const isNotIgnoredFile = !filePathsToIgnore.includes( fileName )
54
+ return isJsFile && isNotPrivateFile && isNotIgnoredFile
55
+ } )
56
+
57
+ for ( let sourceFile of sourcesFiles ) {
58
+
59
+ const specificFilePath = sourceFile.replace( sourcesDir, '' )
60
+ const specificDir = dirname( specificFilePath )
61
+ const fileName = basename( sourceFile, extname( sourceFile ) )
62
+
63
+ const bundleFileName = `${ fileName }.bundle.js`
64
+ const bundleFilePath = join( outputDir, specificDir, bundleFileName )
65
+
66
+ const config = {
67
+ input: sourceFile,
68
+ external: [ '' ],
69
+ plugins: [
70
+ nodeResolve( {
71
+ preferBuiltins: true
72
+ } ),
73
+ cleanup( {
74
+ comments: 'none'
75
+ } )
76
+ ],
77
+ onwarn: ( {
78
+ loc,
79
+ frame,
80
+ message
81
+ } ) => {
82
+
83
+ // Ignore some errors
84
+ if ( message.includes( 'Circular dependency' ) ) { return }
85
+ if ( message.includes( 'Generated an empty chunk' ) ) { return }
86
+
87
+ if ( loc ) {
88
+ process.stderr.write( `/!\\ ${ loc.file } (${ loc.line }:${ loc.column }) ${ frame } ${ message }\n` )
89
+ } else {
90
+ process.stderr.write( `/!\\ ${ message }\n` )
91
+ }
92
+
93
+ },
94
+ treeshake: {
95
+ moduleSideEffects: true,
96
+ annotations: true,
97
+ correctVarValueBeforeDeclaration: true,
98
+ propertyReadSideEffects: true,
99
+ tryCatchDeoptimization: true,
100
+ unknownGlobalSideEffects: true
101
+ },
102
+ output: {
103
+ indent: '\t',
104
+ format: 'esm',
105
+ file: bundleFilePath
106
+ }
107
+ }
108
+
109
+ try {
110
+
111
+ log( `Bundling ${ config.output.file }` )
112
+
113
+ const bundle = await rollup( config )
114
+ await bundle.generate( config.output )
115
+ await bundle.write( config.output )
116
+
117
+ } catch ( error ) {
118
+
119
+ log( red( error.message ) )
120
+
121
+ }
122
+
123
+ }
124
+
125
+ done()
126
+
127
+ }
128
+
129
+ export { checkBundlingFromEsmFilesDirect }
@@ -0,0 +1,149 @@
1
+ import {
2
+ join,
3
+ normalize,
4
+ basename,
5
+ parse,
6
+ dirname,
7
+ relative
8
+ } from 'path'
9
+ import {
10
+ existsSync,
11
+ rmSync,
12
+ mkdirSync,
13
+ writeFileSync
14
+ } from 'fs'
15
+ import log from 'fancy-log'
16
+ import glob from 'glob'
17
+ import { nodeResolve } from '@rollup/plugin-node-resolve'
18
+ import cleanup from 'rollup-plugin-cleanup'
19
+ import { rollup } from 'rollup'
20
+ import colors from 'ansi-colors'
21
+ import { getGulpConfigForTask } from '../../../configs/gulp.conf.mjs'
22
+ import { getDirname } from '../../_utils.mjs'
23
+
24
+ const {
25
+ red,
26
+ green,
27
+ blue,
28
+ cyan,
29
+ yellow,
30
+ magenta
31
+ } = colors
32
+
33
+ async function checkBundlingFromEsmFilesImport( done ) {
34
+
35
+ const baseDir = getDirname()
36
+ const sourcesDir = join( baseDir, 'sources' )
37
+ const testsDir = join( baseDir, 'tests' )
38
+ const bundleDir = join( testsDir, 'bundles' )
39
+ const outputDir = join( bundleDir, 'from_files_import' )
40
+ const temporariesDir = join( outputDir, '.tmp' )
41
+ const filePathsToIgnore = getGulpConfigForTask( 'check-bundling' )
42
+
43
+ if ( existsSync( outputDir ) ) {
44
+ log( 'Clean up', magenta( outputDir ) )
45
+ rmSync( outputDir, { recursive: true } )
46
+ }
47
+
48
+ const sourcesFiles = glob.sync( join( sourcesDir, '/**' ) )
49
+ .map( filePath => {
50
+ return normalize( filePath )
51
+ } )
52
+ .filter( filePath => {
53
+ const fileName = basename( filePath )
54
+ const isJsFile = fileName.endsWith( '.js' )
55
+ const isNotPrivateFile = !fileName.startsWith( '_' )
56
+ const isNotIgnoredFile = !filePathsToIgnore.includes( fileName )
57
+ return isJsFile && isNotPrivateFile && isNotIgnoredFile
58
+ } )
59
+
60
+ for ( let sourceFile of sourcesFiles ) {
61
+
62
+ const {
63
+ dir: sourceDir,
64
+ base: sourceBase,
65
+ name: sourceName
66
+ } = parse( sourceFile )
67
+ const specificFilePath = sourceFile.replace( sourcesDir, '' )
68
+ const specificDir = dirname( specificFilePath )
69
+
70
+ // Create temp import file per file in package
71
+ const temporaryFileName = `${ sourceName }.import.js`
72
+ const temporaryDir = join( temporariesDir, specificDir )
73
+ const temporaryFile = join( temporaryDir, temporaryFileName )
74
+ const importDir = relative( temporaryDir, sourceDir )
75
+ const importFile = join( importDir, sourceBase )
76
+ const temporaryFileData = `import '${ importFile.replace( /\\/g, '/' ) }'`
77
+
78
+ // Bundle tmp file and check content for side effects
79
+ const bundleFileName = `${ sourceName }.bundle.js`
80
+ const bundleFilePath = join( outputDir, specificDir, bundleFileName )
81
+
82
+ const config = {
83
+ input: temporaryFile,
84
+ plugins: [
85
+ nodeResolve(),
86
+ cleanup( {
87
+ comments: 'all' // else remove __PURE__ declaration... -_-'
88
+ } )
89
+ ],
90
+ onwarn: ( {
91
+ loc,
92
+ frame,
93
+ message
94
+ } ) => {
95
+
96
+ // Ignore some errors
97
+ if ( message.includes( 'Circular dependency' ) ) { return }
98
+ if ( message.includes( 'Generated an empty chunk' ) ) { return }
99
+
100
+ if ( loc ) {
101
+ process.stderr.write( `/!\\ ${ loc.file } (${ loc.line }:${ loc.column }) ${ frame } ${ message }\n` )
102
+ } else {
103
+ process.stderr.write( `/!\\ ${ message }\n` )
104
+ }
105
+
106
+ },
107
+ treeshake: {
108
+ moduleSideEffects: true,
109
+ annotations: true,
110
+ correctVarValueBeforeDeclaration: true,
111
+ propertyReadSideEffects: true,
112
+ tryCatchDeoptimization: true,
113
+ unknownGlobalSideEffects: true
114
+ },
115
+ output: {
116
+ indent: '\t',
117
+ format: 'esm',
118
+ file: bundleFilePath
119
+ }
120
+ }
121
+
122
+ // create tmp file
123
+ try {
124
+
125
+ mkdirSync( temporaryDir, { recursive: true } )
126
+ writeFileSync( temporaryFile, temporaryFileData )
127
+
128
+ const bundle = await rollup( config )
129
+ const { output } = await bundle.generate( config.output )
130
+
131
+ let code = output[ 0 ].code
132
+ if ( code.length > 1 ) {
133
+ log( red( `[${ specificFilePath }] contain side-effects !` ) )
134
+ await bundle.write( config.output )
135
+ } else {
136
+ log( green( `[${ specificFilePath }] is side-effect free.` ) )
137
+ }
138
+
139
+ } catch ( error ) {
140
+ log( red( error.message ) )
141
+ }
142
+
143
+ }
144
+
145
+ done()
146
+
147
+ }
148
+
149
+ export { checkBundlingFromEsmFilesImport }
@@ -0,0 +1,33 @@
1
+ import rollupUnitTestsConfigurator from '../../../configs/rollup.units.conf.js'
2
+ import log from 'fancy-log'
3
+ import { rollup } from 'rollup'
4
+ import colors from 'ansi-colors'
5
+
6
+ const red = colors.red
7
+
8
+ async function bundleUnitTests( done ) {
9
+
10
+ const configs = rollupUnitTestsConfigurator()
11
+
12
+ for ( let config of configs ) {
13
+
14
+ log( `Building ${ config.output.file }` )
15
+
16
+ try {
17
+
18
+ const bundle = await rollup( config )
19
+ await bundle.write( config.output )
20
+
21
+ } catch ( error ) {
22
+
23
+ log( red( error ) )
24
+
25
+ }
26
+
27
+ }
28
+
29
+ done()
30
+
31
+ }
32
+
33
+ export { bundleUnitTests }