@rapidd/core 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.dockerignore +71 -0
- package/.env.example +70 -0
- package/.gitignore +11 -0
- package/LICENSE +15 -0
- package/README.md +231 -0
- package/bin/cli.js +145 -0
- package/config/app.json +166 -0
- package/config/rate-limit.json +12 -0
- package/dist/main.js +26 -0
- package/dockerfile +57 -0
- package/locales/ar_SA.json +179 -0
- package/locales/de_DE.json +179 -0
- package/locales/en_US.json +180 -0
- package/locales/es_ES.json +179 -0
- package/locales/fr_FR.json +179 -0
- package/locales/it_IT.json +179 -0
- package/locales/ja_JP.json +179 -0
- package/locales/pt_BR.json +179 -0
- package/locales/ru_RU.json +179 -0
- package/locales/tr_TR.json +179 -0
- package/main.ts +25 -0
- package/package.json +126 -0
- package/prisma/schema.prisma +9 -0
- package/prisma.config.ts +12 -0
- package/public/static/favicon.ico +0 -0
- package/public/static/image/logo.png +0 -0
- package/routes/api/v1/index.ts +113 -0
- package/src/app.ts +197 -0
- package/src/auth/Auth.ts +446 -0
- package/src/auth/stores/ISessionStore.ts +19 -0
- package/src/auth/stores/MemoryStore.ts +70 -0
- package/src/auth/stores/RedisStore.ts +92 -0
- package/src/auth/stores/index.ts +149 -0
- package/src/config/acl.ts +9 -0
- package/src/config/rls.ts +38 -0
- package/src/core/dmmf.ts +226 -0
- package/src/core/env.ts +183 -0
- package/src/core/errors.ts +87 -0
- package/src/core/i18n.ts +144 -0
- package/src/core/middleware.ts +123 -0
- package/src/core/prisma.ts +236 -0
- package/src/index.ts +112 -0
- package/src/middleware/model.ts +61 -0
- package/src/orm/Model.ts +881 -0
- package/src/orm/QueryBuilder.ts +2078 -0
- package/src/plugins/auth.ts +162 -0
- package/src/plugins/language.ts +79 -0
- package/src/plugins/rateLimit.ts +210 -0
- package/src/plugins/response.ts +80 -0
- package/src/plugins/rls.ts +51 -0
- package/src/plugins/security.ts +23 -0
- package/src/plugins/upload.ts +299 -0
- package/src/types.ts +308 -0
- package/src/utils/ApiClient.ts +526 -0
- package/src/utils/Mailer.ts +348 -0
- package/src/utils/index.ts +25 -0
- package/templates/email/example.ejs +17 -0
- package/templates/layouts/email.ejs +35 -0
- package/tsconfig.json +33 -0
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
{
|
|
2
|
+
"save": "Сохранить",
|
|
3
|
+
"edit": "Редактировать",
|
|
4
|
+
"cancel": "Отмена",
|
|
5
|
+
"close": "Закрыть",
|
|
6
|
+
"done": "Готово",
|
|
7
|
+
"yes": "Да",
|
|
8
|
+
"no": "Нет",
|
|
9
|
+
"next": "Далее",
|
|
10
|
+
"error": "Ошибка",
|
|
11
|
+
"download": "Скачать",
|
|
12
|
+
"submit": "Отправить",
|
|
13
|
+
"clear": "Очистить",
|
|
14
|
+
"searchClear": "Очистить поиск",
|
|
15
|
+
"search": "Поиск",
|
|
16
|
+
"actions": "Действия",
|
|
17
|
+
"signIn": "Войти",
|
|
18
|
+
"signUp": "Регистрация",
|
|
19
|
+
"signOut": "Выйти",
|
|
20
|
+
"Remove": "Удалить",
|
|
21
|
+
"removeUser": "Удалить пользователя",
|
|
22
|
+
"sortBy": "Сортировать по",
|
|
23
|
+
"name": "Имя",
|
|
24
|
+
"firstName": "Имя",
|
|
25
|
+
"lastName": "Фамилия",
|
|
26
|
+
"email": "Электронная почта",
|
|
27
|
+
"password": "Пароль",
|
|
28
|
+
"passwordRepeat": "Повторите пароль",
|
|
29
|
+
"account": "Аккаунт",
|
|
30
|
+
"role": "Роль",
|
|
31
|
+
"status": "Статус",
|
|
32
|
+
"reason": "Причина",
|
|
33
|
+
"lastUpdateDate": "Дата последнего обновления",
|
|
34
|
+
"sortByFieldAscending": "{field} по возрастанию",
|
|
35
|
+
"sortByFieldDescending": "{field} по убыванию",
|
|
36
|
+
"couldNotLoadDataMsg": "Не удалось загрузить данные: статус \"{data}\"",
|
|
37
|
+
"FAQ": "Часто задаваемые вопросы",
|
|
38
|
+
"frequentlyAskedQuestions": "Часто задаваемые вопросы",
|
|
39
|
+
"settings": "Настройки",
|
|
40
|
+
"eventsRewards": "События и награды",
|
|
41
|
+
"hostname": "Имя хоста",
|
|
42
|
+
"version": "Версия",
|
|
43
|
+
"profile": "Профиль",
|
|
44
|
+
"security": "Безопасность и доступ",
|
|
45
|
+
"changePassword": "Изменить пароль",
|
|
46
|
+
"securitySettings": "Настройки безопасности",
|
|
47
|
+
"requestData": "Запросить данные",
|
|
48
|
+
"deleteProfile": "Удалить учетную запись",
|
|
49
|
+
"username": "Имя пользователя",
|
|
50
|
+
"loginMethod": "Метод входа",
|
|
51
|
+
"delete": "Удалить",
|
|
52
|
+
"currentPassword": "Текущий пароль",
|
|
53
|
+
"newPassword": "Новый пароль",
|
|
54
|
+
"signUp_haveAnAccount": "У вас уже есть учетная запись?",
|
|
55
|
+
"slots_not_available": "Нет доступного времени",
|
|
56
|
+
"footer_contact_us": "Свяжитесь с нами",
|
|
57
|
+
"footer_contact_us_url": "url",
|
|
58
|
+
"privacy_policy": "Политика конфиденциальности",
|
|
59
|
+
"footer_legal_notice_url": "url",
|
|
60
|
+
"footer_company_details": "Юридическая информация",
|
|
61
|
+
"footer_company_details_url": "url",
|
|
62
|
+
"under_construction_notice": "Этот сайт находится в разработке",
|
|
63
|
+
"signInFailStackLocked_message": "Ваша учетная запись заблокирована после 5 неудачных попыток. Сбросьте пароль!",
|
|
64
|
+
"signOut_message": "Вы успешно вышли из системы",
|
|
65
|
+
"signOutForce_message": "Вы были отключены",
|
|
66
|
+
"signOutNotLatest_message": "Вы были автоматически отключены, так как обнаружена более новая сессия.",
|
|
67
|
+
"code_of_conduct": "Правила поведения",
|
|
68
|
+
"student": "Студент",
|
|
69
|
+
"teacher": "Преподаватель",
|
|
70
|
+
"emailVerified": "Email подтвержден",
|
|
71
|
+
"emailAlreadyVerified": "Email уже подтвержден",
|
|
72
|
+
"redirectNotice": "Вы будете перенаправлены через 5 секунд или <a href=\"{uri}\">нажмите здесь</a>",
|
|
73
|
+
"mailNotShowingProperly": "Письмо отображается некорректно?",
|
|
74
|
+
"viewInBrowser": "Просмотреть в браузере",
|
|
75
|
+
"welcomeMail": "Добро пожаловать в rapidd",
|
|
76
|
+
"resetPassordMail": "Сброс пароля rapidd",
|
|
77
|
+
"appointmentScheduled": "Встреча запланирована",
|
|
78
|
+
"appointmentChanged": "Встреча изменена",
|
|
79
|
+
"appointmentCancelled": "Встреча отменена",
|
|
80
|
+
"appointmentRejected": "Встреча отклонена",
|
|
81
|
+
"salutationMail": "Здравствуйте, {first_name}!",
|
|
82
|
+
"briefWelcomeTextMail": "для вас создана учетная запись на платформе rapidd. Подтвердите свой адрес электронной почты, нажав на <b>{{confirmMail}}</b>.",
|
|
83
|
+
"yourUsername": "Ваше имя пользователя <b>{username}</b>",
|
|
84
|
+
"yourPassword": "Ваш начальный пароль<span style=\"display: inline-block;margin: 0 .8em;padding: .4em .8em;border: 3px dashed #fecb5a;border-radius: .8em;\"><b>{password}</b></span>",
|
|
85
|
+
"changePasswordAfterLogin": "Пожалуйста, измените пароль после первого входа.",
|
|
86
|
+
"passwordResetTextMail": "вы запросили сброс пароля вашей учетной записи rapidd. Нажмите <b>{{confirmResetPassword}}</b>, чтобы сбросить пароль. Проигнорируйте это сообщение, если вы не делали этот запрос.",
|
|
87
|
+
"studentAppointmentTextMail": "для вас запланирована встреча по предмету <b>{subject}</b>.<br><br>{{studentAppointmentInfoMail}}<br><br>{{studentAppointmentRejectInfoMail}}<br><br>",
|
|
88
|
+
"studentAppointmentUpdateTextMail": "ваша встреча по предмету <b>{subject}</b> была обновлена.<br><br>{{studentAppointmentInfoMail}}<br><br>{{studentAppointmentRejectInfoMail}}<br><br>",
|
|
89
|
+
"studentAppointmentCancelledTextMail": "ваша встреча по предмету <b>{subject}</b> была отменена.<br><br>{{studentAppointmentInfoMail}}<br><br>",
|
|
90
|
+
"studentAppointmentInfoMail": "{{teacher}}: <b>{teacher}</b><br>Дата: <b>{date}</b><br>Время: <b>{time}</b><br>Продолжительность: <b>{duration}</b><br>Место / ссылка: <b>{location_url}</b>",
|
|
91
|
+
"studentAppointmentRejectInfoMail": "<i>Вы можете отменить встречу за 24 часа до начала.</i>",
|
|
92
|
+
"teacherAppointmentCancelledTextMail": "ваша встреча по предмету <b>{subject}</b> была отменена.<br><br>{{teacherAppointmentInfoMail}}<br><br>",
|
|
93
|
+
"teacherAppointmentRejectedTextMail": "ваш студент {{student}} отклонил встречу по предмету <b>{subject}</b>.<br><br>{{teacherAppointmentInfoMail}}<br><br>",
|
|
94
|
+
"teacherAppointmentInfoMail": "{{student}}: <b>{student}</b><br>Дата: <b>{date}</b><br>Время: <b>{time}</b><br>Продолжительность: <b>{duration}</b><br>Место / ссылка: <b>{location_url}</b>",
|
|
95
|
+
"confirmMail": "Подтвердить email",
|
|
96
|
+
"confirmResetPassword": "Сбросить пароль",
|
|
97
|
+
"viewAppointment": "Просмотреть встречу",
|
|
98
|
+
"footerText": "Наша цель — помочь каждому раскрыть свой потенциал.",
|
|
99
|
+
"footerCopyright": "© {year}, rapidd GmbH. Все права защищены.",
|
|
100
|
+
"insufficient_permissions": "Недостаточно прав",
|
|
101
|
+
"rate_limit_exceeded": "Превышен лимит запросов",
|
|
102
|
+
"record_not_found": "Запись не найдена",
|
|
103
|
+
"no_permission": "Нет разрешения",
|
|
104
|
+
"invalid_sort_field": "Параметр sortBy '{sortBy}' не является допустимым полем {model}",
|
|
105
|
+
"invalid_filter_field": "Недопустимое поле фильтра: {field}",
|
|
106
|
+
"relation_not_exist": "Связь '{relation}' не существует в {model}",
|
|
107
|
+
"between_requires_two_values": "Оператор between требует два значения, разделенных точкой с запятой",
|
|
108
|
+
"invalid_date_range": "Недопустимая дата в диапазоне: {start} или {end}",
|
|
109
|
+
"invalid_date_format": "Недопустимый формат даты в фильтре: {value}. Ошибка: {error}",
|
|
110
|
+
"invalid_limit": "Недопустимый лимит",
|
|
111
|
+
"sortby_must_be_string": "sortBy должен быть строкой. Передано '{type}'",
|
|
112
|
+
"sortorder_invalid": "sortOrder может быть только 'asc' или 'desc'. Передано '{value}'",
|
|
113
|
+
"unexpected_key": "Ключ '{key}' не ожидается",
|
|
114
|
+
"string_expected": "Ожидается строка, передано {type}",
|
|
115
|
+
"auth_credentials_missing": "Отсутствуют учетные данные для аутентификации",
|
|
116
|
+
"account_suspended": "Ваша учетная запись приостановлена",
|
|
117
|
+
"email_not_verified": "Адрес электронной почты еще не подтвержден",
|
|
118
|
+
"auth_failed_invalid_credentials": "Ошибка аутентификации: неверные учетные данные",
|
|
119
|
+
"user_not_found": "Пользователь не найден",
|
|
120
|
+
"no_active_session": "Нет активной сессии",
|
|
121
|
+
"email_not_string": "'email' в теле не является типом 'string'. Передано '{type}'",
|
|
122
|
+
"password_change_failed": "Не удалось изменить пароль",
|
|
123
|
+
"token_invalid": "Токен недействителен",
|
|
124
|
+
"password_not_string": "password в теле не является типом 'string'. Передано '{type}'",
|
|
125
|
+
"token_not_string": "token в теле не является типом 'string'. Передано '{type}'",
|
|
126
|
+
"file_type_not_allowed": "Тип файла {mimetype} не разрешен",
|
|
127
|
+
"file_extension_not_allowed": "Расширение файла {extension} не разрешено для MIME-типа {mimetype}",
|
|
128
|
+
"invalid_file_name": "Недопустимое имя файла",
|
|
129
|
+
"file_size_exceeds_limit": "Размер файла превышает лимит в {limit}МБ",
|
|
130
|
+
"cors_blocked": "Заблокировано политикой CORS: {origin}",
|
|
131
|
+
"activation_link_expired": "Срок действия ссылки активации истек",
|
|
132
|
+
"password_reset_email_sent": "Письмо для сброса пароля отправлено",
|
|
133
|
+
"password_changed_successfully": "Пароль успешно изменен",
|
|
134
|
+
"username_password_invalid": "Неверное имя пользователя или пароль",
|
|
135
|
+
"activation_mail_sent": "Письмо активации отправлено",
|
|
136
|
+
"session_terminated": "Токен сессии завершен",
|
|
137
|
+
"no_valid_session": "Нет действительной сессии",
|
|
138
|
+
"object_deleted_successfully": "{object} успешно удален",
|
|
139
|
+
"auth_required": "Требуется аутентификация",
|
|
140
|
+
"auth_required_message": "Вы должны войти в систему для доступа к этому ресурсу",
|
|
141
|
+
"forbidden": "Запрещено",
|
|
142
|
+
"forbidden_role_message": "Для этого ресурса требуется одна из следующих ролей: {roles}",
|
|
143
|
+
"email_verification_required": "Требуется подтверждение электронной почты",
|
|
144
|
+
"email_verification_required_message": "Пожалуйста, подтвердите свой адрес электронной почты перед доступом к этому ресурсу",
|
|
145
|
+
"company_account_required": "Требуется корпоративная учетная запись",
|
|
146
|
+
"company_verification_required": "Требуется подтверждение компании",
|
|
147
|
+
"company_verification_required_message": "Ваша компания должна быть подтверждена администратором перед доступом к этому ресурсу",
|
|
148
|
+
"missing_required_fields": "Отсутствуют обязательные поля",
|
|
149
|
+
"required_fields": "Обязательные поля: {fields}",
|
|
150
|
+
"invalid_role": "Недопустимая роль",
|
|
151
|
+
"invalid_role_message": "Роль должна быть либо STUDENT, либо COMPANY",
|
|
152
|
+
"email_already_registered": "Электронная почта уже зарегистрирована",
|
|
153
|
+
"email_already_registered_message": "Пользователь с таким адресом электронной почты уже существует",
|
|
154
|
+
"registration_failed": "Регистрация не удалась",
|
|
155
|
+
"invalid_credentials": "Неверные учетные данные",
|
|
156
|
+
"invalid_credentials_message": "Электронная почта или пароль неверны",
|
|
157
|
+
"invalid_login_method": "Недопустимый метод входа",
|
|
158
|
+
"invalid_login_method_message": "Пожалуйста, войдите через {provider}",
|
|
159
|
+
"login_failed": "Вход не удался",
|
|
160
|
+
"refresh_token_required": "Требуется токен обновления",
|
|
161
|
+
"invalid_refresh_token": "Недопустимый токен обновления",
|
|
162
|
+
"session_expired_or_invalid": "Сеанс истек или недействителен",
|
|
163
|
+
"token_refresh_failed": "Не удалось обновить токен",
|
|
164
|
+
"logged_out_successfully": "Успешный выход из системы",
|
|
165
|
+
"logout_failed": "Выход из системы не удался",
|
|
166
|
+
"not_authenticated": "Не аутентифицирован",
|
|
167
|
+
"missing_required_field": "Отсутствует обязательное поле",
|
|
168
|
+
"field_required": "{field} обязательно",
|
|
169
|
+
"invalid_token": "Недопустимый токен {provider}",
|
|
170
|
+
"invalid_token_message": "{message}",
|
|
171
|
+
"role_required_for_new_users": "Требуется роль для новых пользователей",
|
|
172
|
+
"role_required_for_new_users_message": "Пожалуйста, укажите, являетесь ли вы STUDENT или COMPANY",
|
|
173
|
+
"google_auth_failed": "Аутентификация Google не удалась",
|
|
174
|
+
"facebook_auth_failed": "Аутентификация Facebook не удалась",
|
|
175
|
+
"token_missing_email": "Токен не содержит информацию об электронной почте",
|
|
176
|
+
"oauth_config_missing": "ID приложения и секрет {provider} должны быть настроены в переменных окружения",
|
|
177
|
+
"token_app_mismatch": "Токен не принадлежит этому приложению",
|
|
178
|
+
"oauth_email_permission_missing": "Пользователь {provider} не предоставил разрешение на доступ к электронной почте"
|
|
179
|
+
}
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
{
|
|
2
|
+
"save": "Kaydet",
|
|
3
|
+
"edit": "Düzenle",
|
|
4
|
+
"cancel": "İptal",
|
|
5
|
+
"close": "Kapat",
|
|
6
|
+
"done": "Tamamlandı",
|
|
7
|
+
"yes": "Evet",
|
|
8
|
+
"no": "Hayır",
|
|
9
|
+
"next": "Sonraki",
|
|
10
|
+
"error": "Hata",
|
|
11
|
+
"download": "İndir",
|
|
12
|
+
"submit": "Gönder",
|
|
13
|
+
"clear": "Temizle",
|
|
14
|
+
"searchClear": "Aramayı temizle",
|
|
15
|
+
"search": "Ara",
|
|
16
|
+
"actions": "İşlemler",
|
|
17
|
+
"signIn": "Giriş yap",
|
|
18
|
+
"signUp": "Kayıt ol",
|
|
19
|
+
"signOut": "Çıkış yap",
|
|
20
|
+
"Remove": "Kaldır",
|
|
21
|
+
"removeUser": "Kullanıcıyı kaldır",
|
|
22
|
+
"sortBy": "Sırala",
|
|
23
|
+
"name": "Ad",
|
|
24
|
+
"firstName": "Ad",
|
|
25
|
+
"lastName": "Soyad",
|
|
26
|
+
"email": "E-posta",
|
|
27
|
+
"password": "Şifre",
|
|
28
|
+
"passwordRepeat": "Şifreyi tekrar et",
|
|
29
|
+
"account": "Hesap",
|
|
30
|
+
"role": "Rol",
|
|
31
|
+
"status": "Durum",
|
|
32
|
+
"reason": "Sebep",
|
|
33
|
+
"lastUpdateDate": "Son güncelleme tarihi",
|
|
34
|
+
"sortByFieldAscending": "{field} artan",
|
|
35
|
+
"sortByFieldDescending": "{field} azalan",
|
|
36
|
+
"couldNotLoadDataMsg": "Veriler yüklenemedi: durum \"{data}\"",
|
|
37
|
+
"FAQ": "SSS",
|
|
38
|
+
"frequentlyAskedQuestions": "Sıkça Sorulan Sorular",
|
|
39
|
+
"settings": "Ayarlar",
|
|
40
|
+
"eventsRewards": "Etkinlikler & Ödüller",
|
|
41
|
+
"hostname": "Ana makine adı",
|
|
42
|
+
"version": "Sürüm",
|
|
43
|
+
"profile": "Profil",
|
|
44
|
+
"security": "Güvenlik & erişim",
|
|
45
|
+
"changePassword": "Şifre değiştir",
|
|
46
|
+
"securitySettings": "Güvenlik ayarları",
|
|
47
|
+
"requestData": "Veri talep et",
|
|
48
|
+
"deleteProfile": "Hesabı sil",
|
|
49
|
+
"username": "Kullanıcı adı",
|
|
50
|
+
"loginMethod": "Giriş yöntemi",
|
|
51
|
+
"delete": "Sil",
|
|
52
|
+
"currentPassword": "Mevcut şifre",
|
|
53
|
+
"newPassword": "Yeni şifre",
|
|
54
|
+
"signUp_haveAnAccount": "Zaten bir hesabın var mı?",
|
|
55
|
+
"slots_not_available": "Uygun zaman bilgisi yok",
|
|
56
|
+
"footer_contact_us": "İletişim",
|
|
57
|
+
"footer_contact_us_url": "url",
|
|
58
|
+
"privacy_policy": "Gizlilik Politikası",
|
|
59
|
+
"footer_legal_notice_url": "url",
|
|
60
|
+
"footer_company_details": "Yasal bilgiler",
|
|
61
|
+
"footer_company_details_url": "url",
|
|
62
|
+
"under_construction_notice": "Bu site şu anda yapım aşamasındadır",
|
|
63
|
+
"signInFailStackLocked_message": "Hesabınız 5 başarısız girişten sonra kilitlendi. Lütfen şifrenizi sıfırlayın!",
|
|
64
|
+
"signOut_message": "Başarıyla çıkış yaptınız",
|
|
65
|
+
"signOutForce_message": "Oturumunuz sonlandırıldı",
|
|
66
|
+
"signOutNotLatest_message": "Daha yeni bir oturum tespit edildiği için çıkış yaptınız.",
|
|
67
|
+
"code_of_conduct": "Davranış kuralları",
|
|
68
|
+
"student": "Öğrenci",
|
|
69
|
+
"teacher": "Öğretmen",
|
|
70
|
+
"emailVerified": "E-posta onaylandı",
|
|
71
|
+
"emailAlreadyVerified": "E-posta zaten onaylandı",
|
|
72
|
+
"redirectNotice": "5 saniye içinde yönlendirileceksiniz ya da <a href=\"{uri}\">buraya tıklayın</a>",
|
|
73
|
+
"mailNotShowingProperly": "E-posta düzgün görüntülenmiyor mu?",
|
|
74
|
+
"viewInBrowser": "Tarayıcıda görüntüle",
|
|
75
|
+
"welcomeMail": "rapidd'e Hoş Geldin",
|
|
76
|
+
"resetPassordMail": "rapidd şifreni sıfırla",
|
|
77
|
+
"appointmentScheduled": "Randevu planlandı",
|
|
78
|
+
"appointmentChanged": "Randevu değiştirildi",
|
|
79
|
+
"appointmentCancelled": "Randevu iptal edildi",
|
|
80
|
+
"appointmentRejected": "Randevu reddedildi",
|
|
81
|
+
"salutationMail": "Merhaba {first_name},",
|
|
82
|
+
"briefWelcomeTextMail": "rapidd platformunda senin için bir hesap oluşturuldu. Lütfen <b>{{confirmMail}}</b> tıklayarak e-posta adresini onayla.",
|
|
83
|
+
"yourUsername": "Kullanıcı adın <b>{username}</b>",
|
|
84
|
+
"yourPassword": "İlk şifren<span style=\"display: inline-block;margin: 0 .8em;padding: .4em .8em;border: 3px dashed #fecb5a;border-radius: .8em;\"><b>{password}</b></span>",
|
|
85
|
+
"changePasswordAfterLogin": "İlk girişten sonra şifreni değiştirmeni rica ederiz.",
|
|
86
|
+
"passwordResetTextMail": "rapidd hesabın için şifre sıfırlama talebinde bulundun. Şifreni sıfırlamak için <b>{{confirmResetPassword}}</b> tıkla. Bu işlemi sen yapmadıysan bu mesajı yok say.",
|
|
87
|
+
"studentAppointmentTextMail": "<b>{subject}</b> dersi için sana bir randevu atandı.<br><br>{{studentAppointmentInfoMail}}<br><br>{{studentAppointmentRejectInfoMail}}<br><br>",
|
|
88
|
+
"studentAppointmentUpdateTextMail": "<b>{subject}</b> dersi için randevun güncellendi.<br><br>{{studentAppointmentInfoMail}}<br><br>{{studentAppointmentRejectInfoMail}}<br><br>",
|
|
89
|
+
"studentAppointmentCancelledTextMail": "<b>{subject}</b> dersi için randevun iptal edildi.<br><br>{{studentAppointmentInfoMail}}<br><br>",
|
|
90
|
+
"studentAppointmentInfoMail": "{{teacher}}: <b>{teacher}</b><br>Tarih: <b>{date}</b><br>Saat: <b>{time}</b><br>Süre: <b>{duration}</b><br>Yer / Online bağlantı: <b>{location_url}</b>",
|
|
91
|
+
"studentAppointmentRejectInfoMail": "<i>Dersi başlamadan en geç 24 saat önce reddedebilirsin.</i>",
|
|
92
|
+
"teacherAppointmentCancelledTextMail": "<b>{subject}</b> dersi için randevunuz iptal edildi.<br><br>{{teacherAppointmentInfoMail}}<br><br>",
|
|
93
|
+
"teacherAppointmentRejectedTextMail": "{{student}} öğrenciniz <b>{subject}</b> dersi için randevuyu reddetti.<br><br>{{teacherAppointmentInfoMail}}<br><br>",
|
|
94
|
+
"teacherAppointmentInfoMail": "{{student}}: <b>{student}</b><br>Tarih: <b>{date}</b><br>Saat: <b>{time}</b><br>Süre: <b>{duration}</b><br>Yer / Online bağlantı: <b>{location_url}</b>",
|
|
95
|
+
"confirmMail": "E-postayı onayla",
|
|
96
|
+
"confirmResetPassword": "Şifreyi sıfırla",
|
|
97
|
+
"viewAppointment": "Randevuyu görüntüle",
|
|
98
|
+
"footerText": "Amacımız herkesin potansiyelini gerçekleştirmesine yardımcı olmaktır.",
|
|
99
|
+
"footerCopyright": "© {year}, rapidd GmbH. Tüm hakları saklıdır.",
|
|
100
|
+
"insufficient_permissions": "Yetersiz izinler",
|
|
101
|
+
"rate_limit_exceeded": "İstek limiti aşıldı",
|
|
102
|
+
"record_not_found": "Kayıt bulunamadı",
|
|
103
|
+
"no_permission": "İzin yok",
|
|
104
|
+
"invalid_sort_field": "'{sortBy}' parametresi {modelName} için geçerli bir alan değil",
|
|
105
|
+
"invalid_filter_field": "Geçersiz filtre alanı: {field}",
|
|
106
|
+
"relation_not_exist": "'{relation}' ilişkisi {modelName} içinde mevcut değil",
|
|
107
|
+
"between_requires_two_values": "Between operatörü noktalı virgülle ayrılmış iki değer gerektirir",
|
|
108
|
+
"invalid_date_range": "Aralıkta geçersiz tarih: {start} veya {end}",
|
|
109
|
+
"invalid_date_format": "Filtrede geçersiz tarih formatı: {value}. Hata: {error}",
|
|
110
|
+
"invalid_limit": "Geçersiz limit",
|
|
111
|
+
"sortby_must_be_string": "sortBy bir string olmalıdır. '{type}' verildi",
|
|
112
|
+
"sortorder_invalid": "sortOrder sadece 'asc' veya 'desc' olabilir. '{value}' verildi",
|
|
113
|
+
"unexpected_key": "'{key}' anahtarı beklenmiyordu",
|
|
114
|
+
"string_expected": "String bekleniyor, {type} verildi",
|
|
115
|
+
"auth_credentials_missing": "Kimlik doğrulama bilgileri eksik",
|
|
116
|
+
"account_suspended": "Hesabınız askıya alındı",
|
|
117
|
+
"email_not_verified": "E-posta adresi henüz doğrulanmadı",
|
|
118
|
+
"auth_failed_invalid_credentials": "Kimlik doğrulama başarısız: geçersiz kimlik bilgileri",
|
|
119
|
+
"user_not_found": "Kullanıcı bulunamadı",
|
|
120
|
+
"no_active_session": "Aktif oturum yok",
|
|
121
|
+
"email_not_string": "body içindeki 'email' 'string' tipinde değil. '{type}' verildi",
|
|
122
|
+
"password_change_failed": "Şifre değiştirilemedi",
|
|
123
|
+
"token_invalid": "Token geçersiz",
|
|
124
|
+
"password_not_string": "body içindeki password 'string' tipinde değil. '{type}' verildi",
|
|
125
|
+
"token_not_string": "body içindeki token 'string' tipinde değil. '{type}' verildi",
|
|
126
|
+
"file_type_not_allowed": "Dosya tipi {mimetype} izin verilmiyor",
|
|
127
|
+
"file_extension_not_allowed": "{extension} dosya uzantısına {mimetype} MIME tipi için izin verilmiyor",
|
|
128
|
+
"invalid_file_name": "Geçersiz dosya adı",
|
|
129
|
+
"file_size_exceeds_limit": "Dosya boyutu {limit}MB limitini aşıyor",
|
|
130
|
+
"cors_blocked": "CORS politikası tarafından engellendi: {origin}",
|
|
131
|
+
"activation_link_expired": "Aktivasyon bağlantısının süresi doldu",
|
|
132
|
+
"password_reset_email_sent": "Şifre sıfırlama e-postası gönderildi",
|
|
133
|
+
"password_changed_successfully": "Şifre başarıyla değiştirildi",
|
|
134
|
+
"username_password_invalid": "Kullanıcı adı veya şifre geçersiz",
|
|
135
|
+
"activation_mail_sent": "Aktivasyon e-postası gönderildi",
|
|
136
|
+
"session_terminated": "Oturum sonlandırıldı",
|
|
137
|
+
"no_valid_session": "Geçerli oturum yok",
|
|
138
|
+
"object_deleted_successfully": "{modelName} başarıyla silindi",
|
|
139
|
+
"auth_required": "Kimlik doğrulama gerekli",
|
|
140
|
+
"auth_required_message": "Bu kaynağa erişmek için giriş yapmalısınız",
|
|
141
|
+
"forbidden": "Yasak",
|
|
142
|
+
"forbidden_role_message": "Bu kaynak şu rollerden birini gerektirir: {roles}",
|
|
143
|
+
"email_verification_required": "E-posta doğrulaması gerekli",
|
|
144
|
+
"email_verification_required_message": "Bu kaynağa erişmeden önce lütfen e-posta adresinizi doğrulayın",
|
|
145
|
+
"company_account_required": "Şirket hesabı gerekli",
|
|
146
|
+
"company_verification_required": "Şirket doğrulaması gerekli",
|
|
147
|
+
"company_verification_required_message": "Bu kaynağa erişmeden önce şirketinizin bir yönetici tarafından doğrulanması gerekir",
|
|
148
|
+
"missing_required_fields": "Gerekli alanlar eksik",
|
|
149
|
+
"required_fields": "Gerekli alanlar: {fields}",
|
|
150
|
+
"invalid_role": "Geçersiz rol",
|
|
151
|
+
"invalid_role_message": "Rol STUDENT veya COMPANY olmalıdır",
|
|
152
|
+
"email_already_registered": "E-posta zaten kayıtlı",
|
|
153
|
+
"email_already_registered_message": "Bu e-posta adresine sahip bir kullanıcı zaten mevcut",
|
|
154
|
+
"registration_failed": "Kayıt başarısız",
|
|
155
|
+
"invalid_credentials": "Geçersiz kimlik bilgileri",
|
|
156
|
+
"invalid_credentials_message": "E-posta veya şifre yanlış",
|
|
157
|
+
"invalid_login_method": "Geçersiz giriş yöntemi",
|
|
158
|
+
"invalid_login_method_message": "Lütfen {provider} ile giriş yapın",
|
|
159
|
+
"login_failed": "Giriş başarısız",
|
|
160
|
+
"refresh_token_required": "Yenileme tokeni gerekli",
|
|
161
|
+
"invalid_refresh_token": "Geçersiz yenileme tokeni",
|
|
162
|
+
"session_expired_or_invalid": "Oturum süresi dolmuş veya geçersiz",
|
|
163
|
+
"token_refresh_failed": "Token yenileme başarısız",
|
|
164
|
+
"logged_out_successfully": "Başarıyla çıkış yapıldı",
|
|
165
|
+
"logout_failed": "Çıkış başarısız",
|
|
166
|
+
"not_authenticated": "Kimlik doğrulanmadı",
|
|
167
|
+
"missing_required_field": "Gerekli alan eksik",
|
|
168
|
+
"field_required": "{field} gereklidir",
|
|
169
|
+
"invalid_token": "Geçersiz {provider} tokeni",
|
|
170
|
+
"invalid_token_message": "{message}",
|
|
171
|
+
"role_required_for_new_users": "Yeni kullanıcılar için rol gerekli",
|
|
172
|
+
"role_required_for_new_users_message": "Lütfen STUDENT veya COMPANY olduğunuzu belirtin",
|
|
173
|
+
"google_auth_failed": "Google kimlik doğrulaması başarısız",
|
|
174
|
+
"facebook_auth_failed": "Facebook kimlik doğrulaması başarısız",
|
|
175
|
+
"token_missing_email": "Token e-posta bilgisi içermiyor",
|
|
176
|
+
"oauth_config_missing": "{provider} Uygulama ID'si ve Secret ortam değişkenlerinde yapılandırılmalıdır",
|
|
177
|
+
"token_app_mismatch": "Token bu uygulamaya ait değil",
|
|
178
|
+
"oauth_email_permission_missing": "{provider} kullanıcısı e-posta izni vermemiş"
|
|
179
|
+
}
|
package/main.ts
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import 'dotenv/config';
|
|
2
|
+
import { getEnv } from './src/core/env';
|
|
3
|
+
import { buildApp } from './src/app';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Application entry point
|
|
7
|
+
* Builds Fastify app and starts server
|
|
8
|
+
*/
|
|
9
|
+
export async function start(): Promise<void> {
|
|
10
|
+
const port = getEnv('PORT');
|
|
11
|
+
const host = getEnv('HOST');
|
|
12
|
+
|
|
13
|
+
try {
|
|
14
|
+
const app = await buildApp();
|
|
15
|
+
|
|
16
|
+
await app.listen({ port, host });
|
|
17
|
+
console.log(`[Rapidd] Server running at http://${host}:${port}`);
|
|
18
|
+
console.log(`[Rapidd] Environment: ${getEnv('NODE_ENV')}`);
|
|
19
|
+
} catch (err) {
|
|
20
|
+
console.error('[Startup Error]', (err as Error).message);
|
|
21
|
+
process.exit(1);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
start();
|
package/package.json
ADDED
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@rapidd/core",
|
|
3
|
+
"publishConfig": {
|
|
4
|
+
"access": "public"
|
|
5
|
+
},
|
|
6
|
+
"version": "2.1.0",
|
|
7
|
+
"description": "Code-first REST API framework for TypeScript. Database in, API out.",
|
|
8
|
+
"main": "dist/main.js",
|
|
9
|
+
"bin": {
|
|
10
|
+
"rapidd": "bin/cli.js"
|
|
11
|
+
},
|
|
12
|
+
"files": [
|
|
13
|
+
"bin/",
|
|
14
|
+
"src/",
|
|
15
|
+
"config/",
|
|
16
|
+
"locales/",
|
|
17
|
+
"routes/",
|
|
18
|
+
"templates/",
|
|
19
|
+
"public/",
|
|
20
|
+
"prisma/schema.prisma",
|
|
21
|
+
"prisma.config.ts",
|
|
22
|
+
"main.ts",
|
|
23
|
+
"tsconfig.json",
|
|
24
|
+
".env.example",
|
|
25
|
+
".gitignore",
|
|
26
|
+
".dockerignore",
|
|
27
|
+
"dockerfile"
|
|
28
|
+
],
|
|
29
|
+
"repository": {
|
|
30
|
+
"type": "git",
|
|
31
|
+
"url": "git+https://github.com/MertDalbudak/rapidd.git"
|
|
32
|
+
},
|
|
33
|
+
"homepage": "https://github.com/MertDalbudak/rapidd#readme",
|
|
34
|
+
"bugs": {
|
|
35
|
+
"url": "https://github.com/MertDalbudak/rapidd/issues"
|
|
36
|
+
},
|
|
37
|
+
"keywords": [
|
|
38
|
+
"rest-api",
|
|
39
|
+
"typescript",
|
|
40
|
+
"fastify",
|
|
41
|
+
"prisma",
|
|
42
|
+
"orm",
|
|
43
|
+
"authentication",
|
|
44
|
+
"acl",
|
|
45
|
+
"rls",
|
|
46
|
+
"crud",
|
|
47
|
+
"api-framework",
|
|
48
|
+
"code-generation",
|
|
49
|
+
"postgresql",
|
|
50
|
+
"mysql"
|
|
51
|
+
],
|
|
52
|
+
"scripts": {
|
|
53
|
+
"start": "node dist/main.js",
|
|
54
|
+
"dev": "tsx watch main.ts",
|
|
55
|
+
"build": "tsc",
|
|
56
|
+
"test": "jest --forceExit",
|
|
57
|
+
"typecheck": "tsc --noEmit"
|
|
58
|
+
},
|
|
59
|
+
"engines": {
|
|
60
|
+
"node": ">=24.0.0"
|
|
61
|
+
},
|
|
62
|
+
"author": "Mert Dalbudak",
|
|
63
|
+
"license": "ISC",
|
|
64
|
+
"dependencies": {
|
|
65
|
+
"@fastify/cookie": "^11.0.2",
|
|
66
|
+
"@fastify/cors": "^11.0.0",
|
|
67
|
+
"@fastify/formbody": "^8.0.2",
|
|
68
|
+
"@fastify/multipart": "^9.4.0",
|
|
69
|
+
"@fastify/static": "^9.0.0",
|
|
70
|
+
"@prisma/adapter-mariadb": "^7.0.1",
|
|
71
|
+
"@prisma/adapter-pg": "^7.0.1",
|
|
72
|
+
"@prisma/client": "^7.0.1",
|
|
73
|
+
"@prisma/internals": "^7.0.1",
|
|
74
|
+
"bcrypt": "^6.0.0",
|
|
75
|
+
"dotenv": "^17.3.1",
|
|
76
|
+
"ejs": "^4.0.1",
|
|
77
|
+
"fastify": "^5.2.1",
|
|
78
|
+
"fastify-plugin": "^5.0.1",
|
|
79
|
+
"ioredis": "^5.6.1",
|
|
80
|
+
"jsonwebtoken": "^9.0.2",
|
|
81
|
+
"luxon": "^3.7.2",
|
|
82
|
+
"nodemailer": "^8.0.1",
|
|
83
|
+
"pg": "^8.16.3"
|
|
84
|
+
},
|
|
85
|
+
"devDependencies": {
|
|
86
|
+
"@rapidd/build": "^2.1.3",
|
|
87
|
+
"@types/bcrypt": "^6.0.0",
|
|
88
|
+
"@types/ejs": "^3.1.5",
|
|
89
|
+
"@types/jest": "^30.0.0",
|
|
90
|
+
"@types/jsonwebtoken": "^9.0.8",
|
|
91
|
+
"@types/luxon": "^3.7.1",
|
|
92
|
+
"@types/node": "^22.12.0",
|
|
93
|
+
"@types/nodemailer": "^7.0.9",
|
|
94
|
+
"@types/pg": "^8.11.11",
|
|
95
|
+
"jest": "^29.7.0",
|
|
96
|
+
"prisma": "^7.0.2",
|
|
97
|
+
"ts-jest": "^29.2.5",
|
|
98
|
+
"tsx": "^4.19.2",
|
|
99
|
+
"typescript": "^5.7.3"
|
|
100
|
+
},
|
|
101
|
+
"jest": {
|
|
102
|
+
"testEnvironment": "node",
|
|
103
|
+
"transform": {
|
|
104
|
+
"^.+\\.tsx?$": [
|
|
105
|
+
"ts-jest",
|
|
106
|
+
{
|
|
107
|
+
"tsconfig": "tsconfig.test.json"
|
|
108
|
+
}
|
|
109
|
+
]
|
|
110
|
+
},
|
|
111
|
+
"moduleFileExtensions": [
|
|
112
|
+
"ts",
|
|
113
|
+
"tsx",
|
|
114
|
+
"js",
|
|
115
|
+
"jsx",
|
|
116
|
+
"json"
|
|
117
|
+
],
|
|
118
|
+
"testMatch": [
|
|
119
|
+
"**/__test__/**/*.test.ts",
|
|
120
|
+
"**/__test__/**/*.test.js"
|
|
121
|
+
],
|
|
122
|
+
"coveragePathIgnorePatterns": [
|
|
123
|
+
"/node_modules/"
|
|
124
|
+
]
|
|
125
|
+
}
|
|
126
|
+
}
|
package/prisma.config.ts
ADDED
|
Binary file
|
|
Binary file
|