From 32eeb0c3b223904f2ea47def4c80b81f406f3e06 Mon Sep 17 00:00:00 2001 From: Caian Ertl Date: Thu, 12 May 2022 02:27:17 -0300 Subject: [PATCH] feat: add nodejs sample --- samples/node/.dockerignore | 1 + samples/node/.gitignore | 1 + samples/node/Dockerfile | 28 ++++++ samples/node/entrypoint.sh | 5 + samples/node/index.js | 32 +++++++ samples/node/package-lock.json | 168 +++++++++++++++++++++++++++++++++ samples/node/package.json | 11 +++ 7 files changed, 246 insertions(+) create mode 100644 samples/node/.dockerignore create mode 100644 samples/node/.gitignore create mode 100644 samples/node/Dockerfile create mode 100644 samples/node/entrypoint.sh create mode 100644 samples/node/index.js create mode 100644 samples/node/package-lock.json create mode 100644 samples/node/package.json diff --git a/samples/node/.dockerignore b/samples/node/.dockerignore new file mode 100644 index 0000000..3c3629e --- /dev/null +++ b/samples/node/.dockerignore @@ -0,0 +1 @@ +node_modules diff --git a/samples/node/.gitignore b/samples/node/.gitignore new file mode 100644 index 0000000..3c3629e --- /dev/null +++ b/samples/node/.gitignore @@ -0,0 +1 @@ +node_modules diff --git a/samples/node/Dockerfile b/samples/node/Dockerfile new file mode 100644 index 0000000..62c6a14 --- /dev/null +++ b/samples/node/Dockerfile @@ -0,0 +1,28 @@ +FROM caian/sample-devcontainer:latest AS devcontainer + +ARG DOCKER_DEFAULT_USER=turing +ENV DOCKER_DEFAULT_USER $DOCKER_DEFAULT_USER + +USER ${DOCKER_DEFAULT_USER} +WORKDIR /home/${DOCKER_DEFAULT_USER} + +COPY entrypoint.sh . +RUN sudo chmod +x entrypoint.sh + + +FROM devcontainer AS dependencies +USER root +COPY package.json . +COPY package-lock.json . + +RUN eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)" \ + && npm install --only=production \ + && rm package.json package-lock.json + + +FROM dependencies AS run +COPY index.js . +RUN chown -R "${DOCKER_DEFAULT_USER}:${DOCKER_DEFAULT_USER}" "/home/${DOCKER_DEFAULT_USER}" + +USER ${DOCKER_DEFAULT_USER} +ENTRYPOINT ["./entrypoint.sh"] diff --git a/samples/node/entrypoint.sh b/samples/node/entrypoint.sh new file mode 100644 index 0000000..2ab96fd --- /dev/null +++ b/samples/node/entrypoint.sh @@ -0,0 +1,5 @@ +#!/bin/bash + +eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)" + +node index.js "$@" diff --git a/samples/node/index.js b/samples/node/index.js new file mode 100644 index 0000000..af1e072 --- /dev/null +++ b/samples/node/index.js @@ -0,0 +1,32 @@ +const axios = require('axios') +const dayjs = require('dayjs') + +const capitalize = s => s && s[0].toUpperCase() + s.slice(1) + +const getDate = (daysToAdd = 0) => dayjs().add(daysToAdd, 'days').format('YYYY-MM-DD') + +function getCityArg() { + const fallback = 'manhattan' + + const city = (process.argv.length < 3 ? fallback : process.argv[2]).trim() + return city.length > 0 ? city : fallback +} + +async function getWeatherInfoOf(city) { + const { data } = await axios.get(`https://goweather.herokuapp.com/weather/${city}`) + const forecast = [{ day: '0', temperature: data.temperature, wind: data.wind }, ...data.forecast] + + return forecast.map((f) => ({ day: parseInt(f.day), temp: f.temperature, wind: f.wind })) +} + +async function main() { + const city = getCityArg() + const forecast = await getWeatherInfoOf(city) + + console.log(`Weather forecast for ${capitalize(city)} city\n`) + for (const weather of forecast) { + console.log(` | ${getDate(weather.day)} ~ ${weather.temp}, ${weather.wind}`) + } +} + +main().catch((e) => console.error(e)) diff --git a/samples/node/package-lock.json b/samples/node/package-lock.json new file mode 100644 index 0000000..b5e9128 --- /dev/null +++ b/samples/node/package-lock.json @@ -0,0 +1,168 @@ +{ + "name": "node-weather-app", + "version": "0.1.0", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "node-weather-app", + "version": "0.1.0", + "license": "CC0-1.0", + "dependencies": { + "axios": "^0.27.2", + "dayjs": "^1.11.2" + } + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" + }, + "node_modules/axios": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.27.2.tgz", + "integrity": "sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==", + "dependencies": { + "follow-redirects": "^1.14.9", + "form-data": "^4.0.0" + } + }, + "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/dayjs": { + "version": "1.11.2", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.2.tgz", + "integrity": "sha512-F4LXf1OeU9hrSYRPTTj/6FbO4HTjPKXvEIC1P2kcnFurViINCVk3ZV0xAS3XVx9MkMsXbbqlK6hjseaYbgKEHw==" + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/follow-redirects": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.0.tgz", + "integrity": "sha512-aExlJShTV4qOUOL7yF1U5tvLCB0xQuudbf6toyYA0E/acBNw71mvjFTnLaRp50aQaYocMR0a/RMMBIHeZnGyjQ==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "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" + } + } + }, + "dependencies": { + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" + }, + "axios": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.27.2.tgz", + "integrity": "sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==", + "requires": { + "follow-redirects": "^1.14.9", + "form-data": "^4.0.0" + } + }, + "combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "requires": { + "delayed-stream": "~1.0.0" + } + }, + "dayjs": { + "version": "1.11.2", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.2.tgz", + "integrity": "sha512-F4LXf1OeU9hrSYRPTTj/6FbO4HTjPKXvEIC1P2kcnFurViINCVk3ZV0xAS3XVx9MkMsXbbqlK6hjseaYbgKEHw==" + }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" + }, + "follow-redirects": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.0.tgz", + "integrity": "sha512-aExlJShTV4qOUOL7yF1U5tvLCB0xQuudbf6toyYA0E/acBNw71mvjFTnLaRp50aQaYocMR0a/RMMBIHeZnGyjQ==" + }, + "form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + } + }, + "mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==" + }, + "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==", + "requires": { + "mime-db": "1.52.0" + } + } + } +} diff --git a/samples/node/package.json b/samples/node/package.json new file mode 100644 index 0000000..b62be61 --- /dev/null +++ b/samples/node/package.json @@ -0,0 +1,11 @@ +{ + "name": "node-weather-app", + "version": "0.1.0", + "main": "index.js", + "author": "Caian Ertl ", + "license": "CC0-1.0", + "dependencies": { + "axios": "^0.27.2", + "dayjs": "^1.11.2" + } +}