├── .dockerignore ├── .env.template ├── .eslintrc.js ├── .gitignore ├── .prettierrc ├── Dockerfile ├── README.md ├── docker-compose.prod.yml ├── docker-compose.yml ├── nest-cli.json ├── package.json ├── src ├── app.module.ts ├── auth │ ├── auth.controller.ts │ ├── auth.module.ts │ ├── auth.service.ts │ ├── decorators │ │ ├── auth.decorator.ts │ │ ├── get-user.decorator.ts │ │ ├── index.ts │ │ ├── raw-headers.decorator.ts │ │ └── role-protected.decorator.ts │ ├── dto │ │ ├── create-user.dto.ts │ │ ├── index.ts │ │ └── login-user.dto.ts │ ├── entities │ │ └── user.entity.ts │ ├── guards │ │ └── user-role.guard.ts │ ├── interfaces │ │ ├── index.ts │ │ ├── jwt-payload.interface.ts │ │ └── valid-roles.ts │ └── strategies │ │ └── jwt.strategy.ts ├── common │ ├── common.module.ts │ └── dtos │ │ └── pagination.dto.ts ├── files │ ├── files.controller.ts │ ├── files.module.ts │ ├── files.service.ts │ └── helpers │ │ ├── fileFilter.helper.ts │ │ ├── fileNamer.helper.ts │ │ └── index.ts ├── main.ts ├── messages-ws │ ├── dtos │ │ └── new-message.dto.ts │ ├── messages-ws.gateway.ts │ ├── messages-ws.module.ts │ └── messages-ws.service.ts ├── products │ ├── dto │ │ ├── create-product.dto.ts │ │ └── update-product.dto.ts │ ├── entities │ │ ├── index.ts │ │ ├── product-image.entity.ts │ │ └── product.entity.ts │ ├── products.controller.ts │ ├── products.module.ts │ └── products.service.ts └── seed │ ├── data │ └── seed-data.ts │ ├── seed.controller.ts │ ├── seed.module.ts │ └── seed.service.ts ├── static ├── products │ ├── .gitkeep │ ├── 100042301_0_2000.jpg │ ├── 100042301_alt.jpg │ ├── 100042307_0_2000.jpg │ ├── 100042307_1_2000.jpg │ ├── 100042307_alt.jpg │ ├── 100042307_alt_2000.jpg │ ├── 1473809-00-A_1_2000.jpg │ ├── 1473809-00-A_alt.jpg │ ├── 1473814-00-A_1_2000.jpg │ ├── 1473814-00-A_alt.jpg │ ├── 1473819-00-A_1_2000.jpg │ ├── 1473819-00-A_alt.jpg │ ├── 1473824-00-A_2_2000.jpg │ ├── 1473829-00-A_2_2000.jpg │ ├── 1473834-00-A_2_2000.jpg │ ├── 1506211-00-A_0_2000.jpg │ ├── 1506211-00-A_1_2000.jpg │ ├── 1549268-00-A_0_2000.jpg │ ├── 1549268-00-A_2.jpg │ ├── 1549275-00-A_0_2000.jpg │ ├── 1549275-00-A_1.jpg │ ├── 1623735-00-A_0_2000.jpg │ ├── 1623735-00-A_1.jpg │ ├── 1623736-00-A_0_2000.jpg │ ├── 1623736-00-A_1.jpg │ ├── 1623739-00-A_0_2000.jpg │ ├── 1623739-00-A_1.jpg │ ├── 1633802-00-A_0_2000.jpg │ ├── 1633802-00-A_2.jpg │ ├── 1657891-00-A_0_2000.jpg │ ├── 1657891-00-A_1.jpg │ ├── 1657914-00-A_0_2000.jpg │ ├── 1657914-00-A_1.jpg │ ├── 1657915-00-A_0_2000.jpg │ ├── 1657915-00-A_1.jpg │ ├── 1657916-00-A_0_2000.jpg │ ├── 1657916-00-A_1.jpg │ ├── 1657921-00-A_0_2000.jpg │ ├── 1657921-00-A_1.jpg │ ├── 1657931-00-A_0_2000.jpg │ ├── 1657931-00-A_1.jpg │ ├── 1657932-00-A_0_2000.jpg │ ├── 1657932-00-A_1.jpg │ ├── 1657933-00-A_0_2000.jpg │ ├── 1657933-00-A_1.jpg │ ├── 1693862-00-A_0_2000.jpg │ ├── 1693862-00-A_1.jpg │ ├── 1693862-03-A_0_2000.jpg │ ├── 1693862-03-A_1.jpg │ ├── 1693867-00-A_0_2000.jpg │ ├── 1693867-00-A_1.jpg │ ├── 1693867-02-A_0_2000.jpg │ ├── 1693867-02-A_1.jpg │ ├── 1700280-00-A_0_2000.jpg │ ├── 1700280-00-A_1.jpg │ ├── 1703767-00-A_0_2000.jpg │ ├── 1703767-00-A_1.jpg │ ├── 1715672-00-A_featured.jpg │ ├── 1740051-00-A_0_2000.jpg │ ├── 1740051-00-A_1.jpg │ ├── 1740113-00-A_0_2000.jpg │ ├── 1740113-00-A_1.jpg │ ├── 1740121-00-A_0_2000.jpg │ ├── 1740121-00-A_1.jpg │ ├── 1740140-00-A_0_2000.jpg │ ├── 1740140-00-A_1.jpg │ ├── 1740145-00-A_1.jpg │ ├── 1740145-00-A_2_2000.jpg │ ├── 1740176-00-A_0_2000.jpg │ ├── 1740176-00-A_1.jpg │ ├── 1740211-00-A_0_2000.jpg │ ├── 1740211-00-A_1.jpg │ ├── 1740216-00-A_0_2000.jpg │ ├── 1740216-00-A_1.jpg │ ├── 1740221-00-A_0_2000.jpg │ ├── 1740221-00-A_1.jpg │ ├── 1740226-00-A_0_2000.jpg │ ├── 1740226-00-A_1.jpg │ ├── 1740231-00-A_0_2000.jpg │ ├── 1740231-00-A_1.jpg │ ├── 1740236-00-A_0_2000.jpg │ ├── 1740236-00-A_1.jpg │ ├── 1740245-00-A_0_2000.jpg │ ├── 1740245-00-A_1.jpg │ ├── 1740250-00-A_0_2000.jpg │ ├── 1740250-00-A_1.jpg │ ├── 1740255-00-A_0_2000.jpg │ ├── 1740255-00-A_1.jpg │ ├── 1740260-00-A_0_2000.jpg │ ├── 1740260-00-A_1.jpg │ ├── 1740270-00-A_0_2000.jpg │ ├── 1740270-00-A_1.jpg │ ├── 1740275-00-A_0_2000.jpg │ ├── 1740275-00-A_1.jpg │ ├── 1740280-00-A_0_2000.jpg │ ├── 1740280-00-A_1.jpg │ ├── 1740285-00-A_0_2000.jpg │ ├── 1740285-00-A_1.jpg │ ├── 1740290-00-A_0_2000.jpg │ ├── 1740290-00-A_1.jpg │ ├── 1740406-00-A_0_2000.jpg │ ├── 1740406-00-A_1.jpg │ ├── 1740407-00-A_0_2000.jpg │ ├── 1740407-00-A_1.jpg │ ├── 1740408-00-A_0_2000.jpg │ ├── 1740408-00-A_1.jpg │ ├── 1740409-00-A_0_2000.jpg │ ├── 1740409-00-A_1.jpg │ ├── 1740410-00-A_0_2000.jpg │ ├── 1740410-00-A_1.jpg │ ├── 1740411-00-A_0_2000.jpg │ ├── 1740411-00-A_1.jpg │ ├── 1740413-00-A_0_2000.jpg │ ├── 1740413-00-A_1.jpg │ ├── 1740414-00-A_0_2000.jpg │ ├── 1740414-00-A_1.jpg │ ├── 1740416-00-A_0_2000.jpg │ ├── 1740416-00-A_1.jpg │ ├── 1740417-00-A_0_2000.jpg │ ├── 1740417-00-A_1.jpg │ ├── 1740507-00-A_0_2000.jpg │ ├── 1740507-00-A_1.jpg │ ├── 1740514-00-A_0_2000.jpg │ ├── 1740514-00-A_1.jpg │ ├── 1740521-00-A_0_2000.jpg │ ├── 1740521-00-A_1.jpg │ ├── 1740528-00-A_0_2000.jpg │ ├── 1740528-00-A_1.jpg │ ├── 1740535-00-A_0_2000.jpg │ ├── 1740535-00-A_1.jpg │ ├── 1741111-00-A_0_2000.jpg │ ├── 1741111-00-A_1.jpg │ ├── 1741416-00-A_0_2000.jpg │ ├── 1741416-00-A_1.jpg │ ├── 1741425-00-A_0_2000.jpg │ ├── 1741425-00-A_1.jpg │ ├── 1741441-00-A_0_2000.jpg │ ├── 1741441-00-A_1.jpg │ ├── 1741449-00-A_0_2000.jpg │ ├── 1741449-00-A_1.jpg │ ├── 1741611-00-A_1_2000.jpg │ ├── 1741613-00-A_1_2000.jpg │ ├── 1741615-00-A_1_2000.jpg │ ├── 1741617-00-A_1_2000.jpg │ ├── 1741619-00-A_1_2000.jpg │ ├── 1741621-00-A_1_2000.jpg │ ├── 1742694-00-A_1_2000.jpg │ ├── 1742694-00-A_3.jpg │ ├── 1742702-00-A_0_2000.jpg │ ├── 1742702-00-A_1.jpg │ ├── 31bef8d9-ef07-4980-8db8-059364d31688.png │ ├── 5645680-00-A_0_2000.jpg │ ├── 5645680-00-A_3.jpg │ ├── 5645685-00-A_0_2000.jpg │ ├── 5645685-00-A_3.jpg │ ├── 7652410-00-A_0.jpg │ ├── 7652410-00-A_1_2000.jpg │ ├── 7652421-00-A_0_2000.jpg │ ├── 7652421-00-A_1.jpg │ ├── 7652426-00-A_0_2000.jpg │ ├── 7652426-00-A_1.jpg │ ├── 7652432-00-A_0_2000.jpg │ ├── 7652432-00-A_1.jpg │ ├── 7652453-00-A_0_2000.jpg │ ├── 7652453-00-A_1.jpg │ ├── 7652459-00-A_0_2000.jpg │ ├── 7652459-00-A_1.jpg │ ├── 7652465-00-A_0_2000.jpg │ ├── 7652465-00-A_1.jpg │ ├── 7654393-00-A_2_2000.jpg │ ├── 7654393-00-A_3.jpg │ ├── 7654399-00-A_0_2000.jpg │ ├── 7654399-00-A_1.jpg │ ├── 7654420-00-A_0_2000.jpg │ ├── 7654420-00-A_1_2000.jpg │ ├── 8528833-00-A_0_2000.jpg │ ├── 8528833-00-A_2.jpg │ ├── 8528839-00-A_0_2000.jpg │ ├── 8528839-00-A_2.jpg │ ├── 8528845-00-A_0_2000.jpg │ ├── 8528845-00-A_2.jpg │ ├── 8529100-00-A_0_2000.jpg │ ├── 8529100-00-A_1.jpg │ ├── 8529107-00-A_0_2000.jpg │ ├── 8529107-00-A_1.jpg │ ├── 8529198-00-A_0_2000.jpg │ ├── 8529198-00-A_1.jpg │ ├── 8529205-00-A_0_2000.jpg │ ├── 8529205-00-A_1.jpg │ ├── 8529212-00-A_0_2000.jpg │ ├── 8529212-00-A_1.jpg │ ├── 8529312-00-A_0_2000.jpg │ ├── 8529312-00-A_1.jpg │ ├── 8529318-00-A_0_2000.jpg │ ├── 8529318-00-A_1.jpg │ ├── 8529336-00-A_0_2000.jpg │ ├── 8529336-00-A_1.jpg │ ├── 8529342-00-A_0_2000.jpg │ ├── 8529342-00-A_1.jpg │ ├── 8529348-00-A_0_2000.jpg │ ├── 8529348-00-A_1.jpg │ ├── 8529354-00-A_0_2000.jpg │ ├── 8529354-00-A_1.jpg │ ├── 8529360-00-A_0_2000.jpg │ ├── 8529360-00-A_1.jpg │ ├── 8529366-00-A_0_2000.jpg │ ├── 8529366-00-A_1.jpg │ ├── 8529382-00-A_0_2000.jpg │ ├── 8529382-00-A_1.jpg │ ├── 8529387-00-A_0_2000.jpg │ ├── 8529387-00-A_1.jpg │ ├── 8764600-00-A_0_2000.jpg │ ├── 8764600-00-A_2.jpg │ ├── 8764613-00-A_0_2000.jpg │ ├── 8764613-00-A_1.jpg │ ├── 8764727-00-A_0_2000.jpg │ ├── 8764727-00-A_1.jpg │ ├── 8764734-00-A_0_2000.jpg │ ├── 8764734-00-A_1.jpg │ ├── 8764741-00-A_0_2000.jpg │ ├── 8764741-00-A_2.jpg │ ├── 8764754-00-A_0_2000.jpg │ ├── 8764754-00-A_2.jpg │ ├── 8764760-00-A_0_2000.jpg │ ├── 8764760-00-A_1.jpg │ ├── 8764766-00-A_0_2000.jpg │ ├── 8764766-00-A_2.jpg │ ├── 8764792-00-A_0_2000.jpg │ ├── 8764792-00-A_1.jpg │ ├── 8764806-00-A_0_2000.jpg │ ├── 8764806-00-A_1.jpg │ ├── 8764813-00-A_0_2000.jpg │ ├── 8764813-00-A_1.jpg │ ├── 8765085-00-A_0_2000.jpg │ ├── 8765085-00-A_1.jpg │ ├── 8765090-00-A_0_2000.jpg │ ├── 8765090-00-A_1.jpg │ ├── 8765095-00-A_0_2000.jpg │ ├── 8765095-00-A_1.jpg │ ├── 8765100-00-A_0_2000.jpg │ ├── 8765100-00-A_1.jpg │ ├── 8765105-00-A_0_2000.jpg │ ├── 8765105-00-A_1.jpg │ ├── 8765110-00-A_0_2000.jpg │ ├── 8765110-00-A_1.jpg │ ├── 8765115-00-A_0_2000.jpg │ ├── 8765115-00-A_1.jpg │ ├── 8765120-00-A_0_2000.jpg │ ├── 8765120-00-A_1.jpg │ ├── 8765125-00-A_0_2000.jpg │ ├── 8765125-00-A_1.jpg │ ├── 8765130-00-A_0_2000.jpg │ ├── 8765130-00-A_1.jpg │ ├── 9877034-00-A_0_2000.jpg │ ├── 9877034-00-A_2.jpg │ ├── 9877040-00-A_0_2000.jpg │ └── 9877040-00-A_1.jpg └── uploads │ └── .gitkeep ├── test ├── app.e2e-spec.ts └── jest-e2e.json ├── tsconfig.build.json ├── tsconfig.json └── yarn.lock /.dockerignore: -------------------------------------------------------------------------------- 1 | Dockerfile 2 | docker-compose.yml 3 | .git 4 | node_modules/ 5 | docker-compose.prod.yml 6 | dist 7 | -------------------------------------------------------------------------------- /.env.template: -------------------------------------------------------------------------------- 1 | 2 | APP_VERSION=1.0.1 3 | 4 | 5 | STAGE=dev 6 | 7 | DB_PASSWORD=MySecr3tPassWord@as2 8 | DB_NAME=TesloDB 9 | DB_HOST=localhost 10 | DB_PORT=5432 11 | DB_USERNAME=postgres 12 | 13 | PORT=3000 14 | HOST_API=http://localhost:3000/api 15 | 16 | JWT_SECRET=Est3EsMISE3Dsecreto32s -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | parser: '@typescript-eslint/parser', 3 | parserOptions: { 4 | project: 'tsconfig.json', 5 | tsconfigRootDir : __dirname, 6 | sourceType: 'module', 7 | }, 8 | plugins: ['@typescript-eslint/eslint-plugin'], 9 | extends: [ 10 | 'plugin:@typescript-eslint/recommended', 11 | 'plugin:prettier/recommended', 12 | ], 13 | root: true, 14 | env: { 15 | node: true, 16 | jest: true, 17 | }, 18 | ignorePatterns: ['.eslintrc.js'], 19 | rules: { 20 | '@typescript-eslint/interface-name-prefix': 'off', 21 | '@typescript-eslint/explicit-function-return-type': 'off', 22 | '@typescript-eslint/explicit-module-boundary-types': 'off', 23 | '@typescript-eslint/no-explicit-any': 'off', 24 | }, 25 | }; 26 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # compiled output 2 | /dist 3 | /node_modules 4 | 5 | postgres/ 6 | 7 | .env 8 | 9 | 10 | # Logs 11 | logs 12 | *.log 13 | npm-debug.log* 14 | pnpm-debug.log* 15 | yarn-debug.log* 16 | yarn-error.log* 17 | lerna-debug.log* 18 | 19 | # OS 20 | .DS_Store 21 | 22 | # Tests 23 | /coverage 24 | /.nyc_output 25 | 26 | # IDEs and editors 27 | /.idea 28 | .project 29 | .classpath 30 | .c9/ 31 | *.launch 32 | .settings/ 33 | *.sublime-workspace 34 | 35 | # IDE - VSCode 36 | .vscode/* 37 | !.vscode/settings.json 38 | !.vscode/tasks.json 39 | !.vscode/launch.json 40 | !.vscode/extensions.json -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "singleQuote": true, 3 | "trailingComma": "all" 4 | } -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:19-alpine3.15 as dev 2 | WORKDIR /app 3 | COPY package.json ./ 4 | RUN yarn install 5 | CMD [ "yarn","start:dev" ] 6 | 7 | 8 | 9 | FROM node:19-alpine3.15 as dev-deps 10 | WORKDIR /app 11 | COPY package.json package.json 12 | RUN yarn install --frozen-lockfile 13 | 14 | 15 | FROM node:19-alpine3.15 as builder 16 | WORKDIR /app 17 | COPY --from=dev-deps /app/node_modules ./node_modules 18 | COPY . . 19 | # RUN yarn test 20 | RUN yarn build 21 | 22 | FROM node:19-alpine3.15 as prod-deps 23 | WORKDIR /app 24 | COPY package.json package.json 25 | RUN yarn install --prod --frozen-lockfile 26 | 27 | 28 | FROM node:19-alpine3.15 as prod 29 | EXPOSE 3000 30 | WORKDIR /app 31 | ENV APP_VERSION=${APP_VERSION} 32 | COPY --from=prod-deps /app/node_modules ./node_modules 33 | COPY --from=builder /app/dist ./dist 34 | 35 | CMD [ "node","dist/main.js"] 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | Nest Logo 3 |

