Николай Ланец
26 апр. 2021 г., 5:21

Обзорное видео @prisma-cms/nextjs-nexus

Всем привет!

На выходных таки запилил обновленную версию @prisma-cms/nextjs с поддержкой баз данных. Так как функционал сильно дополненный по сравнению с прошлой версией, вынес это в отдельный репозиторий @prisma-cms/nextjs-nexus. Новая версия позволяет полноценно работать с базами данных (миграции, запросы и т.п.) и полностью подходит для реализации комплексных проектов с нуля. Напомню, предыдущая версия - это Headless CMS и сама по себе как бы не работала с базой данных. Ей требовалось указывать GraphQL-API сервер, откуда данные получать. А вот новая версия уже сама по себе в том числе и GraphQL-API сервер. Плюс к этому сразу запилил структуру объекта User, мутации регистрации и авторизации, а так же фронтовые формы для этих запросов. Ну а формы тоже довольно интересные, с типизацией.

Скажу так: эта версия вообще классная! И именно она будет использоваться для реализации нескольких проектов, которые я уже давно мыслил. Очень советую к освоению.

Для наглядности записал обзорное видео.

UPD: Прикрутил graphql-shield.
Как сделать, чтобы NPM scripts в отдельной вкладке в VSC появились?
А у тебя какая версия VSCode? У меня 1.55.2. Мне кажется, это с обновлением само прилетело. И проверь, в расширениях у тебя имеется такое? Скорее всего оно обеспечивает работу. Это встроенное (buildin). Может ты когда выполнял "Отключить все расширения"?

У меня тоже 1.55.2. и расширеннее это тоже сотит и включено, но вкладки нет.
Больше ничего не могу сказать. Вот только что список всех установленных расширений у меня (здесь ничего нет, что содержало бы npm):
$ code --list-extensions | xargs -L 1 echo code --install-extension
code --install-extension 13xforever.language-x86-64-assembly
code --install-extension alefragnani.pascal
code --install-extension alefragnani.pascal-formatter
code --install-extension CADENAS.vscode-glsllint
code --install-extension CAPTNCAPS.ue4-snippets
code --install-extension cschlosser.doxdocgen
code --install-extension dbaeumer.vscode-eslint
code --install-extension donjayamanne.githistory
code --install-extension ecmel.vscode-html-css
code --install-extension EditorConfig.EditorConfig
code --install-extension EliotVU.uc
code --install-extension EngineDesigns.retroassembler
code --install-extension fi1osof.prisma-cms
code --install-extension GitHub.vscode-pull-request-github
code --install-extension GraphQL.vscode-graphql
code --install-extension Gruntfuggly.todo-tree
code --install-extension henriiik.vscode-perl
code --install-extension imperez.smarty
code --install-extension infeng.vscode-react-typescript
code --install-extension Ionide.Ionide-fsharp
code --install-extension jakob101.RelativePath
code --install-extension jeff-hykin.better-cpp-syntax
code --install-extension jpoissonnier.vscode-styled-components
code --install-extension kumar-harsh.graphql-for-vscode
code --install-extension lonefy.vscode-JS-CSS-HTML-formatter
code --install-extension mgmcdermott.vscode-language-babel
code --install-extension mhutchie.git-graph
code --install-extension mikestead.dotenv
code --install-extension mjmcloug.vscode-elixir
code --install-extension mquandalle.graphql
code --install-extension ms-dotnettools.csharp
code --install-extension ms-vscode-remote.remote-containers
code --install-extension ms-vscode-remote.remote-ssh
code --install-extension ms-vscode-remote.remote-ssh-edit
code --install-extension ms-vscode-remote.remote-wsl
code --install-extension ms-vscode.cmake-tools
code --install-extension ms-vscode.cpptools
code --install-extension ms-vscode.cpptools-extension-pack
code --install-extension ms-vscode.cpptools-themes
code --install-extension ms-vscode.mono-debug
code --install-extension ms-vsliveshare.vsliveshare
code --install-extension ms-vsliveshare.vsliveshare-audio
code --install-extension prb28.amiga-assembly
code --install-extension Prisma.prisma
code --install-extension redhat.java
code --install-extension richterger.perl
code --install-extension Roncho.assembly-8086
code --install-extension scala-lang.scala
code --install-extension searKing.preview-vscode
code --install-extension SimonSiefke.svg-preview
code --install-extension slevesque.shader
code --install-extension syler.sass-indented
code --install-extension sysoev.language-stylus
code --install-extension technosophos.vscode-make
code --install-extension tht13.python
code --install-extension twxs.cmake
code --install-extension vadimcn.vscode-lldb
code --install-extension VisualStudioExptTeam.vscodeintellicode
code --install-extension vscjava.vscode-java-debug
code --install-extension vscjava.vscode-java-dependency
code --install-extension vscjava.vscode-java-pack
code --install-extension vscjava.vscode-java-test
code --install-extension vscjava.vscode-maven
code --install-extension wingrunr21.vscode-ruby
code --install-extension Wscats.eno
code --install-extension xabikos.ReactSnippets
code --install-extension yzhang.markdown-all-in-one
code --install-extension zenor.makefile-creator

