diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..1524074 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,2 @@ +helpers/dist +helpers/node_modules diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9421307 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +node_modules +helpers/dist diff --git a/Dockerfile b/Dockerfile index b6ef318..1c65e5a 100644 --- a/Dockerfile +++ b/Dockerfile @@ -14,26 +14,29 @@ ENV PORT '80' ENV LOG_SPARQL_ALL 'true' ENV DEBUG_AUTH_HEADERS 'true' -WORKDIR /usr/src/app -COPY package.json /usr/src/app/package.json -COPY ./scripts /app/scripts -RUN npm install -COPY . /usr/src/app -RUN chmod +x /usr/src/app/run-development.sh -RUN chmod +x /usr/src/app/build-production.sh +WORKDIR /app +RUN mkdir /template && mkdir -p /app/src +COPY package.json /template/package.json +COPY ./scripts /template/scripts +RUN cd /template && npm install +COPY . /template +RUN chmod +x /template/run-development.sh +RUN chmod +x /template/build-production.sh +RUN chmod +x /template/build-template-package.sh +RUN /template/build-template-package.sh EXPOSE ${PORT} -CMD bash boot.sh +CMD bash /template/boot.sh # This stuff only runs when building an image from the template -ONBUILD RUN rm -Rf /app/scripts -ONBUILD ADD . /app/ -ONBUILD RUN /usr/src/app/build-production.sh +ONBUILD RUN rm -Rf /app/src/scripts +ONBUILD ADD . /app/src +ONBUILD RUN /template/build-production.sh -ONBUILD RUN if [ -f /app/on-build.sh ]; \ +ONBUILD RUN if [ -f /app/src/on-build.sh ]; \ then \ echo "Running custom on-build.sh of child" \ - && chmod +x /app/on-build.sh \ - && /bin/bash /app/on-build.sh ;\ + && chmod +x /app/src/on-build.sh \ + && /bin/bash /app/src/on-build.sh ;\ fi diff --git a/babel.config.json b/babel.config.json index b8eae3d..b64909a 100644 --- a/babel.config.json +++ b/babel.config.json @@ -1,6 +1,7 @@ { "presets": [ - ["@babel/preset-env", + [ + "@babel/preset-env", { "targets": { "node": 18 @@ -9,11 +10,6 @@ ], ["@babel/preset-typescript"] ], - "plugins": [ - ["@babel/plugin-proposal-decorators", { "version": "2023-05" }] - ], - "ignore": [ - "./node_modules", - "/usr/src/processing/build/node_modules" - ] + "plugins": [["@babel/plugin-proposal-decorators", { "version": "2023-05" }]], + "ignore": ["./node_modules", "/app/src/node_modules"] } diff --git a/boot.sh b/boot.sh index c39f0b9..ce3c5e4 100755 --- a/boot.sh +++ b/boot.sh @@ -1,20 +1,24 @@ +source /template/helpers.sh + #!/bin/bash if [ "$NODE_ENV" == "development" ] then # Run live-reload development - exec /usr/src/app/node_modules/.bin/nodemon \ - --watch /app \ + exec /template/node_modules/.bin/nodemon \ + --watch /app/src \ --watch /config \ + --ignore /app/src/dist \ --ext js,coffee,ts,mjs,cjs,json \ - --exec /usr/src/app/run-development.sh + --exec /template/run-development.sh elif [ "$NODE_ENV" == "production" ] then - diff -rq /app /app.original > /dev/null + # diff but accept items created during build process + diff -x 'dist*' -x "node_modules" -x "package-lock.json" -x "package.json" -rq /app /app.original > /dev/null APP_FILES_CHANGED="$?" diff -rq /config /config.original > /dev/null CONFIG_FILES_CHANGED="$?" - if [ ! -f /usr/src/build/app.js ] + if [ ! -f /app/dist/app.js ] then echo "No built sources found. If you mount new sources, please set the NODE_ENV=\"development\" environment variable." sleep 5; @@ -31,7 +35,8 @@ then # move new configuration into app for transpilation if [[ "$(ls -A /config 2> /dev/null)" ]] then - cp -Rf /config/* /usr/src/app/app/config/ + mkdir -p /app/src/config/ + cp -Rf /config/* /app/src/config/ fi # make a backup of the used configuration so we can detect changes @@ -43,14 +48,19 @@ then fi # transpile sources - cd /usr/src/app/ - ./transpile-sources.sh + cd /app/ + + # add node modules from template back in + docker-rsync /template/node_modules/ /app/node_modules/ + /template/transpile-sources.sh # boot transpiled sources - cd /usr/src/build/ - exec node ./app.js + cd /app/ + exec node /app/dist/app.js else - cd /usr/src/build/ - exec node ./app.js + cd /app/ + # add node modules from template back in + docker-rsync /template/node_modules/ /app/node_modules/ + exec node /app/dist/app.js fi fi diff --git a/build-production.sh b/build-production.sh index 33517d7..9598030 100755 --- a/build-production.sh +++ b/build-production.sh @@ -2,14 +2,14 @@ # Builds sources in production # -# We want to compare the used sources from the one available in /app +# We want to compare the used sources from the one available in /app/src/ # so we can warn at runtime in case developers accidentally mount # sources without setting the development environment variable. # Copy sources from /app to where they can be built -cd /usr/src/app -rm -rf ./app /app.original -cp -r /app ./ +cd /app +rm -rf /app/dist +mkdir /app/dist mkdir -p /config /config.original @@ -22,12 +22,15 @@ fi cp -r /app /app.original # Install custom packages if need be -if [ -f ./app/package.json ] +if [ -f /app/src/package.json ] then echo "Running npm install" - cd /usr/src/app/app/ + cd /app/ + cp /app/src/package.json /app/package.json npm install - cd /usr/src/app/ fi -./transpile-sources.sh +# add node modules from template back in +docker-rsync /template/node_modules/ /app/node_modules/ + +/template/transpile-sources.sh diff --git a/build-template-package.sh b/build-template-package.sh new file mode 100644 index 0000000..01143b3 --- /dev/null +++ b/build-template-package.sh @@ -0,0 +1,9 @@ +mkdir /template/built-mu +cd /template +/template/node_modules/.bin/babel \ + /template/helpers/mu/ \ + --source-maps "true" \ + --out-dir /template/built-mu \ + --extensions ".js,.ts" + +cp -R /template/built-mu /template/node_modules/mu diff --git a/helpers/README b/helpers/README new file mode 100644 index 0000000..f960e8e --- /dev/null +++ b/helpers/README @@ -0,0 +1,3 @@ +this allows the mu-helpers to be published as a typescript package as well from within the template repository, making sure that the template and the package are always published together + +One caveat is that the dependencies for the package are fewer than the dependencies that are added by default in the template (e.g. babel, coffeescript etc) so when publishing, care should be taken to keep those in sync to avoid surprises by consumers diff --git a/helpers/mu/index.js b/helpers/mu/index.ts similarity index 58% rename from helpers/mu/index.js rename to helpers/mu/index.ts index 54b0c0d..ff9f159 100644 --- a/helpers/mu/index.js +++ b/helpers/mu/index.ts @@ -1,6 +1,6 @@ -import { app, errorHandler } from './server'; -import sparql from './sparql'; -import { v1 as uuidV1 } from 'uuid'; +import { app, errorHandler } from "./server"; +import sparql from "./sparql"; +import { v1 as uuidV1 } from "uuid"; // generates a uuid const uuid = uuidV1; @@ -21,21 +21,21 @@ const mu = { sparqlEscapeDateTime: sparql.sparqlEscapeDateTime, sparqlEscapeBool: sparql.sparqlEscapeBool, uuid, - errorHandler + errorHandler, }; const SPARQL = mu.SPARQL, - query = mu.query, - update = mu.update, - sparqlEscape = mu.sparqlEscape, - sparqlEscapeString = mu.sparqlEscapeString, - sparqlEscapeUri = mu.sparqlEscapeUri, - sparqlEscapeInt = mu.sparqlEscapeInt, - sparqlEscapeDecimal = mu.sparqlEscapeDecimal, - sparqlEscapeFloat = mu.sparqlEscapeFloat, - sparqlEscapeDate = mu.sparqlEscapeDate, - sparqlEscapeDateTime = mu.sparqlEscapeDateTime, - sparqlEscapeBool = mu.sparqlEscapeBool; + query = mu.query, + update = mu.update, + sparqlEscape = mu.sparqlEscape, + sparqlEscapeString = mu.sparqlEscapeString, + sparqlEscapeUri = mu.sparqlEscapeUri, + sparqlEscapeInt = mu.sparqlEscapeInt, + sparqlEscapeDecimal = mu.sparqlEscapeDecimal, + sparqlEscapeFloat = mu.sparqlEscapeFloat, + sparqlEscapeDate = mu.sparqlEscapeDate, + sparqlEscapeDateTime = mu.sparqlEscapeDateTime, + sparqlEscapeBool = mu.sparqlEscapeBool; export { app, @@ -53,7 +53,7 @@ export { sparqlEscapeDateTime, sparqlEscapeBool, uuid, - errorHandler + errorHandler, }; export default mu; diff --git a/helpers/mu/server.js b/helpers/mu/server.js deleted file mode 100644 index 9ff7aeb..0000000 --- a/helpers/mu/server.js +++ /dev/null @@ -1,49 +0,0 @@ -import httpContext from 'express-http-context'; -import express from 'express'; -import bodyParser from 'body-parser'; - -var app = express(); - -var port = process.env.PORT || '80'; -var hostname = process.env.HOST || '0.0.0.0'; -var bodySizeLimit = process.env.MAX_BODY_SIZE || '100kb'; - -// parse JSONAPI content type -app.use(bodyParser.json({ - type: function(req) { return /^application\/vnd\.api\+json/.test(req.get('content-type')); }, - limit: bodySizeLimit -})); -app.use(bodyParser.urlencoded({ extended: false })); - -// set JSONAPI content type -app.use('/', function(req, res, next) { - res.type('application/vnd.api+json'); - next(); -}); - -app.use(httpContext.middleware); - -app.use(function(req, res, next) { - httpContext.set('request', req); - httpContext.set('response', res); - next(); -}); - -const errorHandler = function(err, req, res, next) { - res.status(err.status || 400); - res.json({ - errors: [ {title: err.message} ] - }); -}; - -// start server -app.listen( port, hostname, function() { - console.log(`Starting server on ${hostname}:${port} in ${app.get('env')} mode`); -}); - -export default app; - -export { - app, - errorHandler -} diff --git a/helpers/mu/server.ts b/helpers/mu/server.ts new file mode 100644 index 0000000..a3653cc --- /dev/null +++ b/helpers/mu/server.ts @@ -0,0 +1,60 @@ +import httpContext from "express-http-context"; +import express from "express"; +import bodyParser from "body-parser"; + +var app = express(); + +var port = parseInt(process.env.PORT || "80") || 80; +var hostname = process.env.HOST || "0.0.0.0"; +var bodySizeLimit = process.env.MAX_BODY_SIZE || "100kb"; + +// parse JSONAPI content type +app.use( + bodyParser.json({ + type: function (req) { + const expressReq = req as express.Request; + return /^application\/vnd\.api\+json/.test( + expressReq.get("content-type") || "" + ); + }, + limit: bodySizeLimit, + }) +); +app.use(bodyParser.urlencoded({ extended: false })); + +// set JSONAPI content type +app.use("/", function (req, res, next) { + res.type("application/vnd.api+json"); + next(); +}); + +app.use(httpContext.middleware); + +app.use(function (req, res, next) { + httpContext.set("request", req); + httpContext.set("response", res); + next(); +}); + +const errorHandler: express.ErrorRequestHandler = function ( + err, + req, + res, + next +) { + res.status(err.status || 400); + res.json({ + errors: [{ title: err.message }], + }); +}; + +// start server +app.listen(port, hostname, function () { + console.log( + `Starting server on ${hostname}:${port} in ${app.get("env")} mode` + ); +}); + +export default app; + +export { app, errorHandler }; diff --git a/helpers/mu/sparql-client-2.d.ts b/helpers/mu/sparql-client-2.d.ts new file mode 100644 index 0000000..3888c5a --- /dev/null +++ b/helpers/mu/sparql-client-2.d.ts @@ -0,0 +1 @@ +declare module "sparql-client-2"; diff --git a/helpers/mu/sparql.js b/helpers/mu/sparql.js deleted file mode 100644 index 4a23432..0000000 --- a/helpers/mu/sparql.js +++ /dev/null @@ -1,192 +0,0 @@ -import httpContext from 'express-http-context'; -import SC2 from 'sparql-client-2'; -import env from 'env-var'; - -const { SparqlClient, SPARQL } = SC2; - -const LOG_SPARQL_QUERIES = process.env.LOG_SPARQL_QUERIES != undefined ? env.get('LOG_SPARQL_QUERIES').asBool() : env.get('LOG_SPARQL_ALL').asBool(); -const LOG_SPARQL_UPDATES = process.env.LOG_SPARQL_UPDATES != undefined ? env.get('LOG_SPARQL_UPDATES').asBool() : env.get('LOG_SPARQL_ALL').asBool(); -const DEBUG_AUTH_HEADERS = env.get('DEBUG_AUTH_HEADERS').asBool(); - -//==-- logic --==// - -// builds a new sparqlClient -function newSparqlClient() { - let options = { requestDefaults: { headers: { } } }; - - if (httpContext.get('request')) { - options.requestDefaults.headers['mu-session-id'] = httpContext.get('request').get('mu-session-id'); - options.requestDefaults.headers['mu-call-id'] = httpContext.get('request').get('mu-call-id'); - options.requestDefaults.headers['mu-auth-allowed-groups'] = httpContext.get('request').get('mu-auth-allowed-groups'); // groups of incoming request - } - - if (httpContext.get('response')) { - const allowedGroups = httpContext.get('response').get('mu-auth-allowed-groups'); // groups returned by a previous SPARQL query - if (allowedGroups) - options.requestDefaults.headers['mu-auth-allowed-groups'] = allowedGroups; - } - - if (DEBUG_AUTH_HEADERS) { - console.log(`Headers set on SPARQL client: ${JSON.stringify(options)}`); - } - - return new SparqlClient(process.env.MU_SPARQL_ENDPOINT, options).register({ - mu: 'http://mu.semte.ch/vocabularies/', - muCore: 'http://mu.semte.ch/vocabularies/core/', - muExt: 'http://mu.semte.ch/vocabularies/ext/' - }); -} - -// executes a query (you can use the template syntax) -function query( queryString ) { - if (LOG_SPARQL_QUERIES) { - console.log(queryString); - } - return executeQuery(queryString); -}; - -// executes an update query -function update( queryString ) { - if (LOG_SPARQL_UPDATES) { - console.log(queryString); - } - return executeQuery(queryString); -}; - -function executeQuery( queryString ) { - return newSparqlClient().query(queryString).executeRaw().then(response => { - const temp = httpContext; - if (httpContext.get('response') && !httpContext.get('response').headersSent) { - // set mu-auth-allowed-groups on outgoing response - const allowedGroups = response.headers['mu-auth-allowed-groups']; - if (allowedGroups) { - httpContext.get('response').setHeader('mu-auth-allowed-groups', allowedGroups); - if (DEBUG_AUTH_HEADERS) { - console.log(`Update mu-auth-allowed-groups to ${allowedGroups}`); - } - } else { - httpContext.get('response').removeHeader('mu-auth-allowed-groups'); - if (DEBUG_AUTH_HEADERS) { - console.log('Remove mu-auth-allowed-groups'); - } - } - - // set mu-auth-used-groups on outgoing response - const usedGroups = response.headers['mu-auth-used-groups']; - if (usedGroups) { - httpContext.get('response').setHeader('mu-auth-used-groups', usedGroups); - if (DEBUG_AUTH_HEADERS) { - console.log(`Update mu-auth-used-groups to ${usedGroups}`); - } - } else { - httpContext.get('response').removeHeader('mu-auth-used-groups'); - if (DEBUG_AUTH_HEADERS) { - console.log('Remove mu-auth-used-groups'); - } - } - } - - function maybeParseJSON(body) { - // Catch invalid JSON - try { - return JSON.parse(body); - } catch (ex) { - return null; - } - } - - return maybeParseJSON(response.body); - }); -} - -function sparqlEscapeString( value ){ - return '"""' + value.replace(/[\\"]/g, function(match) { return '\\' + match; }) + '"""'; -}; - -function sparqlEscapeUri( value ){ - return '<' + value.replace(/[\\"<>]/g, function(match) { return '\\' + match; }) + '>'; -}; - -function sparqlEscapeDecimal( value ){ - return '"' + Number.parseFloat(value) + '"^^xsd:decimal'; -}; - -function sparqlEscapeInt( value ){ - return '"' + Number.parseInt(value) + '"^^xsd:integer'; -}; - -function sparqlEscapeFloat( value ){ - return '"' + Number.parseFloat(value) + '"^^xsd:float'; -}; - -function sparqlEscapeDate( value ){ - return '"' + new Date(value).toISOString().substring(0, 10) + '"^^xsd:date'; // only keep 'YYYY-MM-DD' portion of the string -}; - -function sparqlEscapeDateTime( value ){ - return '"' + new Date(value).toISOString() + '"^^xsd:dateTime'; -}; - -function sparqlEscapeBool( value ){ - return value ? '"true"^^xsd:boolean' : '"false"^^xsd:boolean'; -}; - -function sparqlEscape( value, type ){ - switch(type) { - case 'string': - return sparqlEscapeString(value); - case 'uri': - return sparqlEscapeUri(value); - case 'bool': - return sparqlEscapeBool(value); - case 'decimal': - return sparqlEscapeDecimal(value); - case 'int': - return sparqlEscapeInt(value); - case 'float': - return sparqlEscapeFloat(value); - case 'date': - return sparqlEscapeDate(value); - case 'dateTime': - return sparqlEscapeDateTime(value); - default: - console.error(`WARN: Unknown escape type '${type}'. Escaping as string`); - return sparqlEscapeString(value); - } -} - -//==-- exports --==// -const exports = { - newSparqlClient: newSparqlClient, - SPARQL: SPARQL, - sparql: SPARQL, - query: query, - update: update, - sparqlEscape: sparqlEscape, - sparqlEscapeString: sparqlEscapeString, - sparqlEscapeUri: sparqlEscapeUri, - sparqlEscapeInt: sparqlEscapeInt, - sparqlEscapeFloat: sparqlEscapeFloat, - sparqlEscapeDate: sparqlEscapeDate, - sparqlEscapeDateTime: sparqlEscapeDateTime, - sparqlEscapeBool: sparqlEscapeBool -} -export default exports; - -export { - newSparqlClient, - SPARQL as SPARQL, - SPARQL as sparql, - query, - update, - sparqlEscape, - sparqlEscapeString, - sparqlEscapeUri, - sparqlEscapeDecimal, - sparqlEscapeInt, - sparqlEscapeFloat, - sparqlEscapeDate, - sparqlEscapeDateTime, - sparqlEscapeBool -}; - diff --git a/helpers/mu/sparql.ts b/helpers/mu/sparql.ts new file mode 100644 index 0000000..d6b1ce6 --- /dev/null +++ b/helpers/mu/sparql.ts @@ -0,0 +1,227 @@ +import httpContext from "express-http-context"; +import SC2 from "sparql-client-2"; +import env from "env-var"; + +const { SparqlClient, SPARQL } = SC2; + +const LOG_SPARQL_QUERIES = + process.env.LOG_SPARQL_QUERIES != undefined + ? env.get("LOG_SPARQL_QUERIES").asBool() + : env.get("LOG_SPARQL_ALL").asBool(); +const LOG_SPARQL_UPDATES = + process.env.LOG_SPARQL_UPDATES != undefined + ? env.get("LOG_SPARQL_UPDATES").asBool() + : env.get("LOG_SPARQL_ALL").asBool(); +const DEBUG_AUTH_HEADERS = env.get("DEBUG_AUTH_HEADERS").asBool(); + +//==-- logic --==// + +// builds a new sparqlClient +function newSparqlClient() { + let options = { requestDefaults: { headers: {} as Record } }; + + if (httpContext.get("request")) { + options.requestDefaults.headers["mu-session-id"] = httpContext + .get("request") + .get("mu-session-id"); + options.requestDefaults.headers["mu-call-id"] = httpContext + .get("request") + .get("mu-call-id"); + options.requestDefaults.headers["mu-auth-allowed-groups"] = httpContext + .get("request") + .get("mu-auth-allowed-groups"); // groups of incoming request + } + + if (httpContext.get("response")) { + const allowedGroups = httpContext + .get("response") + .get("mu-auth-allowed-groups"); // groups returned by a previous SPARQL query + if (allowedGroups) + options.requestDefaults.headers["mu-auth-allowed-groups"] = allowedGroups; + } + + if (DEBUG_AUTH_HEADERS) { + console.log(`Headers set on SPARQL client: ${JSON.stringify(options)}`); + } + + return new SparqlClient(process.env.MU_SPARQL_ENDPOINT, options).register({ + mu: "http://mu.semte.ch/vocabularies/", + muCore: "http://mu.semte.ch/vocabularies/core/", + muExt: "http://mu.semte.ch/vocabularies/ext/", + }); +} + +// executes a query (you can use the template syntax) +function query(queryString: string) { + if (LOG_SPARQL_QUERIES) { + console.log(queryString); + } + return executeQuery(queryString); +} + +// executes an update query +function update(queryString: string) { + if (LOG_SPARQL_UPDATES) { + console.log(queryString); + } + return executeQuery(queryString); +} + +function executeQuery(queryString: string) { + return newSparqlClient() + .query(queryString) + .executeRaw() + .then((response: any) => { + const temp = httpContext; + if ( + httpContext.get("response") && + !httpContext.get("response").headersSent + ) { + // set mu-auth-allowed-groups on outgoing response + const allowedGroups = response.headers["mu-auth-allowed-groups"]; + if (allowedGroups) { + httpContext + .get("response") + .setHeader("mu-auth-allowed-groups", allowedGroups); + if (DEBUG_AUTH_HEADERS) { + console.log(`Update mu-auth-allowed-groups to ${allowedGroups}`); + } + } else { + httpContext.get("response").removeHeader("mu-auth-allowed-groups"); + if (DEBUG_AUTH_HEADERS) { + console.log("Remove mu-auth-allowed-groups"); + } + } + + // set mu-auth-used-groups on outgoing response + const usedGroups = response.headers["mu-auth-used-groups"]; + if (usedGroups) { + httpContext + .get("response") + .setHeader("mu-auth-used-groups", usedGroups); + if (DEBUG_AUTH_HEADERS) { + console.log(`Update mu-auth-used-groups to ${usedGroups}`); + } + } else { + httpContext.get("response").removeHeader("mu-auth-used-groups"); + if (DEBUG_AUTH_HEADERS) { + console.log("Remove mu-auth-used-groups"); + } + } + } + + function maybeParseJSON(body: any) { + // Catch invalid JSON + try { + return JSON.parse(body); + } catch (ex) { + return null; + } + } + + return maybeParseJSON(response.body); + }); +} + +function sparqlEscapeString(value: string) { + return ( + '"""' + + value.replace(/[\\"]/g, function (match) { + return "\\" + match; + }) + + '"""' + ); +} + +function sparqlEscapeUri(value: string) { + return ( + "<" + + value.replace(/[\\"<>]/g, function (match) { + return "\\" + match; + }) + + ">" + ); +} + +function sparqlEscapeDecimal(value: number | string) { + return '"' + Number.parseFloat(`${value}`) + '"^^xsd:decimal'; +} + +function sparqlEscapeInt(value: number | string) { + return '"' + Number.parseInt(`${value}`) + '"^^xsd:integer'; +} + +function sparqlEscapeFloat(value: number | string) { + return '"' + Number.parseFloat(`${value}`) + '"^^xsd:float'; +} + +function sparqlEscapeDate(value: string | Date) { + return '"' + new Date(value).toISOString().substring(0, 10) + '"^^xsd:date'; // only keep 'YYYY-MM-DD' portion of the string +} + +function sparqlEscapeDateTime(value: string | Date) { + return '"' + new Date(value).toISOString() + '"^^xsd:dateTime'; +} + +function sparqlEscapeBool(value: boolean | null | undefined) { + return value ? '"true"^^xsd:boolean' : '"false"^^xsd:boolean'; +} + +function sparqlEscape(value: any, type: string) { + switch (type) { + case "string": + return sparqlEscapeString(value); + case "uri": + return sparqlEscapeUri(value); + case "bool": + return sparqlEscapeBool(value); + case "decimal": + return sparqlEscapeDecimal(value); + case "int": + return sparqlEscapeInt(value); + case "float": + return sparqlEscapeFloat(value); + case "date": + return sparqlEscapeDate(value); + case "dateTime": + return sparqlEscapeDateTime(value); + default: + console.error(`WARN: Unknown escape type '${type}'. Escaping as string`); + return sparqlEscapeString(value); + } +} + +const defaultExports = { + newSparqlClient: newSparqlClient, + SPARQL: SPARQL, + sparql: SPARQL, + query: query, + update: update, + sparqlEscape: sparqlEscape, + sparqlEscapeString: sparqlEscapeString, + sparqlEscapeUri: sparqlEscapeUri, + sparqlEscapeInt: sparqlEscapeInt, + sparqlEscapeFloat: sparqlEscapeFloat, + sparqlEscapeDecimal: sparqlEscapeDecimal, + sparqlEscapeDate: sparqlEscapeDate, + sparqlEscapeDateTime: sparqlEscapeDateTime, + sparqlEscapeBool: sparqlEscapeBool, +}; +export default defaultExports; + +export { + newSparqlClient, + SPARQL as SPARQL, + SPARQL as sparql, + query, + update, + sparqlEscape, + sparqlEscapeString, + sparqlEscapeUri, + sparqlEscapeDecimal, + sparqlEscapeInt, + sparqlEscapeFloat, + sparqlEscapeDate, + sparqlEscapeDateTime, + sparqlEscapeBool, +}; diff --git a/helpers/package-lock.json b/helpers/package-lock.json new file mode 100644 index 0000000..89b1b5c --- /dev/null +++ b/helpers/package-lock.json @@ -0,0 +1,1321 @@ +{ + "name": "works-ts-helpers", + "version": "0.0.1", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "works-ts-helpers", + "version": "0.0.1", + "license": "ISC", + "dependencies": { + "body-parser": "~1.20.1", + "env-var": "^7.4.1", + "express": "^4.18.2", + "express-http-context": "~1.2.4", + "sparql-client-2": "^0.6.3", + "uuid": "^9.0.1" + }, + "devDependencies": { + "@types/uuid": "^9.0.7", + "typescript": "^5.3.3" + } + }, + "node_modules/@types/body-parser": { + "version": "1.19.5", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", + "integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==", + "dependencies": { + "@types/connect": "*", + "@types/node": "*" + } + }, + "node_modules/@types/cls-hooked": { + "version": "4.3.8", + "resolved": "https://registry.npmjs.org/@types/cls-hooked/-/cls-hooked-4.3.8.tgz", + "integrity": "sha512-tf/7H883gFA6MPlWI15EQtfNZ+oPL0gLKkOlx9UHFrun1fC/FkuyNBpTKq1B5E3T4fbvjId6WifHUdSGsMMuPg==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/connect": { + "version": "3.4.38", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", + "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/express": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz", + "integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==", + "dependencies": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^4.17.33", + "@types/qs": "*", + "@types/serve-static": "*" + } + }, + "node_modules/@types/express-serve-static-core": { + "version": "4.17.41", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.41.tgz", + "integrity": "sha512-OaJ7XLaelTgrvlZD8/aa0vvvxZdUmlCn6MtWeB7TkiKW70BQLc9XEPpDLPdbo52ZhXUCrznlWdCHWxJWtdyajA==", + "dependencies": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*", + "@types/send": "*" + } + }, + "node_modules/@types/http-errors": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz", + "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==" + }, + "node_modules/@types/mime": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", + "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==" + }, + "node_modules/@types/node": { + "version": "20.10.4", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.10.4.tgz", + "integrity": "sha512-D08YG6rr8X90YB56tSIuBaddy/UXAA9RKJoFvrsnogAum/0pmjkgi4+2nx96A330FmioegBWmEYQ+syqCFaveg==", + "dependencies": { + "undici-types": "~5.26.4" + } + }, + "node_modules/@types/qs": { + "version": "6.9.10", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.10.tgz", + "integrity": "sha512-3Gnx08Ns1sEoCrWssEgTSJs/rsT2vhGP+Ja9cnnk9k4ALxinORlQneLXFeFKOTJMOeZUFD1s7w+w2AphTpvzZw==" + }, + "node_modules/@types/range-parser": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", + "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==" + }, + "node_modules/@types/send": { + "version": "0.17.4", + "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz", + "integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==", + "dependencies": { + "@types/mime": "^1", + "@types/node": "*" + } + }, + "node_modules/@types/serve-static": { + "version": "1.15.5", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.5.tgz", + "integrity": "sha512-PDRk21MnK70hja/YF8AHfC7yIsiQHn1rcXx7ijCFBX/k+XQJhQT/gw3xekXKJvx+5SXaMMS8oqQy09Mzvz2TuQ==", + "dependencies": { + "@types/http-errors": "*", + "@types/mime": "*", + "@types/node": "*" + } + }, + "node_modules/@types/uuid": { + "version": "9.0.7", + "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.7.tgz", + "integrity": "sha512-WUtIVRUZ9i5dYXefDEAI7sh9/O7jGvHg7Df/5O/gtH3Yabe5odI3UWopVR1qbPXQtvOxWu3mM4XxlYeZtMWF4g==", + "dev": true + }, + "node_modules/accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" + }, + "node_modules/asn1": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", + "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", + "dependencies": { + "safer-buffer": "~2.1.0" + } + }, + "node_modules/assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/async-hook-jl": { + "version": "1.7.6", + "resolved": "https://registry.npmjs.org/async-hook-jl/-/async-hook-jl-1.7.6.tgz", + "integrity": "sha512-gFaHkFfSxTjvoxDMYqDuGHlcRyUuamF8s+ZTtJdDzqjws4mCt7v0vuV79/E2Wr2/riMQgtG4/yUtXWs1gZ7JMg==", + "dependencies": { + "stack-chain": "^1.3.7" + }, + "engines": { + "node": "^4.7 || >=6.9 || >=7.3" + } + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + }, + "node_modules/aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==", + "engines": { + "node": "*" + } + }, + "node_modules/aws4": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.12.0.tgz", + "integrity": "sha512-NmWvPnx0F1SfrQbYwOi7OeaNGokp9XhzNioJ/CSBs8Qa4vxug81mhJEAVZwxXuBmYB5KDRfMq/F3RR0BIU7sWg==" + }, + "node_modules/bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==", + "dependencies": { + "tweetnacl": "^0.14.3" + } + }, + "node_modules/body-parser": { + "version": "1.20.2", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz", + "integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==", + "dependencies": { + "bytes": "3.1.2", + "content-type": "~1.0.5", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.11.0", + "raw-body": "2.5.2", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/call-bind": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.5.tgz", + "integrity": "sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==", + "dependencies": { + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.1", + "set-function-length": "^1.1.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==" + }, + "node_modules/cls-hooked": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/cls-hooked/-/cls-hooked-4.2.2.tgz", + "integrity": "sha512-J4Xj5f5wq/4jAvcdgoGsL3G103BtWpZrMo8NEinRltN+xpTZdI+M38pyQqhuFU/P792xkMFvnKSf+Lm81U1bxw==", + "dependencies": { + "async-hook-jl": "^1.7.6", + "emitter-listener": "^1.0.1", + "semver": "^5.4.1" + }, + "engines": { + "node": "^4.7 || >=6.9 || >=7.3 || >=8.2.1" + } + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", + "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" + }, + "node_modules/core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==" + }, + "node_modules/dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==", + "dependencies": { + "assert-plus": "^1.0.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/define-data-property": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.1.tgz", + "integrity": "sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==", + "dependencies": { + "get-intrinsic": "^1.2.1", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/denodeify": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/denodeify/-/denodeify-1.2.1.tgz", + "integrity": "sha512-KNTihKNmQENUZeKu5fzfpzRqR5S2VMp4gl9RFHiWzj9DfvYQPMJ6XHKNaQxaGCXwPk6y9yme3aUoaiAe+KX+vg==" + }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==", + "dependencies": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" + }, + "node_modules/emitter-listener": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/emitter-listener/-/emitter-listener-1.1.2.tgz", + "integrity": "sha512-Bt1sBAGFHY9DKY+4/2cV6izcKJUf5T7/gkdmkxzX/qv9CcGH8xSwVRW5mtX03SWJtRTWSOpzCuWN9rBFYZepZQ==", + "dependencies": { + "shimmer": "^1.2.0" + } + }, + "node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/env-var": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/env-var/-/env-var-7.4.1.tgz", + "integrity": "sha512-H8Ga2SbXTQwt6MKEawWSvmxoH1+J6bnAXkuyE7eDvbGmrhIL2i+XGjzGM3DFHcJu8GY1zY9/AnBJY8uGQYPHiw==", + "engines": { + "node": ">=10" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/express": { + "version": "4.18.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", + "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", + "dependencies": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.20.1", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.5.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.2.0", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.7", + "qs": "6.11.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.18.0", + "serve-static": "1.15.0", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/express-http-context": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/express-http-context/-/express-http-context-1.2.4.tgz", + "integrity": "sha512-jPpBbF1MWWdRcUU1rxsX0CPnA8ueEj8xgWvpRGHoXWGI4l5KqhPY4Bq+Gt6s2IhqHQQ0g0wIvJ3jFfbUuJJycQ==", + "dependencies": { + "@types/cls-hooked": "^4.2.1", + "@types/express": "^4.16.0", + "cls-hooked": "^4.2.2" + }, + "engines": { + "node": ">=8.0.0 <10.0.0 || >=10.4.0" + } + }, + "node_modules/express/node_modules/body-parser": { + "version": "1.20.1", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", + "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", + "dependencies": { + "bytes": "3.1.2", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.11.0", + "raw-body": "2.5.1", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/express/node_modules/raw-body": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", + "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", + "dependencies": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + }, + "node_modules/extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==", + "engines": [ + "node >=0.6.0" + ] + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" + }, + "node_modules/finalhandler": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", + "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "statuses": "2.0.1", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==", + "engines": { + "node": "*" + } + }, + "node_modules/form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 0.12" + } + }, + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-intrinsic": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.2.tgz", + "integrity": "sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA==", + "dependencies": { + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==", + "dependencies": { + "assert-plus": "^1.0.0" + } + }, + "node_modules/gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dependencies": { + "get-intrinsic": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==", + "engines": { + "node": ">=4" + } + }, + "node_modules/har-validator": { + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", + "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", + "deprecated": "this library is no longer supported", + "dependencies": { + "ajv": "^6.12.3", + "har-schema": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz", + "integrity": "sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==", + "dependencies": { + "get-intrinsic": "^1.2.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", + "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz", + "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "dependencies": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==", + "dependencies": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + }, + "engines": { + "node": ">=0.8", + "npm": ">=1.3.7" + } + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==" + }, + "node_modules/isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==" + }, + "node_modules/jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==" + }, + "node_modules/json-schema": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", + "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==" + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + }, + "node_modules/json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==" + }, + "node_modules/jsprim": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz", + "integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==", + "dependencies": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.4.0", + "verror": "1.10.0" + }, + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, + "node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" + }, + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", + "engines": { + "node": "*" + } + }, + "node_modules/object-inspect": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", + "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" + }, + "node_modules/performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==" + }, + "node_modules/promise-nodeify": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/promise-nodeify/-/promise-nodeify-0.1.0.tgz", + "integrity": "sha512-DfFqhZ0M1bZwLighBvNHWxTy/LRvmZfbWE7/NKdPf1cUQzXzgzOAmp8VMCxcjZyoAZHYH+b10xeB5AkviOh0gw==", + "engines": { + "node": ">=0.10", + "npm": ">=1.3.7" + } + }, + "node_modules/proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/psl": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", + "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==" + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "engines": { + "node": ">=6" + } + }, + "node_modules/qs": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", + "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", + "dependencies": { + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", + "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", + "dependencies": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/request": { + "version": "2.88.2", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", + "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", + "deprecated": "request has been deprecated, see https://github.com/request/request/issues/3142", + "dependencies": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.3", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.5.0", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/request/node_modules/qs": { + "version": "6.5.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz", + "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/request/node_modules/uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", + "bin": { + "uuid": "bin/uuid" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/send": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", + "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", + "dependencies": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "2.4.1", + "range-parser": "~1.2.1", + "statuses": "2.0.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/send/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "node_modules/serve-static": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", + "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", + "dependencies": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.18.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/set-function-length": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.1.1.tgz", + "integrity": "sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ==", + "dependencies": { + "define-data-property": "^1.1.1", + "get-intrinsic": "^1.2.1", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" + }, + "node_modules/shimmer": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/shimmer/-/shimmer-1.2.1.tgz", + "integrity": "sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw==" + }, + "node_modules/side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "dependencies": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/sparql-client-2": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/sparql-client-2/-/sparql-client-2-0.6.3.tgz", + "integrity": "sha512-wG2bYg5mkEb3DWLPVrVC7W7rkNnbzz+CeItHvhZuZHWE69JSYAYr/bz51tCmeePGQMzcBl2+k+qcG7sgFtGYbw==", + "dependencies": { + "denodeify": "^1.2.1", + "lodash": "^4.0.1", + "promise-nodeify": "^0.1.0", + "request": "^2.40.0" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/sshpk": { + "version": "1.18.0", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.18.0.tgz", + "integrity": "sha512-2p2KJZTSqQ/I3+HX42EpYOa2l3f8Erv8MWKsy2I9uf4wA7yFIkXRffYdsx86y6z4vHtV8u7g+pPlr8/4ouAxsQ==", + "dependencies": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + }, + "bin": { + "sshpk-conv": "bin/sshpk-conv", + "sshpk-sign": "bin/sshpk-sign", + "sshpk-verify": "bin/sshpk-verify" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/stack-chain": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/stack-chain/-/stack-chain-1.3.7.tgz", + "integrity": "sha512-D8cWtWVdIe/jBA7v5p5Hwl5yOSOrmZPWDPe2KxQ5UAGD+nxbxU0lKXA4h85Ta6+qgdKVL3vUxsbIZjc1kBG7ug==" + }, + "node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/tough-cookie": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "dependencies": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", + "dependencies": { + "safe-buffer": "^5.0.1" + }, + "engines": { + "node": "*" + } + }, + "node_modules/tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==" + }, + "node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/typescript": { + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz", + "integrity": "sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/uuid": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==", + "engines": [ + "node >=0.6.0" + ], + "dependencies": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + } + } +} diff --git a/helpers/package.json b/helpers/package.json new file mode 100644 index 0000000..6d58bc0 --- /dev/null +++ b/helpers/package.json @@ -0,0 +1,27 @@ +{ + "name": "works-ts-helpers", + "version": "0.0.1", + "description": "", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1", + "build": "tsc" + }, + "main": "dist/index.js", + "types": "dist/index.d.ts", + "type": "commonjs", + "keywords": [], + "author": "", + "license": "ISC", + "devDependencies": { + "@types/uuid": "^9.0.7", + "typescript": "^5.3.3" + }, + "dependencies": { + "env-var": "^7.4.1", + "express": "^4.18.2", + "express-http-context": "~1.2.4", + "sparql-client-2": "^0.6.3", + "body-parser": "~1.20.1", + "uuid": "^9.0.1" + } +} diff --git a/helpers/tsconfig.json b/helpers/tsconfig.json new file mode 100644 index 0000000..b281c59 --- /dev/null +++ b/helpers/tsconfig.json @@ -0,0 +1,26 @@ +{ + "include": ["mu/**/*"], + // We don't need to transpile these directories + "exclude": ["node_modules", "dist"], + "compilerOptions": { + // Tells TypeScript to read JS files, as + // normally they are ignored as source files + "allowJs": false, + // Generate d.ts files + "declaration": true, + // This compiler run should + // only output d.ts files + "emitDeclarationOnly": false, + // Types should go into this directory. + // Removing this would place the .d.ts files + // next to the .js files + "outDir": "dist", + // go to js file when using IDE functions like + // "Go to Definition" in VSCode + "declarationMap": true, + "strict": true, + "esModuleInterop": true, + "moduleResolution": "Node", + "module": "commonjs" + } +} diff --git a/package.json b/package.json index 7148a03..d3db713 100644 --- a/package.json +++ b/package.json @@ -20,12 +20,12 @@ "body-parser": "~1.20.1", "coffeescript": "^2.6.1", "env-var": "^7.0.0", - "express": "^4.17.1", + "express": "^4.18.2", "express-http-context": "~1.2.4", "nodemon": "^2.0.20", "sparql-client-2": "https://github.com/erikap/node-sparql-client.git", - "typescript": "^4.6.2", - "uuid": "^9.0.0" + "typescript": "^5.3.3", + "uuid": "^9.0.1" }, "author": "Aad Versteden ", "license": "MIT", diff --git a/run-development.sh b/run-development.sh index f823f79..fcc926e 100755 --- a/run-development.sh +++ b/run-development.sh @@ -1,6 +1,6 @@ #!/bin/bash -source ./helpers.sh +source /template/helpers.sh # We want to run from /app but don't want to touch that folder. # @@ -11,7 +11,7 @@ source ./helpers.sh # - Only run npm install when the package.json has changed. # Move to right folder -cd /usr/src/app/ +cd /app/ @@ -20,51 +20,50 @@ cd /usr/src/app/ ###################### ## Check if package.json existed and did not change since previous build (/usr/src/app/app/ is copied later in this script, at first run from the template itself it doesn't exist but that's fine for comparison) -cmp -s /app/package.json /usr/src/app/app/package.json +cmp -s /check/package.json /app/src/package.json CHANGE_IN_PACKAGE_JSON="$?" -## Ensure we _sync_ the sources from the hosted app and _copy_ the node_modules. -## -## We don't want to do --delete on the node_modules because this allows us -## to depend on the node_modules installed in an earlier update cycle as well as -## taking node_modules from the hosted app into account. -docker-rsync --delete --exclude node_modules /app/ /usr/src/app/app/ -if [ -d /app/node_modules/ ] -then - docker-rsync /app/node_modules /usr/src/app/app/ -fi - ## Copy config folder if [[ "$(ls -A /config/ 2> /dev/null)" ]] then - mkdir -p ./app/config/ - cp -rf /config/* ./app/config/ + mkdir -p /app/src/config/ + cp -rf /config/* /app/src/config/ fi ## Install dependencies on first boot -if [ $CHANGE_IN_PACKAGE_JSON != "0" ] && [ -f ./app/package.json ] +if [ $CHANGE_IN_PACKAGE_JSON != "0" ] && [ -f /app/src/package.json ] then echo "Running npm install" - cd /usr/src/app/app/ + cp /app/src/package.json /app/package.json npm install - cd /usr/src/app/ + rm -rf /check + mkdir /check + cp /app/src/package.json /check/package.json fi - +docker-rsync /template/node_modules/ /app/node_modules/ ############### # Transpilation ############### -./transpile-sources.sh - +/template/transpile-sources.sh ############## # Start server ############## -cd /usr/src/build/ -/usr/src/app/node_modules/.bin/babel-node \ - --inspect="0.0.0.0:9229" \ - ./app.js +cd /app/ +if [ "$NO_BABEL_NODE" == "true" ] +then + echo "running without babel-node" + node \ + --inspect="0.0.0.0:9229" \ + ./dist/app.js +else + /template/node_modules/.bin/babel-node \ + --enable-source-maps \ + --inspect="0.0.0.0:9229" \ + ./dist/app.js +fi diff --git a/transpile-sources.sh b/transpile-sources.sh index d990c1b..01de631 100755 --- a/transpile-sources.sh +++ b/transpile-sources.sh @@ -1,6 +1,6 @@ #!/bin/bash -source ./helpers.sh +source /template/helpers.sh #### #### BUILDS SOURCES @@ -9,14 +9,14 @@ source ./helpers.sh #### /usr/src/app/app/ and stores the resulting build in /usr/src/build # Clean starting state -rm -Rf /usr/src/processing /usr/src/build +# rm -Rf /processing /dist -# Copy template (/usr/src/app/) and app (/usr/src/app/app/) sources -# without package.json, which we want to skip as it would conflict -# building sources. +# # Copy template (/usr/src/app/) and app (/usr/src/app/app/) sources +# # without package.json, which we want to skip as it would conflict +# # building sources. -cp -R /usr/src/app /usr/src/processing -rm -f /usr/src/processing/app/package.json +# cp -R /template /processing +# rm -f /processing/app/package.json ## CoffeeScript @@ -25,84 +25,22 @@ rm -f /usr/src/processing/app/package.json ## app so we have the javascript available which other preprocessors may ## expect to exist. ## -## In order to generate the sourcemaps correctly, it seems we have to be -## next to the folder where we want the sources to land, but in order to -## transpile correctly we also need the node_modules for babel and the -## babelrc file. We temporarily move those around. -cd /usr/src/ +# our babel config is in /template let's run all commands from there +# and use absolute paths +cd /template -# prepare the build folders -mkdir /usr/src/build /usr/src/build.coffee -cp -R /usr/src/processing/app/* /usr/src/build/ -cp /usr/src/processing/babel.config.json /usr/src/ -cp -R /usr/src/processing/node_modules/ /usr/src/ - -# make the build and move to coffeescript-transpilation -/usr/src/app/node_modules/.bin/coffee -M -m --compile -t --output ./build.coffee/ ./build -mv build.coffee/ /usr/src/processing/coffeescript-transpilation - -# clean up -rm -Rf /usr/src/build /usr/src/node_modules/ -rm /usr/src/babel.config.json +# build coffeescript (note: don't use -M as it seems vscode is confused about inline sourcemaps) +# chrome still happily works with .map files too though so we're all good! +/template/node_modules/.bin/coffee -m --compile -t --output /app/dist /app/src ## TypeScript and ES6 ## ## Transpiles TypeScript and ES6 to something nodejs wants to run. -cd /usr/src/processing/ - -mkdir typescript-transpilation build -cp -R ./app/* build -docker-rsync /usr/src/processing/coffeescript-transpilation/ /usr/src/processing/build/ - -/usr/src/app/node_modules/.bin/babel \ - ./build/ \ - --out-dir ./typescript-transpilation/ \ - --source-maps true \ +/template/node_modules/.bin/babel \ + /app/src \ + --out-dir /app/dist/ \ + --source-maps "true" \ --extensions ".ts,.js" -rm -Rf ./build -mv typescript-transpilation /usr/src/build - -# We move the coffeescript files again because the previous step will -# have built the sources coffeescript generated, but these sources were -# already node compliant. We could make coffeescript emit ES6 and -# transpile them to nodejs in this step, but that breaks SourceMaps. -docker-rsync /usr/src/processing/coffeescript-transpilation/ /usr/src/build/ - - -############## -# Node modules -############## -cd /usr/src/processing/ - -## template modules -cp -R /usr/src/processing/node_modules /usr/src/build/ - -## app modules -if [ -d /usr/src/processing/app/node_modules ] -then - docker-rsync /usr/src/processing/app/node_modules /usr/src/build/ -fi - -## mu helpers -cd /usr/src/processing/ - -mkdir /usr/src/processing/built-mu -/usr/src/app/node_modules/.bin/babel \ - /usr/src/processing/helpers/mu/ \ - --source-maps true \ - --out-dir /usr/src/processing/built-mu \ - --extensions ".js" - -cp -R /usr/src/processing/built-mu /usr/src/build/node_modules/mu - - - -## Clean temporary folders -## -## We have created garbage, let's remove it -cd /usr/src/ - -rm -Rf /usr/src/processing