4 | 5 | 6 | # Teslo API 7 | 8 | 1. Clonar proyecto 9 | 2. ```yarn install``` 10 | 3. Clonar el archivo ```.env.template``` y renombrarlo a ```.env``` 11 | 4. Cambiar las variables de entorno 12 | 5. Levantar la base de datos 13 | ``` 14 | docker compose up -d 15 | ``` 16 | 17 | 6. Levantar: ```yarn start:dev``` 18 | 19 | 7. Ejecutar SEED 20 | ``` 21 | http://localhost:3000/api/seed 22 | ``` 23 | 24 | 25 | 26 | # Production notes: 27 | 28 | Ejecutar este comando 29 | ``` 30 | docker compose -f docker-compose.prod.yml build 31 | ``` 32 | 33 | 34 | ## Docker Repo Name 35 | [klerith/teslo-shop-cors:latest](https://hub.docker.com/repository/docker/klerith/teslo-shop-cors/general) 36 | 37 | docker buildx build --platform linux/amd64,linux/arm64 -t klerith/teslo-shop-cors:1.0.0 --push . -------------------------------------------------------------------------------- /docker-compose.prod.yml: -------------------------------------------------------------------------------- 1 | version: '3' 2 | 3 | 4 | services: 5 | 6 | app: 7 | 8 | build: 9 | context: . 10 | target: ${STAGE} 11 | dockerfile: Dockerfile 12 | 13 | image: klerith/teslo-shop-backend:2.5.0 14 | container_name: nest-app 15 | ports: 16 | - ${PORT}:${PORT} 17 | environment: 18 | APP_VERSION: ${APP_VERSION} 19 | STAGE: ${STAGE} 20 | DB_PASSWORD: ${DB_PASSWORD} 21 | DB_NAME: ${DB_NAME} 22 | DB_HOST: ${DB_HOST} 23 | DB_PORT: ${DB_PORT} 24 | DB_USERNAME: ${DB_USERNAME} 25 | PORT: ${PORT} 26 | HOST_API: ${HOST_API} 27 | JWT_SECRET: ${JWT_SECRET} 28 | 29 | db: 30 | image: postgres:14.3 31 | restart: always 32 | ports: 33 | - "5432:5432" 34 | environment: 35 | POSTGRES_PASSWORD: ${DB_PASSWORD} 36 | POSTGRES_DB: ${DB_NAME} 37 | container_name: ${DB_NAME} 38 | volumes: 39 | - postgres-db:/var/lib/postgresql/data 40 | 41 | 42 | volumes: 43 | postgres-db: 44 | external: false -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3' 2 | 3 | 4 | services: 5 | 6 | # app: 7 | 8 | # build: 9 | # context: . 10 | # target: ${STAGE} 11 | # dockerfile: Dockerfile 12 | 13 | # # command: yarn start:dev 14 | # volumes: 15 | # - .:/app/ 16 | # - /app/node_modules 17 | 18 | # container_name: nest-app 19 | # ports: 20 | # - ${PORT}:${PORT} 21 | # environment: 22 | # APP_VERSION: ${APP_VERSION} 23 | # STAGE: ${STAGE} 24 | # DB_PASSWORD: ${DB_PASSWORD} 25 | # DB_NAME: ${DB_NAME} 26 | # DB_HOST: ${DB_HOST} 27 | # DB_PORT: ${DB_PORT} 28 | # DB_USERNAME: ${DB_USERNAME} 29 | # PORT: ${PORT} 30 | # HOST_API: ${HOST_API} 31 | # JWT_SECRET: ${JWT_SECRET} 32 | 33 | db: 34 | image: postgres:14.3 35 | restart: always 36 | ports: 37 | - "5432:5432" 38 | environment: 39 | POSTGRES_PASSWORD: ${DB_PASSWORD} 40 | POSTGRES_DB: ${DB_NAME} 41 | container_name: ${DB_NAME} 42 | volumes: 43 | - postgres-db:/var/lib/postgresql/data 44 | 45 | 46 | volumes: 47 | postgres-db: 48 | external: false -------------------------------------------------------------------------------- /nest-cli.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json.schemastore.org/nest-cli", 3 | "collection": "@nestjs/schematics", 4 | "sourceRoot": "src" 5 | } 6 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "teslo-shop", 3 | "version": "0.0.1", 4 | "description": "", 5 | "author": "", 6 | "private": true, 7 | "license": "UNLICENSED", 8 | "scripts": { 9 | "prebuild": "rimraf dist", 10 | "build": "nest build", 11 | "format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"", 12 | "start": "node dist/main", 13 | "start:dev": "nest start --watch", 14 | "start:debug": "nest start --debug --watch", 15 | "start:prod": "nest start", 16 | "lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix", 17 | "test": "jest", 18 | "test:watch": "jest --watch", 19 | "test:cov": "jest --coverage", 20 | "test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand", 21 | "test:e2e": "jest --config ./test/jest-e2e.json" 22 | }, 23 | "dependencies": { 24 | "@nestjs/common": "^10.2.7", 25 | "@nestjs/config": "^3.1.1", 26 | "@nestjs/core": "^10.2.7", 27 | "@nestjs/jwt": "^10.1.1", 28 | "@nestjs/mapped-types": "^2.0.2", 29 | "@nestjs/passport": "^10.0.2", 30 | "@nestjs/platform-express": "^10.2.7", 31 | "@nestjs/platform-socket.io": "^10.2.7", 32 | "@nestjs/serve-static": "^4.0.0", 33 | "@nestjs/swagger": "^7.1.13", 34 | "@nestjs/typeorm": "^10.0.0", 35 | "@nestjs/websockets": "^10.2.7", 36 | "@types/bcryptjs": "^2.4.2", 37 | "bcryptjs": "^2.4.3", 38 | "class-transformer": "^0.5.1", 39 | "class-validator": "^0.13.2", 40 | "passport": "^0.6.0", 41 | "passport-jwt": "^4.0.0", 42 | "pg": "^8.7.3", 43 | "reflect-metadata": "^0.1.13", 44 | "rimraf": "^3.0.2", 45 | "rxjs": "^7.2.0", 46 | "socket.io": "^4.5.1", 47 | "typeorm": "^0.3.7", 48 | "uuid": "^8.3.2" 49 | }, 50 | "devDependencies": { 51 | "@nestjs/cli": "^10.1.18", 52 | "@nestjs/schematics": "^10.0.2", 53 | "@nestjs/testing": "^10.2.7", 54 | "@types/express": "^4.17.13", 55 | "@types/jest": "27.5.0", 56 | "@types/multer": "^1.4.7", 57 | "@types/node": "^16.0.0", 58 | "@types/passport-jwt": "^3.0.6", 59 | "@types/supertest": "^2.0.11", 60 | "@types/uuid": "^8.3.4", 61 | "@typescript-eslint/eslint-plugin": "^5.0.0", 62 | "@typescript-eslint/parser": "^5.0.0", 63 | "eslint": "^8.0.1", 64 | "jest": "28.0.3", 65 | "source-map-support": "^0.5.20", 66 | "supertest": "^6.1.3", 67 | "ts-jest": "28.0.1", 68 | "ts-loader": "^9.2.3", 69 | "ts-node": "^10.0.0", 70 | "tsconfig-paths": "4.0.0", 71 | "typescript": "^4.3.5" 72 | }, 73 | "jest": { 74 | "moduleFileExtensions": [ 75 | "js", 76 | "json", 77 | "ts" 78 | ], 79 | "rootDir": "src", 80 | "testRegex": ".*\\.spec\\.ts$", 81 | "transform": { 82 | "^.+\\.(t|j)s$": "ts-jest" 83 | }, 84 | "collectCoverageFrom": [ 85 | "**/*.(t|j)s" 86 | ], 87 | "coverageDirectory": "../coverage", 88 | "testEnvironment": "node" 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /src/app.module.ts: -------------------------------------------------------------------------------- 1 | import { join } from 'path'; 2 | 3 | import { Module } from '@nestjs/common'; 4 | import { ConfigModule } from '@nestjs/config'; 5 | import { TypeOrmModule } from '@nestjs/typeorm'; 6 | import { ServeStaticModule } from '@nestjs/serve-static'; 7 | 8 | import { ProductsModule } from './products/products.module'; 9 | import { CommonModule } from './common/common.module'; 10 | import { SeedModule } from './seed/seed.module'; 11 | import { FilesModule } from './files/files.module'; 12 | import { AuthModule } from './auth/auth.module'; 13 | import { MessagesWsModule } from './messages-ws/messages-ws.module'; 14 | 15 | @Module({ 16 | imports: [ 17 | ConfigModule.forRoot(), 18 | 19 | TypeOrmModule.forRoot({ 20 | // ssl: process.env.STAGE === 'prod', 21 | // extra: { 22 | // ssl: process.env.STAGE === 'prod' 23 | // ? { rejectUnauthorized: false } 24 | // : null, 25 | // }, 26 | type: 'postgres', 27 | host: process.env.DB_HOST, 28 | port: +process.env.DB_PORT, 29 | database: process.env.DB_NAME, 30 | username: process.env.DB_USERNAME, 31 | password: process.env.DB_PASSWORD, 32 | autoLoadEntities: true, 33 | synchronize: true, 34 | }), 35 | 36 | ServeStaticModule.forRoot({ 37 | rootPath: join(__dirname,'..','public'), 38 | }), 39 | 40 | ProductsModule, 41 | 42 | CommonModule, 43 | 44 | SeedModule, 45 | 46 | FilesModule, 47 | 48 | AuthModule, 49 | 50 | MessagesWsModule, 51 | 52 | ], 53 | }) 54 | export class AppModule {} 55 | -------------------------------------------------------------------------------- /src/auth/auth.controller.ts: -------------------------------------------------------------------------------- 1 | import { Controller, Get, Post, Body, UseGuards, Req, Headers, SetMetadata } from '@nestjs/common'; 2 | import { AuthGuard } from '@nestjs/passport'; 3 | import { ApiTags } from '@nestjs/swagger'; 4 | 5 | import { IncomingHttpHeaders } from 'http'; 6 | 7 | import { AuthService } from './auth.service'; 8 | import { RawHeaders, GetUser, Auth } from './decorators'; 9 | import { RoleProtected } from './decorators/role-protected.decorator'; 10 | 11 | import { CreateUserDto, LoginUserDto } from './dto'; 12 | import { User } from './entities/user.entity'; 13 | import { UserRoleGuard } from './guards/user-role.guard'; 14 | import { ValidRoles } from './interfaces'; 15 | 16 | @ApiTags('Auth') 17 | @Controller('auth') 18 | export class AuthController { 19 | constructor(private readonly authService: AuthService) {} 20 | 21 | 22 | 23 | @Post('register') 24 | createUser(@Body() createUserDto: CreateUserDto ) { 25 | return this.authService.create( createUserDto ); 26 | } 27 | 28 | @Post('login') 29 | loginUser(@Body() loginUserDto: LoginUserDto ) { 30 | return this.authService.login( loginUserDto ); 31 | } 32 | 33 | @Get('check-status') 34 | @Auth() 35 | checkAuthStatus( 36 | @GetUser() user: User 37 | ) { 38 | return this.authService.checkAuthStatus( user ); 39 | } 40 | 41 | 42 | @Get('private') 43 | @UseGuards( AuthGuard() ) 44 | testingPrivateRoute( 45 | @Req() request: Express.Request, 46 | @GetUser() user: User, 47 | @GetUser('email') userEmail: string, 48 | 49 | @RawHeaders() rawHeaders: string[], 50 | @Headers() headers: IncomingHttpHeaders, 51 | ) { 52 | 53 | 54 | return { 55 | ok: true, 56 | message: 'Hola Mundo Private', 57 | user, 58 | userEmail, 59 | rawHeaders, 60 | headers 61 | } 62 | } 63 | 64 | 65 | // @SetMetadata('roles', ['admin','super-user']) 66 | 67 | @Get('private2') 68 | @RoleProtected( ValidRoles.superUser, ValidRoles.admin ) 69 | @UseGuards( AuthGuard(), UserRoleGuard ) 70 | privateRoute2( 71 | @GetUser() user: User 72 | ) { 73 | 74 | return { 75 | ok: true, 76 | user 77 | } 78 | } 79 | 80 | 81 | @Get('private3') 82 | @Auth( ValidRoles.admin ) 83 | privateRoute3( 84 | @GetUser() user: User 85 | ) { 86 | 87 | return { 88 | ok: true, 89 | user 90 | } 91 | } 92 | 93 | 94 | 95 | } 96 | -------------------------------------------------------------------------------- /src/auth/auth.module.ts: -------------------------------------------------------------------------------- 1 | import { Module } from '@nestjs/common'; 2 | import { ConfigModule, ConfigService } from '@nestjs/config'; 3 | import { TypeOrmModule } from '@nestjs/typeorm'; 4 | import { PassportModule } from '@nestjs/passport'; 5 | import { JwtModule } from '@nestjs/jwt'; 6 | 7 | import { AuthService } from './auth.service'; 8 | import { AuthController } from './auth.controller'; 9 | import { User } from './entities/user.entity'; 10 | import { JwtStrategy } from './strategies/jwt.strategy'; 11 | 12 | @Module({ 13 | controllers: [AuthController], 14 | providers: [AuthService, JwtStrategy ], 15 | imports: [ 16 | ConfigModule, 17 | 18 | TypeOrmModule.forFeature([ User ]), 19 | 20 | PassportModule.register({ defaultStrategy: 'jwt' }), 21 | 22 | JwtModule.registerAsync({ 23 | imports: [ ConfigModule ], 24 | inject: [ ConfigService ], 25 | useFactory: ( configService: ConfigService ) => { 26 | // console.log('JWT Secret', configService.get('JWT_SECRET') ) 27 | // console.log('JWT SECRET', process.env.JWT_SECRET) 28 | return { 29 | secret: configService.get('JWT_SECRET'), 30 | signOptions: { 31 | expiresIn:'2h' 32 | } 33 | } 34 | } 35 | }) 36 | // JwtModule.register({ 37 | // secret: process.env.JWT_SECRET, 38 | // signOptions: { 39 | // expiresIn:'2h' 40 | // } 41 | // }) 42 | 43 | ], 44 | exports: [ TypeOrmModule, JwtStrategy, PassportModule, JwtModule ] 45 | }) 46 | export class AuthModule {} 47 | -------------------------------------------------------------------------------- /src/auth/auth.service.ts: -------------------------------------------------------------------------------- 1 | import { BadRequestException, Injectable, InternalServerErrorException, UnauthorizedException } from '@nestjs/common'; 2 | import { JwtService } from '@nestjs/jwt'; 3 | import { InjectRepository } from '@nestjs/typeorm'; 4 | import { Repository } from 'typeorm'; 5 | 6 | import * as bcrypt from 'bcryptjs'; 7 | 8 | import { User } from './entities/user.entity'; 9 | import { LoginUserDto, CreateUserDto } from './dto'; 10 | import { JwtPayload } from './interfaces/jwt-payload.interface'; 11 | 12 | 13 | @Injectable() 14 | export class AuthService { 15 | 16 | constructor( 17 | @InjectRepository(User) 18 | private readonly userRepository: Repository, 19 | 20 | private readonly jwtService: JwtService, 21 | ) {} 22 | 23 | 24 | async create( createUserDto: CreateUserDto) { 25 | 26 | try { 27 | 28 | const { password, ...userData } = createUserDto; 29 | 30 | const user = this.userRepository.create({ 31 | ...userData, 32 | password: bcrypt.hashSync( password, 10 ) 33 | }); 34 | 35 | await this.userRepository.save( user ) 36 | delete user.password; 37 | 38 | return { 39 | ...user, 40 | token: this.getJwtToken({ id: user.id }) 41 | }; 42 | // TODO: Retornar el JWT de acceso 43 | 44 | } catch (error) { 45 | this.handleDBErrors(error); 46 | } 47 | 48 | } 49 | 50 | async login( loginUserDto: LoginUserDto ) { 51 | 52 | const { password, email } = loginUserDto; 53 | 54 | const user = await this.userRepository.findOne({ 55 | where: { email }, 56 | select: { email: true, password: true, id: true } //! OJO! 57 | }); 58 | 59 | if ( !user ) 60 | throw new UnauthorizedException('Credentials are not valid (email)'); 61 | 62 | if ( !bcrypt.compareSync( password, user.password ) ) 63 | throw new UnauthorizedException('Credentials are not valid (password)'); 64 | 65 | return { 66 | ...user, 67 | token: this.getJwtToken({ id: user.id }) 68 | }; 69 | } 70 | 71 | async checkAuthStatus( user: User ){ 72 | 73 | return { 74 | ...user, 75 | token: this.getJwtToken({ id: user.id }) 76 | }; 77 | 78 | } 79 | 80 | 81 | 82 | private getJwtToken( payload: JwtPayload ) { 83 | const token = this.jwtService.sign( payload ); 84 | return token; 85 | 86 | } 87 | 88 | private handleDBErrors( error: any ): never { 89 | 90 | 91 | if ( error.code === '23505' ) 92 | throw new BadRequestException( error.detail ); 93 | 94 | console.log(error) 95 | 96 | throw new InternalServerErrorException('Please check server logs'); 97 | 98 | } 99 | 100 | 101 | } 102 | -------------------------------------------------------------------------------- /src/auth/decorators/auth.decorator.ts: -------------------------------------------------------------------------------- 1 | import { applyDecorators, UseGuards } from '@nestjs/common'; 2 | import { AuthGuard } from '@nestjs/passport'; 3 | import { UserRoleGuard } from '../guards/user-role.guard'; 4 | import { ValidRoles } from '../interfaces'; 5 | import { RoleProtected } from './role-protected.decorator'; 6 | 7 | 8 | export function Auth(...roles: ValidRoles[]) { 9 | 10 | return applyDecorators( 11 | RoleProtected(...roles), 12 | UseGuards( AuthGuard(), UserRoleGuard ), 13 | ); 14 | 15 | } -------------------------------------------------------------------------------- /src/auth/decorators/get-user.decorator.ts: -------------------------------------------------------------------------------- 1 | import { createParamDecorator, ExecutionContext, InternalServerErrorException } from '@nestjs/common'; 2 | 3 | 4 | 5 | export const GetUser = createParamDecorator( 6 | ( data: string, ctx: ExecutionContext ) => { 7 | 8 | const req = ctx.switchToHttp().getRequest(); 9 | const user = req.user; 10 | 11 | if ( !user ) 12 | throw new InternalServerErrorException('User not found (request)'); 13 | 14 | return ( !data ) 15 | ? user 16 | : user[data]; 17 | 18 | } 19 | ); -------------------------------------------------------------------------------- /src/auth/decorators/index.ts: -------------------------------------------------------------------------------- 1 | export { Auth } from './auth.decorator'; 2 | export { RoleProtected } from './role-protected.decorator'; 3 | 4 | export { RawHeaders } from './raw-headers.decorator'; 5 | export { GetUser } from "./get-user.decorator"; 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/auth/decorators/raw-headers.decorator.ts: -------------------------------------------------------------------------------- 1 | import { createParamDecorator, ExecutionContext, InternalServerErrorException } from '@nestjs/common'; 2 | 3 | 4 | 5 | export const RawHeaders = createParamDecorator( 6 | ( data: string, ctx: ExecutionContext ) => { 7 | 8 | const req = ctx.switchToHttp().getRequest(); 9 | return req.rawHeaders; 10 | } 11 | ); -------------------------------------------------------------------------------- /src/auth/decorators/role-protected.decorator.ts: -------------------------------------------------------------------------------- 1 | import { SetMetadata } from '@nestjs/common'; 2 | import { ValidRoles } from '../interfaces'; 3 | 4 | export const META_ROLES = 'roles'; 5 | 6 | 7 | export const RoleProtected = (...args: ValidRoles[] ) => { 8 | 9 | 10 | return SetMetadata( META_ROLES , args); 11 | } 12 | -------------------------------------------------------------------------------- /src/auth/dto/create-user.dto.ts: -------------------------------------------------------------------------------- 1 | import { IsEmail, IsString, Matches, MaxLength, MinLength } from 'class-validator'; 2 | 3 | 4 | export class CreateUserDto { 5 | 6 | @IsString() 7 | @IsEmail() 8 | email: string; 9 | 10 | @IsString() 11 | @MinLength(6) 12 | @MaxLength(50) 13 | @Matches( 14 | /(?:(?=.*\d)|(?=.*\W+))(?![.\n])(?=.*[A-Z])(?=.*[a-z]).*$/, { 15 | message: 'The password must have a Uppercase, lowercase letter and a number' 16 | }) 17 | password: string; 18 | 19 | @IsString() 20 | @MinLength(1) 21 | fullName: string; 22 | 23 | } -------------------------------------------------------------------------------- /src/auth/dto/index.ts: -------------------------------------------------------------------------------- 1 | export { LoginUserDto } from './login-user.dto'; 2 | export { CreateUserDto } from './create-user.dto'; 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/auth/dto/login-user.dto.ts: -------------------------------------------------------------------------------- 1 | import { IsEmail, IsString, Matches, MaxLength, MinLength } from 'class-validator'; 2 | 3 | 4 | export class LoginUserDto { 5 | 6 | @IsString() 7 | @IsEmail() 8 | email: string; 9 | 10 | @IsString() 11 | @MinLength(6) 12 | @MaxLength(50) 13 | @Matches( 14 | /(?:(?=.*\d)|(?=.*\W+))(?![.\n])(?=.*[A-Z])(?=.*[a-z]).*$/, { 15 | message: 'The password must have a Uppercase, lowercase letter and a number' 16 | }) 17 | password: string; 18 | 19 | } -------------------------------------------------------------------------------- /src/auth/entities/user.entity.ts: -------------------------------------------------------------------------------- 1 | import { BeforeInsert, BeforeUpdate, Column, Entity, OneToMany, PrimaryGeneratedColumn } from 'typeorm'; 2 | import { Product } from '../../products/entities'; 3 | 4 | 5 | @Entity('users') 6 | export class User { 7 | 8 | @PrimaryGeneratedColumn('uuid') 9 | id: string; 10 | 11 | @Column('text', { 12 | unique: true 13 | }) 14 | email: string; 15 | 16 | @Column('text', { 17 | select: false 18 | }) 19 | password: string; 20 | 21 | @Column('text') 22 | fullName: string; 23 | 24 | @Column('bool', { 25 | default: true 26 | }) 27 | isActive: boolean; 28 | 29 | @Column('text', { 30 | array: true, 31 | default: ['user'] 32 | }) 33 | roles: string[]; 34 | 35 | @OneToMany( 36 | () => Product, 37 | ( product ) => product.user 38 | ) 39 | product: Product; 40 | 41 | 42 | @BeforeInsert() 43 | checkFieldsBeforeInsert() { 44 | this.email = this.email.toLowerCase().trim(); 45 | } 46 | 47 | @BeforeUpdate() 48 | checkFieldsBeforeUpdate() { 49 | this.checkFieldsBeforeInsert(); 50 | } 51 | 52 | } 53 | -------------------------------------------------------------------------------- /src/auth/guards/user-role.guard.ts: -------------------------------------------------------------------------------- 1 | import { Reflector } from '@nestjs/core'; 2 | import { CanActivate, ExecutionContext, Injectable, BadRequestException, ForbiddenException } from '@nestjs/common'; 3 | import { Observable } from 'rxjs'; 4 | import { User } from '../entities/user.entity'; 5 | import { META_ROLES } from '../decorators/role-protected.decorator'; 6 | 7 | @Injectable() 8 | export class UserRoleGuard implements CanActivate { 9 | 10 | constructor( 11 | private readonly reflector: Reflector 12 | ) {} 13 | 14 | canActivate( 15 | context: ExecutionContext, 16 | ): boolean | Promise | Observable { 17 | 18 | const validRoles: string[] = this.reflector.get( META_ROLES , context.getHandler() ) 19 | 20 | if ( !validRoles ) return true; 21 | if ( validRoles.length === 0 ) return true; 22 | 23 | const req = context.switchToHttp().getRequest(); 24 | const user = req.user as User; 25 | 26 | if ( !user ) 27 | throw new BadRequestException('User not found'); 28 | 29 | for (const role of user.roles ) { 30 | if ( validRoles.includes( role ) ) { 31 | return true; 32 | } 33 | } 34 | 35 | throw new ForbiddenException( 36 | `User ${ user.fullName } need a valid role: [${ validRoles }]` 37 | ); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/auth/interfaces/index.ts: -------------------------------------------------------------------------------- 1 | export { JwtPayload } from './jwt-payload.interface' 2 | export { ValidRoles } from './valid-roles' 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/auth/interfaces/jwt-payload.interface.ts: -------------------------------------------------------------------------------- 1 | 2 | 3 | export interface JwtPayload { 4 | id: string; 5 | 6 | // TODO: añadir todo lo que quieran grabar. 7 | } 8 | -------------------------------------------------------------------------------- /src/auth/interfaces/valid-roles.ts: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | export enum ValidRoles { 5 | admin = 'admin', 6 | superUser = 'super-user', 7 | user = 'user', 8 | } -------------------------------------------------------------------------------- /src/auth/strategies/jwt.strategy.ts: -------------------------------------------------------------------------------- 1 | import { Injectable, UnauthorizedException } from '@nestjs/common'; 2 | import { ConfigService } from '@nestjs/config'; 3 | import { PassportStrategy } from '@nestjs/passport'; 4 | import { InjectRepository } from '@nestjs/typeorm'; 5 | import { ExtractJwt, Strategy } from 'passport-jwt'; 6 | import { Repository } from 'typeorm'; 7 | import { User } from '../entities/user.entity'; 8 | import { JwtPayload } from '../interfaces/jwt-payload.interface'; 9 | 10 | @Injectable() 11 | export class JwtStrategy extends PassportStrategy( Strategy ) { 12 | 13 | constructor( 14 | @InjectRepository( User ) 15 | private readonly userRepository: Repository, 16 | 17 | configService: ConfigService 18 | ) { 19 | 20 | super({ 21 | secretOrKey: configService.get('JWT_SECRET'), 22 | jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(), 23 | }); 24 | } 25 | 26 | 27 | async validate( payload: JwtPayload ): Promise { 28 | 29 | const { id } = payload; 30 | 31 | const user = await this.userRepository.findOneBy({ id }); 32 | 33 | if ( !user ) 34 | throw new UnauthorizedException('Token not valid') 35 | 36 | if ( !user.isActive ) 37 | throw new UnauthorizedException('User is inactive, talk with an admin'); 38 | 39 | 40 | return user; 41 | } 42 | 43 | } -------------------------------------------------------------------------------- /src/common/common.module.ts: -------------------------------------------------------------------------------- 1 | import { Module } from '@nestjs/common'; 2 | 3 | @Module({}) 4 | export class CommonModule {} 5 | -------------------------------------------------------------------------------- /src/common/dtos/pagination.dto.ts: -------------------------------------------------------------------------------- 1 | import { ApiProperty } from '@nestjs/swagger'; 2 | 3 | import { Type } from 'class-transformer'; 4 | import { IsOptional, IsPositive, Min } from 'class-validator'; 5 | 6 | 7 | export class PaginationDto { 8 | 9 | @ApiProperty({ 10 | default: 10, description: 'How many rows do you need' 11 | }) 12 | @IsOptional() 13 | @IsPositive() 14 | @Type( () => Number ) // enableImplicitConversions: true 15 | limit?: number; 16 | 17 | @ApiProperty({ 18 | default: 0, description: 'How many rows do you want to skip' 19 | }) 20 | @IsOptional() 21 | @Min(0) 22 | @Type( () => Number ) // enableImplicitConversions: true 23 | offset?: number; 24 | 25 | } -------------------------------------------------------------------------------- /src/files/files.controller.ts: -------------------------------------------------------------------------------- 1 | import { Controller, Get, Post, Param, UploadedFile, UseInterceptors, BadRequestException, Res } from '@nestjs/common'; 2 | import { ConfigService } from '@nestjs/config'; 3 | import { ApiTags } from '@nestjs/swagger'; 4 | import { FileInterceptor } from '@nestjs/platform-express'; 5 | 6 | import { Response } from 'express'; 7 | import { diskStorage } from 'multer'; 8 | import { FilesService } from './files.service'; 9 | 10 | import { fileFilter, fileNamer } from './helpers'; 11 | 12 | @ApiTags('Files - Get and Upload') 13 | @Controller('files') 14 | export class FilesController { 15 | constructor( 16 | private readonly filesService: FilesService, 17 | private readonly configService: ConfigService, 18 | ) {} 19 | 20 | @Get('product/:imageName') 21 | findProductImage( 22 | @Res() res: Response, 23 | @Param('imageName') imageName: string 24 | ) { 25 | 26 | const path = this.filesService.getStaticProductImage( imageName ); 27 | 28 | res.sendFile( path ); 29 | } 30 | 31 | 32 | 33 | @Post('product') 34 | @UseInterceptors( FileInterceptor('file', { 35 | fileFilter: fileFilter, 36 | // limits: { fileSize: 1000 } 37 | storage: diskStorage({ 38 | destination: './static/products', 39 | filename: fileNamer 40 | }) 41 | }) ) 42 | uploadProductImage( 43 | @UploadedFile() file: Express.Multer.File, 44 | ){ 45 | 46 | if ( !file ) { 47 | throw new BadRequestException('Make sure that the file is an image'); 48 | } 49 | 50 | // const secureUrl = `${ file.filename }`; 51 | const secureUrl = `${ this.configService.get('HOST_API') }/files/product/${ file.filename }`; 52 | 53 | return { secureUrl }; 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /src/files/files.module.ts: -------------------------------------------------------------------------------- 1 | import { Module } from '@nestjs/common'; 2 | import { ConfigModule } from '@nestjs/config'; 3 | 4 | import { FilesService } from './files.service'; 5 | import { FilesController } from './files.controller'; 6 | 7 | @Module({ 8 | controllers: [FilesController], 9 | providers: [FilesService], 10 | imports: [ 11 | ConfigModule 12 | ] 13 | }) 14 | export class FilesModule {} 15 | -------------------------------------------------------------------------------- /src/files/files.service.ts: -------------------------------------------------------------------------------- 1 | import { existsSync } from 'fs'; 2 | import { join } from 'path'; 3 | 4 | import { Injectable, BadRequestException } from '@nestjs/common'; 5 | 6 | 7 | @Injectable() 8 | export class FilesService { 9 | 10 | getStaticProductImage( imageName: string ) { 11 | 12 | const path = join( __dirname, '../../static/products', imageName ); 13 | 14 | if ( !existsSync(path) ) 15 | throw new BadRequestException(`No product found with image ${ imageName }`); 16 | 17 | return path; 18 | } 19 | 20 | 21 | } 22 | -------------------------------------------------------------------------------- /src/files/helpers/fileFilter.helper.ts: -------------------------------------------------------------------------------- 1 | 2 | 3 | export const fileFilter = ( req: Express.Request, file: Express.Multer.File, callback: Function ) => { 4 | 5 | // console.log({ file }) 6 | if ( !file ) return callback( new Error('File is empty'), false ); 7 | 8 | 9 | const fileExptension = file.mimetype.split('/')[1]; 10 | const validExtensions = ['jpg','jpeg','png','gif']; 11 | 12 | if ( validExtensions.includes( fileExptension ) ) { 13 | return callback( null, true ) 14 | } 15 | 16 | callback(null, false ); 17 | 18 | } 19 | -------------------------------------------------------------------------------- /src/files/helpers/fileNamer.helper.ts: -------------------------------------------------------------------------------- 1 | import { v4 as uuid } from 'uuid' 2 | 3 | export const fileNamer = ( req: Express.Request, file: Express.Multer.File, callback: Function ) => { 4 | 5 | // console.log({ file }) 6 | if ( !file ) return callback( new Error('File is empty'), false ); 7 | 8 | const fileExtension = file.mimetype.split('/')[1]; 9 | 10 | const fileName = `${ uuid() }.${ fileExtension }`; 11 | 12 | 13 | callback(null, fileName ); 14 | 15 | } 16 | -------------------------------------------------------------------------------- /src/files/helpers/index.ts: -------------------------------------------------------------------------------- 1 | export { fileNamer } from './fileNamer.helper'; 2 | export { fileFilter } from './fileFilter.helper'; 3 | -------------------------------------------------------------------------------- /src/main.ts: -------------------------------------------------------------------------------- 1 | import { NestFactory } from '@nestjs/core'; 2 | import { ValidationPipe, Logger } from '@nestjs/common'; 3 | import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger'; 4 | 5 | import { AppModule } from './app.module'; 6 | 7 | async function bootstrap() { 8 | const app = await NestFactory.create(AppModule, { cors: true}); 9 | const logger = new Logger('Bootstrap'); 10 | 11 | app.setGlobalPrefix('api'); 12 | 13 | app.useGlobalPipes( 14 | new ValidationPipe({ 15 | whitelist: true, 16 | forbidNonWhitelisted: true, 17 | }) 18 | ); 19 | 20 | const config = new DocumentBuilder() 21 | .setTitle('Teslo RESTFul API') 22 | .setDescription('Teslo shop endpoints') 23 | .setVersion('1.0') 24 | .build(); 25 | const document = SwaggerModule.createDocument(app, config); 26 | SwaggerModule.setup('api', app, document); 27 | 28 | 29 | await app.listen(process.env.PORT); 30 | logger.log(`App running on port ${ process.env.PORT }`); 31 | } 32 | bootstrap(); 33 | -------------------------------------------------------------------------------- /src/messages-ws/dtos/new-message.dto.ts: -------------------------------------------------------------------------------- 1 | import { IsString, MinLength } from 'class-validator'; 2 | 3 | 4 | export class NewMessageDto { 5 | @IsString() 6 | @MinLength(1) 7 | message: string; 8 | } -------------------------------------------------------------------------------- /src/messages-ws/messages-ws.gateway.ts: -------------------------------------------------------------------------------- 1 | import { JwtService } from '@nestjs/jwt'; 2 | import { OnGatewayConnection, OnGatewayDisconnect, SubscribeMessage, WebSocketGateway, WebSocketServer } from '@nestjs/websockets'; 3 | import { Server, Socket } from 'socket.io'; 4 | import { JwtPayload } from '../auth/interfaces'; 5 | import { NewMessageDto } from './dtos/new-message.dto'; 6 | import { MessagesWsService } from './messages-ws.service'; 7 | 8 | @WebSocketGateway({ cors: true }) 9 | export class MessagesWsGateway implements OnGatewayConnection, OnGatewayDisconnect { 10 | 11 | @WebSocketServer() wss: Server; 12 | 13 | constructor( 14 | private readonly messagesWsService: MessagesWsService, 15 | private readonly jwtService: JwtService 16 | ) {} 17 | 18 | async handleConnection( client: Socket ) { 19 | const token = client.handshake.headers.authentication as string; 20 | let payload: JwtPayload; 21 | 22 | try { 23 | payload = this.jwtService.verify( token ); 24 | await this.messagesWsService.registerClient( client, payload.id ); 25 | 26 | } catch (error) { 27 | client.disconnect(); 28 | return; 29 | } 30 | 31 | // console.log({ payload }) 32 | // console.log('Cliente conectado:', client.id ); 33 | 34 | 35 | this.wss.emit('clients-updated', this.messagesWsService.getConnectedClients() ); 36 | } 37 | 38 | handleDisconnect( client: Socket ) { 39 | // console.log('Cliente desconectado', client.id ) 40 | this.messagesWsService.removeClient( client.id ); 41 | 42 | this.wss.emit('clients-updated', this.messagesWsService.getConnectedClients() ); 43 | } 44 | 45 | @SubscribeMessage('message-from-client') 46 | onMessageFromClient( client: Socket, payload: NewMessageDto ) { 47 | 48 | //! Emite únicamente al cliente. 49 | // client.emit('message-from-server', { 50 | // fullName: 'Soy Yo!', 51 | // message: payload.message || 'no-message!!' 52 | // }); 53 | 54 | //! Emitir a todos MENOS, al cliente inicial 55 | // client.broadcast.emit('message-from-server', { 56 | // fullName: 'Soy Yo!', 57 | // message: payload.message || 'no-message!!' 58 | // }); 59 | 60 | this.wss.emit('message-from-server', { 61 | fullName: this.messagesWsService.getUserFullName(client.id), 62 | message: payload.message || 'no-message!!' 63 | }); 64 | 65 | } 66 | 67 | 68 | } 69 | -------------------------------------------------------------------------------- /src/messages-ws/messages-ws.module.ts: -------------------------------------------------------------------------------- 1 | import { Module } from '@nestjs/common'; 2 | import { MessagesWsService } from './messages-ws.service'; 3 | import { MessagesWsGateway } from './messages-ws.gateway'; 4 | 5 | import { AuthModule } from '../auth/auth.module'; 6 | 7 | @Module({ 8 | providers: [MessagesWsGateway, MessagesWsService], 9 | imports: [ AuthModule ] 10 | }) 11 | export class MessagesWsModule {} 12 | -------------------------------------------------------------------------------- /src/messages-ws/messages-ws.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@nestjs/common'; 2 | import { InjectRepository } from '@nestjs/typeorm'; 3 | 4 | import { Socket } from 'socket.io'; 5 | import { User } from '../auth/entities/user.entity'; 6 | import { Repository } from 'typeorm'; 7 | 8 | interface ConnectedClients { 9 | [id: string]: { 10 | socket: Socket, 11 | user: User 12 | } 13 | } 14 | 15 | @Injectable() 16 | export class MessagesWsService { 17 | 18 | private connectedClients: ConnectedClients = {} 19 | 20 | constructor( 21 | @InjectRepository(User) 22 | private readonly userRepository: Repository 23 | ) {} 24 | 25 | 26 | async registerClient( client: Socket, userId: string ) { 27 | 28 | const user = await this.userRepository.findOneBy({ id: userId }); 29 | if ( !user ) throw new Error('User not found'); 30 | if ( !user.isActive ) throw new Error('User not active'); 31 | 32 | this.checkUserConnection( user ); 33 | 34 | this.connectedClients[client.id] = { 35 | socket: client, 36 | user: user, 37 | }; 38 | } 39 | 40 | removeClient( clientId: string ) { 41 | delete this.connectedClients[clientId]; 42 | } 43 | 44 | 45 | getConnectedClients(): string[] { 46 | return Object.keys( this.connectedClients ); 47 | } 48 | 49 | 50 | getUserFullName( socketId: string ) { 51 | return this.connectedClients[socketId].user.fullName; 52 | } 53 | 54 | 55 | private checkUserConnection( user: User ) { 56 | 57 | for (const clientId of Object.keys( this.connectedClients ) ) { 58 | 59 | const connectedClient = this.connectedClients[clientId]; 60 | 61 | if ( connectedClient.user.id === user.id ){ 62 | connectedClient.socket.disconnect(); 63 | break; 64 | } 65 | } 66 | 67 | } 68 | 69 | } 70 | -------------------------------------------------------------------------------- /src/products/dto/create-product.dto.ts: -------------------------------------------------------------------------------- 1 | import { ApiProperty } from '@nestjs/swagger'; 2 | import { IsArray, IsIn, IsInt, IsNumber, IsOptional, 3 | IsPositive, IsString, MinLength 4 | } from 'class-validator'; 5 | 6 | 7 | export class CreateProductDto { 8 | 9 | @ApiProperty({ 10 | description: 'Product title (unique)', 11 | nullable: false, 12 | minLength: 1 13 | }) 14 | @IsString() 15 | @MinLength(1) 16 | title: string; 17 | 18 | @ApiProperty() 19 | @IsNumber() 20 | @IsPositive() 21 | @IsOptional() 22 | price?: number; 23 | 24 | @ApiProperty() 25 | @IsString() 26 | @IsOptional() 27 | description?: string; 28 | 29 | @ApiProperty() 30 | @IsString() 31 | @IsOptional() 32 | slug?: string; 33 | 34 | @ApiProperty() 35 | @IsInt() 36 | @IsPositive() 37 | @IsOptional() 38 | stock?: number; 39 | 40 | @ApiProperty() 41 | @IsString({ each: true }) 42 | @IsArray() 43 | sizes: string[] 44 | 45 | @ApiProperty() 46 | @IsIn(['men','women','kid','unisex']) 47 | gender: string; 48 | 49 | @ApiProperty() 50 | @IsString({ each: true }) 51 | @IsArray() 52 | @IsOptional() 53 | tags: string[]; 54 | 55 | @ApiProperty() 56 | @IsString({ each: true }) 57 | @IsArray() 58 | @IsOptional() 59 | images?: string[]; 60 | 61 | 62 | } 63 | -------------------------------------------------------------------------------- /src/products/dto/update-product.dto.ts: -------------------------------------------------------------------------------- 1 | // import { PartialType } from '@nestjs/mapped-types'; 2 | import { PartialType } from '@nestjs/swagger'; 3 | import { CreateProductDto } from './create-product.dto'; 4 | 5 | export class UpdateProductDto extends PartialType(CreateProductDto) {} 6 | -------------------------------------------------------------------------------- /src/products/entities/index.ts: -------------------------------------------------------------------------------- 1 | export { Product } from './product.entity'; 2 | export { ProductImage } from './product-image.entity'; 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/products/entities/product-image.entity.ts: -------------------------------------------------------------------------------- 1 | import { Product } from './'; 2 | import { Column, Entity, ManyToOne, PrimaryGeneratedColumn } from 'typeorm'; 3 | 4 | 5 | @Entity({ name: 'product_images' }) 6 | export class ProductImage { 7 | 8 | @PrimaryGeneratedColumn() 9 | id: number; 10 | 11 | @Column('text') 12 | url: string; 13 | 14 | @ManyToOne( 15 | () => Product, 16 | ( product ) => product.images, 17 | { onDelete: 'CASCADE' } 18 | ) 19 | product: Product 20 | 21 | } -------------------------------------------------------------------------------- /src/products/entities/product.entity.ts: -------------------------------------------------------------------------------- 1 | import { BeforeInsert, BeforeUpdate, Column, Entity, ManyToOne, OneToMany, PrimaryGeneratedColumn } from 'typeorm'; 2 | import { ApiProperty } from '@nestjs/swagger'; 3 | 4 | import { ProductImage } from './'; 5 | import { User } from '../../auth/entities/user.entity'; 6 | 7 | @Entity({ name: 'products' }) 8 | export class Product { 9 | 10 | @ApiProperty({ 11 | example: 'cd533345-f1f3-48c9-a62e-7dc2da50c8f8', 12 | description: 'Product ID', 13 | uniqueItems: true 14 | }) 15 | @PrimaryGeneratedColumn('uuid') 16 | id: string; 17 | 18 | @ApiProperty({ 19 | example: 'T-Shirt Teslo', 20 | description: 'Product Title', 21 | uniqueItems: true 22 | }) 23 | @Column('text', { 24 | unique: true, 25 | }) 26 | title: string; 27 | 28 | @ApiProperty({ 29 | example: 0, 30 | description: 'Product price', 31 | }) 32 | @Column('float',{ 33 | default: 0 34 | }) 35 | price: number; 36 | 37 | @ApiProperty({ 38 | example: 'Anim reprehenderit nulla in anim mollit minim irure commodo.', 39 | description: 'Product description', 40 | default: null, 41 | }) 42 | @Column({ 43 | type: 'text', 44 | nullable: true 45 | }) 46 | description: string; 47 | 48 | @ApiProperty({ 49 | example: 't_shirt_teslo', 50 | description: 'Product SLUG - for SEO', 51 | uniqueItems: true 52 | }) 53 | @Column('text', { 54 | unique: true 55 | }) 56 | slug: string; 57 | 58 | @ApiProperty({ 59 | example: 10, 60 | description: 'Product stock', 61 | default: 0 62 | }) 63 | @Column('int', { 64 | default: 0 65 | }) 66 | stock: number; 67 | 68 | @ApiProperty({ 69 | example: ['M','XL','XXL'], 70 | description: 'Product sizes', 71 | }) 72 | @Column('text',{ 73 | array: true 74 | }) 75 | sizes: string[]; 76 | 77 | @ApiProperty({ 78 | example: 'women', 79 | description: 'Product gender', 80 | }) 81 | @Column('text') 82 | gender: string; 83 | 84 | @ApiProperty() 85 | @Column('text', { 86 | array: true, 87 | default: [] 88 | }) 89 | tags: string[]; 90 | 91 | // images 92 | @ApiProperty() 93 | @OneToMany( 94 | () => ProductImage, 95 | (productImage) => productImage.product, 96 | { cascade: true, eager: true } 97 | ) 98 | images?: ProductImage[]; 99 | 100 | 101 | @ManyToOne( 102 | () => User, 103 | ( user ) => user.product, 104 | { eager: true } 105 | ) 106 | user: User 107 | 108 | 109 | @BeforeInsert() 110 | checkSlugInsert() { 111 | 112 | if ( !this.slug ) { 113 | this.slug = this.title; 114 | } 115 | 116 | this.slug = this.slug 117 | .toLowerCase() 118 | .replaceAll(' ','_') 119 | .replaceAll("'",'') 120 | 121 | } 122 | 123 | @BeforeUpdate() 124 | checkSlugUpdate() { 125 | this.slug = this.slug 126 | .toLowerCase() 127 | .replaceAll(' ','_') 128 | .replaceAll("'",'') 129 | } 130 | 131 | 132 | } 133 | -------------------------------------------------------------------------------- /src/products/products.controller.ts: -------------------------------------------------------------------------------- 1 | import { Controller, Get, Post, Body, Patch, Param, Delete, ParseUUIDPipe, Query } from '@nestjs/common'; 2 | import { ApiResponse, ApiTags } from '@nestjs/swagger'; 3 | 4 | import { Product } from './entities/product.entity'; 5 | import { ProductsService } from './products.service'; 6 | import { CreateProductDto } from './dto/create-product.dto'; 7 | import { UpdateProductDto } from './dto/update-product.dto'; 8 | import { PaginationDto } from './../common/dtos/pagination.dto'; 9 | 10 | import { Auth, GetUser } from '../auth/decorators'; 11 | import { User } from '../auth/entities/user.entity'; 12 | import { ValidRoles } from '../auth/interfaces'; 13 | 14 | @ApiTags('Products') 15 | @Controller('products') 16 | export class ProductsController { 17 | constructor(private readonly productsService: ProductsService) {} 18 | 19 | @Post() 20 | @Auth() 21 | @ApiResponse({ status: 201, description: 'Product was created', type: Product }) 22 | @ApiResponse({ status: 400, description: 'Bad request' }) 23 | @ApiResponse({ status: 403, description: 'Forbidden. Token related.' }) 24 | create( 25 | @Body() createProductDto: CreateProductDto, 26 | @GetUser() user: User, 27 | ) { 28 | return this.productsService.create(createProductDto, user ); 29 | } 30 | 31 | @Get() 32 | findAll( @Query() paginationDto:PaginationDto ) { 33 | // console.log(paginationDto) 34 | return this.productsService.findAll( paginationDto ); 35 | } 36 | 37 | @Get(':term') 38 | findOne(@Param( 'term' ) term: string) { 39 | return this.productsService.findOnePlain( term ); 40 | } 41 | 42 | @Patch(':id') 43 | @Auth( ValidRoles.admin ) 44 | update( 45 | @Param('id', ParseUUIDPipe ) id: string, 46 | @Body() updateProductDto: UpdateProductDto, 47 | @GetUser() user: User, 48 | ) { 49 | return this.productsService.update( id, updateProductDto, user ); 50 | } 51 | 52 | @Delete(':id') 53 | @Auth( ValidRoles.admin ) 54 | remove(@Param('id', ParseUUIDPipe ) id: string) { 55 | return this.productsService.remove( id ); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/products/products.module.ts: -------------------------------------------------------------------------------- 1 | import { TypeOrmModule } from '@nestjs/typeorm'; 2 | import { Module } from '@nestjs/common'; 3 | 4 | import { AuthModule } from './../auth/auth.module'; 5 | 6 | import { ProductsController } from './products.controller'; 7 | import { ProductsService } from './products.service'; 8 | 9 | import { Product, ProductImage } from './entities'; 10 | 11 | @Module({ 12 | controllers: [ProductsController], 13 | providers: [ProductsService], 14 | imports: [ 15 | TypeOrmModule.forFeature([ Product, ProductImage ]), 16 | AuthModule, 17 | ], 18 | exports: [ 19 | ProductsService, 20 | TypeOrmModule, 21 | ] 22 | }) 23 | export class ProductsModule {} 24 | -------------------------------------------------------------------------------- /src/products/products.service.ts: -------------------------------------------------------------------------------- 1 | import { BadRequestException, Injectable, InternalServerErrorException, Logger, NotFoundException } from '@nestjs/common'; 2 | import { InjectRepository } from '@nestjs/typeorm'; 3 | import { DataSource, Repository } from 'typeorm'; 4 | 5 | import { CreateProductDto } from './dto/create-product.dto'; 6 | import { UpdateProductDto } from './dto/update-product.dto'; 7 | import { PaginationDto } from 'src/common/dtos/pagination.dto'; 8 | 9 | import { validate as isUUID } from 'uuid'; 10 | import { ProductImage, Product } from './entities'; 11 | import { User } from '../auth/entities/user.entity'; 12 | 13 | @Injectable() 14 | export class ProductsService { 15 | 16 | private readonly logger = new Logger('ProductsService'); 17 | 18 | constructor( 19 | 20 | @InjectRepository(Product) 21 | private readonly productRepository: Repository, 22 | 23 | @InjectRepository(ProductImage) 24 | private readonly productImageRepository: Repository, 25 | 26 | private readonly dataSource: DataSource, 27 | 28 | ) {} 29 | 30 | 31 | 32 | async create(createProductDto: CreateProductDto, user: User) { 33 | 34 | try { 35 | const { images = [], ...productDetails } = createProductDto; 36 | 37 | const product = this.productRepository.create({ 38 | ...productDetails, 39 | images: images.map( image => this.productImageRepository.create({ url: image }) ), 40 | user, 41 | }); 42 | 43 | await this.productRepository.save( product ); 44 | 45 | return { ...product, images }; 46 | 47 | } catch (error) { 48 | this.handleDBExceptions(error); 49 | } 50 | 51 | 52 | } 53 | 54 | 55 | async findAll( paginationDto: PaginationDto ) { 56 | 57 | const { limit = 10, offset = 0 } = paginationDto; 58 | 59 | const products = await this.productRepository.find({ 60 | take: limit, 61 | skip: offset, 62 | relations: { 63 | images: true, 64 | } 65 | }) 66 | 67 | return products.map( ( product ) => ({ 68 | ...product, 69 | images: product.images.map( img => img.url ) 70 | })) 71 | } 72 | 73 | async findOne( term: string ) { 74 | 75 | let product: Product; 76 | 77 | if ( isUUID(term) ) { 78 | product = await this.productRepository.findOneBy({ id: term }); 79 | } else { 80 | const queryBuilder = this.productRepository.createQueryBuilder('prod'); 81 | product = await queryBuilder 82 | .where('UPPER(title) =:title or slug =:slug', { 83 | title: term.toUpperCase(), 84 | slug: term.toLowerCase(), 85 | }) 86 | .leftJoinAndSelect('prod.images','prodImages') 87 | .getOne(); 88 | } 89 | 90 | 91 | if ( !product ) 92 | throw new NotFoundException(`Product with ${ term } not found`); 93 | 94 | return product; 95 | } 96 | 97 | async findOnePlain( term: string ) { 98 | const { images = [], ...rest } = await this.findOne( term ); 99 | return { 100 | ...rest, 101 | images: images.map( image => image.url ) 102 | } 103 | } 104 | 105 | 106 | 107 | async update( id: string, updateProductDto: UpdateProductDto, user: User ) { 108 | 109 | const { images, ...toUpdate } = updateProductDto; 110 | 111 | 112 | const product = await this.productRepository.preload({ id, ...toUpdate }); 113 | 114 | if ( !product ) throw new NotFoundException(`Product with id: ${ id } not found`); 115 | 116 | // Create query runner 117 | const queryRunner = this.dataSource.createQueryRunner(); 118 | await queryRunner.connect(); 119 | await queryRunner.startTransaction(); 120 | 121 | try { 122 | 123 | if( images ) { 124 | await queryRunner.manager.delete( ProductImage, { product: { id } }); 125 | 126 | product.images = images.map( 127 | image => this.productImageRepository.create({ url: image }) 128 | ) 129 | } 130 | 131 | // await this.productRepository.save( product ); 132 | product.user = user; 133 | 134 | await queryRunner.manager.save( product ); 135 | 136 | await queryRunner.commitTransaction(); 137 | await queryRunner.release(); 138 | 139 | return this.findOnePlain( id ); 140 | 141 | } catch (error) { 142 | 143 | await queryRunner.rollbackTransaction(); 144 | await queryRunner.release(); 145 | this.handleDBExceptions(error); 146 | } 147 | 148 | } 149 | 150 | async remove(id: string) { 151 | const product = await this.findOne( id ); 152 | await this.productRepository.remove( product ); 153 | 154 | } 155 | 156 | 157 | private handleDBExceptions( error: any ) { 158 | 159 | if ( error.code === '23505' ) 160 | throw new BadRequestException(error.detail); 161 | 162 | this.logger.error(error) 163 | // console.log(error) 164 | throw new InternalServerErrorException('Unexpected error, check server logs'); 165 | 166 | } 167 | 168 | async deleteAllProducts() { 169 | const query = this.productRepository.createQueryBuilder('product'); 170 | 171 | try { 172 | return await query 173 | .delete() 174 | .where({}) 175 | .execute(); 176 | 177 | } catch (error) { 178 | this.handleDBExceptions(error); 179 | } 180 | 181 | } 182 | 183 | } 184 | -------------------------------------------------------------------------------- /src/seed/data/seed-data.ts: -------------------------------------------------------------------------------- 1 | import * as bcrypt from 'bcryptjs'; 2 | 3 | interface SeedProduct { 4 | description: string; 5 | images: string[]; 6 | stock: number; 7 | price: number; 8 | sizes: ValidSizes[]; 9 | slug: string; 10 | tags: string[]; 11 | title: string; 12 | type: ValidTypes; 13 | gender: 'men'|'women'|'kid'|'unisex' 14 | } 15 | 16 | type ValidSizes = 'XS'|'S'|'M'|'L'|'XL'|'XXL'|'XXXL'; 17 | type ValidTypes = 'shirts'|'pants'|'hoodies'|'hats'; 18 | 19 | interface SeedUser { 20 | email: string; 21 | fullName: string; 22 | password: string; 23 | roles: string[]; 24 | } 25 | 26 | 27 | interface SeedData { 28 | users: SeedUser[]; 29 | products: SeedProduct[]; 30 | } 31 | 32 | 33 | export const initialData: SeedData = { 34 | 35 | users: [ 36 | { 37 | email: 'test1@google.com', 38 | fullName: 'Test One', 39 | password: bcrypt.hashSync( 'Abc123', 10 ), 40 | roles: ['admin'] 41 | }, 42 | { 43 | email: 'test2@google.com', 44 | fullName: 'Test Two', 45 | password: bcrypt.hashSync( 'Abc123', 10 ), 46 | roles: ['user','super'] 47 | } 48 | ], 49 | 50 | products: [ 51 | { 52 | description: "Introducing the Tesla Chill Collection. The Men’s Chill Crew Neck Sweatshirt has a premium, heavyweight exterior and soft fleece interior for comfort in any season. The sweatshirt features a subtle thermoplastic polyurethane T logo on the chest and a Tesla wordmark below the back collar. Made from 60% cotton and 40% recycled polyester.", 53 | images: [ 54 | '1740176-00-A_0_2000.jpg', 55 | '1740176-00-A_1.jpg', 56 | ], 57 | stock: 7, 58 | price: 75, 59 | sizes: ['XS','S','M','L','XL','XXL'], 60 | slug: "mens_chill_crew_neck_sweatshirt", 61 | type: 'shirts', 62 | tags: ['sweatshirt'], 63 | title: "Men’s Chill Crew Neck Sweatshirt", 64 | gender: 'men' 65 | }, 66 | { 67 | description: "The Men's Quilted Shirt Jacket features a uniquely fit, quilted design for warmth and mobility in cold weather seasons. With an overall street-smart aesthetic, the jacket features subtle silicone injected Tesla logos below the back collar and on the right sleeve, as well as custom matte metal zipper pulls. Made from 87% nylon and 13% polyurethane.", 68 | images: [ 69 | '1740507-00-A_0_2000.jpg', 70 | '1740507-00-A_1.jpg', 71 | ], 72 | stock: 5, 73 | price: 200, 74 | sizes: ['XS','S','M','XL','XXL'], 75 | slug: "men_quilted_shirt_jacket", 76 | type: 'shirts', 77 | tags: ['jacket'], 78 | title: "Men's Quilted Shirt Jacket", 79 | gender: 'men' 80 | }, 81 | 82 | { 83 | description: "Introducing the Tesla Raven Collection. The Men's Raven Lightweight Zip Up Bomber has a premium, modern silhouette made from a sustainable bamboo cotton blend for versatility in any season. The hoodie features subtle thermoplastic polyurethane Tesla logos on the left chest and below the back collar, a concealed chest pocket with custom matte zipper pulls and a french terry interior. Made from 70% bamboo and 30% cotton.", 84 | images: [ 85 | '1740250-00-A_0_2000.jpg', 86 | '1740250-00-A_1.jpg' 87 | ], 88 | stock: 10, 89 | price: 130, 90 | sizes: ['S','M','L','XL','XXL'], 91 | slug: "men_raven_lightweight_zip_up_bomber_jacket", 92 | type: 'shirts', 93 | tags: ['shirt'], 94 | title: "Men's Raven Lightweight Zip Up Bomber Jacket", 95 | gender: 'men' 96 | }, 97 | 98 | { 99 | description: "Introducing the Tesla Turbine Collection. Designed for style, comfort and everyday lifestyle, the Men's Turbine Long Sleeve Tee features a subtle, water-based T logo on the left chest and our Tesla wordmark below the back collar. The lightweight material is double-dyed, creating a soft, casual style for ideal wear in any season. Made from 50% cotton and 50% polyester.", 100 | images: [ 101 | '1740280-00-A_0_2000.jpg', 102 | '1740280-00-A_1.jpg', 103 | ], 104 | stock: 50, 105 | price: 45, 106 | sizes: ['XS','S','M','L'], 107 | slug: "men_turbine_long_sleeve_tee", 108 | type: 'shirts', 109 | tags: ['shirt'], 110 | title: "Men's Turbine Long Sleeve Tee", 111 | gender: 'men' 112 | }, 113 | { 114 | description: "Introducing the Tesla Turbine Collection. Designed for style, comfort and everyday lifestyle, the Men's Turbine Short Sleeve Tee features a subtle, water-based Tesla wordmark across the chest and our T logo below the back collar. The lightweight material is double-dyed, creating a soft, casual style for ideal wear in any season. Made from 50% cotton and 50% polyester.", 115 | images: [ 116 | '1741416-00-A_0_2000.jpg', 117 | '1741416-00-A_1.jpg', 118 | ], 119 | stock: 50, 120 | price: 40, 121 | sizes: ['M','L','XL','XXL'], 122 | slug: "men_turbine_short_sleeve_tee", 123 | type: 'shirts', 124 | tags: ['shirt'], 125 | title: "Men's Turbine Short Sleeve Tee", 126 | gender: 'men' 127 | }, 128 | { 129 | description: "Designed for comfort, the Cybertruck Owl Tee is made from 100% cotton and features our signature Cybertruck icon on the back.", 130 | images: [ 131 | '7654393-00-A_2_2000.jpg', 132 | '7654393-00-A_3.jpg', 133 | ], 134 | stock: 0, 135 | price: 35, 136 | sizes: ['M','L','XL','XXL'], 137 | slug: "men_cybertruck_owl_tee", 138 | type: 'shirts', 139 | tags: ['shirt'], 140 | title: "Men's Cybertruck Owl Tee", 141 | gender: 'men' 142 | }, 143 | { 144 | description: "Inspired by our fully integrated home solar and storage system, the Tesla Solar Roof Tee advocates for clean, sustainable energy wherever you go. Designed for fit, comfort and style, the tee features an aerial view of our seamless Solar Roof design on the front with our signature T logo above 'Solar Roof' on the back. Made from 100% Peruvian cotton.", 145 | images: [ 146 | '1703767-00-A_0_2000.jpg', 147 | '1703767-00-A_1.jpg', 148 | ], 149 | stock: 15, 150 | price: 35, 151 | sizes: ['S','M','L','XL'], 152 | slug: "men_solar_roof_tee", 153 | type: 'shirts', 154 | tags: ['shirt'], 155 | title: "Men's Solar Roof Tee", 156 | gender: 'men' 157 | }, 158 | { 159 | description: "Inspired by the world’s most unlimited resource, the Let the Sun Shine Tee highlights our fully integrated home solar and storage system. Designed for fit, comfort and style, the tee features a sunset graphic along with our Tesla wordmark on the front and our signature T logo printed above 'Solar Roof' on the back. Made from 100% Peruvian cotton.", 160 | images: [ 161 | '1700280-00-A_0_2000.jpg', 162 | '1700280-00-A_1.jpg', 163 | ], 164 | stock: 17, 165 | price: 35, 166 | sizes: ['XS','S','XL','XXL'], 167 | slug: "men_let_the_sun_shine_tee", 168 | type: 'shirts', 169 | tags: ['shirt'], 170 | title: "Men's Let the Sun Shine Tee", 171 | gender: 'men' 172 | }, 173 | { 174 | description: "Designed for fit, comfort and style, the Men's 3D Large Wordmark Tee is made from 100% Peruvian cotton with a 3D silicone-printed Tesla wordmark printed across the chest.", 175 | images: [ 176 | '8764734-00-A_0_2000.jpg', 177 | '8764734-00-A_1.jpg', 178 | ], 179 | stock: 12, 180 | price: 35, 181 | sizes: ['XS','S','M'], 182 | slug: "men_3d_large_wordmark_tee", 183 | type: 'shirts', 184 | tags: ['shirt'], 185 | title: "Men's 3D Large Wordmark Tee", 186 | gender: 'men' 187 | }, 188 | { 189 | description: "Designed for fit, comfort and style, the Tesla T Logo Tee is made from 100% Peruvian cotton and features a silicone-printed T Logo on the left chest.", 190 | images: [ 191 | '7652426-00-A_0_2000.jpg', 192 | '7652426-00-A_1.jpg', 193 | ], 194 | stock: 5, 195 | price: 35, 196 | sizes: ['XS','S'], 197 | slug: "men_3d_t_logo_tee", 198 | type: 'shirts', 199 | tags: ['shirt'], 200 | title: "Men's 3D T Logo Tee", 201 | gender: 'men' 202 | }, 203 | { 204 | description: "Designed for comfort and style in any size, the Tesla Small Wordmark Tee is made from 100% Peruvian cotton and features a 3D silicone-printed wordmark on the left chest.", 205 | images: [ 206 | '8528839-00-A_0_2000.jpg', 207 | '8528839-00-A_2.jpg', 208 | ], 209 | stock: 2, 210 | price: 35, 211 | sizes: ['XS','S','M'], 212 | slug: "men_3d_small_wordmark_tee", 213 | type: 'shirts', 214 | tags: ['shirt'], 215 | title: "Men’s 3D Small Wordmark Tee", 216 | gender: 'men' 217 | }, 218 | { 219 | description: "Designed to celebrate Tesla's incredible performance mode, the Plaid Mode Tee features great fit, comfort and style. Made from 100% cotton, it's the next best thing to riding shotgun at the Nürburgring.", 220 | images: [ 221 | '1549268-00-A_0_2000.jpg', 222 | '1549268-00-A_2.jpg', 223 | ], 224 | stock: 82, 225 | price: 35, 226 | sizes: ['XS','S','M','L','XL','XXL'], 227 | slug: "men_plaid_mode_tee", 228 | type: 'shirts', 229 | tags: ['shirt'], 230 | title: "Men's Plaid Mode Tee", 231 | gender: 'men' 232 | }, 233 | { 234 | description: "Inspired by our popular home battery, the Tesla Powerwall Tee is made from 100% cotton and features the phrase 'Pure Energy' under our signature logo in the back. Designed for fit, comfort and style, the exclusive tee promotes sustainable energy in any environment.", 235 | images: [ 236 | '9877034-00-A_0_2000.jpg', 237 | '9877034-00-A_2.jpg', 238 | ], 239 | stock: 24, 240 | price: 35, 241 | sizes: ['XL','XXL'], 242 | slug: "men_powerwall_tee", 243 | type: 'shirts', 244 | tags: ['shirt'], 245 | title: "Men's Powerwall Tee", 246 | gender: 'men' 247 | }, 248 | { 249 | description: "Inspired by Tesla Battery Day and featuring the unveiled tabless battery cell, Battery Day Tee celebrates the future of energy storage and cell manufacturing. Designed for fit, comfort and style, Battery Day Tee is made from 100% cotton with a stylized cell printed across the chest. Made in Peru.", 250 | images: [ 251 | '1633802-00-A_0_2000.jpg', 252 | '1633802-00-A_2.jpg', 253 | ], 254 | stock: 5, 255 | price: 30, 256 | sizes: ['XS','S','XXL'], 257 | slug: "men_battery_day_tee", 258 | type: 'shirts', 259 | tags: ['shirt'], 260 | title: "Men's Battery Day Tee", 261 | gender: 'men' 262 | }, 263 | { 264 | description: "Designed for exceptional comfort and inspired by the Cybertruck unveil event, the Cybertruck Bulletproof Tee is made from 100% cotton and features our signature Cybertruck icon on the back.", 265 | images: [ 266 | '7654399-00-A_0_2000.jpg', 267 | '7654399-00-A_1.jpg', 268 | ], 269 | stock: 150, 270 | price: 30, 271 | sizes: ['M','L'], 272 | slug: "men_cybertruck_bulletproof_tee", 273 | type: 'shirts', 274 | tags: ['shirt'], 275 | title: "Men’s Cybertruck Bulletproof Tee", 276 | gender: 'men' 277 | }, 278 | { 279 | description: "Inspired by the Model Y order confirmation graphic, the limited edition Haha Yes Tee is designed for comfort and style. Made from 100% Peruvian cotton and featuring the Tesla wordmark across the chest, the exclusive tee will commemorate your order for years to come.", 280 | images: [ 281 | '7652410-00-A_0.jpg', 282 | '7652410-00-A_1_2000.jpg', 283 | ], 284 | stock: 10, 285 | price: 35, 286 | sizes: ['XS','S','M','L','XL','XXL'], 287 | slug: "men_haha_yes_tee", 288 | type: 'shirts', 289 | tags: ['shirt'], 290 | title: "Men's Haha Yes Tee", 291 | gender: 'men' 292 | }, 293 | { 294 | description: "Designed for fit, comfort and style, the limited edition S3XY Tee is made from 100% cotton with a 3D silicone-printed “S3XY” logo across the chest. Made in Peru. Available in black.", 295 | images: [ 296 | '8764600-00-A_0_2000.jpg', 297 | '8764600-00-A_2.jpg', 298 | ], 299 | stock: 34, 300 | price: 35, 301 | sizes: ['XS','S','M','L'], 302 | slug: "men_s3xy_tee", 303 | type: 'shirts', 304 | tags: ['shirt'], 305 | title: "Men's S3XY Tee", 306 | gender: 'men' 307 | }, 308 | { 309 | description: "Designed for fit, comfort and style, the Men's 3D Wordmark Long Sleeve Tee is made from 100% cotton and features an understated wordmark logo on the left chest.", 310 | images: [ 311 | '8764813-00-A_0_2000.jpg', 312 | '8764813-00-A_1.jpg', 313 | ], 314 | stock: 15, 315 | price: 40, 316 | sizes: ['XL','XXL'], 317 | slug: "men_3d_wordmark_long_sleeve_tee", 318 | type: 'shirts', 319 | tags: ['shirt'], 320 | title: "Men's 3D Wordmark Long Sleeve Tee", 321 | gender: 'men' 322 | }, 323 | { 324 | description: "Designed for fit, comfort and style, the Men's 3D T Logo Long Sleeve Tee is made from 100% cotton and features an understated T logo on the left chest.", 325 | images: [ 326 | '8529198-00-A_0_2000.jpg', 327 | '8529198-00-A_1.jpg', 328 | ], 329 | stock: 12, 330 | price: 40, 331 | sizes: ['XS','XXL'], 332 | slug: "men_3d_t_logo_long_sleeve_tee", 333 | type: 'shirts', 334 | tags: ['shirt'], 335 | title: "Men's 3D T Logo Long Sleeve Tee", 336 | gender: 'men' 337 | }, 338 | { 339 | description: "Introducing the Tesla Raven Collection. The Men's Raven Lightweight Hoodie has a premium, relaxed silhouette made from a sustainable bamboo cotton blend. The hoodie features subtle thermoplastic polyurethane Tesla logos across the chest and on the sleeve with a french terry interior for versatility in any season. Made from 70% bamboo and 30% cotton.", 340 | images: [ 341 | '1740245-00-A_0_2000.jpg', 342 | '1740245-00-A_1.jpg', 343 | ], 344 | stock: 10, 345 | price: 115, 346 | sizes: ['XS','S','M','L','XL','XXL'], 347 | slug: "men_raven_lightweight_hoodie", 348 | type: 'hoodies', 349 | tags: ['hoodie'], 350 | title: "Men's Raven Lightweight Hoodie", 351 | gender: 'men' 352 | }, 353 | { 354 | description: "Introducing the Tesla Chill Collection. The Chill Pullover Hoodie has a premium, heavyweight exterior and soft fleece interior for comfort in any season. The unisex hoodie features subtle thermoplastic polyurethane Tesla logos across the chest and on the sleeve, a double layer single seam hood and pockets with custom matte zipper pulls. Made from 60% cotton and 40% recycled polyester.", 355 | images: [ 356 | '1740051-00-A_0_2000.jpg', 357 | '1740051-00-A_1.jpg', 358 | ], 359 | stock: 10, 360 | price: 130, 361 | sizes: ['XS','S','M','L','XL','XXL'], 362 | slug: "chill_pullover_hoodie", 363 | type: 'hoodies', 364 | tags: ['hoodie'], 365 | title: "Chill Pullover Hoodie", 366 | gender: 'unisex' 367 | }, 368 | { 369 | description: "Introducing the Tesla Chill Collection. The Men's Chill Full Zip Hoodie has a premium, heavyweight exterior and soft fleece interior for comfort in any season. The hoodie features subtle thermoplastic polyurethane Tesla logos on the left chest and sleeve, a double layer single seam hood and pockets with custom matte zipper pulls. Made from 60% cotton and 40% recycled polyester.", 370 | images: [ 371 | '1741111-00-A_0_2000.jpg', 372 | '1741111-00-A_1.jpg', 373 | ], 374 | stock: 100, 375 | price: 85, 376 | sizes: ['XS','L','XL','XXL'], 377 | slug: "men_chill_full_zip_hoodie", 378 | type: 'shirts', 379 | tags: ['shirt'], 380 | title: "Men's Chill Full Zip Hoodie", 381 | gender: 'men' 382 | }, 383 | { 384 | description: "Introducing the Tesla Chill Collection. The Men’s Chill Quarter Zip Pullover has a premium, heavyweight exterior and soft fleece interior for comfort in any season. The pullover features subtle thermoplastic polyurethane Tesla logos on the left chest and below the back collar, as well as a custom matte zipper pull. Made from 60% cotton and 40% recycled polyester.", 385 | images: [ 386 | '1740140-00-A_0_2000.jpg', 387 | '1740140-00-A_1.jpg', 388 | ], 389 | stock: 7, 390 | price: 85, 391 | sizes: ['XS','S','M'], 392 | slug: "men_chill_quarter_zip_pullover_-_gray", 393 | type: 'shirts', 394 | tags: ['shirt'], 395 | title: "Men's Chill Quarter Zip Pullover - Gray", 396 | gender: 'men' 397 | }, 398 | { 399 | description: "Introducing the Tesla Chill Collection. The Men’s Chill Quarter Zip Pullover has a premium, heavyweight exterior and soft fleece interior for comfort in any season. The pullover features subtle thermoplastic polyurethane Tesla logos on the left chest and below the back collar, as well as a custom matte zipper pull. Made from 60% cotton and 40% recycled polyester.", 400 | images: [ 401 | '1740145-00-A_2_2000.jpg', 402 | '1740145-00-A_1.jpg', 403 | ], 404 | stock: 15, 405 | price: 85, 406 | sizes: ['XS','S','M','L'], 407 | slug: "men_chill_quarter_zip_pullover_-_white", 408 | type: 'shirts', 409 | tags: ['shirt'], 410 | title: "Men's Chill Quarter Zip Pullover - White", 411 | gender: 'men' 412 | }, 413 | { 414 | description: "The Unisex 3D Large Wordmark Pullover Hoodie features soft fleece and an adjustable, jersey-lined hood for comfort and coverage. Designed in a unisex style, the pullover hoodie includes a tone-on-tone 3D silicone-printed wordmark across the chest.", 415 | images: [ 416 | '8529107-00-A_0_2000.jpg', 417 | '8529107-00-A_1.jpg', 418 | ], 419 | stock: 15, 420 | price: 70, 421 | sizes: ['XS','S','XL','XXL'], 422 | slug: "3d_large_wordmark_pullover_hoodie", 423 | type: 'hoodies', 424 | tags: ['hoodie'], 425 | title: "3D Large Wordmark Pullover Hoodie", 426 | gender: 'unisex' 427 | }, 428 | { 429 | description: "As with the iconic Tesla logo, the Cybertruck Graffiti Hoodie is a classic in the making. Unisex style featuring soft fleece and an adjustable, jersey-lined hood for comfortable coverage.", 430 | images: [ 431 | '7654420-00-A_0_2000.jpg', 432 | '7654420-00-A_1_2000.jpg', 433 | ], 434 | stock: 13, 435 | price: 60, 436 | sizes: ['XS','S','M','L','XL','XXL'], 437 | slug: "cybertruck_graffiti_hoodie", 438 | type: 'hoodies', 439 | tags: ['hoodie'], 440 | title: "Cybertruck Graffiti Hoodie", 441 | gender: 'unisex' 442 | }, 443 | { 444 | description: "The Relaxed T Logo Hat is a classic silhouette combined with modern details, featuring a 3D T logo and a custom metal buckle closure. The ultrasoft design is flexible and abrasion resistant, while the inner sweatband includes quilted padding for extra comfort and moisture wicking. The visor is fully made from recycled plastic bottles. 100% Cotton.", 445 | images: [ 446 | '1657932-00-A_0_2000.jpg', 447 | '1657932-00-A_1.jpg', 448 | ], 449 | stock: 11, 450 | price: 30, 451 | sizes: ['XS','S','M','L','XL','XXL'], 452 | slug: "relaxed_t_logo_hat", 453 | type: 'hats', 454 | tags: ['hats'], 455 | title: "Relaxed T Logo Hat", 456 | gender: 'unisex' 457 | }, 458 | { 459 | description: "The Relaxed T Logo Hat is a classic silhouette combined with modern details, featuring a 3D T logo and a custom metal buckle closure. The ultrasoft design is flexible and abrasion resistant, while the inner sweatband includes quilted padding for extra comfort and moisture wicking. The visor is fully made from recycled plastic bottles. 100% Cotton.", 460 | images: [ 461 | '1740417-00-A_0_2000.jpg', 462 | '1740417-00-A_1.jpg', 463 | ], 464 | stock: 13, 465 | price: 35, 466 | sizes: ['XS','S','M','L','XL','XXL'], 467 | slug: "thermal_cuffed_beanie", 468 | type: 'hats', 469 | tags: ['hats'], 470 | title: "Thermal Cuffed Beanie", 471 | gender: 'unisex' 472 | }, 473 | { 474 | description: "The Women's Cropped Puffer Jacket features a uniquely cropped silhouette for the perfect, modern style while on the go during the cozy season ahead. The puffer features subtle silicone injected Tesla logos below the back collar and on the right sleeve, custom matte metal zipper pulls and a soft, fleece lined collar. Made from 87% nylon and 13% polyurethane.", 475 | images: [ 476 | '1740535-00-A_0_2000.jpg', 477 | '1740535-00-A_1.jpg', 478 | ], 479 | stock: 85, 480 | price: 225, 481 | sizes: ['XS','S','M'], 482 | slug: "women_cropped_puffer_jacket", 483 | type: 'hoodies', 484 | tags: ['hoodie'], 485 | title: "Women's Cropped Puffer Jacket", 486 | gender: 'women' 487 | }, 488 | { 489 | description: "Introducing the Tesla Chill Collection. The Women's Chill Half Zip Cropped Hoodie has a premium, soft fleece exterior and cropped silhouette for comfort in everyday lifestyle. The hoodie features an elastic hem that gathers at the waist, subtle thermoplastic polyurethane Tesla logos along the hood and on the sleeve, a double layer single seam hood and a custom ring zipper pull. Made from 60% cotton and 40% recycled polyester.", 490 | images: [ 491 | '1740226-00-A_0_2000.jpg', 492 | '1740226-00-A_1.jpg', 493 | ], 494 | stock: 10, 495 | price: 130, 496 | sizes: ['XS','S','M','XXL'], 497 | slug: "women_chill_half_zip_cropped_hoodie", 498 | type: 'hoodies', 499 | tags: ['hoodie'], 500 | title: "Women's Chill Half Zip Cropped Hoodie", 501 | gender: 'women' 502 | }, 503 | { 504 | description: "Introducing the Tesla Raven Collection. The Women's Raven Slouchy Crew Sweatshirt has a premium, relaxed silhouette made from a sustainable bamboo cotton blend. The slouchy crew features a subtle thermoplastic polyurethane Tesla wordmark on the left sleeve and a french terry interior for a cozy look and feel in every season. Pair it with your Raven Joggers or favorite on the go fit. Made from 70% bamboo and 30% cotton.", 505 | images: [ 506 | '1740260-00-A_0_2000.jpg', 507 | '1740260-00-A_1.jpg', 508 | ], 509 | stock: 9, 510 | price: 110, 511 | sizes: ['XS','S','M','L','XL','XXL'], 512 | slug: "women_raven_slouchy_crew_sweatshirt", 513 | type: 'hoodies', 514 | tags: ['hoodie'], 515 | title: "Women's Raven Slouchy Crew Sweatshirt", 516 | gender: 'women' 517 | }, 518 | { 519 | description: "Introducing the Tesla Turbine Collection. Designed for style, comfort and everyday lifestyle, the Women's Turbine Cropped Long Sleeve Tee features a subtle, water-based Tesla wordmark across the chest and our T logo below the back collar. The lightweight material is double-dyed, creating a soft, casual style with a cropped silhouette. Made from 50% cotton and 50%", 520 | images: [ 521 | '1740290-00-A_0_2000.jpg', 522 | '1740290-00-A_1.jpg', 523 | ], 524 | stock: 10, 525 | price: 45, 526 | sizes: ['XS','S','M','L','XL','XXL'], 527 | slug: "women_turbine_cropped_long_sleeve_tee", 528 | type: 'shirts', 529 | tags: ['shirt'], 530 | title: "Women's Turbine Cropped Long Sleeve Tee", 531 | gender: 'women' 532 | }, 533 | { 534 | description: "ntroducing the Tesla Turbine Collection. Designed for style, comfort and everyday lifestyle, the Women's Turbine Cropped Short Sleeve Tee features a subtle, water-based Tesla wordmark across the chest and our T logo below the back collar. The lightweight material is double-dyed, creating a soft, casual style with a cropped silhouette. Made from 50% cotton and 50% polyester.", 535 | images: [ 536 | '1741441-00-A_0_2000.jpg', 537 | '1741441-00-A_1.jpg', 538 | ], 539 | stock: 0, 540 | price: 40, 541 | sizes: ['XS','S'], 542 | slug: "women_turbine_cropped_short_sleeve_tee", 543 | type: 'shirts', 544 | tags: ['shirt'], 545 | title: "Women's Turbine Cropped Short Sleeve Tee", 546 | gender: 'women' 547 | }, 548 | { 549 | description: "Designed for style and comfort, the ultrasoft Women's T Logo Short Sleeve Scoop Neck Tee features a tonal 3D silicone-printed T logo on the left chest. Made of 50% Peruvian cotton and 50% Peruvian viscose.", 550 | images: [ 551 | '8765090-00-A_0_2000.jpg', 552 | '8765090-00-A_1.jpg', 553 | ], 554 | stock: 30, 555 | price: 35, 556 | sizes: ['XS','S','M','L','XL','XXL'], 557 | slug: "women_t_logo_short_sleeve_scoop_neck_tee", 558 | type: 'shirts', 559 | tags: ['shirt'], 560 | title: "Women's T Logo Short Sleeve Scoop Neck Tee", 561 | gender: 'women' 562 | }, 563 | { 564 | description: "Designed for style and comfort, the ultrasoft Women's T Logo Long Sleeve Scoop Neck Tee features a tonal 3D silicone-printed T logo on the left chest. Made of 50% Peruvian cotton and 50% Peruvian viscose.", 565 | images: [ 566 | '8765100-00-A_0_2000.jpg', 567 | '8765100-00-A_1.jpg', 568 | ], 569 | stock: 16, 570 | price: 40, 571 | sizes: ['XS','S','L','XL','XXL'], 572 | slug: "women_t_logo_long_sleeve_scoop_neck_tee", 573 | type: 'shirts', 574 | tags: ['shirt'], 575 | title: "Women's T Logo Long Sleeve Scoop Neck Tee", 576 | gender: 'women' 577 | }, 578 | { 579 | description: "Designed for style and comfort, the Women's Small Wordmark Short Sleeve V-Neck Tee features a tonal 3D silicone-printed wordmark on the left chest. Made of 100% Peruvian cotton.", 580 | images: [ 581 | '8765120-00-A_0_2000.jpg', 582 | '8765120-00-A_1.jpg', 583 | ], 584 | stock: 18, 585 | price: 35, 586 | sizes: ['XS','S','M','L','XL','XXL'], 587 | slug: "women_small_wordmark_short_sleeve_v-neck_tee", 588 | type: 'shirts', 589 | tags: ['shirt'], 590 | title: "Women's Small Wordmark Short Sleeve V-Neck Tee", 591 | gender: 'women' 592 | }, 593 | { 594 | description: "Designed for style and comfort, the Women's Large Wordmark Short Sleeve Crew Neck Tee features a tonal 3D silicone-printed wordmark across the chest. Made of 100% Peruvian pima cotton.", 595 | images: [ 596 | '8765115-00-A_0_2000.jpg', 597 | '8765115-00-A_1.jpg', 598 | ], 599 | stock: 5, 600 | price: 35, 601 | sizes: ['XL','XXL'], 602 | slug: "women_large_wordmark_short_sleeve_crew_neck_tee", 603 | type: 'shirts', 604 | tags: ['shirt'], 605 | title: "Women's Large Wordmark Short Sleeve Crew Neck Tee", 606 | gender: 'women' 607 | }, 608 | { 609 | description: "Designed to celebrate Tesla's incredible performance mode, the Plaid Mode Tee features great fit, comfort and style. Made from 100% cotton, it's the next best thing to riding shotgun at the Nürburgring.", 610 | images: [ 611 | '1549275-00-A_0_2000.jpg', 612 | '1549275-00-A_1.jpg', 613 | ], 614 | stock: 16, 615 | price: 35, 616 | sizes: ['S','M'], 617 | slug: "women_plaid_mode_tee", 618 | type: 'shirts', 619 | tags: ['shirt'], 620 | title: "Women's Plaid Mode Tee", 621 | gender: 'women' 622 | }, 623 | { 624 | description: "Inspired by our popular home battery, the Tesla Powerwall Tee is made from 100% cotton and features the phrase 'Pure Energy' under our signature logo in the back. Designed for fit, comfort and style, the exclusive tee promotes sustainable energy in any", 625 | images: [ 626 | '9877040-00-A_0_2000.jpg', 627 | '9877040-00-A_1.jpg', 628 | ], 629 | stock: 10, 630 | price: 130, 631 | sizes: ['XS','S','M','L','XL','XXL'], 632 | slug: "women_powerwall_tee", 633 | type: 'shirts', 634 | tags: ['shirt'], 635 | title: "Women’s Powerwall Tee", 636 | gender: 'women' 637 | }, 638 | { 639 | description: "Fully customized and uniquely styled, the Women's Corp Jacket features a silicone-printed 'T' logo on the left chest and prominent Tesla wordmark across the back.", 640 | images: [ 641 | '5645680-00-A_0_2000.jpg', 642 | '5645680-00-A_3.jpg', 643 | ], 644 | stock: 3, 645 | price: 90, 646 | sizes: ['M','L','XL','XXL'], 647 | slug: "women_corp_jacket", 648 | type: 'shirts', 649 | tags: ['shirt'], 650 | title: "Women's Corp Jacket", 651 | gender: 'women' 652 | }, 653 | { 654 | description: "Introducing the Tesla Raven Collection. The Women's Raven Joggers have a premium, relaxed silhouette made from a sustainable bamboo cotton blend. The joggers feature a subtle thermoplastic polyurethane Tesla wordmark and T logo and a french terry interior for a cozy look and feel in every season. Pair them with your Raven Slouchy Crew Sweatshirt, Raven Lightweight Zip Up Jacket or other favorite on the go fit. Made from 70% bamboo and 30% cotton.", 655 | images: [ 656 | '1740270-00-A_0_2000.jpg', 657 | '1740270-00-A_1.jpg', 658 | ], 659 | stock: 162, 660 | price: 100, 661 | sizes: ['XS','S','M','L','XL','XXL'], 662 | slug: "women_raven_joggers", 663 | type: 'shirts', 664 | tags: ['shirt'], 665 | title: "Women's Raven Joggers", 666 | gender: 'women' 667 | }, 668 | { 669 | description: "Designed for fit, comfort and style, the Kids Cybertruck Graffiti Long Sleeve Tee features a water-based Cybertruck graffiti wordmark across the chest, a Tesla wordmark down the left arm and our signature T logo on the back collar. Made from 50% cotton and 50% polyester.", 670 | images: [ 671 | '1742694-00-A_1_2000.jpg', 672 | '1742694-00-A_3.jpg', 673 | ], 674 | stock: 10, 675 | price: 30, 676 | sizes: ['XS','S','M'], 677 | slug: "kids_cybertruck_long_sleeve_tee", 678 | type: 'shirts', 679 | tags: ['shirt'], 680 | title: "Kids Cybertruck Long Sleeve Tee", 681 | gender: 'kid' 682 | }, 683 | { 684 | description: "The Kids Scribble T Logo Tee is made from 100% Peruvian cotton and features a Tesla T sketched logo for every young artist to wear.", 685 | images: [ 686 | '8529312-00-A_0_2000.jpg', 687 | '8529312-00-A_1.jpg', 688 | ], 689 | stock: 0, 690 | price: 25, 691 | sizes: ['XS','S','M'], 692 | slug: "kids_scribble_t_logo_tee", 693 | type: 'shirts', 694 | tags: ['shirt'], 695 | title: "Kids Scribble T Logo Tee", 696 | gender: 'kid' 697 | }, 698 | { 699 | description: "The Kids Cybertruck Tee features the iconic Cybertruck graffiti wordmark and is made from 100% Peruvian cotton for maximum comfort.", 700 | images: [ 701 | '8529342-00-A_0_2000.jpg', 702 | '8529342-00-A_1.jpg', 703 | ], 704 | stock: 10, 705 | price: 25, 706 | sizes: ['XS','S','M'], 707 | slug: "kids_cybertruck_tee", 708 | type: 'shirts', 709 | tags: ['shirt'], 710 | title: "Kids Cybertruck Tee", 711 | gender: 'kid' 712 | }, 713 | { 714 | description: "The refreshed Kids Racing Stripe Tee is made from 100% Peruvian cotton, featuring a newly enhanced racing stripe with a brushed Tesla wordmark that's perfect for any speed racer.", 715 | images: [ 716 | '8529354-00-A_0_2000.jpg', 717 | '8529354-00-A_1.jpg', 718 | ], 719 | stock: 10, 720 | price: 30, 721 | sizes: ['XS','S','M'], 722 | slug: "kids_racing_stripe_tee", 723 | type: 'shirts', 724 | tags: ['shirt'], 725 | title: "Kids Racing Stripe Tee", 726 | gender: 'kid' 727 | }, 728 | { 729 | description: "Designed for fit, comfort and style, the Tesla T Logo Tee is made from 100% Peruvian cotton and features a silicone-printed T Logo on the left chest.", 730 | images: [ 731 | '7652465-00-A_0_2000.jpg', 732 | '7652465-00-A_1.jpg', 733 | ], 734 | stock: 10, 735 | price: 30, 736 | sizes: ['XS','S','M'], 737 | slug: "kids_3d_t_logo_tee", 738 | type: 'shirts', 739 | tags: ['shirt'], 740 | title: "Kids 3D T Logo Tee", 741 | gender: 'kid' 742 | }, 743 | { 744 | description: "The checkered tee is made from long grain, GMO free Peruvian cotton. Peru is the only country in the world where cotton is picked by hand on a large scale. The 4,500-year-old tradition prevents damage to the fiber during the picking process and removes the need to use chemicals to open the cotton plants before harvest. This environmentally friendly process results in cotton that is soft, strong, and lustrous – and the tee will get even softer with every wash.", 745 | images: [ 746 | '100042307_0_2000.jpg', 747 | '100042307_alt_2000.jpg', 748 | ], 749 | stock: 10, 750 | price: 30, 751 | sizes: ['XS','S','M'], 752 | slug: "kids_checkered_tee", 753 | type: 'shirts', 754 | tags: ['shirt'], 755 | title: "Kids Checkered Tee", 756 | gender: 'kid' 757 | }, 758 | { 759 | description: "For the future space traveler with discerning taste, a soft, cotton onesie with snap closure bottom. Clear labeling provided in case of contact with a new spacefaring civilization. 100% Cotton. Made in Peru", 760 | images: [ 761 | '1473809-00-A_1_2000.jpg', 762 | '1473809-00-A_alt.jpg', 763 | ], 764 | stock: 16, 765 | price: 25, 766 | sizes: ['XS','S'], 767 | slug: "made_on_earth_by_humans_onesie", 768 | type: 'shirts', 769 | tags: ['shirt'], 770 | title: "Made on Earth by Humans Onesie", 771 | gender: 'kid' 772 | }, 773 | { 774 | description: "The Kids Scribble T Logo Onesie is made from 100% Peruvian cotton and features a Tesla T sketched logo for every little artist to wear.", 775 | images: [ 776 | '8529387-00-A_0_2000.jpg', 777 | '8529387-00-A_1.jpg', 778 | ], 779 | stock: 0, 780 | price: 30, 781 | sizes: ['XS','S'], 782 | slug: "scribble_t_logo_onesie", 783 | type: 'shirts', 784 | tags: ['shirt'], 785 | title: "Scribble T Logo Onesie", 786 | gender: 'kid' 787 | }, 788 | { 789 | description: "Show your commitment to sustainable energy with this cheeky onesie for your young one. Note: Does not prevent emissions. 100% Cotton. Made in Peru.", 790 | images: [ 791 | '1473834-00-A_2_2000.jpg', 792 | '1473829-00-A_2_2000.jpg', 793 | ], 794 | stock: 10, 795 | price: 30, 796 | sizes: ['XS','S'], 797 | slug: "zero_emissions_(almost)_onesie", 798 | type: 'shirts', 799 | tags: ['shirt'], 800 | title: "Zero Emissions (Almost) Onesie", 801 | gender: 'kid' 802 | }, 803 | { 804 | description: "Wear your Kids Cyberquad Bomber Jacket during your adventures on Cyberquad for Kids. The bomber jacket features a graffiti-style illustration of our Cyberquad silhouette and wordmark. With three zippered pockets and our signature T logo and Tesla wordmark printed along the sleeves, Kids Cyberquad Bomber Jacket is perfect for wherever the trail takes you. Made from 60% cotton and 40% polyester.", 805 | images: [ 806 | '1742702-00-A_0_2000.jpg', 807 | '1742702-00-A_1.jpg', 808 | ], 809 | stock: 10, 810 | price: 65, 811 | sizes: ['XS','S','M'], 812 | slug: "kids_cyberquad_bomber_jacket", 813 | type: 'shirts', 814 | tags: ['shirt'], 815 | title: "Kids Cyberquad Bomber Jacket", 816 | gender: 'kid' 817 | }, 818 | { 819 | description: "Cruise the playground in style with the Kids Corp Jacket. Modeled after the original Tesla Corp Jacket, the Kids Corp Jacket features the same understated style and high-quality materials but at a pint-sized scale.", 820 | images: [ 821 | '1506211-00-A_0_2000.jpg', 822 | '1506211-00-A_1_2000.jpg', 823 | ], 824 | stock: 10, 825 | price: 30, 826 | sizes: ['XS','S','M'], 827 | slug: "kids_corp_jacket", 828 | type: 'shirts', 829 | tags: ['shirt'], 830 | title: "Kids Corp Jacket", 831 | gender: 'kid' 832 | }, 833 | ] 834 | } -------------------------------------------------------------------------------- /src/seed/seed.controller.ts: -------------------------------------------------------------------------------- 1 | import { Controller, Get, } from '@nestjs/common'; 2 | import { ApiTags } from '@nestjs/swagger'; 3 | 4 | import { ValidRoles } from '../auth/interfaces'; 5 | import { Auth } from '../auth/decorators'; 6 | 7 | import { SeedService } from './seed.service'; 8 | 9 | @ApiTags('Seed') 10 | @Controller('seed') 11 | export class SeedController { 12 | constructor(private readonly seedService: SeedService) {} 13 | 14 | @Get() 15 | // @Auth( ValidRoles.admin ) 16 | executeSeed() { 17 | return this.seedService.runSeed() 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/seed/seed.module.ts: -------------------------------------------------------------------------------- 1 | import { Module } from '@nestjs/common'; 2 | 3 | import { AuthModule } from './../auth/auth.module'; 4 | import { ProductsModule } from './../products/products.module'; 5 | 6 | import { SeedService } from './seed.service'; 7 | import { SeedController } from './seed.controller'; 8 | 9 | @Module({ 10 | controllers: [SeedController], 11 | providers: [SeedService], 12 | imports: [ 13 | ProductsModule, 14 | AuthModule, 15 | ] 16 | }) 17 | export class SeedModule {} 18 | -------------------------------------------------------------------------------- /src/seed/seed.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@nestjs/common'; 2 | import { Repository } from 'typeorm'; 3 | import { InjectRepository } from '@nestjs/typeorm'; 4 | import { ProductsService } from './../products/products.service'; 5 | import { initialData } from './data/seed-data'; 6 | import { User } from '../auth/entities/user.entity'; 7 | 8 | 9 | @Injectable() 10 | export class SeedService { 11 | 12 | constructor( 13 | private readonly productsService: ProductsService, 14 | 15 | @InjectRepository( User ) 16 | private readonly userRepository: Repository 17 | ) {} 18 | 19 | 20 | async runSeed() { 21 | 22 | await this.deleteTables(); 23 | const adminUser = await this.insertUsers(); 24 | 25 | await this.insertNewProducts( adminUser ); 26 | 27 | return 'SEED EXECUTED'; 28 | } 29 | 30 | private async deleteTables() { 31 | 32 | await this.productsService.deleteAllProducts(); 33 | 34 | const queryBuilder = this.userRepository.createQueryBuilder(); 35 | await queryBuilder 36 | .delete() 37 | .where({}) 38 | .execute() 39 | 40 | } 41 | 42 | private async insertUsers() { 43 | 44 | const seedUsers = initialData.users; 45 | 46 | const users: User[] = []; 47 | 48 | seedUsers.forEach( user => { 49 | users.push( this.userRepository.create( user ) ) 50 | }); 51 | 52 | const dbUsers = await this.userRepository.save( seedUsers ) 53 | 54 | return dbUsers[0]; 55 | } 56 | 57 | 58 | private async insertNewProducts( user: User ) { 59 | await this.productsService.deleteAllProducts(); 60 | 61 | const products = initialData.products; 62 | 63 | const insertPromises = []; 64 | 65 | products.forEach( product => { 66 | insertPromises.push( this.productsService.create( product, user ) ); 67 | }); 68 | 69 | await Promise.all( insertPromises ); 70 | 71 | 72 | return true; 73 | } 74 | 75 | 76 | } 77 | -------------------------------------------------------------------------------- /static/products/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/.gitkeep -------------------------------------------------------------------------------- /static/products/100042301_0_2000.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/100042301_0_2000.jpg -------------------------------------------------------------------------------- /static/products/100042301_alt.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/100042301_alt.jpg -------------------------------------------------------------------------------- /static/products/100042307_0_2000.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/100042307_0_2000.jpg -------------------------------------------------------------------------------- /static/products/100042307_1_2000.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/100042307_1_2000.jpg -------------------------------------------------------------------------------- /static/products/100042307_alt.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/100042307_alt.jpg -------------------------------------------------------------------------------- /static/products/100042307_alt_2000.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/100042307_alt_2000.jpg -------------------------------------------------------------------------------- /static/products/1473809-00-A_1_2000.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1473809-00-A_1_2000.jpg -------------------------------------------------------------------------------- /static/products/1473809-00-A_alt.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1473809-00-A_alt.jpg -------------------------------------------------------------------------------- /static/products/1473814-00-A_1_2000.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1473814-00-A_1_2000.jpg -------------------------------------------------------------------------------- /static/products/1473814-00-A_alt.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1473814-00-A_alt.jpg -------------------------------------------------------------------------------- /static/products/1473819-00-A_1_2000.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1473819-00-A_1_2000.jpg -------------------------------------------------------------------------------- /static/products/1473819-00-A_alt.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1473819-00-A_alt.jpg -------------------------------------------------------------------------------- /static/products/1473824-00-A_2_2000.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1473824-00-A_2_2000.jpg -------------------------------------------------------------------------------- /static/products/1473829-00-A_2_2000.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1473829-00-A_2_2000.jpg -------------------------------------------------------------------------------- /static/products/1473834-00-A_2_2000.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1473834-00-A_2_2000.jpg -------------------------------------------------------------------------------- /static/products/1506211-00-A_0_2000.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1506211-00-A_0_2000.jpg -------------------------------------------------------------------------------- /static/products/1506211-00-A_1_2000.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1506211-00-A_1_2000.jpg -------------------------------------------------------------------------------- /static/products/1549268-00-A_0_2000.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1549268-00-A_0_2000.jpg -------------------------------------------------------------------------------- /static/products/1549268-00-A_2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1549268-00-A_2.jpg -------------------------------------------------------------------------------- /static/products/1549275-00-A_0_2000.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1549275-00-A_0_2000.jpg -------------------------------------------------------------------------------- /static/products/1549275-00-A_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1549275-00-A_1.jpg -------------------------------------------------------------------------------- /static/products/1623735-00-A_0_2000.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1623735-00-A_0_2000.jpg -------------------------------------------------------------------------------- /static/products/1623735-00-A_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1623735-00-A_1.jpg -------------------------------------------------------------------------------- /static/products/1623736-00-A_0_2000.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1623736-00-A_0_2000.jpg -------------------------------------------------------------------------------- /static/products/1623736-00-A_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1623736-00-A_1.jpg -------------------------------------------------------------------------------- /static/products/1623739-00-A_0_2000.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1623739-00-A_0_2000.jpg -------------------------------------------------------------------------------- /static/products/1623739-00-A_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1623739-00-A_1.jpg -------------------------------------------------------------------------------- /static/products/1633802-00-A_0_2000.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1633802-00-A_0_2000.jpg -------------------------------------------------------------------------------- /static/products/1633802-00-A_2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1633802-00-A_2.jpg -------------------------------------------------------------------------------- /static/products/1657891-00-A_0_2000.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1657891-00-A_0_2000.jpg -------------------------------------------------------------------------------- /static/products/1657891-00-A_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1657891-00-A_1.jpg -------------------------------------------------------------------------------- /static/products/1657914-00-A_0_2000.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1657914-00-A_0_2000.jpg -------------------------------------------------------------------------------- /static/products/1657914-00-A_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1657914-00-A_1.jpg -------------------------------------------------------------------------------- /static/products/1657915-00-A_0_2000.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1657915-00-A_0_2000.jpg -------------------------------------------------------------------------------- /static/products/1657915-00-A_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1657915-00-A_1.jpg -------------------------------------------------------------------------------- /static/products/1657916-00-A_0_2000.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1657916-00-A_0_2000.jpg -------------------------------------------------------------------------------- /static/products/1657916-00-A_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1657916-00-A_1.jpg -------------------------------------------------------------------------------- /static/products/1657921-00-A_0_2000.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1657921-00-A_0_2000.jpg -------------------------------------------------------------------------------- /static/products/1657921-00-A_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1657921-00-A_1.jpg -------------------------------------------------------------------------------- /static/products/1657931-00-A_0_2000.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1657931-00-A_0_2000.jpg -------------------------------------------------------------------------------- /static/products/1657931-00-A_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1657931-00-A_1.jpg -------------------------------------------------------------------------------- /static/products/1657932-00-A_0_2000.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1657932-00-A_0_2000.jpg -------------------------------------------------------------------------------- /static/products/1657932-00-A_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1657932-00-A_1.jpg -------------------------------------------------------------------------------- /static/products/1657933-00-A_0_2000.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1657933-00-A_0_2000.jpg -------------------------------------------------------------------------------- /static/products/1657933-00-A_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1657933-00-A_1.jpg -------------------------------------------------------------------------------- /static/products/1693862-00-A_0_2000.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1693862-00-A_0_2000.jpg -------------------------------------------------------------------------------- /static/products/1693862-00-A_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1693862-00-A_1.jpg -------------------------------------------------------------------------------- /static/products/1693862-03-A_0_2000.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1693862-03-A_0_2000.jpg -------------------------------------------------------------------------------- /static/products/1693862-03-A_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1693862-03-A_1.jpg -------------------------------------------------------------------------------- /static/products/1693867-00-A_0_2000.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1693867-00-A_0_2000.jpg -------------------------------------------------------------------------------- /static/products/1693867-00-A_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1693867-00-A_1.jpg -------------------------------------------------------------------------------- /static/products/1693867-02-A_0_2000.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1693867-02-A_0_2000.jpg -------------------------------------------------------------------------------- /static/products/1693867-02-A_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1693867-02-A_1.jpg -------------------------------------------------------------------------------- /static/products/1700280-00-A_0_2000.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1700280-00-A_0_2000.jpg -------------------------------------------------------------------------------- /static/products/1700280-00-A_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1700280-00-A_1.jpg -------------------------------------------------------------------------------- /static/products/1703767-00-A_0_2000.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1703767-00-A_0_2000.jpg -------------------------------------------------------------------------------- /static/products/1703767-00-A_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1703767-00-A_1.jpg -------------------------------------------------------------------------------- /static/products/1715672-00-A_featured.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1715672-00-A_featured.jpg -------------------------------------------------------------------------------- /static/products/1740051-00-A_0_2000.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1740051-00-A_0_2000.jpg -------------------------------------------------------------------------------- /static/products/1740051-00-A_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1740051-00-A_1.jpg -------------------------------------------------------------------------------- /static/products/1740113-00-A_0_2000.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1740113-00-A_0_2000.jpg -------------------------------------------------------------------------------- /static/products/1740113-00-A_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1740113-00-A_1.jpg -------------------------------------------------------------------------------- /static/products/1740121-00-A_0_2000.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1740121-00-A_0_2000.jpg -------------------------------------------------------------------------------- /static/products/1740121-00-A_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1740121-00-A_1.jpg -------------------------------------------------------------------------------- /static/products/1740140-00-A_0_2000.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1740140-00-A_0_2000.jpg -------------------------------------------------------------------------------- /static/products/1740140-00-A_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1740140-00-A_1.jpg -------------------------------------------------------------------------------- /static/products/1740145-00-A_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1740145-00-A_1.jpg -------------------------------------------------------------------------------- /static/products/1740145-00-A_2_2000.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1740145-00-A_2_2000.jpg -------------------------------------------------------------------------------- /static/products/1740176-00-A_0_2000.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1740176-00-A_0_2000.jpg -------------------------------------------------------------------------------- /static/products/1740176-00-A_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1740176-00-A_1.jpg -------------------------------------------------------------------------------- /static/products/1740211-00-A_0_2000.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1740211-00-A_0_2000.jpg -------------------------------------------------------------------------------- /static/products/1740211-00-A_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1740211-00-A_1.jpg -------------------------------------------------------------------------------- /static/products/1740216-00-A_0_2000.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1740216-00-A_0_2000.jpg -------------------------------------------------------------------------------- /static/products/1740216-00-A_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1740216-00-A_1.jpg -------------------------------------------------------------------------------- /static/products/1740221-00-A_0_2000.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1740221-00-A_0_2000.jpg -------------------------------------------------------------------------------- /static/products/1740221-00-A_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1740221-00-A_1.jpg -------------------------------------------------------------------------------- /static/products/1740226-00-A_0_2000.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1740226-00-A_0_2000.jpg -------------------------------------------------------------------------------- /static/products/1740226-00-A_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1740226-00-A_1.jpg -------------------------------------------------------------------------------- /static/products/1740231-00-A_0_2000.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1740231-00-A_0_2000.jpg -------------------------------------------------------------------------------- /static/products/1740231-00-A_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1740231-00-A_1.jpg -------------------------------------------------------------------------------- /static/products/1740236-00-A_0_2000.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1740236-00-A_0_2000.jpg -------------------------------------------------------------------------------- /static/products/1740236-00-A_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1740236-00-A_1.jpg -------------------------------------------------------------------------------- /static/products/1740245-00-A_0_2000.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1740245-00-A_0_2000.jpg -------------------------------------------------------------------------------- /static/products/1740245-00-A_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1740245-00-A_1.jpg -------------------------------------------------------------------------------- /static/products/1740250-00-A_0_2000.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1740250-00-A_0_2000.jpg -------------------------------------------------------------------------------- /static/products/1740250-00-A_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1740250-00-A_1.jpg -------------------------------------------------------------------------------- /static/products/1740255-00-A_0_2000.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1740255-00-A_0_2000.jpg -------------------------------------------------------------------------------- /static/products/1740255-00-A_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1740255-00-A_1.jpg -------------------------------------------------------------------------------- /static/products/1740260-00-A_0_2000.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1740260-00-A_0_2000.jpg -------------------------------------------------------------------------------- /static/products/1740260-00-A_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1740260-00-A_1.jpg -------------------------------------------------------------------------------- /static/products/1740270-00-A_0_2000.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1740270-00-A_0_2000.jpg -------------------------------------------------------------------------------- /static/products/1740270-00-A_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1740270-00-A_1.jpg -------------------------------------------------------------------------------- /static/products/1740275-00-A_0_2000.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1740275-00-A_0_2000.jpg -------------------------------------------------------------------------------- /static/products/1740275-00-A_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1740275-00-A_1.jpg -------------------------------------------------------------------------------- /static/products/1740280-00-A_0_2000.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1740280-00-A_0_2000.jpg -------------------------------------------------------------------------------- /static/products/1740280-00-A_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1740280-00-A_1.jpg -------------------------------------------------------------------------------- /static/products/1740285-00-A_0_2000.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1740285-00-A_0_2000.jpg -------------------------------------------------------------------------------- /static/products/1740285-00-A_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1740285-00-A_1.jpg -------------------------------------------------------------------------------- /static/products/1740290-00-A_0_2000.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1740290-00-A_0_2000.jpg -------------------------------------------------------------------------------- /static/products/1740290-00-A_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1740290-00-A_1.jpg -------------------------------------------------------------------------------- /static/products/1740406-00-A_0_2000.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1740406-00-A_0_2000.jpg -------------------------------------------------------------------------------- /static/products/1740406-00-A_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1740406-00-A_1.jpg -------------------------------------------------------------------------------- /static/products/1740407-00-A_0_2000.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1740407-00-A_0_2000.jpg -------------------------------------------------------------------------------- /static/products/1740407-00-A_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1740407-00-A_1.jpg -------------------------------------------------------------------------------- /static/products/1740408-00-A_0_2000.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1740408-00-A_0_2000.jpg -------------------------------------------------------------------------------- /static/products/1740408-00-A_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1740408-00-A_1.jpg -------------------------------------------------------------------------------- /static/products/1740409-00-A_0_2000.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1740409-00-A_0_2000.jpg -------------------------------------------------------------------------------- /static/products/1740409-00-A_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1740409-00-A_1.jpg -------------------------------------------------------------------------------- /static/products/1740410-00-A_0_2000.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1740410-00-A_0_2000.jpg -------------------------------------------------------------------------------- /static/products/1740410-00-A_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1740410-00-A_1.jpg -------------------------------------------------------------------------------- /static/products/1740411-00-A_0_2000.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1740411-00-A_0_2000.jpg -------------------------------------------------------------------------------- /static/products/1740411-00-A_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1740411-00-A_1.jpg -------------------------------------------------------------------------------- /static/products/1740413-00-A_0_2000.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1740413-00-A_0_2000.jpg -------------------------------------------------------------------------------- /static/products/1740413-00-A_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1740413-00-A_1.jpg -------------------------------------------------------------------------------- /static/products/1740414-00-A_0_2000.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1740414-00-A_0_2000.jpg -------------------------------------------------------------------------------- /static/products/1740414-00-A_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1740414-00-A_1.jpg -------------------------------------------------------------------------------- /static/products/1740416-00-A_0_2000.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1740416-00-A_0_2000.jpg -------------------------------------------------------------------------------- /static/products/1740416-00-A_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1740416-00-A_1.jpg -------------------------------------------------------------------------------- /static/products/1740417-00-A_0_2000.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1740417-00-A_0_2000.jpg -------------------------------------------------------------------------------- /static/products/1740417-00-A_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1740417-00-A_1.jpg -------------------------------------------------------------------------------- /static/products/1740507-00-A_0_2000.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1740507-00-A_0_2000.jpg -------------------------------------------------------------------------------- /static/products/1740507-00-A_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1740507-00-A_1.jpg -------------------------------------------------------------------------------- /static/products/1740514-00-A_0_2000.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1740514-00-A_0_2000.jpg -------------------------------------------------------------------------------- /static/products/1740514-00-A_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1740514-00-A_1.jpg -------------------------------------------------------------------------------- /static/products/1740521-00-A_0_2000.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1740521-00-A_0_2000.jpg -------------------------------------------------------------------------------- /static/products/1740521-00-A_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1740521-00-A_1.jpg -------------------------------------------------------------------------------- /static/products/1740528-00-A_0_2000.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1740528-00-A_0_2000.jpg -------------------------------------------------------------------------------- /static/products/1740528-00-A_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1740528-00-A_1.jpg -------------------------------------------------------------------------------- /static/products/1740535-00-A_0_2000.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1740535-00-A_0_2000.jpg -------------------------------------------------------------------------------- /static/products/1740535-00-A_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1740535-00-A_1.jpg -------------------------------------------------------------------------------- /static/products/1741111-00-A_0_2000.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1741111-00-A_0_2000.jpg -------------------------------------------------------------------------------- /static/products/1741111-00-A_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1741111-00-A_1.jpg -------------------------------------------------------------------------------- /static/products/1741416-00-A_0_2000.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1741416-00-A_0_2000.jpg -------------------------------------------------------------------------------- /static/products/1741416-00-A_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1741416-00-A_1.jpg -------------------------------------------------------------------------------- /static/products/1741425-00-A_0_2000.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1741425-00-A_0_2000.jpg -------------------------------------------------------------------------------- /static/products/1741425-00-A_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1741425-00-A_1.jpg -------------------------------------------------------------------------------- /static/products/1741441-00-A_0_2000.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1741441-00-A_0_2000.jpg -------------------------------------------------------------------------------- /static/products/1741441-00-A_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1741441-00-A_1.jpg -------------------------------------------------------------------------------- /static/products/1741449-00-A_0_2000.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1741449-00-A_0_2000.jpg -------------------------------------------------------------------------------- /static/products/1741449-00-A_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1741449-00-A_1.jpg -------------------------------------------------------------------------------- /static/products/1741611-00-A_1_2000.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1741611-00-A_1_2000.jpg -------------------------------------------------------------------------------- /static/products/1741613-00-A_1_2000.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1741613-00-A_1_2000.jpg -------------------------------------------------------------------------------- /static/products/1741615-00-A_1_2000.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1741615-00-A_1_2000.jpg -------------------------------------------------------------------------------- /static/products/1741617-00-A_1_2000.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1741617-00-A_1_2000.jpg -------------------------------------------------------------------------------- /static/products/1741619-00-A_1_2000.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1741619-00-A_1_2000.jpg -------------------------------------------------------------------------------- /static/products/1741621-00-A_1_2000.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1741621-00-A_1_2000.jpg -------------------------------------------------------------------------------- /static/products/1742694-00-A_1_2000.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1742694-00-A_1_2000.jpg -------------------------------------------------------------------------------- /static/products/1742694-00-A_3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1742694-00-A_3.jpg -------------------------------------------------------------------------------- /static/products/1742702-00-A_0_2000.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1742702-00-A_0_2000.jpg -------------------------------------------------------------------------------- /static/products/1742702-00-A_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/1742702-00-A_1.jpg -------------------------------------------------------------------------------- /static/products/31bef8d9-ef07-4980-8db8-059364d31688.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/31bef8d9-ef07-4980-8db8-059364d31688.png -------------------------------------------------------------------------------- /static/products/5645680-00-A_0_2000.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/5645680-00-A_0_2000.jpg -------------------------------------------------------------------------------- /static/products/5645680-00-A_3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/5645680-00-A_3.jpg -------------------------------------------------------------------------------- /static/products/5645685-00-A_0_2000.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/5645685-00-A_0_2000.jpg -------------------------------------------------------------------------------- /static/products/5645685-00-A_3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/5645685-00-A_3.jpg -------------------------------------------------------------------------------- /static/products/7652410-00-A_0.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/7652410-00-A_0.jpg -------------------------------------------------------------------------------- /static/products/7652410-00-A_1_2000.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/7652410-00-A_1_2000.jpg -------------------------------------------------------------------------------- /static/products/7652421-00-A_0_2000.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/7652421-00-A_0_2000.jpg -------------------------------------------------------------------------------- /static/products/7652421-00-A_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/7652421-00-A_1.jpg -------------------------------------------------------------------------------- /static/products/7652426-00-A_0_2000.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/7652426-00-A_0_2000.jpg -------------------------------------------------------------------------------- /static/products/7652426-00-A_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/7652426-00-A_1.jpg -------------------------------------------------------------------------------- /static/products/7652432-00-A_0_2000.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/7652432-00-A_0_2000.jpg -------------------------------------------------------------------------------- /static/products/7652432-00-A_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/7652432-00-A_1.jpg -------------------------------------------------------------------------------- /static/products/7652453-00-A_0_2000.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/7652453-00-A_0_2000.jpg -------------------------------------------------------------------------------- /static/products/7652453-00-A_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/7652453-00-A_1.jpg -------------------------------------------------------------------------------- /static/products/7652459-00-A_0_2000.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/7652459-00-A_0_2000.jpg -------------------------------------------------------------------------------- /static/products/7652459-00-A_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/7652459-00-A_1.jpg -------------------------------------------------------------------------------- /static/products/7652465-00-A_0_2000.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/7652465-00-A_0_2000.jpg -------------------------------------------------------------------------------- /static/products/7652465-00-A_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/7652465-00-A_1.jpg -------------------------------------------------------------------------------- /static/products/7654393-00-A_2_2000.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/7654393-00-A_2_2000.jpg -------------------------------------------------------------------------------- /static/products/7654393-00-A_3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/7654393-00-A_3.jpg -------------------------------------------------------------------------------- /static/products/7654399-00-A_0_2000.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/7654399-00-A_0_2000.jpg -------------------------------------------------------------------------------- /static/products/7654399-00-A_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/7654399-00-A_1.jpg -------------------------------------------------------------------------------- /static/products/7654420-00-A_0_2000.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/7654420-00-A_0_2000.jpg -------------------------------------------------------------------------------- /static/products/7654420-00-A_1_2000.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/7654420-00-A_1_2000.jpg -------------------------------------------------------------------------------- /static/products/8528833-00-A_0_2000.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/8528833-00-A_0_2000.jpg -------------------------------------------------------------------------------- /static/products/8528833-00-A_2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/8528833-00-A_2.jpg -------------------------------------------------------------------------------- /static/products/8528839-00-A_0_2000.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/8528839-00-A_0_2000.jpg -------------------------------------------------------------------------------- /static/products/8528839-00-A_2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/8528839-00-A_2.jpg -------------------------------------------------------------------------------- /static/products/8528845-00-A_0_2000.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/8528845-00-A_0_2000.jpg -------------------------------------------------------------------------------- /static/products/8528845-00-A_2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/8528845-00-A_2.jpg -------------------------------------------------------------------------------- /static/products/8529100-00-A_0_2000.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/8529100-00-A_0_2000.jpg -------------------------------------------------------------------------------- /static/products/8529100-00-A_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/8529100-00-A_1.jpg -------------------------------------------------------------------------------- /static/products/8529107-00-A_0_2000.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/8529107-00-A_0_2000.jpg -------------------------------------------------------------------------------- /static/products/8529107-00-A_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/8529107-00-A_1.jpg -------------------------------------------------------------------------------- /static/products/8529198-00-A_0_2000.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/8529198-00-A_0_2000.jpg -------------------------------------------------------------------------------- /static/products/8529198-00-A_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/8529198-00-A_1.jpg -------------------------------------------------------------------------------- /static/products/8529205-00-A_0_2000.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/8529205-00-A_0_2000.jpg -------------------------------------------------------------------------------- /static/products/8529205-00-A_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/8529205-00-A_1.jpg -------------------------------------------------------------------------------- /static/products/8529212-00-A_0_2000.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/8529212-00-A_0_2000.jpg -------------------------------------------------------------------------------- /static/products/8529212-00-A_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/8529212-00-A_1.jpg -------------------------------------------------------------------------------- /static/products/8529312-00-A_0_2000.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/8529312-00-A_0_2000.jpg -------------------------------------------------------------------------------- /static/products/8529312-00-A_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/8529312-00-A_1.jpg -------------------------------------------------------------------------------- /static/products/8529318-00-A_0_2000.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/8529318-00-A_0_2000.jpg -------------------------------------------------------------------------------- /static/products/8529318-00-A_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/8529318-00-A_1.jpg -------------------------------------------------------------------------------- /static/products/8529336-00-A_0_2000.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/8529336-00-A_0_2000.jpg -------------------------------------------------------------------------------- /static/products/8529336-00-A_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/8529336-00-A_1.jpg -------------------------------------------------------------------------------- /static/products/8529342-00-A_0_2000.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/8529342-00-A_0_2000.jpg -------------------------------------------------------------------------------- /static/products/8529342-00-A_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/8529342-00-A_1.jpg -------------------------------------------------------------------------------- /static/products/8529348-00-A_0_2000.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/8529348-00-A_0_2000.jpg -------------------------------------------------------------------------------- /static/products/8529348-00-A_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/8529348-00-A_1.jpg -------------------------------------------------------------------------------- /static/products/8529354-00-A_0_2000.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/8529354-00-A_0_2000.jpg -------------------------------------------------------------------------------- /static/products/8529354-00-A_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/8529354-00-A_1.jpg -------------------------------------------------------------------------------- /static/products/8529360-00-A_0_2000.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/8529360-00-A_0_2000.jpg -------------------------------------------------------------------------------- /static/products/8529360-00-A_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/8529360-00-A_1.jpg -------------------------------------------------------------------------------- /static/products/8529366-00-A_0_2000.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/8529366-00-A_0_2000.jpg -------------------------------------------------------------------------------- /static/products/8529366-00-A_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/8529366-00-A_1.jpg -------------------------------------------------------------------------------- /static/products/8529382-00-A_0_2000.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/8529382-00-A_0_2000.jpg -------------------------------------------------------------------------------- /static/products/8529382-00-A_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/8529382-00-A_1.jpg -------------------------------------------------------------------------------- /static/products/8529387-00-A_0_2000.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/8529387-00-A_0_2000.jpg -------------------------------------------------------------------------------- /static/products/8529387-00-A_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/8529387-00-A_1.jpg -------------------------------------------------------------------------------- /static/products/8764600-00-A_0_2000.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/8764600-00-A_0_2000.jpg -------------------------------------------------------------------------------- /static/products/8764600-00-A_2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/8764600-00-A_2.jpg -------------------------------------------------------------------------------- /static/products/8764613-00-A_0_2000.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/8764613-00-A_0_2000.jpg -------------------------------------------------------------------------------- /static/products/8764613-00-A_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/8764613-00-A_1.jpg -------------------------------------------------------------------------------- /static/products/8764727-00-A_0_2000.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/8764727-00-A_0_2000.jpg -------------------------------------------------------------------------------- /static/products/8764727-00-A_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/8764727-00-A_1.jpg -------------------------------------------------------------------------------- /static/products/8764734-00-A_0_2000.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/8764734-00-A_0_2000.jpg -------------------------------------------------------------------------------- /static/products/8764734-00-A_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/8764734-00-A_1.jpg -------------------------------------------------------------------------------- /static/products/8764741-00-A_0_2000.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/8764741-00-A_0_2000.jpg -------------------------------------------------------------------------------- /static/products/8764741-00-A_2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/8764741-00-A_2.jpg -------------------------------------------------------------------------------- /static/products/8764754-00-A_0_2000.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/8764754-00-A_0_2000.jpg -------------------------------------------------------------------------------- /static/products/8764754-00-A_2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/8764754-00-A_2.jpg -------------------------------------------------------------------------------- /static/products/8764760-00-A_0_2000.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/8764760-00-A_0_2000.jpg -------------------------------------------------------------------------------- /static/products/8764760-00-A_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/8764760-00-A_1.jpg -------------------------------------------------------------------------------- /static/products/8764766-00-A_0_2000.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/8764766-00-A_0_2000.jpg -------------------------------------------------------------------------------- /static/products/8764766-00-A_2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/8764766-00-A_2.jpg -------------------------------------------------------------------------------- /static/products/8764792-00-A_0_2000.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/8764792-00-A_0_2000.jpg -------------------------------------------------------------------------------- /static/products/8764792-00-A_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/8764792-00-A_1.jpg -------------------------------------------------------------------------------- /static/products/8764806-00-A_0_2000.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/8764806-00-A_0_2000.jpg -------------------------------------------------------------------------------- /static/products/8764806-00-A_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/8764806-00-A_1.jpg -------------------------------------------------------------------------------- /static/products/8764813-00-A_0_2000.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/8764813-00-A_0_2000.jpg -------------------------------------------------------------------------------- /static/products/8764813-00-A_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/8764813-00-A_1.jpg -------------------------------------------------------------------------------- /static/products/8765085-00-A_0_2000.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/8765085-00-A_0_2000.jpg -------------------------------------------------------------------------------- /static/products/8765085-00-A_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/8765085-00-A_1.jpg -------------------------------------------------------------------------------- /static/products/8765090-00-A_0_2000.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/8765090-00-A_0_2000.jpg -------------------------------------------------------------------------------- /static/products/8765090-00-A_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/8765090-00-A_1.jpg -------------------------------------------------------------------------------- /static/products/8765095-00-A_0_2000.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/8765095-00-A_0_2000.jpg -------------------------------------------------------------------------------- /static/products/8765095-00-A_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/8765095-00-A_1.jpg -------------------------------------------------------------------------------- /static/products/8765100-00-A_0_2000.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/8765100-00-A_0_2000.jpg -------------------------------------------------------------------------------- /static/products/8765100-00-A_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/8765100-00-A_1.jpg -------------------------------------------------------------------------------- /static/products/8765105-00-A_0_2000.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/8765105-00-A_0_2000.jpg -------------------------------------------------------------------------------- /static/products/8765105-00-A_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/8765105-00-A_1.jpg -------------------------------------------------------------------------------- /static/products/8765110-00-A_0_2000.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/8765110-00-A_0_2000.jpg -------------------------------------------------------------------------------- /static/products/8765110-00-A_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/8765110-00-A_1.jpg -------------------------------------------------------------------------------- /static/products/8765115-00-A_0_2000.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/8765115-00-A_0_2000.jpg -------------------------------------------------------------------------------- /static/products/8765115-00-A_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/8765115-00-A_1.jpg -------------------------------------------------------------------------------- /static/products/8765120-00-A_0_2000.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/8765120-00-A_0_2000.jpg -------------------------------------------------------------------------------- /static/products/8765120-00-A_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/8765120-00-A_1.jpg -------------------------------------------------------------------------------- /static/products/8765125-00-A_0_2000.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/8765125-00-A_0_2000.jpg -------------------------------------------------------------------------------- /static/products/8765125-00-A_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/8765125-00-A_1.jpg -------------------------------------------------------------------------------- /static/products/8765130-00-A_0_2000.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/8765130-00-A_0_2000.jpg -------------------------------------------------------------------------------- /static/products/8765130-00-A_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/8765130-00-A_1.jpg -------------------------------------------------------------------------------- /static/products/9877034-00-A_0_2000.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/9877034-00-A_0_2000.jpg -------------------------------------------------------------------------------- /static/products/9877034-00-A_2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/9877034-00-A_2.jpg -------------------------------------------------------------------------------- /static/products/9877040-00-A_0_2000.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/9877040-00-A_0_2000.jpg -------------------------------------------------------------------------------- /static/products/9877040-00-A_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/products/9877040-00-A_1.jpg -------------------------------------------------------------------------------- /static/uploads/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Klerith/docker-teslo-shop/294d88d083db4d9e653499de84204bf2d31fe5c2/static/uploads/.gitkeep -------------------------------------------------------------------------------- /test/app.e2e-spec.ts: -------------------------------------------------------------------------------- 1 | import { Test, TestingModule } from '@nestjs/testing'; 2 | import { INestApplication } from '@nestjs/common'; 3 | import * as request from 'supertest'; 4 | import { AppModule } from './../src/app.module'; 5 | 6 | describe('AppController (e2e)', () => { 7 | let app: INestApplication; 8 | 9 | beforeEach(async () => { 10 | const moduleFixture: TestingModule = await Test.createTestingModule({ 11 | imports: [AppModule], 12 | }).compile(); 13 | 14 | app = moduleFixture.createNestApplication(); 15 | await app.init(); 16 | }); 17 | 18 | it('/ (GET)', () => { 19 | return request(app.getHttpServer()) 20 | .get('/') 21 | .expect(200) 22 | .expect('Hello World!'); 23 | }); 24 | }); 25 | -------------------------------------------------------------------------------- /test/jest-e2e.json: -------------------------------------------------------------------------------- 1 | { 2 | "moduleFileExtensions": ["js", "json", "ts"], 3 | "rootDir": ".", 4 | "testEnvironment": "node", 5 | "testRegex": ".e2e-spec.ts$", 6 | "transform": { 7 | "^.+\\.(t|j)s$": "ts-jest" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /tsconfig.build.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "exclude": ["node_modules", "test", "dist", "**/*spec.ts"] 4 | } 5 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "declaration": true, 5 | "removeComments": true, 6 | "emitDecoratorMetadata": true, 7 | "experimentalDecorators": true, 8 | "allowSyntheticDefaultImports": true, 9 | "target": "es2021", 10 | "sourceMap": true, 11 | "outDir": "./dist", 12 | "baseUrl": "./", 13 | "incremental": true, 14 | "skipLibCheck": true, 15 | "strictNullChecks": false, 16 | "noImplicitAny": false, 17 | "strictBindCallApply": false, 18 | "forceConsistentCasingInFileNames": false, 19 | "noFallthroughCasesInSwitch": false 20 | } 21 | } 22 | --------------------------------------------------------------------------------