Так что придется тебе гуглить, если очень нужна эта фича.
Кстати, на всякий случай замечу, что эти скрипты не обязательно именно через эту панель запускать. Это просто для удобства. А так все эти скрипты прописаны в package.json и можно запускать просто в терминале, как тот же yarn dev
Ларчик просто открывался)
У меня не получалось заскринить, в убунте встроенный скринсейвер часто виснет с выпадающими менюшками :)

Николай, приветствую!
Возник вопрос по расширению схемы, может ты сталкивался:
Как добавить enum на русском?


model Post { id String @id @default(cuid()) @db.VarChar(32) createdAt DateTime @default(now("0")) @db.DateTime(0) updatedAt DateTime @default(now("0")) @updatedAt @db.DateTime(0) mashroom Mashrooms @default(value: Noinfo) text String createdById String? @db.VarChar(32) CreatedBy User? @relation(fields: [createdById], references: [id]) @@index([createdById], name: "User") } enum Mashrooms { Noinfo Mash1 Mash2 }
Так залетело без вопросов


model Post { id String @id @default(cuid()) @db.VarChar(32) createdAt DateTime @default(now("0")) @db.DateTime(0) updatedAt DateTime @default(now("0")) @updatedAt @db.DateTime(0) mashroom Mashrooms @default(value: Неизвестно) text String createdById String? @db.VarChar(32) CreatedBy User? @relation(fields: [createdById], references: [id]) @@index([createdById], name: "User") } enum Mashrooms { Неизвестно Белый гриб Подосиновик }
А так заругалось. Явно, что ругается на кириллицу.

Можно как-то запихать названия или надо будет уже при выводе переводить?

Спасибо!




Дима, привет!

Как это любят говорить на западе: Good catch! :)
Поймал багу. Сейчас этого в призме нельзя. Еще не тестировал @prisma/client-3, может там пофиксили. Сам же я не натыкался на такое, потому что в енамы как правило загоняют какие-то константы, а на фронте выводится значение по справочнику или еще как. Ведь если ты захочешь склонение поменять или мультиязычность ввести, что ты будешь делать? Значение енамов никогда по идее не должно меняться (добавляться - да, а удаляться/меняться - это экстренный случай). Для примера как выводится текст на этом же проекте:

import { UserTechnologyHiringStatus } from 'src/modules/gql/generated' /** * Возвращает перевод статуса заинтересованности в трудоустройстве */ export const getUserTechnologyHiringStatusText = ( status: UserTechnologyHiringStatus ): string => { switch (status) { case UserTechnologyHiringStatus.ACTIVE: return 'Очень заинтересован' case UserTechnologyHiringStatus.NEGATIVE: return 'Не заинтересован' case UserTechnologyHiringStatus.NEUTRAL: return 'Не против' default: return '' } }

