diff --git a/CODEOWNERS b/CODEOWNERS index 6b8e7be..4f818bf 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -1 +1 @@ -* @Yalz @rorlic @WLefever-Cegeka @pj-cegeka @Tomvbe @RubenHuybrighs @jobulcke +* @Yalz @rorlic @pj-cegeka @Tomvbe @jobulcke \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index 5dc04be..ce8254b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,7 +1,7 @@ # build environment -FROM node:18-bullseye-slim AS builder +FROM node:20-bullseye-slim AS builder # fix vulnerabilities -ARG NPM_TAG=9.6.4 +ARG NPM_TAG=10.2.3 RUN npm install -g npm@${NPM_TAG} # build it WORKDIR /build @@ -10,7 +10,7 @@ RUN npm ci RUN npm run build # run environment -FROM node:18.16.0-bullseye-slim +FROM node:20.9.0-bullseye-slim # fix vulnerabilities # note: trivy insists this to be on the same RUN line RUN apt-get -y update && apt-get -y upgrade @@ -39,7 +39,9 @@ ARG TEMPLATE= ENV TEMPLATE=${TEMPLATE} ARG MIMETYPE= ENV MIMETYPE=${MIMETYPE} +ARG RANGE= +ENV RANGE=${RANGE} ## set start command ENTRYPOINT ["/usr/bin/dumb-init", "--"] USER node -CMD ["sh", "-c", "node index.js --silent=${SILENT} --mimeType=\"${MIMETYPE}\" --targetUrl=${TARGETURL} --cron=\"${CRON}\" --template=\"${TEMPLATE}\" --templateFile=${TEMPLATEFILE}"] +CMD ["sh", "-c", "node index.js --silent=${SILENT} --range=${RANGE} --mimeType=\"${MIMETYPE}\" --targetUrl=${TARGETURL} --cron=\"${CRON}\" --template=\"${TEMPLATE}\" --templateFile=${TEMPLATEFILE}"] diff --git a/README.md b/README.md index a9d7cd5..1795696 100644 --- a/README.md +++ b/README.md @@ -17,6 +17,7 @@ You can also pass the following arguments when running the container: * `SILENT=true` to display no logging to the console * `TARGETURL=` to POST the output to the target URI instead of to the console * `MIMETYPE=` to specify a mime-type when POSTing +* `RANGE=` allows to create the same range of values (1 to `range`) on each tick instead of an increasing index Alternatively, you can also pass the template as string instead of as file, use `TEMPLATE`. @@ -47,6 +48,7 @@ The generator takes the following command line arguments: * `--cron` defines the time schedule, defaults to `* * * * * * ` (every second) * `--template=''` allows to provide the template on the command line, no default (if not provided, you MUST provide `--templateFile`) * `--templateFile=` allows to provide the template in a file, no default (if not provided, you MUST provide `--template`) +* `--range=` allows to create a range of values (1 to ``) on every tick instead of an increasing index The template or template file should simply contain a message with mustache variables (between `{{` and `}}`). E.g.: ```json @@ -57,8 +59,8 @@ The template or template file should simply contain a message with mustache vari ``` Currently the only allowed variables are: -* `index`: increasing integer value, starting from 1 -* `timestamp`: current date and time formatted as [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) in UTC (e.g. `2007-04-05T14:30:00.000Z`) +* `index`: on each tick, increasing integer value starting from 1 OR a range of values [1 .. N] given by `--range=N` +* `timestamp`: on each tick, current date and time formatted as [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) in UTC, e.g. `2007-04-05T14:30:00.000Z` (all values in the range have the same timestamp) You can run the generator after building it, e.g.: diff --git a/src/generator.ts b/src/generator.ts index c97bf8f..5a3d7d9 100644 --- a/src/generator.ts +++ b/src/generator.ts @@ -18,4 +18,9 @@ export class Generator { var next = Mustache.render(this._template, data); return next; } + + public createRange(range: number): any[] { + var timestamp = this.timestamp(); + return Array.from(Array(range).keys()).map(index => Mustache.render(this._template, { index: index + 1, timestamp: timestamp })); + } } diff --git a/src/index.ts b/src/index.ts index 97cd712..57ac84e 100644 --- a/src/index.ts +++ b/src/index.ts @@ -14,22 +14,26 @@ let template: string = args['template'] || (args['templateFile'] && readFileSync if (!template) throw new Error('Missing template or templateFile'); const generator: Generator = new Generator(template); +const range = Number.parseInt(args['range'] || '0'); const job = new CronJob(cron, async () => { - const body = generator.createNext(); - const targetUrl = args['targetUrl'] || (existsSync('./TARGETURL') && readFileSync('./TARGETURL', 'utf-8').trimEnd()); - if (targetUrl) { - if (!mimeType) throw new Error('Missing mimeType'); - if (!silent) console.debug(`Sending to '${targetUrl}':`, body); - const response = await fetch(targetUrl, { - method: 'post', - body: body, - headers: {'Content-Type': mimeType} - }); - if (!silent) console.debug(`Response: ${response.statusText}`); - } else { // if no targetUrl specified, send to console - console.info(body); - } + const messages = range ? generator.createRange(range) : [generator.createNext()]; + for await (const body of messages) { + const targetUrl = args['targetUrl'] || (existsSync('./TARGETURL') && readFileSync('./TARGETURL', 'utf-8').trimEnd()); + if (targetUrl) { + if (!mimeType) throw new Error('Missing mimeType'); + if (!silent) console.debug(`Sending to '${targetUrl}':`, body); + const response = await fetch(targetUrl, { + method: 'post', + body: body, + headers: {'Content-Type': mimeType} + }); + if (!silent) console.debug(`Response: ${response.statusText}`); + } else { // if no targetUrl specified, send to console + console.info(body); + } + }; + if (!silent) console.debug('Next run at: ', job.nextDate().toString()); });