├── .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 |
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 |
--------------------------------------------------------------------------------