Понял, спасибо! Значит буду перебор делать)
Николай, всё-таки нужно подтолкнуть в верном направлении)

- Добавил модель Post в schema.prisma
- выполнил prisma:db:push - получил новую таблицу в БД
- выполнил generate:types - ошибок нет, но в папках gql в src никаких изменений нет, в api, соответственно, тоже.

Что забыл добавить ,чтобы изменения подхватились и добавились?
Дима, пересматривай начиная с 25 минуты минут 10-15, там все это подробно объясняется (слишком подробно и растянуто, но все же).
Уточняю в чем твоя ошибка:

>> - Добавил модель Post в schema.prisma
- выполнил prisma:db:push - получил новую таблицу в БД

Это фаза 1 (работа с базой данных).

>> - выполнил generate:types

А вот это уже фаза 3, то есть подтягивание GraphQL-API на сторону фронта и формирование методов и типов.

Ты пропустил фазу 2 - не поправил GraphQL-API. За это отвечает Nexus. То есть пока ты не обновишь схему для фронтового АПИ, ничего у тебя на фронте нового не появится. Призма - отдельно, GraphQL-API - отдельно.
Спасибо, изучаю заново)
И еще: не забудь по завершении всего выполнить еще yarn prisma:migrate:create, чтобы сформировать новую миграцию. То, что ты обновляешь призма-схему и пушишь руками в БД - это еще не формирует скриптов миграции, которые срабатывают на yarn prisma:deploy. Этот момент тоже есть в видео.
Только тут важный момент: при создании миграции у тебя будет очищена база данных. Почему так происходит? Потому что ты уже выполнил prisma:db:push и в базе данных уже есть изменения структуры. Нельзя поверх выполнить еще такие же структурные запросы. Поэтому призма удаляет все таблицы, выполняет имеющиеся миграции и создает новую миграцию, накатывает ее и сохранят файл миграции в prisma/migrations/.
По этой причине, чтобы не потерять данные, надо делать так:
1. Прежде чем внести какие-либо структурные изменения в БД, снимаешь полный дамп базы.
2. Вносишь изменения.
3. Создаешь миграцию (данные все при этом будут потеряны).
4. Удаляешь все таблицы в базе данных.
5. Выполняешь импорт своего дампа.
6. Выполняешь yarn prisma:deploy чтобы накатить новую миграцию. При этом данные не будут потеряны, если все ОК. Если не ОК, то миграция просто не будет выполнена.

То есть в режиме разработки не редко теряется база данных при внесении изменений таким образом, но на боевую yarn prisma:deploy обычно проходит без проблем.
Николай, посмотри, пожалуйста, последовательность действий: все ли верно понял.
Для того, чтобы добавить новую таблицу:
1. Добавляем описание таблицы в prisma
2. prisma:db:push - в БД появляется новая таблица
3. Сюда https://github.com/prisma-cms/nextjs-nexus/tree/master/src/gql добавляем .graphql для новой таблицы
4. Сюда https://github.com/prisma-cms/nextjs-nexus/tree/master/server/nexus/types надо добавить описание таблицы для nexus, который проверяет соответствие типов полей в gql
5. generate:types - генерация кода

Правильно понял или что-то забыл?

-----------------------

6. Действия предыдущего поста

Дима, в целом правильно, но очередность чуть другая. Надо так: 3. Сюда https://github.com/prisma-cms/nextjs-nexus/tree/master/server/nexus/types надо добавить описание таблицы для nexus, который проверяет соответствие типов полей в gql
4. Сюда https://github.com/prisma-cms/nextjs-nexus/tree/master/src/gql добавляем .graphql для новой таблицы

