From 2fb7b4ccadafbeff34188d0a7c69a48a0c80fd48 Mon Sep 17 00:00:00 2001 From: headlessNode Date: Sun, 12 Jan 2025 00:10:41 +0500 Subject: [PATCH 1/5] feat: add initial infrastructure for test code coverage website --- .editorconfig | 181 ++++++++++++++ .gitignore | 171 ++++++++++++++ .npmrc | 28 +++ Makefile | 75 ++++++ NOTICE | 1 + etc/README.md | 53 +++++ etc/esbuild/build.js | 46 ++++ etc/esbuild/config.js | 51 ++++ lib/server/README.md | 23 ++ lib/server/lib/defaults.json | 19 ++ lib/server/lib/index.js | 54 +++++ lib/server/lib/main.js | 223 ++++++++++++++++++ .../node_modules/middleware-sequence/index.js | 89 +++++++ .../node_modules/middleware/error/index.js | 41 ++++ lib/server/lib/routes/home/home.js | 57 +++++ lib/server/lib/routes/home/index.js | 43 ++++ lib/server/lib/routes/home/main.js | 51 ++++ lib/server/lib/routes/home/schema.json | 12 + lib/server/lib/routes/index.js | 47 ++++ lib/server/lib/validate.js | 137 +++++++++++ lib/server/package.json | 55 +++++ package.json | 47 ++++ public/css/main/bundle.json | 3 + public/css/main/bundle.min.css | 1 + public/css/main/layout.css | 44 ++++ public/index.html | 15 ++ public/js/bundle.js | 18 ++ server/index.js | 21 ++ server/server.js | 68 ++++++ src/app.jsx | 41 ++++ src/index.jsx | 28 +++ tools/README.md | 49 ++++ tools/make/Makefile | 65 +++++ tools/make/README.md | 44 ++++ tools/make/common.mk | 127 ++++++++++ tools/make/lib/css/Makefile | 36 +++ tools/make/lib/css/README.md | 51 ++++ tools/make/lib/help/Makefile | 60 +++++ tools/make/lib/help/README.md | 51 ++++ tools/make/lib/install/Makefile | 34 +++ tools/make/lib/install/README.md | 51 ++++ tools/make/lib/install/node.mk | 53 +++++ tools/make/lib/js/Makefile | 42 ++++ tools/make/usage.txt | 11 + tools/scripts/README.md | 49 ++++ tools/scripts/minify_css.js | 126 ++++++++++ 46 files changed, 2592 insertions(+) create mode 100644 .editorconfig create mode 100644 .gitignore create mode 100644 .npmrc create mode 100644 Makefile create mode 100644 NOTICE create mode 100644 etc/README.md create mode 100644 etc/esbuild/build.js create mode 100644 etc/esbuild/config.js create mode 100644 lib/server/README.md create mode 100644 lib/server/lib/defaults.json create mode 100644 lib/server/lib/index.js create mode 100644 lib/server/lib/main.js create mode 100644 lib/server/lib/node_modules/middleware-sequence/index.js create mode 100644 lib/server/lib/node_modules/middleware/error/index.js create mode 100644 lib/server/lib/routes/home/home.js create mode 100644 lib/server/lib/routes/home/index.js create mode 100644 lib/server/lib/routes/home/main.js create mode 100644 lib/server/lib/routes/home/schema.json create mode 100644 lib/server/lib/routes/index.js create mode 100644 lib/server/lib/validate.js create mode 100644 lib/server/package.json create mode 100644 package.json create mode 100644 public/css/main/bundle.json create mode 100644 public/css/main/bundle.min.css create mode 100644 public/css/main/layout.css create mode 100644 public/index.html create mode 100644 public/js/bundle.js create mode 100644 server/index.js create mode 100644 server/server.js create mode 100644 src/app.jsx create mode 100644 src/index.jsx create mode 100644 tools/README.md create mode 100644 tools/make/Makefile create mode 100644 tools/make/README.md create mode 100644 tools/make/common.mk create mode 100644 tools/make/lib/css/Makefile create mode 100644 tools/make/lib/css/README.md create mode 100644 tools/make/lib/help/Makefile create mode 100644 tools/make/lib/help/README.md create mode 100644 tools/make/lib/install/Makefile create mode 100644 tools/make/lib/install/README.md create mode 100644 tools/make/lib/install/node.mk create mode 100644 tools/make/lib/js/Makefile create mode 100644 tools/make/usage.txt create mode 100644 tools/scripts/README.md create mode 100644 tools/scripts/minify_css.js diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000000..5c93bb86b7 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,181 @@ +#/ +# @license Apache-2.0 +# +# Copyright (c) 2025 The Stdlib Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +#/ + +# EditorConfig configuration file (see ). + +# Indicate that this file is a root-level configuration file: +root = true + +# Set properties for all files: +[*] +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true + +# Set properties for JavaScript files: +[*.{js,js.txt}] +indent_style = tab + +# Set properties for JavaScript ES module files: +[*.{mjs,mjs.txt}] +indent_style = tab + +# Set properties for JavaScript CommonJS files: +[*.{cjs,cjs.txt}] +indent_style = tab + +# Set properties for JSX files: +[*.{jsx,jsx.txt}] +indent_style = tab + +# Set properties for JSON files: +[*.{json,json.txt}] +indent_style = space +indent_size = 2 + +# Set properties for TypeScript files: +[*.ts] +indent_style = tab + +# Set properties for Python files: +[*.{py,py.txt}] +indent_style = space +indent_size = 4 + +# Set properties for Julia files: +[*.{jl,jl.txt}] +indent_style = tab + +# Set properties for R files: +[*.{R,R.txt}] +indent_style = tab + +# Set properties for C files: +[*.{c,c.txt}] +indent_style = tab + +# Set properties for C header files: +[*.{h,h.txt}] +indent_style = tab + +# Set properties for C++ files: +[*.{cpp,cpp.txt}] +indent_style = tab + +# Set properties for C++ header files: +[*.{hpp,hpp.txt}] +indent_style = tab + +# Set properties for Fortran files: +[*.{f,f.txt}] +indent_style = space +indent_size = 2 +insert_final_newline = false + +# Set properties for shell files: +[*.{sh,sh.txt}] +indent_style = tab + +# Set properties for AWK files: +[*.{awk,awk.txt}] +indent_style = tab + +# Set properties for HTML files: +[*.{html,html.txt}] +indent_style = tab +tab_width = 2 + +# Set properties for XML files: +[*.{xml,xml.txt}] +indent_style = tab +tab_width = 2 + +# Set properties for CSS files: +[*.{css,css.txt}] +indent_style = tab + +# Set properties for Makefiles: +[Makefile] +indent_style = tab + +[*.{mk,mk.txt}] +indent_style = tab + +# Set properties for Markdown files: +[*.{md,md.txt}] +indent_style = space +indent_size = 4 +trim_trailing_whitespace = false + +# Set properties for `usage.txt` files: +[usage.txt] +indent_style = space +indent_size = 2 + +# Set properties for `repl.txt` files: +[repl.txt] +indent_style = space +indent_size = 4 + +# Set properties for `package.json` files: +[package.{json,json.txt}] +indent_style = space +indent_size = 2 + +# Set properties for `datapackage.json` files: +[datapackage.json] +indent_style = space +indent_size = 2 + +# Set properties for `manifest.json` files: +[manifest.json] +indent_style = space +indent_size = 2 + +# Set properties for `tslint.json` files: +[tslint.json] +indent_style = space +indent_size = 2 + +# Set properties for `tsconfig.json` files: +[tsconfig.json] +indent_style = space +indent_size = 2 + +# Set properties for LaTeX files: +[*.{tex,tex.txt}] +indent_style = tab + +# Set properties for LaTeX Bibliography files: +[*.{bib,bib.txt}] +indent_style = tab + +# Set properties for YAML files: +[*.{yml,yml.txt}] +indent_style = space +indent_size = 2 + +# Set properties for GYP files: +[binding.gyp] +indent_style = space +indent_size = 2 + +[*.gypi] +indent_style = space +indent_size = 2 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000..263ece930d --- /dev/null +++ b/.gitignore @@ -0,0 +1,171 @@ +#/ +# @license Apache-2.0 +# +# Copyright (c) 2025 The Stdlib Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +#/ + +# Files # +######### + + +# Directories # +############### +build/ + +# Compiled source # +################### +*.com +*.class +*.dll +*.o +*.so +*.slo +*.lo +*.obj +*.dylib +*.lai +*.la +*.a +*.lib +*.ko +*.elf +*.node + +# Precompiled headers # +####################### +*.gch +*.pch + +# Executables # +############### +*.exe +*.out +*.app + +# Packages # +############ +# it's better to unpack these files and commit the raw source +# git has its own built in compression methods +*.7z +*.dmg +*.gz +*.iso +*.jar +*.rar +*.tar +*.zip + +# Logs and databases # +###################### +*.log +*.sql +*.sqlite + +# OS generated files # +###################### +.DS_Store +.DS_Store? +._* +.Spotlight-V100 +.Trashes +Icon? +!icons/ +ehthumbs.db +Thumbs.db +Desktop.ini + +# Temporary files # +################### +*~ + +# Node.js # +########### +/node_modules/ +pids +*.pid +*.seed + +# Matlab # +########## +*.asv +*.mex* + +# Fortran # +########### +*.mod + +# R # +##### +.Rhistory +.Rapp.history +.Rproj.user/ + +# Python # +########## +__pycache__/ +*.py[cod] +*$py.class + +# TeX # +####### +*.aux +*.lof +*.log +*.lot +*.fls +*.out +*.toc +*.dvi +*-converted-to.* +*.bbl +*.bcf +*.blg +*-blx.aux +*-blx.bib +*.brf +*.run.xml +*.fdb_latexmk +*.synctex +*.synctex.gz +*.synctex.gz(busy) +*.pdfsync +*.alg +*.loa +acs-*.bib +*.thm +*.nav +*.snm +*.vrb +*.acn +*.acr +*.glg +*.glo +*.gls +*-concordance.tex +*.tikz +*-tikzDictionary +*.idx +*.ilg +*.ind +*.ist + +# Visual Studio # +################# +.vscode/ +jsconfig.json + +# Sublime Text # +################ +*.sublime-workspace \ No newline at end of file diff --git a/.npmrc b/.npmrc new file mode 100644 index 0000000000..37a820168d --- /dev/null +++ b/.npmrc @@ -0,0 +1,28 @@ +#/ +# @license Apache-2.0 +# +# Copyright (c) 2025 The Stdlib Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +#/ + +# Configuration for [npm][1]. +# +# [1]: https://docs.npmjs.com/files/npmrc + +# Disable the creation of a lock file: +package-lock = false +shrinkwrap = false + +# Disable automatically "saving" dependencies on install: +save = false \ No newline at end of file diff --git a/Makefile b/Makefile new file mode 100644 index 0000000000..bec0b6687b --- /dev/null +++ b/Makefile @@ -0,0 +1,75 @@ +#/ +# @license Apache-2.0 +# +# Copyright (c) 2025 The Stdlib Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +#/ + +# VARIABLES # + +# Determine the filename: +this_file := $(lastword $(MAKEFILE_LIST)) + +# Determine the absolute path of the Makefile (see http://blog.jgc.org/2007/01/what-makefile-am-i-in.html): +this_dir := $(dir $(CURDIR)/$(word $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST))) + +# Remove the trailing slash: +this_dir := $(patsubst %/,%,$(this_dir)) + +# Define the root project directory: +ROOT_DIR ?= $(this_dir) + +# Define the root tools directory: +TOOLS_DIR ?= $(ROOT_DIR)/tools + +# Define the directory containing the entry point for Makefile dependencies: +TOOLS_MAKE_DIR ?= $(TOOLS_DIR)/make + +# Define the subdirectory containing Makefile dependencies: +TOOLS_MAKE_LIB_DIR ?= $(TOOLS_MAKE_DIR)/lib + +# Define the root build directory: +BUILD_DIR ?= $(ROOT_DIR)/public + +# Define the root configuration directory: +CONFIG_DIR ?= $(ROOT_DIR)/etc + +# Define the directory for public WWW assets: +WWW_DIR ?= $(ROOT_DIR)/public + +# Define the top-level directory containing node module dependencies: +NODE_MODULES ?= $(ROOT_DIR)/node_modules + +# Define the top-level directory containing node module executables: +BIN_DIR ?= $(NODE_MODULES)/.bin + +# Define the folder name convention for executables: +BIN_FOLDER ?= bin + +# Define the folder name convention for configuration files: +CONFIG_FOLDER ?= etc + +# Define the folder name convention for build artifacts: +BUILD_FOLDER ?= js + +# Define filename extension conventions (keep in alphabetical order): +CSS_FILENAME_EXT ?= css + +# Define Node paths: (WARNING: we cannot use an absolute path here because of Webpack which only allows relative paths) +NODE_PATH ?= ./node_modules/@stdlib/stdlib/lib/node_modules + + +# DEPENDENCIES # + +include $(TOOLS_MAKE_DIR)/Makefile \ No newline at end of file diff --git a/NOTICE b/NOTICE new file mode 100644 index 0000000000..cbd3a299d9 --- /dev/null +++ b/NOTICE @@ -0,0 +1 @@ +Copyright (c) 2016-2025 The Stdlib Authors. diff --git a/etc/README.md b/etc/README.md new file mode 100644 index 0000000000..b63b63323d --- /dev/null +++ b/etc/README.md @@ -0,0 +1,53 @@ + + +# etc + +> Configuration files. + + + +
+ +This directory contains configuration files. + +
+ + + + + +
+ +## Notes + +* Configuration files for external tools and environments should be placed in subdirectories. The subdirectory name should correspond to the name of the tool or environment. + +
+ + + + + + + + \ No newline at end of file diff --git a/etc/esbuild/build.js b/etc/esbuild/build.js new file mode 100644 index 0000000000..1d9e53524c --- /dev/null +++ b/etc/esbuild/build.js @@ -0,0 +1,46 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2025 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + + +// MODULES // + +var esbuild = require( 'esbuild' ); +var config = require( './config' ); + + +// MAIN // + +/** +* Builds the website using esbuild. +* +* @async +* @throws {Error} build failure +*/ +async function main() { + try { + await esbuild.build( config ); + console.log( 'Build completed successfully!' ); + } catch ( error ) { + console.error( 'Build failed:', error ); + process.exit( 1 ); + } +} + +main(); diff --git a/etc/esbuild/config.js b/etc/esbuild/config.js new file mode 100644 index 0000000000..1807b9d50b --- /dev/null +++ b/etc/esbuild/config.js @@ -0,0 +1,51 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2025 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + + +// MODULES // + +var path = require( 'path' ); + + +// VARIABLES // + +var SRC_DIR = path.resolve( __dirname, '../../src' ); +var BUILD_DIR = path.resolve( __dirname, '../../public/js' ); + + +// EXPORTS // + +module.exports = { + entryPoints: [ + SRC_DIR + '/index.jsx' + ], + bundle: true, + outfile: BUILD_DIR + '/bundle.js', + minify: true, + sourcemap: false, + target: 'es2015', + jsxFactory: 'h', + jsxFragment: 'Fragment', + jsxImportSource: 'preact', + alias: { + 'react': 'preact/compat', + 'react-dom': 'preact/compat' + } +}; diff --git a/lib/server/README.md b/lib/server/README.md new file mode 100644 index 0000000000..c86a07a8c9 --- /dev/null +++ b/lib/server/README.md @@ -0,0 +1,23 @@ + + +# Test code coverage Server + +> Create an HTTP server for serving test code coverage. \ No newline at end of file diff --git a/lib/server/lib/defaults.json b/lib/server/lib/defaults.json new file mode 100644 index 0000000000..446a6746a3 --- /dev/null +++ b/lib/server/lib/defaults.json @@ -0,0 +1,19 @@ +{ + "address": "127.0.0.1", + "latest": "", + "logger": false, + "port": 0, + "prefix": "/", + "root": "", + "static": "", + "trustProxy": false, + "ignoreTrailingSlash": true, + "app": { + "title": "Test Code Coverage | stdlib", + "description": "Test code coverage website for stdlib, a standard library for JavaScript and Node.js, with an emphasis on numerical and scientific computing.", + "theme": "", + "mode": "default", + "exampleSyntax": "es5", + "prevNextNavigation": "alphabetical" + } +} diff --git a/lib/server/lib/index.js b/lib/server/lib/index.js new file mode 100644 index 0000000000..68c2fc7f34 --- /dev/null +++ b/lib/server/lib/index.js @@ -0,0 +1,54 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2025 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +/** +* Create an HTTP server for serving test code coverage. +* +* @module @stdlib/_tools/docs/www-test-code-coverage/server +* +* @example +* var httpServer = require( '@stdlib/_tools/docs/www-test-code-coverage/server' ); +* var App = require( 'my-app' ); +* +* var opts = { +* 'port': 7331, +* 'address': '0.0.0.0' +* }; +* var createServer = httpServer( opts ); +* +* function done( error, fastify ) { +* if ( error ) { +* return console.error( error.message ); +* } +* console.log( 'Success!' ); +* fastify.close(); +* } +* +* createServer( App, done ); +*/ + +// MODULES // + +var main = require( './main.js' ); + + +// EXPORTS // + +module.exports = main; \ No newline at end of file diff --git a/lib/server/lib/main.js b/lib/server/lib/main.js new file mode 100644 index 0000000000..a1903c63ca --- /dev/null +++ b/lib/server/lib/main.js @@ -0,0 +1,223 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2025 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var resolve = require( 'path' ).resolve; +var fastify = require( 'fastify' ); +var helmet = require( '@fastify/helmet' ); +var cookie = require( '@fastify/cookie' ); +var fastifyStatic = require( '@fastify/static' ); +var isFunction = require( '@stdlib/assert/is-function' ); +var isString = require( '@stdlib/assert/is-string' ); +var cwd = require( '@stdlib/process/cwd' ); +var copy = require( '@stdlib/utils/copy' ); +var format = require( '@stdlib/string/format' ); +var routes = require( './routes' ); +var DEFAULTS = require( './defaults.json' ); +var validate = require( './validate.js' ); + +// MAIN // + +/** +* Returns a function which creates an HTTP server for serving test code coverage. +* +* @param {Options} [options] - server options +* @param {string} [options.address="127.0.0.1"] - server address +* @param {string} [options.hostname] - server hostname +* @param {string} [options.latest=""] - latest version (e.g., `v0.0.90`) +* @param {(boolean|string)} [options.logger=false] - either a boolean indicating whether to enable logging or a log level +* @param {NonNegativeInteger} [options.port=0] - server port +* @param {(string|StringArray)} [options.prefix="/"] - URL path prefix(es) used to create a virtual mount path(s) for static directories +* @param {string} [options.root] - root directory +* @param {(string|StringArray)} [options.static] - path of the directory (or directories) containing static files to serve +* @param {boolean} [options.trustProxy=false] - boolean indicating whether to trust `X-forwarded-by` headers when the server is sitting behind a proxy +* @param {boolean} [options.ignoreTrailingSlash=true] - boolean indicating whether to ignore trailing slashes in routes +* @throws {TypeError} must provide valid options +* @throws {Error} must provide valid options +* @returns {Function} function which creates an HTTP server +* +* @example +* var App = require( 'my-app' ); +* +* var opts = { +* 'port': 7331, +* 'address': '0.0.0.0' +* }; +* var createServer = httpServer( opts ); +* +* function done( error, fastify ) { +* if ( error ) { +* return console.error( error.message ); +* } +* console.log( 'Success!' ); +* fastify.close(); +* } +* +* createServer( App, done ); +*/ +function httpServer( options ) { + var opts; + var err; + var dir; + var i; + + opts = copy( DEFAULTS ); + if ( arguments.length ) { + err = validate( opts, options ); + if ( err ) { + throw err; + } + } + if ( opts.hostname === void 0 ) { + opts.hostname = opts.address; + } + dir = cwd(); + opts.root = resolve( dir, opts.root ); + if ( opts.static ) { + if ( isString( opts.static ) ) { + if ( !isString( opts.prefix ) ) { + throw new TypeError( format( 'invalid option. Must provide a string `prefix` when `static` is a string. Option: `%s`.', opts.prefix ) ); + } + opts.static = resolve( dir, opts.static ); + } else { + if ( !isString( opts.prefix ) && opts.prefix.length !== opts.static.length ) { // eslint-disable-line max-len + throw new Error( 'invalid option. Number of prefixes must equal the number of static directories.' ); + } + for ( i = 0; i < opts.static.length; i++ ) { + opts.static[ i ] = resolve( dir, opts.static[ i ] ); + } + } + } + return createServer; + + /** + * Creates an HTTP server. + * + * @private + * @param {Callback} done - function to invoke after creating a server + * @throws {TypeError} first argument must be a function + * @throws {Error} unable to load application template + */ + function createServer( done ) { + var f; + + if ( !isFunction( done ) ) { + throw new TypeError( format( 'invalid argument. First argument must be a function. Value: `%s`.', done ) ); + } + + // Create a fastify instance: + f = fastify( opts ); + + // Set basic security headers: + f.register( helmet, { + 'contentSecurityPolicy': false, + 'crossOriginEmbedderPolicy': false, + 'referrerPolicy': { + 'policy': 'origin' + }, + 'hidePoweredBy': true + }); + + // Add support for reading cookies: + f.register( cookie ); + + // Decorate route handler `this` contexts with additional functionality: + f.decorate( 'rootDir', opts.root ); + f.decorate( 'latestVersion', opts.latest ); + + // Decorate each `request` object with a `locals` object for passing along intermediate results within middleware handlers: + f.decorateRequest( 'locals', null ); + + // Register a plugin for serving static files: + f.register( fastifyStatic, { + root: opts.root, + prefix: opts.prefix, + wildcard: true, + }); + + // Register routes: + f.register( routes, {} ); + + // Add a hook to perform clean-up tasks when the server is closed: + f.addHook( 'onClose', onClose ); + + // Add a hook to configure the `locals` object for each request: + f.addHook( 'onRequest', onRequest ); + + // Start listening for HTTP requests: + f.listen( opts, onListen ); + + /** + * Callback invoked once a server is listening and ready to accept HTTP requests. + * + * @private + * @param {(Error|null)} error - error object + * @param {string} address - server address + * @returns {void} + */ + function onListen( error, address ) { + if ( error ) { + f.log.error( error.message ); + return done( error ); + } + f.log.info( 'HTTP server initialized. Server is listening for requests on %s.', address ); + done( null, f ); + } + + /** + * Callback invoked upon receiving an HTTP request. + * + * @private + * @param {Object} request - request object + * @param {Object} reply - reply object + * @param {Callback} clbk - callback to invoke once finished + */ + function onRequest( request, reply, clbk ) { + request.locals = {}; + clbk(); + } + + /** + * Callback invoked when a server is closed. + * + * @private + * @param {Object} instance - fastify instance + * @param {Callback} clbk - callback to invoke once finished + */ + function onClose( instance, clbk ) { + setTimeout( onEnd, 0 ); + + /** + * Callback invoked upon performing clean-up tasks. + * + * @private + */ + function onEnd() { + clbk(); + } + } + } +} + + +// EXPORTS // + +module.exports = httpServer; diff --git a/lib/server/lib/node_modules/middleware-sequence/index.js b/lib/server/lib/node_modules/middleware-sequence/index.js new file mode 100644 index 0000000000..85ad15a7b7 --- /dev/null +++ b/lib/server/lib/node_modules/middleware-sequence/index.js @@ -0,0 +1,89 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2025 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var isFunctionArray = require( '@stdlib/assert/is-function-array' ); +var isFunction = require( '@stdlib/assert/is-function' ); +var format = require( '@stdlib/string/format' ); + + +// MAIN // + +/** +* Returns a reusable middleware function. +* +* @param {FunctionArray} fcns - array of middleware functions +* @param {Callback} errback - callback to invoke upon encountering an error +* @param {Callback} [done] - callback to invoke upon completion +* @throws {TypeError} first argument must be an array of functions +* @throws {TypeError} second argument must be a function +* @returns {Function} middleware function +*/ +function factory( fcns, errback ) { + if ( !isFunctionArray( fcns ) ) { + throw new TypeError( format( 'invalid argument. First argument must be a function array. Value: `%s`.', fcns ) ); + } + if ( !isFunction( errback ) ) { + throw new TypeError( format( 'invalid argument. Second argument must be a function. Value: `%s`.', errback ) ); + } + return middleware; + + /** + * Executes middleware functions in order. + * + * @private + * @param {Object} request - request object + * @param {Object} reply - reply object + * @param {Callback} [done] - callback to invoke upon completion + * @returns {void} + */ + function middleware( request, reply, done ) { + var self = this; // eslint-disable-line no-invalid-this + var idx = -1; + return next(); + + /** + * Executes the next middleware function. + * + * @private + * @param {(Error|null)} error - error object + * @returns {void} + */ + function next() { + // Check for an error... + if ( arguments[ 0 ] ) { + return errback( arguments[ 0 ], request, reply, next ); + } + // Update the counter and check if we have run all functions... + idx += 1; + if ( idx >= fcns.length ) { + return ( done ) ? done() : void 0; + } + // Call the next middleware function: + fcns[ idx ].call( self, request, reply, next ); + } + } +} + + +// EXPORTS // + +module.exports = factory; diff --git a/lib/server/lib/node_modules/middleware/error/index.js b/lib/server/lib/node_modules/middleware/error/index.js new file mode 100644 index 0000000000..c18a99596f --- /dev/null +++ b/lib/server/lib/node_modules/middleware/error/index.js @@ -0,0 +1,41 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2025 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + + +// MAIN // + +/** +* Callback invoked upon encountering an error. +* +* @private +* @param {Object} error - error object +* @param {Object} request - request object +* @param {Object} reply - reply object +* @param {Callback} next - callback to invoke upon completion +* @returns {void} +*/ +function onError( error, request, reply ) { + return reply.status( error.statusCode ).send( error ); +} + + +// EXPORTS // + +module.exports = onError; diff --git a/lib/server/lib/routes/home/home.js b/lib/server/lib/routes/home/home.js new file mode 100644 index 0000000000..e76a38f857 --- /dev/null +++ b/lib/server/lib/routes/home/home.js @@ -0,0 +1,57 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2025 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +/* eslint-disable no-invalid-this */ + +'use strict'; + + +// MAIN // + +/** +* Callback invoked upon receiving an HTTP request. +* +* @private +* @param {Object} request - request object +* @param {Object} reply - reply object +* @returns {void} +*/ +function handler( request, reply ) { + var version; + var url; + + // Set version + version = this.latestVersion; + request.log.info( 'Version: %s', version ); + + // Handle URL and add version path + url = request.url; + if ( url[url.length - 1] !== '/' ) { + url += '/'; + } + url += version; + request.log.info( 'Resolved URL: %s', request.url ); + + // Send the HTML shell to the client + reply.type( 'text/html' ); + reply.sendFile( 'index.html' ); +} + +// EXPORTS // + +module.exports = handler; diff --git a/lib/server/lib/routes/home/index.js b/lib/server/lib/routes/home/index.js new file mode 100644 index 0000000000..3e41b2caa9 --- /dev/null +++ b/lib/server/lib/routes/home/index.js @@ -0,0 +1,43 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2025 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var schema = require( './schema.json' ); +var handler = require( './main.js' ); + + +// MAIN // + +/** +* Defines a route handler for returning a shell-app for test coverage website landing page. +* +* @private +* @returns {Object} route declaration +*/ +function route() { + schema.handler = handler; + return schema; +} + + +// EXPORTS // + +module.exports = route; diff --git a/lib/server/lib/routes/home/main.js b/lib/server/lib/routes/home/main.js new file mode 100644 index 0000000000..3c93b5d792 --- /dev/null +++ b/lib/server/lib/routes/home/main.js @@ -0,0 +1,51 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2025 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var middleware = require( 'middleware-sequence' ); +var onError = require( 'middleware/error' ); +var home = require( './home.js' ); + + +// VARIABLES // + +var steps = [ + home +]; + + +// MAIN // + +/** +* Request handler for processing a request. +* +* @private +* @name handler +* @type {Function} +* @param {Object} request - request object +* @param {Object} reply - reply object +*/ +var handler = middleware( steps, onError ); + + +// EXPORTS // + +module.exports = handler; \ No newline at end of file diff --git a/lib/server/lib/routes/home/schema.json b/lib/server/lib/routes/home/schema.json new file mode 100644 index 0000000000..f9fbed1dc3 --- /dev/null +++ b/lib/server/lib/routes/home/schema.json @@ -0,0 +1,12 @@ +{ + "method": "GET", + "url": "/", + "schema": { + "response": { + "200": { + "type": "string" + } + } + }, + "handler": null +} diff --git a/lib/server/lib/routes/index.js b/lib/server/lib/routes/index.js new file mode 100644 index 0000000000..71c598617c --- /dev/null +++ b/lib/server/lib/routes/index.js @@ -0,0 +1,47 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2025 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + + +// MODULES // + +var home = require( './home' ); + + +// MAIN // + +/** +* Registers routes on a Fastify instance. +* +* @private +* @param {Object} fastify - Fastify instance +* @param {Object} options - options +* @param {Function} done - callback to invoke upon registering route handlers +*/ +function register( fastify, options, done ) { + // Landing page route: + fastify.route( home() ); + + done(); +} + + +// EXPORTS // + +module.exports = register; diff --git a/lib/server/lib/validate.js b/lib/server/lib/validate.js new file mode 100644 index 0000000000..b67e4e4b5f --- /dev/null +++ b/lib/server/lib/validate.js @@ -0,0 +1,137 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2025 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var hasOwnProp = require( '@stdlib/assert/has-own-property' ); +var isObject = require( '@stdlib/assert/is-plain-object' ); +var isNonNegativeInteger = require( '@stdlib/assert/is-nonnegative-integer' ).isPrimitive; +var isString = require( '@stdlib/assert/is-string' ).isPrimitive; +var isStringArray = require( '@stdlib/assert/is-string-array' ).primitives; +var isBoolean = require( '@stdlib/assert/is-boolean' ).isPrimitive; +var format = require( '@stdlib/string/format' ); + + +// MAIN // + +/** +* Validates function options. +* +* @private +* @param {Object} opts - destination object +* @param {Options} options - function options +* @param {string} [options.address] - server address +* @param {string} [options.hostname] - server hostname +* @param {string} [options.latest] - latest version +* @param {(boolean|string)} [options.logger] - either boolean indicating whether to enable logging or a log level +* @param {NonNegativeInteger} [options.port] - server port +* @param {(string|StringArray)} [options.prefix] - URL path prefix(es) used to create a virtual mount path(s) for static directories +* @param {string} [options.root] - root directory +* @param {(string|StringArray)} [options.static] - path of the directory (or directories) containing static files to serve +* @param {boolean} [options.trustProxy] - boolean indicating whether to trust `X-forwarded-by` headers when the server is sitting behind a proxy +* @param {boolean} [options.ignoreTrailingSlash] - boolean indicating whether to ignore trailing slashes in routes +* @returns {(Error|null)} error or null +* +* @example +* var options = { +* 'port': 7331, +* 'address': '127.0.0.1' +* }; +* var opts = {}; +* var err = validate( opts, options ); +* if ( err ) { +* throw err; +* } +*/ +function validate( opts, options ) { + if ( !isObject( options ) ) { + return new TypeError( format( 'invalid argument. Options argument must be an object. Value: `%s.`', options ) ); + } + if ( hasOwnProp( options, 'address' ) ) { + opts.address = options.address; + if ( !isString( opts.address ) ) { + return new TypeError( format( 'invalid option. `address` option must be a string. Option: `%s`.', opts.address ) ); + } + } + if ( hasOwnProp( options, 'hostname' ) ) { + opts.hostname = options.hostname; + if ( !isString( opts.hostname ) ) { + return new TypeError( format( 'invalid option. `hostname` option must be a string. Option: `%s`.', opts.hostname ) ); + } + } + if ( hasOwnProp( options, 'latest' ) ) { + opts.latest = options.latest; + if ( !isString( opts.latest ) ) { + return new TypeError( format( 'invalid option. `latest` option must be a string. Option: `%s`.', opts.latest ) ); + } + } + if ( hasOwnProp( options, 'logger' ) ) { + opts.logger = options.logger; + if ( isString( opts.logger ) ) { + opts.logger = { + 'level': opts.logger + }; + } else if ( !isBoolean( opts.logger ) ) { + return new TypeError( format( 'invalid option. `logger` option must be either a boolean or a string. Option: `%s`.', opts.logger ) ); + } + } + if ( hasOwnProp( options, 'port' ) ) { + opts.port = options.port; + if ( !isNonNegativeInteger( opts.port ) ) { + return new TypeError( format( 'invalid option. `port` must be a nonnegative integer. Option: `%s`.', opts.port ) ); + } + } + if ( hasOwnProp( options, 'prefix' ) ) { + opts.prefix = options.prefix; + if ( !isString( opts.prefix ) && !isStringArray( opts.prefix ) ) { + return new TypeError( format( 'invalid option. `prefix` option must be either a string or an array of strings. Option: `%s`.', opts.prefix ) ); + } + } + if ( hasOwnProp( options, 'root' ) ) { + opts.root = options.root; + if ( !isString( opts.root ) ) { + return new TypeError( format( 'invalid option. `root` option must be a string. Option: `%s`.', opts.root ) ); + } + } + if ( hasOwnProp( options, 'static' ) ) { + opts.static = options.static; + if ( !isString( opts.static ) && !isStringArray( opts.static ) ) { + return new TypeError( format( 'invalid option. `static` option must be either a string or an array of strings. Option: `%s`.', opts.static ) ); + } + } + if ( hasOwnProp( options, 'trustProxy' ) ) { + opts.trustProxy = options.trustProxy; + if ( !isBoolean( opts.trustProxy ) ) { + return new TypeError( format( 'invalid option. `trustProxy` option must be a boolean. Option: `%s`.', opts.trustProxy ) ); + } + } + if ( hasOwnProp( options, 'ignoreTrailingSlash' ) ) { + opts.ignoreTrailingSlash = options.ignoreTrailingSlash; + if ( !isBoolean( opts.ignoreTrailingSlash ) ) { + return new TypeError( format( 'invalid option. `ignoreTrailingSlash` option must be a boolean. Option: `%s`.', opts.ignoreTrailingSlash ) ); + } + } + return null; +} + + +// EXPORTS // + +module.exports = validate; \ No newline at end of file diff --git a/lib/server/package.json b/lib/server/package.json new file mode 100644 index 0000000000..e6ae3f9d80 --- /dev/null +++ b/lib/server/package.json @@ -0,0 +1,55 @@ +{ + "private": true, + "name": "", + "version": "0.0.0", + "description": "Create an HTTP server for serving test code coverage.", + "license": "Apache-2.0", + "author": { + "name": "The Stdlib Authors", + "url": "https://github.com/stdlib-js/www-test-code-coverage/graphs/contributors" + }, + "contributors": [ + { + "name": "The Stdlib Authors", + "url": "https://github.com/stdlib-js/www-test-code-coverage/graphs/contributors" + } + ], + "main": "./lib", + "directories": { + "lib": "./lib" + }, + "scripts": {}, + "homepage": "https://github.com/stdlib-js/www-test-code-coverage", + "repository": { + "type": "git", + "url": "git://github.com/stdlib-js/www-test-code-coverage.git" + }, + "bugs": { + "url": "https://github.com/stdlib-js/www-test-code-coverage/issues" + }, + "dependencies": {}, + "devDependencies": {}, + "engines": { + "node": ">=0.10.0", + "npm": ">2.7.0" + }, + "os": [ + "aix", + "darwin", + "freebsd", + "linux", + "macos", + "openbsd", + "sunos", + "win32", + "windows" + ], + "keywords": [ + "stdlib", + "tools", + "tool", + "test", + "server", + "api" + ] +} diff --git a/package.json b/package.json new file mode 100644 index 0000000000..cbd6917593 --- /dev/null +++ b/package.json @@ -0,0 +1,47 @@ +{ + "name": "www-test-code-coverage", + "version": "0.0.0", + "description": "Website for stdlib project code coverage.", + "main": "", + "license": "Apache-2.0", + "author": { + "name": "The Stdlib Authors", + "url": "https://github.com/stdlib-js/www-test-code-coverage/graphs/contributors" + }, + "contributors": [ + { + "name": "The Stdlib Authors", + "url": "https://github.com/stdlib-js/www-test-code-coverage/graphs/contributors" + } + ], + "scripts": { + "build": "make build", + "clean": "make clean", + "install:prod": "make install", + "start": "NODE_ENV=production node ./server/index.js", + "start-dev": "NODE_ENV=development node ./server/index.js" + }, + "repository": { + "type": "git", + "url": "git://github.com/stdlib-js/www-test-code-coverage.git" + }, + "homepage": "https://github.com/stdlib-js/www-test-code-coverage", + "keywords": [], + "bugs": { + "url": "https://github.com/stdlib-js/www-test-code-coverage/issues" + }, + "dependencies": { + "@fastify/cookie": "^11.0.2", + "@fastify/helmet": "^13.0.1", + "@fastify/static": "^8.0.3", + "@preact/compat": "^18.3.1", + "@stdlib/stdlib": "^0.3.2", + "fastify": "^5.2.1", + "preact": "^10.25.4", + "preact-iso": "^2.8.1" + }, + "devDependencies": { + "esbuild": "^0.24.2", + "clean-css": "^5.3.3" + } +} diff --git a/public/css/main/bundle.json b/public/css/main/bundle.json new file mode 100644 index 0000000000..a4ac5ac68e --- /dev/null +++ b/public/css/main/bundle.json @@ -0,0 +1,3 @@ +[ + "./layout.css" +] diff --git a/public/css/main/bundle.min.css b/public/css/main/bundle.min.css new file mode 100644 index 0000000000..d4fd7bfa55 --- /dev/null +++ b/public/css/main/bundle.min.css @@ -0,0 +1 @@ +*{margin:0;padding:0;box-sizing:border-box} \ No newline at end of file diff --git a/public/css/main/layout.css b/public/css/main/layout.css new file mode 100644 index 0000000000..a7d2e6f140 --- /dev/null +++ b/public/css/main/layout.css @@ -0,0 +1,44 @@ +/* +* @license Apache-2.0 +* +* Copyright (c) 2025 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +/* +* Layout stylesheet. +* +* 1. General rules. +* 2. Clearfix. +* 3. Positioning. +* 4. Grid. +* 5. Main. +* 6. Lists. +* 7. Definition lists. +* 8. Blockquotes. +* 9. Horizontal rules. +* 10. Tables. +* 11. Code. +* 12. Classes. +*/ + +/* +* General top-level rules. +*/ + +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} \ No newline at end of file diff --git a/public/index.html b/public/index.html new file mode 100644 index 0000000000..fec5b8f4b1 --- /dev/null +++ b/public/index.html @@ -0,0 +1,15 @@ + + + + + + Test Code Coverage | stdlib + + + + + +
+ + + diff --git a/public/js/bundle.js b/public/js/bundle.js new file mode 100644 index 0000000000..742a9e188c --- /dev/null +++ b/public/js/bundle.js @@ -0,0 +1,18 @@ +(()=>{var Ze=Object.defineProperty,Ve=Object.defineProperties;var et=Object.getOwnPropertyDescriptors;var ke=Object.getOwnPropertySymbols;var tt=Object.prototype.hasOwnProperty,nt=Object.prototype.propertyIsEnumerable;var be=(t,e,n)=>e in t?Ze(t,e,{enumerable:!0,configurable:!0,writable:!0,value:n}):t[e]=n,xe=(t,e)=>{for(var n in e||(e={}))tt.call(e,n)&&be(t,n,e[n]);if(ke)for(var n of ke(e))nt.call(e,n)&&be(t,n,e[n]);return t},Ce=(t,e)=>Ve(t,et(e));var _t=(t,e)=>()=>(t&&(e=t(t=0)),e);function R(t,e){for(var n in e)t[n]=e[n];return t}function ie(t){t&&t.parentNode&&t.parentNode.removeChild(t)}function E(t,e,n){var _,o,r,u={};for(r in e)r=="key"?_=e[r]:r=="ref"?o=e[r]:u[r]=e[r];if(arguments.length>2&&(u.children=arguments.length>3?q.call(arguments,2):n),typeof t=="function"&&t.defaultProps!=null)for(r in t.defaultProps)u[r]===void 0&&(u[r]=t.defaultProps[r]);return B(t,u,_,o,null)}function B(t,e,n,_,o){var r={type:t,props:e,key:n,ref:_,__k:null,__:null,__b:0,__e:null,__c:null,constructor:void 0,__v:o==null?++Se:o,__i:-1,__u:0};return o==null&&m.vnode!=null&&m.vnode(r),r}function Y(t){return t.children}function K(t,e){this.props=t,this.context=e}function F(t,e){if(e==null)return t.__?F(t.__,t.__i+1):null;for(var n;ee&&U.sort(te));G.__r=0}function Te(t,e,n,_,o,r,u,c,l,s,p){var i,f,a,v,x,g,h=_&&_.__k||De,d=e.length;for(l=it(n,e,h,l,d),i=0;i0?B(u.type,u.props,u.key,u.ref?u.ref:null,u.__v):u).__=t,u.__b=t.__b+1,c=null,(s=u.__i=ut(u,n,l,i))!==-1&&(i--,(c=n[s])&&(c.__u|=2)),c==null||c.__v===null?(s==-1&&f--,typeof u.type!="function"&&(u.__u|=4)):s!=l&&(s==l-1?f--:s==l+1?f++:(s>l?f--:f++,u.__u|=4))):t.__k[r]=null;if(i)for(r=0;r(l!=null&&!(2&l.__u)?1:0))for(o=n-1,r=n+1;o>=0||r=0){if((l=e[o])&&!(2&l.__u)&&u==l.key&&c===l.type)return o;o--}if(r2&&(c.children=arguments.length>3?q.call(arguments,2):n),B(t.type,c,_||t.key,o||t.ref,null)}function fe(t,e){var n={__c:e="__cC"+Le++,__:t,Consumer:function(_,o){return _.children(o)},Provider:function(_){var o,r;return this.getChildContext||(o=new Set,(r={})[e]=this,this.getChildContext=function(){return r},this.componentWillUnmount=function(){o=null},this.shouldComponentUpdate=function(u){this.props.value!==u.value&&o.forEach(function(c){c.__e=!0,re(c)})},this.sub=function(u){o.add(u);var c=u.componentWillUnmount;u.componentWillUnmount=function(){o&&o.delete(u),c&&c.call(u)}}),_.children}};return n.Provider.__=n.Consumer.contextType=n}var q,m,Se,rt,U,Ee,He,te,Re,oe,ne,_e,Le,N,De,ot,J,T=_t(()=>{N={},De=[],ot=/acit|ex(?:s|g|n|p|$)|rph|grid|ows|mnc|ntw|ine[ch]|zoo|^ord|itera/i,J=Array.isArray;q=De.slice,m={__e:function(t,e,n,_){for(var o,r,u;e=e.__;)if((o=e.__c)&&!o.__)try{if((r=o.constructor)&&r.getDerivedStateFromError!=null&&(o.setState(r.getDerivedStateFromError(t)),u=o.__d),o.componentDidCatch!=null&&(o.componentDidCatch(t,_||{}),u=o.__d),u)return o.__E=o}catch(c){t=c}throw t}},Se=0,rt=function(t){return t!=null&&t.constructor==null},K.prototype.setState=function(t,e){var n;n=this.__s!=null&&this.__s!==this.state?this.__s:this.__s=R({},this.state),typeof t=="function"&&(t=t(R({},n),this.props)),t&&R(n,t),t!=null&&this.__v&&(e&&this._sb.push(e),re(this))},K.prototype.forceUpdate=function(t){this.__v&&(this.__e=!0,t&&this.__h.push(t),re(this))},K.prototype.render=Y,U=[],He=typeof Promise=="function"?Promise.prototype.then.bind(Promise.resolve()):setTimeout,te=function(t,e){return t.__v.__b-e.__v.__b},G.__r=0,Re=/(PointerCapture)$|Capture$/i,oe=0,ne=we(!1),_e=we(!0),Le=0});T();T();T();T();var I,y,pe,Ie,he=0,je=[],b=m,We=b.__b,Be=b.__r,Ne=b.diffed,qe=b.__c,$e=b.unmount,Oe=b.__;function X(t,e){b.__h&&b.__h(y,t,he||e),he=0;var n=y.__H||(y.__H={__:[],__h:[]});return t>=n.__.length&&n.__.push({}),n.__[t]}function me(t,e,n){var _=X(I++,2);if(_.t=t,!_.__c&&(_.__=[n?n(e):ft(void 0,e),function(c){var l=_.__N?_.__N[0]:_.__[0],s=_.t(l,c);l!==s&&(_.__N=[s,_.__[1]],_.__c.setState({}))}],_.__c=y,!y.u)){var o=function(c,l,s){if(!_.__c.__H)return!0;var p=_.__c.__H.__.filter(function(f){return!!f.__c});if(p.every(function(f){return!f.__N}))return!r||r.call(this,c,l,s);var i=_.__c.props!==c;return p.forEach(function(f){if(f.__N){var a=f.__[0];f.__=f.__N,f.__N=void 0,a!==f.__[0]&&(i=!0)}}),r&&r.call(this,c,l,s)||i};y.u=!0;var r=y.shouldComponentUpdate,u=y.componentWillUpdate;y.componentWillUpdate=function(c,l,s){if(this.__e){var p=r;r=void 0,o(c,l,s),r=p}u&&u.call(this,c,l,s)},y.shouldComponentUpdate=o}return _.__N||_.__}function ve(t,e){var n=X(I++,4);!b.__s&&Ke(n.__H,e)&&(n.__=t,n.i=e,y.__h.push(n))}function w(t){return he=5,Z(function(){return{current:t}},[])}function Z(t,e){var n=X(I++,7);return Ke(n.__H,e)&&(n.__=t(),n.__H=e,n.__h=t),n.__}function ye(t){var e=y.context[t.__c],n=X(I++,9);return n.c=t,e?(n.__==null&&(n.__=!0,e.sub(y)),e.props.value):t.__}function lt(){for(var t;t=je.shift();)if(t.__P&&t.__H)try{t.__H.__h.forEach(Q),t.__H.__h.forEach(de),t.__H.__h=[]}catch(e){t.__H.__h=[],b.__e(e,t.__v)}}b.__b=function(t){y=null,We&&We(t)},b.__=function(t,e){t&&e.__k&&e.__k.__m&&(t.__m=e.__k.__m),Oe&&Oe(t,e)},b.__r=function(t){Be&&Be(t),I=0;var e=(y=t.__c).__H;e&&(pe===y?(e.__h=[],y.__h=[],e.__.forEach(function(n){n.__N&&(n.__=n.__N),n.i=n.__N=void 0})):(e.__h.forEach(Q),e.__h.forEach(de),e.__h=[],I=0)),pe=y},b.diffed=function(t){Ne&&Ne(t);var e=t.__c;e&&e.__H&&(e.__H.__h.length&&(je.push(e)!==1&&Ie===b.requestAnimationFrame||((Ie=b.requestAnimationFrame)||at)(lt)),e.__H.__.forEach(function(n){n.i&&(n.__H=n.i),n.i=void 0})),pe=y=null},b.__c=function(t,e){e.some(function(n){try{n.__h.forEach(Q),n.__h=n.__h.filter(function(_){return!_.__||de(_)})}catch(_){e.some(function(o){o.__h&&(o.__h=[])}),e=[],b.__e(_,n.__v)}}),qe&&qe(t,e)},b.unmount=function(t){$e&&$e(t);var e,n=t.__c;n&&n.__H&&(n.__H.__.forEach(function(_){try{Q(_)}catch(o){e=o}}),n.__H=void 0,e&&b.__e(e,n.__v))};var ze=typeof requestAnimationFrame=="function";function at(t){var e,n=function(){clearTimeout(_),ze&&cancelAnimationFrame(e),setTimeout(t)},_=setTimeout(n,100);ze&&(e=requestAnimationFrame(n))}function Q(t){var e=y,n=t.__c;typeof n=="function"&&(t.__c=void 0,n()),y=e}function de(t){var e=y;t.__c=t.__(),y=e}function Ke(t,e){return!t||t.length!==e.length||e.some(function(n,_){return n!==t[_]})}function ft(t,e){return typeof e=="function"?e(t):e}var A,$,pt=(t,e)=>{if(A=void 0,e&&e.type==="click"){if(e.ctrlKey||e.metaKey||e.altKey||e.shiftKey||e.button!==0)return t;let n=e.target.closest("a[href]"),_=n&&n.getAttribute("href");if(!n||n.origin!=location.origin||/^#/.test(_)||!/^(_?self)?$/i.test(n.target)||$&&(typeof $=="string"?!_.startsWith($):!$.test(_)))return t;A=!0,e.preventDefault(),e=n.href.replace(location.origin,"")}else typeof e=="string"?A=!0:e&&e.url?(A=!e.replace,e=e.url):e=location.pathname+location.search;return A===!0?history.pushState(null,"",e):A===!1&&history.replaceState(null,"",e),e},ht=(t,e,n)=>{t=t.split("/").filter(Boolean),e=(e||"").split("/").filter(Boolean);for(let _=0,o,r;_{let r=new URL(e,location.origin),u=r.pathname.replace(/\/+$/g,"")||"/";return{url:e,path:u,query:Object.fromEntries(r.searchParams),route:(c,l)=>n({url:c,replace:l}),wasPush:_}},[e]);return ve(()=>(addEventListener("click",n),addEventListener("popstate",n),()=>{removeEventListener("click",n),removeEventListener("popstate",n)}),[]),E(O.ctx.Provider,{value:o},t.children)}var dt=Promise.resolve();function Je(t){let[e,n]=me(k=>k+1,0),{url:_,query:o,wasPush:r,path:u}=Ye(),{rest:c=u,params:l={}}=ye(Ge),s=w(!1),p=w(u),i=w(0),f=w(),a=w(),v=w(),x=w(!1),g=w();g.current=!1;let h=w(!1),d,L,C;ue(t.children).some(k=>{if(ht(c,k.props.path,C=Ce(xe({},k.props),{path:c,query:o,params:l,rest:""})))return d=ae(k,C);k.props.default&&(L=ae(k,C))});let S=d||L;Z(()=>{a.current=f.current;let k=a.current&&a.current.props.children;!k||!S||S.type!==k.type||S.props.component!==k.props.component?(this.__v&&this.__v.__k&&this.__v.__k.reverse(),i.current++,h.current=!0):h.current=!1},[_]);let D=f.current&&f.current.__u&V&&f.current.__u&ee,z=f.current&&f.current.__h;f.current=E(Ge.Provider,{value:C},S),D?(f.current.__u|=V,f.current.__u|=ee):z&&(f.current.__h=!0);let M=a.current;return a.current=null,this.__c=(k,H)=>{g.current=!0,a.current=M,t.onLoadStart&&t.onLoadStart(_),s.current=!0;let P=i.current;k.then(()=>{P===i.current&&(a.current=null,f.current&&(H.__h&&(f.current.__h=H.__h),H.__u&ee&&(f.current.__u|=ee),H.__u&V&&(f.current.__u|=V)),dt.then(n))})},ve(()=>{let k=this.__v&&this.__v.__e;if(g.current){!x.current&&!v.current&&(v.current=k);return}!x.current&&v.current&&(v.current!==k&&v.current.remove(),v.current=null),x.current=!0,p.current!==u&&(r&&scrollTo(0,0),t.onRouteChange&&t.onRouteChange(_),p.current=u),t.onLoadEnd&&s.current&&t.onLoadEnd(_),s.current=!1},[u,r,e]),h.current?[E(ge,{r:f}),E(ge,{r:a})]:E(ge,{r:f})}var V=32,ee=128,ge=({r:t})=>t.current;Je.Provider=O;O.ctx=fe({});var Ge=fe({});var Ye=()=>ye(O.ctx);T();var Qe=m.__e;m.__e=(t,e,n)=>{if(t&&t.then){let _=e;for(;_=_.__;)if(_.__c&&_.__c.__c)return e.__e==null&&(e.__e=n.__e,e.__k=n.__k),e.__k||(e.__k=[]),_.__c.__c(t,e)}Qe&&Qe(t,e,n)};T();function mt(){return E("div",null,E("h1",null,"Lorem ipsum dolor sit amet, consectetur adipisicing elit."))}var Xe=mt;le(E(Xe,null),document.getElementById("root"));})(); +/** +* @license Apache-2.0 +* +* Copyright (c) 2025 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ diff --git a/server/index.js b/server/index.js new file mode 100644 index 0000000000..c260a1baa1 --- /dev/null +++ b/server/index.js @@ -0,0 +1,21 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2025 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +// MAIN // + +require( './server.js' ); \ No newline at end of file diff --git a/server/server.js b/server/server.js new file mode 100644 index 0000000000..346ae9acfe --- /dev/null +++ b/server/server.js @@ -0,0 +1,68 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2025 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var path = require( 'path' ); +var httpServer = require( './../lib/server' ); + + +// VARIABLES // + +var PUBLIC_DIR = path.resolve( __dirname, '..', 'public' ); +var PORT = 3000; + + +// FUNCTIONS // + +/** +* Callback invoked upon starting a server. +* +* @private +* @param {(Error|null)} error - error object +* @param {Object} fastify - fastify instance +*/ +function done( error ) { + if ( error ) { + throw error; + } + console.log( 'Server is running...' ); +} + + +// MAIN // + +/** +* Main execution sequence. +* +* @private +*/ +function main() { + var opts = { + // 'latest': config.versions[ 0 ], + 'logger': 'info', + 'port': PORT, + 'prefix': '/', + 'root': PUBLIC_DIR + }; + httpServer( opts )( done ); +} + +main(); \ No newline at end of file diff --git a/src/app.jsx b/src/app.jsx new file mode 100644 index 0000000000..4f940a9cff --- /dev/null +++ b/src/app.jsx @@ -0,0 +1,41 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2025 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + + +// MODULES // + +import { h } from 'preact' +import { Router } from 'preact-iso' + + +// MAIN // + +/** +* Main application component. +* +* @returns {PreactComponent} preact component +*/ +function App() { + return( +
+

Lorem ipsum dolor sit amet, consectetur adipisicing elit.

+
+ ) +} + +export default App; diff --git a/src/index.jsx b/src/index.jsx new file mode 100644 index 0000000000..3750520ef2 --- /dev/null +++ b/src/index.jsx @@ -0,0 +1,28 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2025 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + + +// MODULES // + +import { h, render } from 'preact'; +import App from './app.jsx'; + + +// MAIN // + +render( , document.getElementById( 'root' ) ); diff --git a/tools/README.md b/tools/README.md new file mode 100644 index 0000000000..1dfae75f62 --- /dev/null +++ b/tools/README.md @@ -0,0 +1,49 @@ + + +# Tools + +> Development tools. + + + +
+ +This directory contains development utilities for building and managing the website. + +
+ + + + + +
+ +
+ + + + + + + + diff --git a/tools/make/Makefile b/tools/make/Makefile new file mode 100644 index 0000000000..cc084f2bd7 --- /dev/null +++ b/tools/make/Makefile @@ -0,0 +1,65 @@ +#/ +# @license Apache-2.0 +# +# Copyright (c) 2025 The Stdlib Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +#/ + +# DEPENDENCIES # + +# Order is important: +include $(TOOLS_MAKE_DIR)/common.mk +include $(TOOLS_MAKE_LIB_DIR)/help/Makefile + +# Please keep sorted in alphabetical order: +include $(TOOLS_MAKE_LIB_DIR)/css/Makefile +include $(TOOLS_MAKE_LIB_DIR)/install/Makefile +include $(TOOLS_MAKE_LIB_DIR)/js/Makefile + + +# RULES # + +#/ +# Default target. +# +# @example +# make +# +# @example +# make all +#/ +all: help + +.PHONY: all + +#/ +# Runs the project's cleanup sequence. +# +# @example +# make clean +#/ +clean: clean-node clean-js-bundle + $(QUIET) $(DELETE) $(DELETE_FLAGS) + +.PHONY: clean + +#/ +# Runs the project's build sequence. +# +# @example +# make build +#/ +build: $(NODE_MODULES) build-js css-minify + +.PHONY: build \ No newline at end of file diff --git a/tools/make/README.md b/tools/make/README.md new file mode 100644 index 0000000000..ca87856bdc --- /dev/null +++ b/tools/make/README.md @@ -0,0 +1,44 @@ + + +# Makefile + +> Development utility. + +This project uses [`make`][make] as its development utility. For an overview of `make`, see the `make` [manual][make]. + + +## Usage + +#### Help + +To view a list of available `Makefile` targets, + +```bash +$ make help +``` + + + + \ No newline at end of file diff --git a/tools/make/common.mk b/tools/make/common.mk new file mode 100644 index 0000000000..9453b879ce --- /dev/null +++ b/tools/make/common.mk @@ -0,0 +1,127 @@ +#/ +# @license Apache-2.0 +# +# Copyright (c) 2025 The Stdlib Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +#/ + +# VERBOSITY # + +ifndef VERBOSE + QUIET := @ +endif + + +# ENVIRONMENTS # + +# Determine the OS: +# +# [1]: https://en.wikipedia.org/wiki/Uname#Examples +# [2]: http://stackoverflow.com/a/27776822/2225624 +OS ?= $(shell uname) +ifneq (, $(findstring MINGW,$(OS))) + OS := WINNT +else +ifneq (, $(findstring MSYS,$(OS))) + OS := WINNT +else +ifneq (, $(findstring CYGWIN,$(OS))) + OS := WINNT +else +ifneq (, $(findstring Windows_NT,$(OS))) + OS := WINNT +endif +endif +endif +endif + +# Define whether the make commands are running on a hosted continuous integration service: +TRAVIS ?= +APPVEYOR ?= +CIRCLECI ?= +GITHUB ?= +ifeq ($(TRAVIS), true) + CI_SERVICE ?= travis +else +ifeq ($(APPVEYOR), true) + CI_SERVICE ?= appveyor +else +ifeq ($(CIRCLECI), true) + CI_SERVICE ?= circle +else +ifeq ($(GITHUB), true) + CI_SERVICE ?= github +else + CI_SERVICE ?= none +endif +endif +endif +endif + + +# COMMANDS # + +# Define whether delete operations should be safe (i.e., deleted items are sent to trash, rather than permanently deleted): +SAFE_DELETE ?= false + +# Define the delete command: +ifeq ($(SAFE_DELETE), true) + # FIXME: -rm -rf + DELETE := -rm + DELETE_FLAGS := -rf +else + DELETE ?= -rm + DELETE_FLAGS ?= -rf +endif + +# Define the command for setting executable permissions: +MAKE_EXECUTABLE ?= chmod +x + +# Define the command for recursively creating directories (WARNING: portability issues on some systems!): +MKDIR_RECURSIVE ?= mkdir -p + +# Define the command for extracting tarfiles: +TAR ?= tar + +# Define the command to `cat` a file: +CAT ?= cat + +# Define the command to copy files: +CP ?= cp + +# Define the command to recursively sync directories: +RSYNC_RECURSIVE ?= rsync -r + +# Define the `git` command: +GIT ?= git + +# Define the command for staging files: +GIT_ADD ?= $(GIT) add + +# Define the command for committing files: +GIT_COMMIT ?= $(GIT) commit + +# Determine the `open` command: +ifeq ($(OS), Darwin) + OPEN ?= open +else + OPEN ?= xdg-open +endif +# TODO: add Windows command + +# Define the command for `node`: +NODE ?= node + +# Define the command for `npm`: +NPM ?= npm \ No newline at end of file diff --git a/tools/make/lib/css/Makefile b/tools/make/lib/css/Makefile new file mode 100644 index 0000000000..3d257d6b81 --- /dev/null +++ b/tools/make/lib/css/Makefile @@ -0,0 +1,36 @@ +#/ +# @license Apache-2.0 +# +# Copyright (c) 2025 The Stdlib Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +#/ + +# VARIABLES # + +# Define the path to the script for generating minified CSS bundles: +css_minifier ?= $(TOOLS_DIR)/scripts/minify_css.js + + +# RULES # + +#/ +# Minifies CSS source files. +# +# @example +# make css-minify +#/ +css-minify: $(NODE_MODULES) $(css_minifier) + $(QUIET) NODE_PATH="$(NODE_PATH)" $(NODE) "$(css_minifier)" + +.PHONY: css-minify \ No newline at end of file diff --git a/tools/make/lib/css/README.md b/tools/make/lib/css/README.md new file mode 100644 index 0000000000..e544358ec7 --- /dev/null +++ b/tools/make/lib/css/README.md @@ -0,0 +1,51 @@ + + +# CSS + +> CSS recipes. + + + +
+ +This directory contains [`make`][make] recipes for managing CSS files. + +
+ + + + + +
+ +
+ + + + + + + + \ No newline at end of file diff --git a/tools/make/lib/help/Makefile b/tools/make/lib/help/Makefile new file mode 100644 index 0000000000..8331a03fbe --- /dev/null +++ b/tools/make/lib/help/Makefile @@ -0,0 +1,60 @@ +#/ +# @license Apache-2.0 +# +# Copyright (c) 2025 The Stdlib Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +#/ + +# VARIABLES # + +# Define the path to the Makefile usage text file for displaying help information: +MAKE_USAGE ?= $(TOOLS_MAKE_DIR)/usage.txt + +# Define command flags: +FIND_MAKEFILES_FLAGS ?= \ + -name 'Makefile' \ + -o \ + -name '*.mk' + + +# RULES # + +#/ +# Prints a help message and lists available targets. +# +# @example +# make help +#/ +help: + $(QUIET) $(CAT) $(MAKE_USAGE) + +.PHONY: help + +#/ +# Lists all Makefile targets. +# +# ## Notes +# +# - The list of targets is NOT exhaustive, as it does not include targets which have not been explicitly declared PHONY targets and does not include targets declared via variables. These targets could be included by dumping the Makefile database `make -qp`, but not seen as necessary due to predominant use of PHONY. +# +# @example +# make list-targets +#/ +list-targets: + $(QUIET) find $(TOOLS_MAKE_DIR) $(FIND_MAKEFILES_FLAGS) \ + | xargs grep '^.PHONY: ' \ + | awk '{print $$2}' \ + | sort + +.PHONY: list-targets \ No newline at end of file diff --git a/tools/make/lib/help/README.md b/tools/make/lib/help/README.md new file mode 100644 index 0000000000..61490b6836 --- /dev/null +++ b/tools/make/lib/help/README.md @@ -0,0 +1,51 @@ + + +# Help + +> Help recipes. + + + +
+ +This directory contains [`make`][make] recipes for printing help information when using [`make`][make], such as the project [`make`][make] usage text, targets, and more. + +
+ + + + + +
+ +
+ + + + + + + + \ No newline at end of file diff --git a/tools/make/lib/install/Makefile b/tools/make/lib/install/Makefile new file mode 100644 index 0000000000..b84d5eff75 --- /dev/null +++ b/tools/make/lib/install/Makefile @@ -0,0 +1,34 @@ +#/ +# @license Apache-2.0 +# +# Copyright (c) 2025 The Stdlib Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +#/ + +# DEPENDENCIES # + +include $(TOOLS_MAKE_LIB_DIR)/install/node.mk + + +# RULES # + +#/ +# Runs the project's install process. +# +# @example +# make install +#/ +install: install-node + +.PHONY: install \ No newline at end of file diff --git a/tools/make/lib/install/README.md b/tools/make/lib/install/README.md new file mode 100644 index 0000000000..9141a22668 --- /dev/null +++ b/tools/make/lib/install/README.md @@ -0,0 +1,51 @@ + + +# Install + +> Install recipes. + + + +
+ +This directory contains [`make`][make] recipes for running the project's installation process. + +
+ + + + + +
+ +
+ + + + + + + + \ No newline at end of file diff --git a/tools/make/lib/install/node.mk b/tools/make/lib/install/node.mk new file mode 100644 index 0000000000..09d59fd887 --- /dev/null +++ b/tools/make/lib/install/node.mk @@ -0,0 +1,53 @@ +#/ +# @license Apache-2.0 +# +# Copyright (c) 2025 The Stdlib Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +#/ + +# VARIABLES # + +# Define the path to the root `package.json`: +ROOT_PACKAGE_JSON ?= $(ROOT_DIR)/package.json + + +# VARIABLES # + +#/ +# Installs package dependencies by executing [`npm install`][1]. +# +# ## Notes +# +# - Packages will be installed in a local `node_modules` directory relative to the project's `package.json` file. +# +# [1]: https://docs.npmjs.com/cli/install +# +# @example +# make install-node +#/ +install-node: $(ROOT_PACKAGE_JSON) + $(QUIET) $(NPM) install + +.PHONY: install-node + +#/ +# Cleans the `node_modules` directory by removing it entirely. +# +# @example +# make clean-node +#/ +clean-node: + $(QUIET) $(DELETE) $(DELETE_FLAGS) $(NODE_MODULES) + +.PHONY: clean-node \ No newline at end of file diff --git a/tools/make/lib/js/Makefile b/tools/make/lib/js/Makefile new file mode 100644 index 0000000000..7635f4e4c8 --- /dev/null +++ b/tools/make/lib/js/Makefile @@ -0,0 +1,42 @@ +#/ +# @license Apache-2.0 +# +# Copyright (c) 2025 The Stdlib Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +#/ + + +# RULES # + +#/ +# Builds javascript. +# +# @example +# make build-js +#/ +build-js: $(NODE_MODULES) + $(QUIET) NODE_PATH="$(NODE_PATH)" $(NODE) "$(ROOT_DIR)/etc/esbuild/build.js" + +.PHONY: build-js + +#/ +# Removes javascript bundle. +# +# @example +# make clean-js +#/ +clean-js-bundle: + $(QUIET) $(DELETE) $(BUILD_DIR)/js/bundle.js + +.PHONY: clean-js-bundle diff --git a/tools/make/usage.txt b/tools/make/usage.txt new file mode 100644 index 0000000000..042e26d837 --- /dev/null +++ b/tools/make/usage.txt @@ -0,0 +1,11 @@ + +Usage: make + + make help Print this message. + make notes Search for code annotations. + make list-files List files. + make install Run install sequence. + make clean Run all cleanup tasks. + make clean-node Remove Node dependencies. + make inspect.VARIABLE Print the runtime value of a VARIABLE. + make assert.VARIABLE Assert that a VARIABLE is set. \ No newline at end of file diff --git a/tools/scripts/README.md b/tools/scripts/README.md new file mode 100644 index 0000000000..2d81c25553 --- /dev/null +++ b/tools/scripts/README.md @@ -0,0 +1,49 @@ + + +# Scripts + +> Generic scripts. + + + +
+ +This directory contains generic project scripts. + +
+ + + + + +
+ +
+ + + + + + + + \ No newline at end of file diff --git a/tools/scripts/minify_css.js b/tools/scripts/minify_css.js new file mode 100644 index 0000000000..ca7799af91 --- /dev/null +++ b/tools/scripts/minify_css.js @@ -0,0 +1,126 @@ +#!/usr/bin/env node + +/** +* @license Apache-2.0 +* +* Copyright (c) 2025 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var fs = require( 'fs' ); +var path = require( 'path' ); +var CleanCSS = require( 'clean-css' ); + + +// VARIABLES // + +// Parent directory containing source CSS files: +var dirpath = path.join( __dirname, '../../public/css' ); + +// Child directories containing source CSS files to bundle and minify: +var dirs = [ + path.join( dirpath, 'main' ) +]; + +// CSS processor options: +var copts = { + 'returnPromise': false, + 'compatibility': 'ie9', + 'level': 1 +}; + + +// FUNCTIONS // + +/** +* Synchronously reads a list of CSS files. +* +* @private +* @param {Array} list - list of files +* @returns {Array} array of file contents +*/ +function readFiles( list ) { + var opts; + var out; + var i; + + opts = { + 'encoding': 'utf8' + }; + out = []; + for ( i = 0; i < list.length; i++ ) { + out.push( fs.readFileSync( list[ i ], opts ) ); + } + return out; +} + + +// MAIN // + +/** +* Main execution sequence. +* +* @private +*/ +function main() { + var minifier; + var fpath; + var fopts; + var tmp; + var i; + var j; + + minifier = new CleanCSS( copts ); + fopts = { + 'encoding': 'utf8' + }; + + // Process each CSS directory... + for ( i = 0; i < dirs.length; i++ ) { + // Read the bundle list: + tmp = require( path.join( dirs[ i ], 'bundle.json' ) ); + + // Resolve each file in the list to an absolute path: + for ( j = 0; j < tmp.length; j++ ) { + tmp[ j ] = path.resolve( dirs[ i ], tmp[ j ] ); + } + // Read each CSS file: + tmp = readFiles( tmp ); + + // Concatenate file contents into a single string: + tmp = tmp.join( '\n' ); + + // Minify the CSS: + tmp = minifier.minify( tmp ); + if ( tmp.errors.length ) { + console.error( 'Directory: %s\n', dirs[ i ] ); + console.error( 'Errors:\n' ); + console.error( tmp.errors.join( '\n' ) ); + } + if ( tmp.warnings.length ) { + console.error( 'Directory: %s\n', dirs[ i ] ); + console.error( 'Warnings:\n' ); + console.error( tmp.warnings.join( '\n' ) ); + } + // Write the minified CSS to file: + fpath = path.join( dirs[ i ], 'bundle.min.css' ); + fs.writeFileSync( fpath, tmp.styles, fopts ); + } +} + +main(); \ No newline at end of file From 30b0c555be35fd1bd861830f625824532860fa11 Mon Sep 17 00:00:00 2001 From: Muhammad Haris <101793258+headlessNode@users.noreply.github.com> Date: Wed, 15 Jan 2025 10:06:03 +0500 Subject: [PATCH 2/5] docs: apply code review suggestion Co-authored-by: Philipp Burckhardt Signed-off-by: Muhammad Haris <101793258+headlessNode@users.noreply.github.com> --- lib/server/lib/main.js | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/server/lib/main.js b/lib/server/lib/main.js index a1903c63ca..2fdea0a630 100644 --- a/lib/server/lib/main.js +++ b/lib/server/lib/main.js @@ -34,6 +34,7 @@ var routes = require( './routes' ); var DEFAULTS = require( './defaults.json' ); var validate = require( './validate.js' ); + // MAIN // /** From aa5d58c6fefcb633269f697bcd9ced63ce0c3069 Mon Sep 17 00:00:00 2001 From: Muhammad Haris <101793258+headlessNode@users.noreply.github.com> Date: Wed, 15 Jan 2025 10:06:20 +0500 Subject: [PATCH 3/5] docs: apply code review suggestion Co-authored-by: Philipp Burckhardt Signed-off-by: Muhammad Haris <101793258+headlessNode@users.noreply.github.com> --- tools/make/lib/js/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/make/lib/js/Makefile b/tools/make/lib/js/Makefile index 7635f4e4c8..3df17abcef 100644 --- a/tools/make/lib/js/Makefile +++ b/tools/make/lib/js/Makefile @@ -31,7 +31,7 @@ build-js: $(NODE_MODULES) .PHONY: build-js #/ -# Removes javascript bundle. +# Removes JavaScript bundle. # # @example # make clean-js From 4c4526e90b8d83b337b60aa00ef01de2a86598bf Mon Sep 17 00:00:00 2001 From: Muhammad Haris <101793258+headlessNode@users.noreply.github.com> Date: Wed, 15 Jan 2025 10:06:33 +0500 Subject: [PATCH 4/5] docs: apply code review suggestion Co-authored-by: Philipp Burckhardt Signed-off-by: Muhammad Haris <101793258+headlessNode@users.noreply.github.com> --- tools/make/lib/js/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/make/lib/js/Makefile b/tools/make/lib/js/Makefile index 3df17abcef..be9c5b95ec 100644 --- a/tools/make/lib/js/Makefile +++ b/tools/make/lib/js/Makefile @@ -20,7 +20,7 @@ # RULES # #/ -# Builds javascript. +# Builds JavaScript. # # @example # make build-js From 69dcfa124f53fcb3d9d7c603bd1e9f7e67ca8e9f Mon Sep 17 00:00:00 2001 From: Athan Reines Date: Sat, 8 Feb 2025 03:41:02 -0800 Subject: [PATCH 5/5] chore: clean-up --- .editorconfig | 4 +- .gitignore | 2 +- .npmrc | 2 +- Makefile | 6 +-- etc/README.md | 4 +- etc/esbuild/build.js | 6 +-- etc/esbuild/config.js | 40 +++++++++---------- lib/server/README.md | 4 +- lib/server/lib/defaults.json | 6 +-- lib/server/lib/index.js | 6 +-- lib/server/lib/main.js | 8 ++-- .../node_modules/middleware-sequence/index.js | 3 +- .../node_modules/middleware/error/index.js | 1 - lib/server/lib/routes/home/home.js | 15 ++----- lib/server/lib/routes/home/index.js | 2 +- lib/server/lib/routes/home/main.js | 2 +- lib/server/lib/routes/index.js | 1 - lib/server/lib/validate.js | 27 +++++-------- lib/server/package.json | 2 +- package.json | 1 + server/server.js | 3 +- src/app.jsx | 4 ++ src/index.jsx | 3 +- tools/make/Makefile | 2 +- tools/make/README.md | 3 +- tools/make/common.mk | 2 +- tools/make/lib/css/Makefile | 2 +- tools/make/lib/css/README.md | 2 +- tools/make/lib/help/Makefile | 2 +- tools/make/lib/help/README.md | 2 +- tools/make/lib/install/Makefile | 2 +- tools/make/lib/install/README.md | 2 +- tools/make/lib/install/node.mk | 2 +- tools/make/lib/js/Makefile | 1 + tools/make/usage.txt | 2 +- tools/scripts/minify_css.js | 2 +- 36 files changed, 78 insertions(+), 100 deletions(-) diff --git a/.editorconfig b/.editorconfig index 5c93bb86b7..dbeac67c45 100644 --- a/.editorconfig +++ b/.editorconfig @@ -86,7 +86,7 @@ indent_style = tab [*.{f,f.txt}] indent_style = space indent_size = 2 -insert_final_newline = false +insert_final_newline = true # Set properties for shell files: [*.{sh,sh.txt}] @@ -121,7 +121,7 @@ indent_style = tab [*.{md,md.txt}] indent_style = space indent_size = 4 -trim_trailing_whitespace = false +trim_trailing_whitespace = true # Set properties for `usage.txt` files: [usage.txt] diff --git a/.gitignore b/.gitignore index 263ece930d..3616e53dd8 100644 --- a/.gitignore +++ b/.gitignore @@ -168,4 +168,4 @@ jsconfig.json # Sublime Text # ################ -*.sublime-workspace \ No newline at end of file +*.sublime-workspace diff --git a/.npmrc b/.npmrc index 37a820168d..f955402ed6 100644 --- a/.npmrc +++ b/.npmrc @@ -25,4 +25,4 @@ package-lock = false shrinkwrap = false # Disable automatically "saving" dependencies on install: -save = false \ No newline at end of file +save = false diff --git a/Makefile b/Makefile index bec0b6687b..ac5edc43cf 100644 --- a/Makefile +++ b/Makefile @@ -66,10 +66,10 @@ BUILD_FOLDER ?= js # Define filename extension conventions (keep in alphabetical order): CSS_FILENAME_EXT ?= css -# Define Node paths: (WARNING: we cannot use an absolute path here because of Webpack which only allows relative paths) -NODE_PATH ?= ./node_modules/@stdlib/stdlib/lib/node_modules +# Define Node paths: +NODE_PATH ?= # DEPENDENCIES # -include $(TOOLS_MAKE_DIR)/Makefile \ No newline at end of file +include $(TOOLS_MAKE_DIR)/Makefile diff --git a/etc/README.md b/etc/README.md index b63b63323d..5f88206948 100644 --- a/etc/README.md +++ b/etc/README.md @@ -38,7 +38,7 @@ This directory contains configuration files. ## Notes -* Configuration files for external tools and environments should be placed in subdirectories. The subdirectory name should correspond to the name of the tool or environment. +- Configuration files for external tools and environments should be placed in subdirectories. The subdirectory name should correspond to the name of the tool or environment. @@ -50,4 +50,4 @@ This directory contains configuration files. - \ No newline at end of file + diff --git a/etc/esbuild/build.js b/etc/esbuild/build.js index 1d9e53524c..d7f40113f9 100644 --- a/etc/esbuild/build.js +++ b/etc/esbuild/build.js @@ -18,20 +18,20 @@ 'use strict'; - // MODULES // var esbuild = require( 'esbuild' ); -var config = require( './config' ); +var config = require( './config.js' ); // MAIN // /** -* Builds the website using esbuild. +* Builds the website. * * @async * @throws {Error} build failure +* @returns {Promise} promise which resolves upon building the website */ async function main() { try { diff --git a/etc/esbuild/config.js b/etc/esbuild/config.js index 1807b9d50b..761b59205c 100644 --- a/etc/esbuild/config.js +++ b/etc/esbuild/config.js @@ -18,34 +18,32 @@ 'use strict'; - // MODULES // -var path = require( 'path' ); - - -// VARIABLES // +var resolve = require( 'path' ).resolve; -var SRC_DIR = path.resolve( __dirname, '../../src' ); -var BUILD_DIR = path.resolve( __dirname, '../../public/js' ); +// MAIN // -// EXPORTS // - -module.exports = { - entryPoints: [ - SRC_DIR + '/index.jsx' +var config = { + 'entryPoints': [ + resolve( __dirname, '../../src/index.jsx' ) ], - bundle: true, - outfile: BUILD_DIR + '/bundle.js', - minify: true, - sourcemap: false, - target: 'es2015', - jsxFactory: 'h', - jsxFragment: 'Fragment', - jsxImportSource: 'preact', - alias: { + 'bundle': true, + 'outfile': resolve( __dirname, '../../public/js/bundle.js' ), + 'minify': true, + 'sourcemap': false, + 'target': 'es2015', + 'jsxFactory': 'h', + 'jsxFragment': 'Fragment', + 'jsxImportSource': 'preact', + 'alias': { 'react': 'preact/compat', 'react-dom': 'preact/compat' } }; + + +// EXPORTS // + +module.exports = config; diff --git a/lib/server/README.md b/lib/server/README.md index c86a07a8c9..4db40e2e03 100644 --- a/lib/server/README.md +++ b/lib/server/README.md @@ -18,6 +18,6 @@ limitations under the License. --> -# Test code coverage Server +# Server -> Create an HTTP server for serving test code coverage. \ No newline at end of file +> HTTP server for serving test code coverage. diff --git a/lib/server/lib/defaults.json b/lib/server/lib/defaults.json index 446a6746a3..bce21ac4b8 100644 --- a/lib/server/lib/defaults.json +++ b/lib/server/lib/defaults.json @@ -1,6 +1,5 @@ { "address": "127.0.0.1", - "latest": "", "logger": false, "port": 0, "prefix": "/", @@ -11,9 +10,6 @@ "app": { "title": "Test Code Coverage | stdlib", "description": "Test code coverage website for stdlib, a standard library for JavaScript and Node.js, with an emphasis on numerical and scientific computing.", - "theme": "", - "mode": "default", - "exampleSyntax": "es5", - "prevNextNavigation": "alphabetical" + "theme": "" } } diff --git a/lib/server/lib/index.js b/lib/server/lib/index.js index 68c2fc7f34..2de16f0eae 100644 --- a/lib/server/lib/index.js +++ b/lib/server/lib/index.js @@ -21,10 +21,10 @@ /** * Create an HTTP server for serving test code coverage. * -* @module @stdlib/_tools/docs/www-test-code-coverage/server +* @module @stdlib/www-test-coverage-server * * @example -* var httpServer = require( '@stdlib/_tools/docs/www-test-code-coverage/server' ); +* var httpServer = require( '@stdlib/www-test-coverage-server' ); * var App = require( 'my-app' ); * * var opts = { @@ -51,4 +51,4 @@ var main = require( './main.js' ); // EXPORTS // -module.exports = main; \ No newline at end of file +module.exports = main; diff --git a/lib/server/lib/main.js b/lib/server/lib/main.js index 2fdea0a630..bfbe743f77 100644 --- a/lib/server/lib/main.js +++ b/lib/server/lib/main.js @@ -43,7 +43,6 @@ var validate = require( './validate.js' ); * @param {Options} [options] - server options * @param {string} [options.address="127.0.0.1"] - server address * @param {string} [options.hostname] - server hostname -* @param {string} [options.latest=""] - latest version (e.g., `v0.0.90`) * @param {(boolean|string)} [options.logger=false] - either a boolean indicating whether to enable logging or a log level * @param {NonNegativeInteger} [options.port=0] - server port * @param {(string|StringArray)} [options.prefix="/"] - URL path prefix(es) used to create a virtual mount path(s) for static directories @@ -142,16 +141,15 @@ function httpServer( options ) { // Decorate route handler `this` contexts with additional functionality: f.decorate( 'rootDir', opts.root ); - f.decorate( 'latestVersion', opts.latest ); // Decorate each `request` object with a `locals` object for passing along intermediate results within middleware handlers: f.decorateRequest( 'locals', null ); // Register a plugin for serving static files: f.register( fastifyStatic, { - root: opts.root, - prefix: opts.prefix, - wildcard: true, + 'root': opts.root, + 'prefix': opts.prefix, + 'wildcard': true }); // Register routes: diff --git a/lib/server/lib/node_modules/middleware-sequence/index.js b/lib/server/lib/node_modules/middleware-sequence/index.js index 85ad15a7b7..467e4ecf88 100644 --- a/lib/server/lib/node_modules/middleware-sequence/index.js +++ b/lib/server/lib/node_modules/middleware-sequence/index.js @@ -32,14 +32,13 @@ var format = require( '@stdlib/string/format' ); * * @param {FunctionArray} fcns - array of middleware functions * @param {Callback} errback - callback to invoke upon encountering an error -* @param {Callback} [done] - callback to invoke upon completion * @throws {TypeError} first argument must be an array of functions * @throws {TypeError} second argument must be a function * @returns {Function} middleware function */ function factory( fcns, errback ) { if ( !isFunctionArray( fcns ) ) { - throw new TypeError( format( 'invalid argument. First argument must be a function array. Value: `%s`.', fcns ) ); + throw new TypeError( format( 'invalid argument. First argument must be an array of functions. Value: `%s`.', fcns ) ); } if ( !isFunction( errback ) ) { throw new TypeError( format( 'invalid argument. Second argument must be a function. Value: `%s`.', errback ) ); diff --git a/lib/server/lib/node_modules/middleware/error/index.js b/lib/server/lib/node_modules/middleware/error/index.js index c18a99596f..306c0d3cbf 100644 --- a/lib/server/lib/node_modules/middleware/error/index.js +++ b/lib/server/lib/node_modules/middleware/error/index.js @@ -18,7 +18,6 @@ 'use strict'; - // MAIN // /** diff --git a/lib/server/lib/routes/home/home.js b/lib/server/lib/routes/home/home.js index e76a38f857..9c4ae727fb 100644 --- a/lib/server/lib/routes/home/home.js +++ b/lib/server/lib/routes/home/home.js @@ -16,11 +16,8 @@ * limitations under the License. */ -/* eslint-disable no-invalid-this */ - 'use strict'; - // MAIN // /** @@ -32,26 +29,20 @@ * @returns {void} */ function handler( request, reply ) { - var version; var url; - // Set version - version = this.latestVersion; - request.log.info( 'Version: %s', version ); - - // Handle URL and add version path url = request.url; - if ( url[url.length - 1] !== '/' ) { + if ( url[ url.length-1 ] !== '/' ) { url += '/'; } - url += version; request.log.info( 'Resolved URL: %s', request.url ); - // Send the HTML shell to the client + // Send the HTML shell to the client: reply.type( 'text/html' ); reply.sendFile( 'index.html' ); } + // EXPORTS // module.exports = handler; diff --git a/lib/server/lib/routes/home/index.js b/lib/server/lib/routes/home/index.js index 3e41b2caa9..f5dba8ad1d 100644 --- a/lib/server/lib/routes/home/index.js +++ b/lib/server/lib/routes/home/index.js @@ -27,7 +27,7 @@ var handler = require( './main.js' ); // MAIN // /** -* Defines a route handler for returning a shell-app for test coverage website landing page. +* Defines a route handler for returning a shell-app for a landing page. * * @private * @returns {Object} route declaration diff --git a/lib/server/lib/routes/home/main.js b/lib/server/lib/routes/home/main.js index 3c93b5d792..750049b41b 100644 --- a/lib/server/lib/routes/home/main.js +++ b/lib/server/lib/routes/home/main.js @@ -48,4 +48,4 @@ var handler = middleware( steps, onError ); // EXPORTS // -module.exports = handler; \ No newline at end of file +module.exports = handler; diff --git a/lib/server/lib/routes/index.js b/lib/server/lib/routes/index.js index 71c598617c..d75f219d51 100644 --- a/lib/server/lib/routes/index.js +++ b/lib/server/lib/routes/index.js @@ -18,7 +18,6 @@ 'use strict'; - // MODULES // var home = require( './home' ); diff --git a/lib/server/lib/validate.js b/lib/server/lib/validate.js index b67e4e4b5f..95f0de29be 100644 --- a/lib/server/lib/validate.js +++ b/lib/server/lib/validate.js @@ -39,7 +39,6 @@ var format = require( '@stdlib/string/format' ); * @param {Options} options - function options * @param {string} [options.address] - server address * @param {string} [options.hostname] - server hostname -* @param {string} [options.latest] - latest version * @param {(boolean|string)} [options.logger] - either boolean indicating whether to enable logging or a log level * @param {NonNegativeInteger} [options.port] - server port * @param {(string|StringArray)} [options.prefix] - URL path prefix(es) used to create a virtual mount path(s) for static directories @@ -67,19 +66,13 @@ function validate( opts, options ) { if ( hasOwnProp( options, 'address' ) ) { opts.address = options.address; if ( !isString( opts.address ) ) { - return new TypeError( format( 'invalid option. `address` option must be a string. Option: `%s`.', opts.address ) ); + return new TypeError( format( 'invalid option. `%s` option must be a string. Option: `%s`.', 'address', opts.address ) ); } } if ( hasOwnProp( options, 'hostname' ) ) { opts.hostname = options.hostname; if ( !isString( opts.hostname ) ) { - return new TypeError( format( 'invalid option. `hostname` option must be a string. Option: `%s`.', opts.hostname ) ); - } - } - if ( hasOwnProp( options, 'latest' ) ) { - opts.latest = options.latest; - if ( !isString( opts.latest ) ) { - return new TypeError( format( 'invalid option. `latest` option must be a string. Option: `%s`.', opts.latest ) ); + return new TypeError( format( 'invalid option. `%s` option must be a string. Option: `%s`.', 'hostname', opts.hostname ) ); } } if ( hasOwnProp( options, 'logger' ) ) { @@ -89,43 +82,43 @@ function validate( opts, options ) { 'level': opts.logger }; } else if ( !isBoolean( opts.logger ) ) { - return new TypeError( format( 'invalid option. `logger` option must be either a boolean or a string. Option: `%s`.', opts.logger ) ); + return new TypeError( format( 'invalid option. `%s` option must be either a boolean or a string. Option: `%s`.', 'logger', opts.logger ) ); } } if ( hasOwnProp( options, 'port' ) ) { opts.port = options.port; if ( !isNonNegativeInteger( opts.port ) ) { - return new TypeError( format( 'invalid option. `port` must be a nonnegative integer. Option: `%s`.', opts.port ) ); + return new TypeError( format( 'invalid option. `%s` must be a nonnegative integer. Option: `%s`.', 'port', opts.port ) ); } } if ( hasOwnProp( options, 'prefix' ) ) { opts.prefix = options.prefix; if ( !isString( opts.prefix ) && !isStringArray( opts.prefix ) ) { - return new TypeError( format( 'invalid option. `prefix` option must be either a string or an array of strings. Option: `%s`.', opts.prefix ) ); + return new TypeError( format( 'invalid option. `%s` option must be either a string or an array of strings. Option: `%s`.', 'prefix', opts.prefix ) ); } } if ( hasOwnProp( options, 'root' ) ) { opts.root = options.root; if ( !isString( opts.root ) ) { - return new TypeError( format( 'invalid option. `root` option must be a string. Option: `%s`.', opts.root ) ); + return new TypeError( format( 'invalid option. `%s` option must be a string. Option: `%s`.', 'root', opts.root ) ); } } if ( hasOwnProp( options, 'static' ) ) { opts.static = options.static; if ( !isString( opts.static ) && !isStringArray( opts.static ) ) { - return new TypeError( format( 'invalid option. `static` option must be either a string or an array of strings. Option: `%s`.', opts.static ) ); + return new TypeError( format( 'invalid option. `%s` option must be either a string or an array of strings. Option: `%s`.', 'static', opts.static ) ); } } if ( hasOwnProp( options, 'trustProxy' ) ) { opts.trustProxy = options.trustProxy; if ( !isBoolean( opts.trustProxy ) ) { - return new TypeError( format( 'invalid option. `trustProxy` option must be a boolean. Option: `%s`.', opts.trustProxy ) ); + return new TypeError( format( 'invalid option. `%s` option must be a boolean. Option: `%s`.', 'trustProxy', opts.trustProxy ) ); } } if ( hasOwnProp( options, 'ignoreTrailingSlash' ) ) { opts.ignoreTrailingSlash = options.ignoreTrailingSlash; if ( !isBoolean( opts.ignoreTrailingSlash ) ) { - return new TypeError( format( 'invalid option. `ignoreTrailingSlash` option must be a boolean. Option: `%s`.', opts.ignoreTrailingSlash ) ); + return new TypeError( format( 'invalid option. `%s` option must be a boolean. Option: `%s`.', 'ignoreTrailingSlash', opts.ignoreTrailingSlash ) ); } } return null; @@ -134,4 +127,4 @@ function validate( opts, options ) { // EXPORTS // -module.exports = validate; \ No newline at end of file +module.exports = validate; diff --git a/lib/server/package.json b/lib/server/package.json index e6ae3f9d80..defef6202e 100644 --- a/lib/server/package.json +++ b/lib/server/package.json @@ -1,6 +1,6 @@ { "private": true, - "name": "", + "name": "@stdlib/www-test-coverage-server", "version": "0.0.0", "description": "Create an HTTP server for serving test code coverage.", "license": "Apache-2.0", diff --git a/package.json b/package.json index cbd6917593..55215639cd 100644 --- a/package.json +++ b/package.json @@ -1,4 +1,5 @@ { + "private": true, "name": "www-test-code-coverage", "version": "0.0.0", "description": "Website for stdlib project code coverage.", diff --git a/server/server.js b/server/server.js index 346ae9acfe..4ab4e130e9 100644 --- a/server/server.js +++ b/server/server.js @@ -56,7 +56,6 @@ function done( error ) { */ function main() { var opts = { - // 'latest': config.versions[ 0 ], 'logger': 'info', 'port': PORT, 'prefix': '/', @@ -65,4 +64,4 @@ function main() { httpServer( opts )( done ); } -main(); \ No newline at end of file +main(); diff --git a/src/app.jsx b/src/app.jsx index 4f940a9cff..472eae3035 100644 --- a/src/app.jsx +++ b/src/app.jsx @@ -16,6 +16,7 @@ * limitations under the License. */ +'use strict'; // MODULES // @@ -38,4 +39,7 @@ function App() { ) } + +// EXPORTS // + export default App; diff --git a/src/index.jsx b/src/index.jsx index 3750520ef2..ba3acf112a 100644 --- a/src/index.jsx +++ b/src/index.jsx @@ -16,10 +16,11 @@ * limitations under the License. */ +'use strict'; // MODULES // -import { h, render } from 'preact'; +import { render } from 'preact'; import App from './app.jsx'; diff --git a/tools/make/Makefile b/tools/make/Makefile index cc084f2bd7..005d80944c 100644 --- a/tools/make/Makefile +++ b/tools/make/Makefile @@ -62,4 +62,4 @@ clean: clean-node clean-js-bundle #/ build: $(NODE_MODULES) build-js css-minify -.PHONY: build \ No newline at end of file +.PHONY: build diff --git a/tools/make/README.md b/tools/make/README.md index ca87856bdc..b0fa75f1c0 100644 --- a/tools/make/README.md +++ b/tools/make/README.md @@ -24,7 +24,6 @@ limitations under the License. This project uses [`make`][make] as its development utility. For an overview of `make`, see the `make` [manual][make]. - ## Usage #### Help @@ -41,4 +40,4 @@ $ make help - \ No newline at end of file + diff --git a/tools/make/common.mk b/tools/make/common.mk index 9453b879ce..95b0c839e6 100644 --- a/tools/make/common.mk +++ b/tools/make/common.mk @@ -124,4 +124,4 @@ endif NODE ?= node # Define the command for `npm`: -NPM ?= npm \ No newline at end of file +NPM ?= npm diff --git a/tools/make/lib/css/Makefile b/tools/make/lib/css/Makefile index 3d257d6b81..c2b9cb20cf 100644 --- a/tools/make/lib/css/Makefile +++ b/tools/make/lib/css/Makefile @@ -33,4 +33,4 @@ css_minifier ?= $(TOOLS_DIR)/scripts/minify_css.js css-minify: $(NODE_MODULES) $(css_minifier) $(QUIET) NODE_PATH="$(NODE_PATH)" $(NODE) "$(css_minifier)" -.PHONY: css-minify \ No newline at end of file +.PHONY: css-minify diff --git a/tools/make/lib/css/README.md b/tools/make/lib/css/README.md index e544358ec7..ce14bd217b 100644 --- a/tools/make/lib/css/README.md +++ b/tools/make/lib/css/README.md @@ -48,4 +48,4 @@ This directory contains [`make`][make] recipes for managing CSS files. - \ No newline at end of file + diff --git a/tools/make/lib/help/Makefile b/tools/make/lib/help/Makefile index 8331a03fbe..e06e026275 100644 --- a/tools/make/lib/help/Makefile +++ b/tools/make/lib/help/Makefile @@ -57,4 +57,4 @@ list-targets: | awk '{print $$2}' \ | sort -.PHONY: list-targets \ No newline at end of file +.PHONY: list-targets diff --git a/tools/make/lib/help/README.md b/tools/make/lib/help/README.md index 61490b6836..f272ba0650 100644 --- a/tools/make/lib/help/README.md +++ b/tools/make/lib/help/README.md @@ -48,4 +48,4 @@ This directory contains [`make`][make] recipes for printing help information whe - \ No newline at end of file + diff --git a/tools/make/lib/install/Makefile b/tools/make/lib/install/Makefile index b84d5eff75..cd8ceda0a3 100644 --- a/tools/make/lib/install/Makefile +++ b/tools/make/lib/install/Makefile @@ -31,4 +31,4 @@ include $(TOOLS_MAKE_LIB_DIR)/install/node.mk #/ install: install-node -.PHONY: install \ No newline at end of file +.PHONY: install diff --git a/tools/make/lib/install/README.md b/tools/make/lib/install/README.md index 9141a22668..3088c575fb 100644 --- a/tools/make/lib/install/README.md +++ b/tools/make/lib/install/README.md @@ -48,4 +48,4 @@ This directory contains [`make`][make] recipes for running the project's install - \ No newline at end of file + diff --git a/tools/make/lib/install/node.mk b/tools/make/lib/install/node.mk index 09d59fd887..0aecf81470 100644 --- a/tools/make/lib/install/node.mk +++ b/tools/make/lib/install/node.mk @@ -50,4 +50,4 @@ install-node: $(ROOT_PACKAGE_JSON) clean-node: $(QUIET) $(DELETE) $(DELETE_FLAGS) $(NODE_MODULES) -.PHONY: clean-node \ No newline at end of file +.PHONY: clean-node diff --git a/tools/make/lib/js/Makefile b/tools/make/lib/js/Makefile index be9c5b95ec..f8a6c428c0 100644 --- a/tools/make/lib/js/Makefile +++ b/tools/make/lib/js/Makefile @@ -40,3 +40,4 @@ clean-js-bundle: $(QUIET) $(DELETE) $(BUILD_DIR)/js/bundle.js .PHONY: clean-js-bundle + diff --git a/tools/make/usage.txt b/tools/make/usage.txt index 042e26d837..aecad7e54a 100644 --- a/tools/make/usage.txt +++ b/tools/make/usage.txt @@ -8,4 +8,4 @@ Usage: make make clean Run all cleanup tasks. make clean-node Remove Node dependencies. make inspect.VARIABLE Print the runtime value of a VARIABLE. - make assert.VARIABLE Assert that a VARIABLE is set. \ No newline at end of file + make assert.VARIABLE Assert that a VARIABLE is set. diff --git a/tools/scripts/minify_css.js b/tools/scripts/minify_css.js index ca7799af91..c851389b0e 100644 --- a/tools/scripts/minify_css.js +++ b/tools/scripts/minify_css.js @@ -123,4 +123,4 @@ function main() { } } -main(); \ No newline at end of file +main();