diff --git a/.github/workflows/devnet-bundle-release.yml b/.github/workflows/devnet-bundle-release.yml index 128585e..273d217 100644 --- a/.github/workflows/devnet-bundle-release.yml +++ b/.github/workflows/devnet-bundle-release.yml @@ -28,3 +28,6 @@ jobs: release_version: ${{ github.event.inputs.releaseVersion }} next_dev_version: ${{ github.event.inputs.nextDevVersion }} ms_teams_webhook_uri: ${{secrets.MS_TEAMS_WEBHOOK_URI}} + demo_user: ${{secrets.DEMO_USER}} + demo_user_pw: ${{secrets.DEMO_USER_PW}} + demo_url: ${{secrets.DEMO_URL}} diff --git a/.stylelintignore b/.stylelintignore new file mode 100644 index 0000000..b07fa47 --- /dev/null +++ b/.stylelintignore @@ -0,0 +1,3 @@ +# add path patterns to ignore style files +**/external-libs/** +**/styles/dijit/** \ No newline at end of file diff --git a/.stylelintrc b/.stylelintrc new file mode 100644 index 0000000..57c90c1 --- /dev/null +++ b/.stylelintrc @@ -0,0 +1,3 @@ +{ + "extends": "stylelint-config-ct-prodeng" +} diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 0000000..67efcac --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,8 @@ +{ + "recommendations": [ + "dbaeumer.vscode-eslint", + "Vue.volar", + "Esri.arcgis-jsapi-snippets", + "ctjdr.vscode-apprt-bundles" + ] +} \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..e8ab909 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,15 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "type": "chrome", + "request": "launch", + "name": "Launch Chrome against localhost", + "url": "http://localhost:9090", + "webRoot": "${workspaceFolder}/src/main" + } + ] +} \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 93297ba..30fd3c8 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -3,27 +3,40 @@ "tasks": [ { "label": "Initialize", + "detail": "Initialize map.apps for Developers project", "type": "shell", "command": "mvn initialize", "group": "build" }, { - "label": "Run HTTP Server", + "label": "Run", + "detail": "Run map.apps for Developers development server", "type": "shell", - "command": "mvn jetty:run -Denv=dev '-Dlocal.configfile=./build.properties'", - "group": "build" + "command": "mvn", + "args": ["clean", "compile", "-Denv=dev", "'-Dlocal.configfile=./build.properties'", "-Pinclude-mapapps-deps"], + "group": "build", + "isBackground": true }, { - "label": "Run stand-alone HTTP Server", + "label": "Run (Remote project mode)", + "detail": "Run map.apps for Developers development server in 'remote project' mode", "type": "shell", - "command": "mvn jetty:run -Denv=dev '-Dlocal.configfile=./build.properties' -Pinclude-mapapps-deps", - "group": "build" + "command": "mvn", + "args": ["clean", "compile", "-Denv=dev", "'-Dlocal.configfile=./build.properties'"], + "group": "build", + "isBackground": true }, { "label": "Compress", + "detail": "Prepare bundles and apps for deployment on a map.apps instance", "type": "shell", - "command": "mvn install -P compress", - "group": "build" + "command": "mvn", + "args": ["clean", "install", "-Pcompress"], + "group": "build", + "presentation": { + "reveal": "always", + "panel": "dedicated" + } }, { "label": "Clean", diff --git a/gulpfile.js b/gulpfile.js index 0f5fabb..4cd2847 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -15,38 +15,168 @@ */ const gulp = require("gulp"); const mapapps = require('ct-mapapps-gulp-js'); +const mapappsBrowserSync = require("ct-mapapps-browser-sync"); + +const isProduction = process.env.NODE_ENV === "production"; +console.info(`Configuring gulp build for ${isProduction ? "production" : "development"}`); + +const localOverrides = (function () { + if (isProduction) { + // Never override defaults in production mode + return undefined; + } + + try { + return require("./gulpfile.overrides"); + } catch (e) { + // File may not exist + return undefined; + } +})(); + +// used to transport test urls in "run-browser-tests-local" task +const runBrowserTests = []; mapapps.registerTasks({ + /** Enable debug logging */ + debug: localOverrides?.debug ?? false, + /** enable linting */ + lintOnWatch: localOverrides?.lintOnWatch ?? true, + /** enable es6 by default */ + forceTranspile: true, /* A detailed description of available setting is available at https://www.npmjs.com/package/ct-mapapps-gulp-js */ + compress: isProduction, + + /* build source maps as e.g. ".js.map" */ + sourceMaps: "file", + + /** Build Unit-Tests only in dev mode */ + rollupBuildTests: !isProduction, + /** Amount of Threads used to build the bundles, if there are only a few bundles 1 is ok. + * More as 3 is normally not required. + */ + rollupBuildMaxWorkers: localOverrides?.rollupBuildMaxWorkers ?? 1, + + /** List of build time flags, usage like: import { debug } from "build-config!". + */ + rollupConfig: { + debug: !isProduction + }, + /* a list of themes inside this project */ themes: [/*"sample-theme"*/], /* state that the custom theme will be dependant from map.apps everlasting theme that provides the base styles */ hasBaseThemes: true, /* state that we want to support vuetify components and therefore need the vuetify core styles*/ - hasVuetify: true - /*themeChangeTargets: { + hasVuetify: true, + themeChangeTargets: { "vuetify": [ - "sample_theme" + // "sample_theme" ] - }*/ -}); + }, + /* A list oft target browser versions. This should be streamlined with Esri JS API requirements. */ + transpileTargets: { + firefox: 102, + edge: 104, + chrome: 104, + safari: 15 + }, + runBrowserTests, + watchFinishedReceiver() { + if (localOverrides?.autoReload ?? true) { + mapappsBrowserSync.state.reload(); + } + } +}, gulp); -gulp.task("default", +mapappsBrowserSync.registerTask({ + // on which port to listen + port: localOverrides?.port ?? 9090, + // activate https protocol, generates a self signed certificate for "localhost" + // https://browsersync.io/docs/options#option-https + https: localOverrides?.https ?? false, + + // to prevent auto open of browser, set this to false + urlToOpen: localOverrides?.openBrowser ?? true, + properties: { + paths: [ + // Ensure @@key@@ expressions filtered in tests files + /^\/js\/tests\/(runTests.html|test-init.js|init-packs.js)$/ + ] + }, + jsreg: { + //npmDir : __dirname + "/node_modules/", + npmModules: [ + "mocha", + "chai", + "@conterra/mapapps-mocha-runner" + ] + }, + // prevent reload by browser sync (reload triggered on watch end) + externalReloadTrigger: true +}, gulp); + +gulp.task("build", gulp.series( "copy-resources", "themes-copy", gulp.parallel( - //"js-lint", - //"style-lint", "js-transpile", + "rollup-build", "themes-compile" ) ) ); +gulp.task("lint", + gulp.parallel( + "js-lint" + /*, comment in to lint .css/.less files + "style-lint" + */ + )); + +gulp.task("preview", + gulp.series( + "build", + "lint", + gulp.parallel( + "watch", + "browser-sync" + ) + )); + +gulp.task("run-tests", + gulp.series( + "browser-sync-start", + function transportTestUrls() { + // transport test url to run-browser-tests + // eslint-disable-next-line max-len + const testsAt = mapappsBrowserSync.state.url + "/resources/jsregistry/root/@conterra/mapapps-mocha-runner/latest/mocha.html?boot=/js/tests/test-init.js&timeout=5000&test=dn_popupstypes/tests/all&reporter=tap"; + runBrowserTests.push(testsAt); + return Promise.resolve(); + }, + "run-browser-tests", + "browser-sync-stop" + )); + +gulp.task("test", + gulp.series( + "build", + "lint", + "run-tests" + )); + gulp.task("compress", gulp.series( - "default", - "themes-compress" + "build", + "themes-compress", + "lint" ) ); + +gulp.task("default", + gulp.series( + "build", + "lint" + )); diff --git a/package.json b/package.json index 4b544a4..899af04 100644 --- a/package.json +++ b/package.json @@ -1,17 +1,25 @@ { - "name": "test", + "name": "mapapps-4-developers", "description": "test build", "version": "0.0.1", + "license": "CC0-1.0", + "scripts": { + "check-licenses": "node ./src/support/js/check-licenses.js" + }, "devDependencies": { - "@conterra/ct-mapapps-typings": "4.13.1", - "@conterra/mapapps-mocha-runner": "^1.0.0", - "@types/arcgis-js-api": "4.22.0", - "ct-mapapps-gulp-js": "^0.6.18", - "vue-template-compiler": "2.6.14", - "puppeteer": "^13.3.2", - "eslint-config-ct-prodeng": "^1.2.5", - "stylelint-config-ct-prodeng": "1.0.3", - "chai": "^4.3.4", - "mocha": "^9.0.0" + "@conterra/ct-mapapps-typings": "4.15.1", + "@conterra/mapapps-mocha-runner": "^1.1.1", + "@types/arcgis-js-api": "4.26.0", + "chai": "^4.3.7", + "ct-mapapps-browser-sync": "0.0.30", + "ct-mapapps-gulp-js": "0.9.4", + "eslint-config-ct-prodeng": "1.3.0-next-2", + "license-checker": "^25.0.1", + "mocha": "^10.2.0", + "puppeteer": "^19.11.1", + "vue-template-compiler": "2.7.8", + "stylelint-config-ct-prodeng": "1.0.4", + "stylelint-config-recommended": "5.0.0", + "stylelint": "^13.13.1" } } diff --git a/pom.xml b/pom.xml index ed0b70d..ebacb99 100644 --- a/pom.xml +++ b/pom.xml @@ -17,7 +17,7 @@ --> + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> 4.0.0 de.conterra.devnet mapapps-popups-types @@ -46,19 +46,14 @@ pom import + + de.conterra.mapapps + ct-mapapps-js + ${mapapps.version} + - - de.conterra.jsregistry - ct-jsregistry-embedded - test - - - de.conterra.ct-proxy - ct-proxy-servlet - test - org.vuejs @@ -91,20 +86,11 @@ - - de.conterra.mapapps - mapapps-maven-plugin - ${mapapps.version} - de.conterra.jsregistry ct-jsregistry-maven-plugin ${ct.jsregistry.version} - - maven-deploy-plugin - 2.8.2 - org.apache.maven.plugins maven-resources-plugin @@ -130,6 +116,8 @@ apps/** **/tests/** + **/sample_tests/** + **/theme-common/** @@ -137,21 +125,6 @@ maven-war-plugin 3.2.3 - - org.codehaus.mojo - exec-maven-plugin - 1.6.0 - - - org.eclipse.jetty - jetty-maven-plugin - 10.0.8 - - - jar - - - org.codehaus.mojo properties-maven-plugin @@ -167,8 +140,8 @@ frontend-maven-plugin 1.12.1 - v16.14.0 - 8.3.1 + v18.13.0 + 8.19.3 @@ -274,8 +247,7 @@ de.conterra.mapapps - ct-mapapps-js-api - ${mapapps.version} + ct-mapapps-js src ${project.build.directory}/unpacked layout/theme-everlasting/**,layout/theme-common/** @@ -293,58 +265,32 @@ + + copy js-libs into 'bundle-imports' + generate-resources + + copy-dependencies + + + ${project.build.directory}/bundle-imports + + org.apache.maven.plugins maven-resources-plugin - - UTF-8 - - - - de.conterra.jsregistry - ct-jsregistry-maven-plugin - build-jsregistry.properties - process-resources + - buildPacksProperties + testResources + process-resources - ${js.build.outputPath} - ${js.build.outputPath} - - - - org.eclipse.jetty - jetty-maven-plugin - - - ${jetty.port} - - 9966 - jetty-stop - 60000 - 0 - ${basedir}/src/test/webapp/WEB-INF/web.xml - true - - / - - ${root.build.outputPath} - ${basedir}/src/test/webapp - - - .*/ct-jsregistry-embedded-[^/]*\.jar$ - - - - ${project.build.directory} - + UTF-8 @@ -352,23 +298,17 @@ frontend-maven-plugin + run gulp ${gulp.task} gulp + process-resources ${gulp.task} - - - - - watch-changes - - gulp - - none - - watch + + ${gulp.node.env} + @@ -429,15 +369,37 @@ - \s*"bundleLocations"\s*:\s*\[\s*"localbundles"\s*,\s*"bundles"\s*\]\s*,\s* - - + + \s*"bundleLocations"\s*:\s*\[\s*"localbundles"\s*,\s*"bundles"\s*\]\s*,\s* + + + de.conterra.jsregistry + ct-jsregistry-maven-plugin + + + build-jsregistry.properties + process-resources + + buildPacksProperties + + + + apps/**,bundles/sample_tests + + + + + ${js.build.outputPath} + ${js.build.outputPath} + + de.conterra.mapapps mapapps-maven-plugin @@ -525,121 +487,54 @@ UTF-8 - ${project.build.directory}/webapp ${root.build.outputPath}/js - 4.13.1 + 4.15.1 ${mapapps.version} - 1.4.4 + 1.5.10 2.0.2 sample - + *://*:*/**; * - 9090 + $\{mapapps.remote.base\} + mvn + development - - + - - + - - + - + + true - false + true false - - run-js-tests - - - - org.codehaus.mojo - build-helper-maven-plugin - - - reserve-jetty-port - - reserve-network-port - - process-test-resources - - - jetty.server.port - - - - - - - org.eclipse.jetty - jetty-maven-plugin - - - jetty-start - process-test-classes - - start - - - - ${jetty.server.port} - - 0 - true - - - - jetty-stop - prepare-package - - stop - - - - - - com.github.eirslett - frontend-maven-plugin - - - run gulp js tests - test - - gulp - - - run-browser-tests --tests http://localhost:${jetty.server.port}/resources/jsregistry/root/@conterra/mapapps-mocha-runner/latest/mocha.html?boot=/js/tests/test-init.js&timeout=5000&test=dn_popupstypes/tests/all&reporter=tap - - - - - - - include-mapapps-deps de.conterra.mapapps - ct-mapapps-js-api + ct-mapapps-js test @@ -713,8 +608,8 @@ env-dev @@ -724,9 +619,8 @@ ${basedir}/build.properties - + + preview @@ -752,89 +646,16 @@ - watch-all - - - env - dev - - - - - - org.codehaus.mojo - exec-maven-plugin - - - trigger-watch-changes - test-compile - - exec - - - true - ${maven.home}/bin/${mvn.cmd} - - com.github.eirslett:frontend-maven-plugin:gulp@watch-changes - - - - - - - - - - write-release-versions + run-js-tests - ${project.version} - ${project.version} + test - - - - - com.google.code.maven-replacer-plugin - replacer - - - - Set Versions from ${replace.source.version} to ${replace.target.version} - validate - - replace - - - ${basedir} - - src/main/js/**/manifest.json - src/main/js/**/package.json - - - src/main/js/**/tests/** - - false - - - "${replace.source.version}" - "${replace.target.version}" - - - "~${replace.source.version}" - "~${replace.target.version}" - - - - - - - - compress compress + production @@ -854,25 +675,23 @@ calculateDependencies + @@ -922,26 +741,54 @@ - windows - - - Windows - - - - mvn.cmd - - - - unix - - - unix - - + write-release-versions - mvn + ${project.version} + ${project.version} + + + + + com.google.code.maven-replacer-plugin + replacer + + + + Set Versions from ${replace.source.version} to ${replace.target.version} + validate + + replace + + + ${basedir} + + src/main/js/**/manifest.json + + + src/main/js/**/tests/** + + false + + + "${replace.source.version}" + "${replace.target.version}" + + + "~${replace.source.version}" + "~${replace.target.version}" + + + ^${replace.source.version} + ^${replace.target.version} + + + + + + + + diff --git a/src/main/js/.eslintrc b/src/main/js/.eslintrc deleted file mode 100644 index c20bc85..0000000 --- a/src/main/js/.eslintrc +++ /dev/null @@ -1,6 +0,0 @@ -{ - "extends": "eslint-config-ct-prodeng", - "plugins": [ - "vue" - ] -} diff --git a/src/support/js/check-licenses.js b/src/support/js/check-licenses.js new file mode 100644 index 0000000..8ce6054 --- /dev/null +++ b/src/support/js/check-licenses.js @@ -0,0 +1,57 @@ +/* + Checks licenses of node dependencies against a list of allowed licenses. + Fails with exit code != 0 and an error message if a disallowed license is encountered. + The script should be executed from the project root directory after dependencies have been installed: + + $ ./node/node ./src/support/js/check-licenses.js + + To run checks yourself (e.g. to update the allow list or to get details), install + license-checker yourself and run it from the project root directory: + + $ npm install -g license-checker + $ license-checker --summary # outputs list of used licenses + $ license-checker --json # outputs details + + See also https://www.npmjs.com/package/license-checker +*/ + +const checker = require("license-checker"); +const process = require("process"); + +// Licenses known to be OK. +const ACCEPTED_LICENSES = [ + "MIT", + "ISC", + "Apache-2.0", + "Apache 2.0", + "BSD-2-Clause", + "BSD-3-Clause", + "BSD", + "CC0-1.0", + "CC-BY-3.0", + "CC-BY-4.0", + "Python-2.0", + "Unlicense" // Note: not unlicenseD (https://opensource.org/licenses/unlicense) +]; + +// Packages with licenses that are not recognized properly by license-checker. +// These must be checked manually. +const SKIP_PACKAGES = [ + "event-stream@3.0.20", // MIT License not recognized + "taffydb@2.6.2" // BSD-1-Clause License in source code +]; + +checker.init( + { + start: process.cwd(), + onlyAllow: ACCEPTED_LICENSES.join(";"), + excludePackages: SKIP_PACKAGES.join(";") + }, + (error, packages) => { + if (error) { + console.error("Error: ", error); + process.exit(1); + } + process.exit(0); + } +); diff --git a/src/test/resources/application.properties b/src/test/resources/application.properties index a1e1839..fba37e9 100644 --- a/src/test/resources/application.properties +++ b/src/test/resources/application.properties @@ -15,13 +15,13 @@ # # Global configuration properties -# These properties are used inside the test jetty server +# These properties are used inside the development server # and can be used to document required global properties # url to the remote map.apps instance mapapps.remote.base=${mapapps.remote.base} # title in apps -client.config.productname=Developer Network +client.config.productname=mapapps-4-developers # defines runtime version for the sample project. Defaults to map.apps 3.x # to develope mapapps 4.x apps, change this property apprt.version=${apprt.version} @@ -34,9 +34,6 @@ client.config.initjs=$\{mapapps.remote.base\}/resources/jsregistry/root/apprt-bo # or change the name of the main layer file client.config.mainlayerfiles=apprt/launch/layer -#local (embedded) js registry root url -jsregistry.root.url=${applicationURL.noscheme}/resources/jsregistry/root - # This is used to filter a default app name in the *.html files default.app.name=${default.app.name} @@ -47,12 +44,6 @@ default.app.name=${default.app.name} # [,,];\ (username/password currently not encrypted) proxy.allowedServerUrls=${proxy.allowedServerUrls} -# the following is support for proxied ssl connections -# if you configure '*' then you trust all ssl server certificates -# you can also confige the dns of the certificate subjects to trust them, separated by '|' -# or leave the configuration empty, then the normal java mechanism is used. -proxy.allowedSSLDNs=${proxy.allowedSSLDNs} - # Defines rules for proxy access based on host names. # It provides more fine grained control what requests use a proxy page. # Sample: @@ -62,7 +53,37 @@ proxy.allowedSSLDNs=${proxy.allowedSSLDNs} # sample2.mapapps.de goes over own proxy page "/proxyPage' proxy.use.rules=${proxy.use.rules} -jsregistry.replacement.paths=**/tests/*.html +# Starting with version 4.6.0 map.apps assumes accessed resources/webservers support CORS +# http://enable-cors.org/ +# These properties won't be considered anymore: +# proxy.cors.enabledServers, proxy.cors.detection, proxy.cors.enabled +# comma separated list of servers like: +# http://servicesbeta.esri.com,http://server.organization.com +cors.request.trustedServers=${cors.request.trustedServers} + +# Enable debug logging (in browser console). +client.config.logging=DEBUG + +############## Using the Identity Service ############## + +security.login.base=$\{mapapps.remote.base\} +security.login.service.url=$\{security.login.base\}/account/login +security.logout.service.url=$\{security.login.base\}/account/logout +security.self.service.url=$\{security.login.base\}/account/self +security.identity.tokens.service.url=$\{security.login.base\}/account/tokens +security.identity.self.service.url=$\{security.self.service.url\} + +# Configuration options for a remote identity service instance +#security.mode=IDENTITY +#security.login.base=https://identity.service.hostname/identity +#esri.api.arcgisPortalUrl=https://myhost.example.com/portal +# Optional: +#security.identity.cookieName=ctIDENTITY +#cors.request.trustedServers=https://identity.service.hostname -jsregistry.directoryscanner.npmfolder=${basedir}/node_modules -jsregistry.directoryscanner.npmincludes=mocha,chai,@conterra,@conterra/mapapps-mocha-runner +# Configuration options for a local identity service instance e.g. based on ct-identity docker image +#security.mode=IDENTITY +# URL of the docker container providing the identity service +#security.login.base=http://localhost:8080 +#esri.api.arcgisPortalUrl=https://myhost.example.com/portal +#proxy.allowedServerUrls=http://localhost:8080/**,trusted:true; diff --git a/src/test/webapp/WEB-INF/web.xml b/src/test/webapp/WEB-INF/web.xml index a30e8a8..47a22e5 100644 --- a/src/test/webapp/WEB-INF/web.xml +++ b/src/test/webapp/WEB-INF/web.xml @@ -4,8 +4,8 @@ xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0"> - map.apps remote sample - + map.apps sample + @@ -18,5 +18,17 @@ ProxyServlet /proxy - + + + + + default + + useFileMappedBuffer + false + + + diff --git a/src/test/webapp/favicon.png b/src/test/webapp/favicon.png new file mode 100644 index 0000000..899ca55 Binary files /dev/null and b/src/test/webapp/favicon.png differ diff --git a/src/test/webapp/index.html b/src/test/webapp/index.html index dfaf991..c16f912 100644 --- a/src/test/webapp/index.html +++ b/src/test/webapp/index.html @@ -29,7 +29,7 @@ - + @@ -42,7 +42,7 @@ overflow: hidden; } - map.apps remote sample + map.apps sample