Судя по всему, ты думаешь, что сначала должно что-то появиться в /src/gql и только потом уже можно добавлять что-то в типы /server/nexus/types. Это не так. Если разбирать наименование папки /server/nexus/types, то здесь types - это не тайпскриптовые типы, а графкюэльные. То есть здесь надо более хорошо прокачаться в GraphQL и понимать, что там все есть типы (даже скалярные). При этом есть типы на чтение (все типы, что мы перечисляем в теле запроса для получения данных), а есть входящие типы (input-types), это все то, что мы передаем в параметрах. Nexus - это библиотека, которая позволяет генерировать GraphQL-схему (включая типы) на основе нашего кода. Для примера
import { objectType, extendType, inputObjectType, nonNull } from 'nexus' export const User = objectType({ name: 'User', description: 'Пользователь', sourceType: { module: '@prisma/client', export: 'User', }, definition(t) { t.nonNull.string('id') t.nonNull.date('createdAt', { description: 'Когда создан', }) t.string('email') t.string('fullname') t.string('username') t.boolean('sudo') t.string('image', { description: 'Avatar', }) }, })
Таким образом мы описываем структуру GraphQL-типа User. Этот тип генерируется и попадает в server/nexus/generated/schema.graphql
Это именно та схема, которую использует GraphQL-сервер. Посмотри внимательно эту схему у себя в проекте. Если ты там не видишь того, что ожидаешь получить на фронте, то ты этого не получишь. К примеру, у меня сейчас так (помимо прочего):

""" Пользователь """ type User { """ Когда создан """ createdAt: DateTime! email: String fullname: String id: String! """ Avatar """ image: String sudo: Boolean username: String }
То есть то, что я прописал в нексусе, попало сюда. И вот теперь этот тип я вижу и в плейграунде


Вот пока ты в GraphQL-Playground не увидишь то, что ожидаешь, на фронте ты не сможешь это получить. И лишь только тогда, когда ты там увидишь желаемое, только тогда ты можешь добавлять фронтовые файлы .graphql и выполнять yarn generate:types, а иначе ты просто будешь получать ошибку.
Понял, спасибо! Ковыряю дальше)
Николай, привет!
Ковыряю nexus, нужна помощь.

Я добавил в схему призмы таблицу:

model Post { id String @id @default(cuid()) @db.VarChar(32) createdAt DateTime @default(now("0")) @db.DateTime(0) updatedAt DateTime @default(now("0")) @updatedAt @db.DateTime(0) mashroom Mashrooms @default(value: Noinfo) text String createdById String? @db.VarChar(32) CreatedBy User? @relation(fields: [createdById], references: [id]) @@index([createdById], name: "User") } enum Mashrooms { Noinfo Mash1 Mash2 }
Пишу проверку типов в нексусе для поста:


import { objectType, enumType} from 'nexus' export const Post = objectType({ name: 'Post', description: 'Пост', sourceType: { module: '@prisma/client', export: 'Post', }, definition(t) { t.nonNull.string('id') t.nonNull.date('createdAt', { description: 'Когда создан', }) t.nonNull.date('updatedAt', { description: 'Когда обновлен', }) t<typeof Mashrooms>('mashroom', { description: 'Гриб', }) t.string('text') }, }) export const Mashrooms = enumType({ name: 'Mashrooms', members: ['Noinfo', 'Mash1', 'Mash2'], description: 'Список грибов', })

Вопрос: что не так со списками и как правильно связать с "создателем" (
createdById String? @db.VarChar(32) CreatedBy User? @relation(fields: [createdById], references: [id])
) ?
Нашел про списки:
Правильно t.field('mashroom, { type: Mashrooms })
>> Нашел про списки:
Правильно t.field('mashroom, { type: Mashrooms })

В целом да, правильно, но есть НО: ты прописал type: Mashrooms и здесь у тебя Mashrooms - это не строковое название типа, а именно сам объект, то есть
export const Mashrooms = enumType({ name: 'Mashrooms', members: ['Noinfo', 'Mash1', 'Mash2'], description: 'Список грибов', })
Правильней указать строковое имя, то есть { type: "Mashrooms" }

Вторая подсказка: категорически избегай названий типов с окончанием на s (то есть множественность). В каком-то месте тебе надо будет массив таких типов и как ты будешь писать? Mashroomss? Особенно не советую наименование типов (именно тех, которые идут потом в названия таблиц, а не колонки) на s заканчивать в самой призма-схеме. Призма втупляет с формированием имен множественных переменных и получается все очень плохо.

Подсказка 3: имена типов в графе уникальные. Если ты назвал енам Mashroom, то имей ввиду, что потом если захочешь создать тип Mashroom (чтобы у него была своя таблица), не получится. Нельзя и тип и енам иметь с одним названием. Обычно енамы для каких-то совсем не больших списков используют (к примеру, статусов). Но сущность типа Гриб лучше было бы сразу загнать в таблицу.

Спасибо!
>>Но сущность типа Гриб лучше было бы сразу загнать в таблицу.

То есть завести прям отдельную таблицу, в которой связаны по id пост и гриб? Тогда enum вообще лишний?
>> Вопрос: что не так со списками и как правильно связать с "создателем" (
createdById String? @db.VarChar(32) CreatedBy User? @relation(fields: [createdById], references: [id])
) ?

Смотри модель пользователя текущего сайта, наверняка поймешь.
>> То есть завести прям отдельную таблицу, в которой связаны по id пост и гриб? Тогда enum вообще лишний?

Таки да.
Николай, приветствую!

Можешь посмотреть, в верном направлении иду?

Подскажи, на каком этапе схема должна плоявиться в playground?
После этого? 4. Сюда https://github.com/prisma-cms/nextjs-nexus/tree/master/src/gql добавляем .graphql для новой таблицы

Привет!

>> Можешь посмотреть, в верном направлении иду?

Дал комменты в коммите.

>> Подскажи, на каком этапе схема должна плоявиться в playground?
После этого? 4. Сюда https://github.com/prisma-cms/nextjs-nexus/tree/master/src/gql добавляем .graphql для новой таблицы

Нет. Это этап уже прописывания граф-запросов на стороне фронта, то есть уже в этот момент граф-схема в АПИ должна содержать все, что ты запрашиваешь. И прописывается это все на уровне редактирования нексус-файлов.

Спасибо!
Значит кроме prisma:migrate:create надо ещё что-то запустить. Что забыл?
>> Что забыл?

Да как обычно: забыл расписать что хотел получить, что делал и что на выходе получил. Опять из меня телепата делаешь. Можешь написать что именно искал и где что не нашел?
Николай, привет!
Не, телепатом лучше не быть))
Вопрос в следующем:
- Добавили описния таблиц в схему призмы
- Сделали prisma:db:push - таблицы залетели в БД
- Добавили описния таблиц в нексус
- Сделали yarn prisma:migrate:create - получили файлы миграции

Если я тебя правильно понял ,то в этот момент уже на /api схема должна появиться.

Если её нет, то я чего-то забыл сделать.
Дима, привет!
Ты сказал, что сделал, но так и не сказал чего именно не смог найти. API у тебя наверняка работает. Очевидно, что ты не видишь какие-то определенные граф-типы. Так вот будь конкретней в том, что именно не так, что именно не видишь. Можешь назвать хоть один тип, который ты прописал в нексусе, но не видишь в АПИ?
Николай, привет!

В нексусе прописал типы Post и Mashroom: они в API не появились.

Ссылку делел - увидел ,что в sourceType использую @prisma/client, а импорт его отключен. Может быть в этом проблема?
>> В нексусе прописал типы Post и Mashroom: они в API не появились.

А вот и нифига, они там есть.



А теперь учись правильней и четче формулировать что же ты на самом деле ищешь и чего не можешь найти. Это программирование, а не урок философии.

Николай, привет!
Занятно вышло. Вылетело из головы, что при открытии DOCS в playground отражаются не все типы.
Как тот суслик...
Спасибо!
Дима, привет!

При открытии DOCS выводятся корневые свойства типов Query, Mutation, Subscription.

Кстати, довольно удобно для изучения схемы использовать GraphQL-Voyager. Вот твоя схема:


Видно, что в списке типов твои злосчастные типы имеются, но получить к ним доступ нет связей.

К сожалению, я не вылил гугл-расширение в гугл-стор (ибо это заморочки), но установить можно. Вот инструкция краткая:

2. Устанавливаешь зависимости
yarn install
3. Собираешь билд
yarn build
Если все ОК, появится папка dist
4. Удаляешь папку node_modules
rm -rf node_modules
Просто иначе при установке в браузер гугл съест и ее и будет чуть-чуть ругаться и места много лишнего будет скушано.
5. В хроме открываешь управление расширениями, включаешь Developer mode (в правом верхнем углу) и жмешь Load unpacked (в левом правом углу), выбираешь папку проекта и жмешь Select (то есть выбираешь не какой-то файл, а именно указываешь путь в папку).


Если все ОК, появится установленное расширение.


Иконку запуска ищи там же, где и все остальные иконки расширений. Чтобы работало, конечно же надо, чтобы АПИ работало (то есть http://localhost:3000/api/ ).
Супер, спасибо! Ставлю вояджер!
Николай, вопрос по вояджеру: по ссылке ошибка 404 вылезает((

Приватная репа была :) Открыл.
Николай, посмотри, пожалуйста, 2 коммита на предмет правильности: добавлены запросы на посты и грибы в нексус.

Да, в целом ОК. Только переименуй PostQuery в PostExtendQuery и MashroomQuery в MashroomExtendQuery.
Ну и самое веселое: вынеси Mashroom в отдельный файл. Сейчас у тебя это в одном файле с постами. Знаю, ты так сделал, потому что не знаешь как это сделать , и решил просто не спрашивать про возникающую ошибку :) Но это можно сделать. Поломай немного голову (попробуй найти решение в схеме freecode.academy)

Спасибо!
Но вообще занятность в том, что сначала грибы были енумом - вот я его и пихнул в посты) То есть мне еще надо понять, о какой ошибке ты пишешь...
Будешь делать, увидишь. Вопрос только как быстро решишь.
Да, вылезла ошибка: изучаю freecode.academy
Николай, не подскажешь, почему не могу рестартнуть mysql?

dima@dima-Lenovo-ideapad-720-15IKB:~$ mc

dima@dima-Lenovo-ideapad-720-15IKB:~/projects/prisma/doker-prisma/dockerdocker-compose ps
Name Command State Ports
------------------------------------------------------------------------------
docker-nextjs-test_mysql_1 docker-entrypoint.sh mysqld Exit 255
docker-nextjs-test_pma_1 /docker-entrypoint.sh apac ... Exit 0
dima@dima-Lenovo-ideapad-720-15IKB:~/projects/prisma/doker-prisma/docker-nextjs-test$ docker-compose restart docker-nextjs-test_mysql_1
ERROR: No such service: docker-nextjs-test_mysql_1
dima@dima-Lenovo-ideapad-720-15IKB:~/projects/prisma/doker-prisma/docker-nextjs-test$ docker-compose restart
Restarting docker-nextjs-test_pma_1 ... done
Restarting docker-nextjs-test_mysql_1 ... error

ERROR: for docker-nextjs-test_mysql_1 Cannot restart container 1a61ad005a0430d13896ca3f54b808af6216ce4a7b3f5dfb3fa4da42eb2aa7e9: driver failed programming external connectivity on endpoint docker-nextjs-test_mysql_1 (d1d8083dc58e7f22e9a43c3fcbd9e48cd0623c8c6b0da710cc540858bb48d2c6): Error starting userland proxy: listen tcp4 0.0.0.0:3306: bind: address already in use
dima@dima-Lenovo-ideapad-720-15IKB:~/projects/prisma/doker-prisma/docker-nextjs-test$

-------------------------------------------------------
test$ sudo netstat -tulpn
[sudo] пароль для dima:
Активные соединения с интернетом (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 127.0.0.1:33060 0.0.0.0:* LISTEN 1174/mysqld
tcp 0 0 127.0.0.1:3306 0.0.0.0:* LISTEN 1174/mysqld
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 1081/nginx: master
tcp 0 0 127.0.0.53:53 0.0.0.0:* LISTEN 861/systemd-resolve
tcp 0 0 127.0.0.1:631 0.0.0.0:* LISTEN 1003/cupsd
tcp 0 0 127.0.0.1:5432 0.0.0.0:* LISTEN 1141/postgres
tcp 0 0 127.0.0.1:5433 0.0.0.0:* LISTEN 1137/postgres
tcp 0 0 0.0.0.0:8090 0.0.0.0:* LISTEN 4808/docker-proxy
tcp6 0 0 :::80 :::* LISTEN 1081/nginx: master
tcp6 0 0 :::1716 :::* LISTEN 2456/kdeconnectd
tcp6 0 0 ::1:631 :::* LISTEN 1003/cupsd
tcp6 0 0 :::8090 :::* LISTEN 4816/docker-proxy
udp 0 0 224.0.0.251:5353 0.0.0.0:* 3101/chrome --enabl
udp 0 0 224.0.0.251:5353 0.0.0.0:* 3101/chrome --enabl
udp 0 0 224.0.0.251:5353 0.0.0.0:* 3290/chrome --type=
udp 0 0 0.0.0.0:5353 0.0.0.0:* 898/avahi-daemon: r
udp 0 0 127.0.0.53:53 0.0.0.0:* 861/systemd-resolve
udp 0 0 0.0.0.0:631 0.0.0.0:* 1184/cups-browsed
udp 0 0 0.0.0.0:34730 0.0.0.0:* 898/avahi-daemon: r
udp6 0 0 :::5353 :::* 898/avahi-daemon: r
udp6 0 0 fe80::31ed:c2:4a84::546 :::* 903/NetworkManager
udp6 0 0 :::41997 :::* 898/avahi-daemon: r
udp6 0 0 :::1716 :::* 2456/kdeconnectd


>> Error starting userland proxy: listen tcp4 0.0.0.0:3306: bind: address already in use

Потому что что я тебе говорил? Не забудь удалить локальный MySQL. Скорее всего он у тебя работает и конечно же занял пор 3306.
tcp 0 0 127.0.0.1:3306 0.0.0.0:* LISTEN 1174/mysqld

К слову. можно конкретный порт вот так проверить: sudo lsof -i :3306

И еще (но это не к этой ошибке), вот ты выполняешь: docker-compose restart docker-nextjs-test_mysql_1
Я говорил, что docker-compose оперирует именами служб, а не именами контейнеров. То есть в твоем случае надо было docker-compose restart mysql
А если по имени контейнера, то это уже через сам докер.
docker restart docker-nextjs-test_mysql_1

Спасибо!
То есть после перезагрузки локальный mysql запустился и занял порт, понял)
Николай, про грибы)

Я так и не понял, куда смотреть в коде freecode.academy.
Понял, что ошибка связана с типами, но вот дальше застрял.

Нужна подсказка(

Суть ошибки:

описываю типы Post и Mashroom в одном файле и все работает.
При попытке вывести Mashroom в отдельный файл выдаёт ошибки.
Логика подсказала, что если ошибка после разделения с Post, то как минимум можно сделать импорт Post - частично решило.
Ошибка, которую не пойму как решить:
---
Argument of type '{ description: string; filtering: true; ordering: true; }' is not assignable to parameter of type '{ type: "ERROR: No subset types are available. Please make sure that one of your GraphQL type is a subset of your t.model('<ModelName>')"; } & { alias?: undefined; resolve?: CustomFieldResolver<...> | undefined; computedInputs?: LocalComputedInputs<...> | undefined; } & NexusGenPluginFieldConfig<...> & CommonFieldCo...'. Property 'type' is missing in type '{ description: string; filtering: true; ordering: true; }' but required in type '{ type: "ERROR: No subset types are available. Please make sure that one of your GraphQL type is a subset of your t.model('<ModelName>')"; }'.ts(2345)
static.d.ts(60, 5): 'type' is declared here.(property) CommonFieldConfig.description?: string | undefined
The description to annotate the GraphQL SDL
---

Если я правильно понимаю, тип Mashroom должен быть прописан в t.model('<ModelName>'), но вот что это значит - не понимаю.
И опять никаких деталей... Что за ошибка? Не ленись приводить листинг или скриншот.
Закомиться и вылей что есть. Так я тебе долго объяснять буду.
Судя по всему ты просто опять забыл запустить yarn dev (о чем я уже не раз напоминал). То есть в целом у тебя там было ОК, просто надо было, чтобы нексус перегенерировал методы и типы (он это делает автоматически при изменении файлов, но надо, чтобы был запущен проект). Ну и конечно надо было удалить грибы из файла постов, чтобы у тебя дублей классов не было. Отправил ПР: https://github.com/linklib/gribok-prisma/pull/1

Ну и еще момент, который, как я и предполагал, ты не победишь, хотя следовало бы. Вот ты в грибах импортируешь класс поста. Обрати внимание, что у меня такого нигде нет. В том же типе User из текущего проекта много связей на другие типы, но там нет импортов этих типов. А все почему? Потому что в "type": у меня прописываются не константы-объекты, а строчные имена этих типов. Пересмотри еще раз видео, там тоже это все показывается/рассказывается. Обращай внмиание на типы переменных (видь разницу между объектами и простыми строками).

Николай, добавил тип и запрос Like для поста: все работает, но здесь: https://github.com/linklib/gribok-prisma/blob/4ba6667eec2883af7536ba12d166c48c786bfabb/server/nexus/types/Post/index.ts#L26
IDE подсвечивает ошибку на ...like... (Property 'like' does not exist on type 'PrismaClient<PrismaClientOptions, never, RejectOnNotFound | RejectPerOperation | undefined>'.ts(2339) )

ни yarn types, ни yarn types:server ничего не находят.

Я закинул коммит --no-verify на всякий случай) Не посмотришь, что это за ошибка может быть?

Дима, у тебя там все ОК. А ошибки в IDE в таких случаях - это не редкость. Дело в том, что когда ты внес изменения в призма-схему и перегенерил все, изменилось много файлов и типов. Тайпскрипт не держит все в голове и в такой момент вполне возникают ситуации, когда в кеше тайпскрипта не актуальные типы (или он еще не увидел новые типы). В таких случаях помогает рестарт тайпскрипт-сервера. В главном меню vscode выбери View -> Command Palette, а там найди TypeScript: Restart TS Server. Кликай его.


И немного жди. Занимает некоторое время. Внизу левее будет виден статус, что идет Initializing JS/TS. Как исчезнет, так ОК.


Еще важный момент: vscode бывает не ту версию тайпскрипта загружает. Из-за этого разное поведение при проверке типов (бывает в IDE совсем не то, что в консоли выполняется). Что надо сделать?

1. Проверить какая версия TS установлена в зависимостях.
yarn why typescript


Как видим, сейчас стоит 4.4.3
Смотрим в трее справа используемую текущую версию (Важно: должен быть открыт JS или TS файл для редактирования, чтобы IDE понимала, что сейчас нужен TS, иначе этой информации в трее просто не будет). Видим, что в IDE сейчас тоже используется 4.4.3. ОК, кликаем в 4.4.3 и выбираем в выпавшем меню Select typescript version.


И вот здесь как раз и кроется Дьявол: видно, что сейчас используется версия тайпскрипта, установленная в саму IDE. У меня все свежее установлено, поэтому версии и совпадают. Но часто бывает, что есть разница в версиях и бывает очень серьезная такая разница. В результате консольные команды дают одно, а в IDE мы видим другое. Надежней выбирать именно Use Workspace Version, то есть будет браться из node_modules текущего проекта.
Николай, привет! Спасибо!

Добавить комментарий