Add ktlint plugin

This commit is contained in:
Hubert Van De Walle 2020-10-26 17:21:48 +01:00
parent 7995a0b3e0
commit c709f2b44d
40 changed files with 128 additions and 88 deletions

View File

@ -1,7 +1,7 @@
plugins { plugins {
`kotlin-dsl` `kotlin-dsl`
kotlin("jvm") version "1.4.10" kotlin("jvm") version "1.4.10"
id("com.github.johnrengelman.shadow") version "6.1.0" id("com.github.johnrengelman.shadow") version "6.1.0" apply false
} }
repositories { repositories {
@ -12,4 +12,5 @@ repositories {
dependencies { dependencies {
implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:1.4.10") implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:1.4.10")
implementation("com.github.jengelman.gradle.plugins:shadow:6.1.0") implementation("com.github.jengelman.gradle.plugins:shadow:6.1.0")
implementation("org.jlleitschuh.gradle:ktlint-gradle:9.4.1")
} }

View File

@ -6,6 +6,7 @@ plugins {
java java
kotlin("jvm") kotlin("jvm")
`java-library` `java-library`
id("org.jlleitschuh.gradle.ktlint")
} }
repositories { repositories {
@ -21,6 +22,7 @@ version = "1.0-SNAPSHOT"
dependencies { dependencies {
implementation(kotlin("stdlib-jdk8")) implementation(kotlin("stdlib-jdk8"))
implementation(platform("org.jetbrains.kotlin:kotlin-bom:1.4.10"))
} }
tasks.withType<Test> { tasks.withType<Test> {

View File

@ -2,10 +2,10 @@ package be.simplenotes.app.api
import be.simplenotes.app.extensions.auto import be.simplenotes.app.extensions.auto
import be.simplenotes.app.utils.parseSearchTerms import be.simplenotes.app.utils.parseSearchTerms
import be.simplenotes.types.PersistedNote
import be.simplenotes.types.PersistedNoteMetadata
import be.simplenotes.domain.usecases.NoteService import be.simplenotes.domain.usecases.NoteService
import be.simplenotes.types.LoggedInUser import be.simplenotes.types.LoggedInUser
import be.simplenotes.types.PersistedNote
import be.simplenotes.types.PersistedNoteMetadata
import kotlinx.serialization.Contextual import kotlinx.serialization.Contextual
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import kotlinx.serialization.json.Json import kotlinx.serialization.json.Json
@ -28,7 +28,7 @@ class ApiNoteController(private val noteService: NoteService, private val json:
) )
} }
fun notes(request: Request, loggedInUser: LoggedInUser): Response { fun notes(@Suppress("UNUSED_PARAMETER") request: Request, loggedInUser: LoggedInUser): Response {
val notes = noteService.paginatedNotes(loggedInUser.userId, page = 1).notes val notes = noteService.paginatedNotes(loggedInUser.userId, page = 1).notes
return persistedNotesMetadataLens(notes, Response(OK)) return persistedNotesMetadataLens(notes, Response(OK))
} }
@ -40,12 +40,15 @@ class ApiNoteController(private val noteService: NoteService, private val json:
fun update(request: Request, loggedInUser: LoggedInUser): Response { fun update(request: Request, loggedInUser: LoggedInUser): Response {
val content = noteContentLens(request) val content = noteContentLens(request)
return noteService.update(loggedInUser.userId, uuidLens(request), content).fold({ return noteService.update(loggedInUser.userId, uuidLens(request), content).fold(
Response(BAD_REQUEST) {
}, { Response(BAD_REQUEST)
if (it == null) Response(NOT_FOUND) },
else Response(OK) {
}) if (it == null) Response(NOT_FOUND)
else Response(OK)
}
)
} }
fun search(request: Request, loggedInUser: LoggedInUser): Response { fun search(request: Request, loggedInUser: LoggedInUser): Response {
@ -61,7 +64,6 @@ class ApiNoteController(private val noteService: NoteService, private val json:
private val persistedNotesMetadataLens = json.auto<List<PersistedNoteMetadata>>().toLens() private val persistedNotesMetadataLens = json.auto<List<PersistedNoteMetadata>>().toLens()
private val persistedNoteLens = json.auto<PersistedNote>().toLens() private val persistedNoteLens = json.auto<PersistedNote>().toLens()
private val uuidLens = Path.uuid().of("uuid") private val uuidLens = Path.uuid().of("uuid")
} }
@Serializable @Serializable

View File

@ -7,6 +7,6 @@ import org.http4k.core.Status.Companion.OK
import org.http4k.core.Status.Companion.SERVICE_UNAVAILABLE import org.http4k.core.Status.Companion.SERVICE_UNAVAILABLE
class HealthCheckController(private val dbHealthCheck: DbHealthCheck) { class HealthCheckController(private val dbHealthCheck: DbHealthCheck) {
fun healthCheck(request: Request) = fun healthCheck(@Suppress("UNUSED_PARAMETER") request: Request) =
if (dbHealthCheck.isOk()) Response(OK) else Response(SERVICE_UNAVAILABLE) if (dbHealthCheck.isOk()) Response(OK) else Response(SERVICE_UNAVAILABLE)
} }

View File

@ -3,12 +3,12 @@ package be.simplenotes.app.controllers
import be.simplenotes.app.extensions.html import be.simplenotes.app.extensions.html
import be.simplenotes.app.extensions.redirect import be.simplenotes.app.extensions.redirect
import be.simplenotes.app.utils.parseSearchTerms import be.simplenotes.app.utils.parseSearchTerms
import be.simplenotes.views.NoteView
import be.simplenotes.domain.usecases.NoteService import be.simplenotes.domain.usecases.NoteService
import be.simplenotes.domain.usecases.markdown.InvalidMeta import be.simplenotes.domain.usecases.markdown.InvalidMeta
import be.simplenotes.domain.usecases.markdown.MissingMeta import be.simplenotes.domain.usecases.markdown.MissingMeta
import be.simplenotes.domain.usecases.markdown.ValidationError import be.simplenotes.domain.usecases.markdown.ValidationError
import be.simplenotes.types.LoggedInUser import be.simplenotes.types.LoggedInUser
import be.simplenotes.views.NoteView
import org.http4k.core.Method import org.http4k.core.Method
import org.http4k.core.Request import org.http4k.core.Request
import org.http4k.core.Response import org.http4k.core.Response
@ -33,8 +33,16 @@ class NoteController(
return noteService.create(loggedInUser.userId, markdownForm).fold( return noteService.create(loggedInUser.userId, markdownForm).fold(
{ {
val html = when (it) { val html = when (it) {
MissingMeta -> view.noteEditor(loggedInUser, error = "Missing note metadata", textarea = markdownForm) MissingMeta -> view.noteEditor(
InvalidMeta -> view.noteEditor(loggedInUser, error = "Invalid note metadata", textarea = markdownForm) loggedInUser,
error = "Missing note metadata",
textarea = markdownForm
)
InvalidMeta -> view.noteEditor(
loggedInUser,
error = "Invalid note metadata",
textarea = markdownForm
)
is ValidationError -> view.noteEditor( is ValidationError -> view.noteEditor(
loggedInUser, loggedInUser,
validationErrors = it.validationErrors, validationErrors = it.validationErrors,
@ -105,8 +113,16 @@ class NoteController(
return noteService.update(loggedInUser.userId, note.uuid, markdownForm).fold( return noteService.update(loggedInUser.userId, note.uuid, markdownForm).fold(
{ {
val html = when (it) { val html = when (it) {
MissingMeta -> view.noteEditor(loggedInUser, error = "Missing note metadata", textarea = markdownForm) MissingMeta -> view.noteEditor(
InvalidMeta -> view.noteEditor(loggedInUser, error = "Invalid note metadata", textarea = markdownForm) loggedInUser,
error = "Missing note metadata",
textarea = markdownForm
)
InvalidMeta -> view.noteEditor(
loggedInUser,
error = "Invalid note metadata",
textarea = markdownForm
)
is ValidationError -> view.noteEditor( is ValidationError -> view.noteEditor(
loggedInUser, loggedInUser,
validationErrors = it.validationErrors, validationErrors = it.validationErrors,

View File

@ -2,11 +2,11 @@ package be.simplenotes.app.controllers
import be.simplenotes.app.extensions.html import be.simplenotes.app.extensions.html
import be.simplenotes.app.extensions.redirect import be.simplenotes.app.extensions.redirect
import be.simplenotes.views.SettingView
import be.simplenotes.domain.usecases.UserService import be.simplenotes.domain.usecases.UserService
import be.simplenotes.domain.usecases.users.delete.DeleteError import be.simplenotes.domain.usecases.users.delete.DeleteError
import be.simplenotes.domain.usecases.users.delete.DeleteForm import be.simplenotes.domain.usecases.users.delete.DeleteForm
import be.simplenotes.types.LoggedInUser import be.simplenotes.types.LoggedInUser
import be.simplenotes.views.SettingView
import org.http4k.core.* import org.http4k.core.*
import org.http4k.core.body.form import org.http4k.core.body.form
import org.http4k.core.cookie.invalidateCookie import org.http4k.core.cookie.invalidateCookie
@ -67,7 +67,10 @@ class SettingsController(
Response(Status.OK) Response(Status.OK)
.with(attachment("$filename.json", "application/json")) .with(attachment("$filename.json", "application/json"))
.body(userService.exportAsJson(loggedInUser.userId)) .body(userService.exportAsJson(loggedInUser.userId))
} else Response(Status.OK).body(userService.exportAsJson(loggedInUser.userId)).header("Content-Type", "application/json") } else Response(Status.OK).body(userService.exportAsJson(loggedInUser.userId)).header(
"Content-Type",
"application/json"
)
} }
private fun Request.deleteForm(loggedInUser: LoggedInUser) = private fun Request.deleteForm(loggedInUser: LoggedInUser) =

View File

@ -3,14 +3,14 @@ package be.simplenotes.app.controllers
import be.simplenotes.app.extensions.html import be.simplenotes.app.extensions.html
import be.simplenotes.app.extensions.isSecure import be.simplenotes.app.extensions.isSecure
import be.simplenotes.app.extensions.redirect import be.simplenotes.app.extensions.redirect
import be.simplenotes.views.UserView import be.simplenotes.config.JwtConfig
import be.simplenotes.domain.usecases.UserService import be.simplenotes.domain.usecases.UserService
import be.simplenotes.domain.usecases.users.login.* import be.simplenotes.domain.usecases.users.login.*
import be.simplenotes.domain.usecases.users.register.InvalidRegisterForm import be.simplenotes.domain.usecases.users.register.InvalidRegisterForm
import be.simplenotes.domain.usecases.users.register.RegisterForm import be.simplenotes.domain.usecases.users.register.RegisterForm
import be.simplenotes.domain.usecases.users.register.UserExists import be.simplenotes.domain.usecases.users.register.UserExists
import be.simplenotes.config.JwtConfig
import be.simplenotes.types.LoggedInUser import be.simplenotes.types.LoggedInUser
import be.simplenotes.views.UserView
import org.http4k.core.Method.GET import org.http4k.core.Method.GET
import org.http4k.core.Request import org.http4k.core.Request
import org.http4k.core.Response import org.http4k.core.Response

View File

@ -23,7 +23,8 @@ fun Request.isSecure() = header("X-Forwarded-Proto")?.contains("https") ?: false
val bodyLens = httpBodyRoot( val bodyLens = httpBodyRoot(
listOf(Meta(true, "body", ParamMeta.ObjectParam, "body")), listOf(Meta(true, "body", ParamMeta.ObjectParam, "body")),
ContentType.APPLICATION_JSON.withNoDirectives(), ContentNegotiation.StrictNoDirective ContentType.APPLICATION_JSON.withNoDirectives(),
ContentNegotiation.StrictNoDirective
).map( ).map(
{ it.payload.asString() }, { it.payload.asString() },
{ Body(it) } { Body(it) }

View File

@ -25,7 +25,7 @@ class AuthFilter(
JwtSource.Header -> it.bearerTokenHeader() JwtSource.Header -> it.bearerTokenHeader()
JwtSource.Cookie -> it.bearerTokenCookie() JwtSource.Cookie -> it.bearerTokenCookie()
} }
val jwtPayload = token?.let { token -> extractor(token) } val jwtPayload = token?.let { extractor(token) }
when { when {
jwtPayload != null -> { jwtPayload != null -> {
ctx[it][authKey] = jwtPayload ctx[it][authKey] = jwtPayload

View File

@ -12,9 +12,12 @@ import org.http4k.servlet.asServlet
class Jetty(private val port: Int, private val server: Server) : ServerConfig { class Jetty(private val port: Int, private val server: Server) : ServerConfig {
constructor(port: Int = 8000) : this(port, http(port)) constructor(port: Int = 8000) : this(port, http(port))
constructor(port: Int, vararg inConnectors: ConnectorBuilder) : this(port, Server().apply { constructor(port: Int, vararg inConnectors: ConnectorBuilder) : this(
inConnectors.forEach { addConnector(it(this)) } port,
}) Server().apply {
inConnectors.forEach { addConnector(it(this)) }
}
)
override fun toServer(httpHandler: HttpHandler): Http4kServer { override fun toServer(httpHandler: HttpHandler): Http4kServer {
server.insertHandler(httpHandler.toJettyHandler()) server.insertHandler(httpHandler.toJettyHandler())

View File

@ -10,7 +10,6 @@ import be.simplenotes.app.jetty.Jetty
import be.simplenotes.app.routes.Router import be.simplenotes.app.routes.Router
import be.simplenotes.app.utils.StaticFileResolver import be.simplenotes.app.utils.StaticFileResolver
import be.simplenotes.app.utils.StaticFileResolverImpl import be.simplenotes.app.utils.StaticFileResolverImpl
import be.simplenotes.views.ErrorView
import be.simplenotes.config.ServerConfig import be.simplenotes.config.ServerConfig
import org.eclipse.jetty.server.ServerConnector import org.eclipse.jetty.server.ServerConnector
import org.http4k.core.Filter import org.http4k.core.Filter

View File

@ -10,7 +10,7 @@ import java.util.*
internal class UuidSerializer : KSerializer<UUID> { internal class UuidSerializer : KSerializer<UUID> {
override val descriptor: SerialDescriptor override val descriptor: SerialDescriptor
get() = PrimitiveSerialDescriptor("LocalDateTime", PrimitiveKind.STRING) get() = PrimitiveSerialDescriptor("UUID", PrimitiveKind.STRING)
override fun serialize(encoder: Encoder, value: UUID) { override fun serialize(encoder: Encoder, value: UUID) {
encoder.encodeString(value.toString()) encoder.encodeString(value.toString())

View File

@ -1,8 +1,8 @@
package be.simplenotes.app.filters package be.simplenotes.app.filters
import be.simplenotes.config.JwtConfig
import be.simplenotes.domain.security.JwtPayloadExtractor import be.simplenotes.domain.security.JwtPayloadExtractor
import be.simplenotes.domain.security.SimpleJwt import be.simplenotes.domain.security.SimpleJwt
import be.simplenotes.config.JwtConfig
import be.simplenotes.types.LoggedInUser import be.simplenotes.types.LoggedInUser
import com.natpryce.hamkrest.assertion.assertThat import com.natpryce.hamkrest.assertion.assertThat
import org.http4k.core.* import org.http4k.core.*

View File

@ -30,7 +30,9 @@ internal class SearchTermsParserKtTest {
createResult("tag:'example' title:'other' end", title = "other", tag = "example", all = "end"), createResult("tag:'example' title:'other' end", title = "other", tag = "example", all = "end"),
createResult( createResult(
"tag:'example abc' title:'other with words' this is the end ", "tag:'example abc' title:'other with words' this is the end ",
title = "other with words", tag = "example abc", all = "this is the end" title = "other with words",
tag = "example abc",
all = "this is the end"
), ),
) )

View File

@ -1,7 +1,7 @@
package be.simplenotes.domain.usecases.export package be.simplenotes.domain.usecases.export
import be.simplenotes.types.ExportedNote
import be.simplenotes.persistance.repositories.NoteRepository import be.simplenotes.persistance.repositories.NoteRepository
import be.simplenotes.types.ExportedNote
import kotlinx.serialization.builtins.ListSerializer import kotlinx.serialization.builtins.ListSerializer
import kotlinx.serialization.json.Json import kotlinx.serialization.json.Json
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry import org.apache.commons.compress.archivers.zip.ZipArchiveEntry
@ -31,7 +31,6 @@ internal class ExportUseCaseImpl(private val noteRepository: NoteRepository, pri
} }
} }
class ZipOutput : AutoCloseable { class ZipOutput : AutoCloseable {
val outputStream = ByteArrayOutputStream() val outputStream = ByteArrayOutputStream()
private val zipOutputStream = ZipArchiveOutputStream(outputStream) private val zipOutputStream = ZipArchiveOutputStream(outputStream)

View File

@ -12,14 +12,15 @@ internal class DeleteUseCaseImpl(
private val userRepository: UserRepository, private val userRepository: UserRepository,
private val passwordHash: PasswordHash, private val passwordHash: PasswordHash,
private val searcher: NoteSearcher, private val searcher: NoteSearcher,
) : DeleteUseCase { ) : DeleteUseCase {
override fun delete(form: DeleteForm) = either.eager<DeleteError, Unit> { override fun delete(form: DeleteForm) = either.eager<DeleteError, Unit> {
val user = !UserValidations.validateDelete(form) val user = !UserValidations.validateDelete(form)
val persistedUser = !userRepository.find(user.username).rightIfNotNull { DeleteError.Unregistered } val persistedUser = !userRepository.find(user.username).rightIfNotNull { DeleteError.Unregistered }
!Either.conditionally( !Either.conditionally(
passwordHash.verify(user.password, persistedUser.password), passwordHash.verify(user.password, persistedUser.password),
{ DeleteError.WrongPassword }, { DeleteError.WrongPassword },
{ Unit }) { Unit }
)
!Either.conditionally(userRepository.delete(persistedUser.id), { DeleteError.Unregistered }, { Unit }) !Either.conditionally(userRepository.delete(persistedUser.id), { DeleteError.Unregistered }, { Unit })
searcher.dropIndex(persistedUser.id) searcher.dropIndex(persistedUser.id)
} }

View File

@ -3,10 +3,10 @@ package be.simplenotes.domain.usecases.users.register
import arrow.core.Either import arrow.core.Either
import arrow.core.filterOrElse import arrow.core.filterOrElse
import arrow.core.leftIfNull import arrow.core.leftIfNull
import be.simplenotes.types.PersistedUser
import be.simplenotes.domain.security.PasswordHash import be.simplenotes.domain.security.PasswordHash
import be.simplenotes.domain.validation.UserValidations import be.simplenotes.domain.validation.UserValidations
import be.simplenotes.persistance.repositories.UserRepository import be.simplenotes.persistance.repositories.UserRepository
import be.simplenotes.types.PersistedUser
internal class RegisterUseCaseImpl( internal class RegisterUseCaseImpl(
private val userRepository: UserRepository, private val userRepository: UserRepository,

View File

@ -1,8 +1,8 @@
package be.simplenotes.domain.usecases.users.register package be.simplenotes.domain.usecases.users.register
import arrow.core.Either import arrow.core.Either
import be.simplenotes.types.PersistedUser
import be.simplenotes.domain.usecases.users.login.LoginForm import be.simplenotes.domain.usecases.users.login.LoginForm
import be.simplenotes.types.PersistedUser
import io.konform.validation.ValidationErrors import io.konform.validation.ValidationErrors
sealed class RegisterError sealed class RegisterError

View File

@ -3,13 +3,13 @@ package be.simplenotes.domain.validation
import arrow.core.Either import arrow.core.Either
import arrow.core.left import arrow.core.left
import arrow.core.right import arrow.core.right
import be.simplenotes.types.User
import be.simplenotes.domain.usecases.users.delete.DeleteError import be.simplenotes.domain.usecases.users.delete.DeleteError
import be.simplenotes.domain.usecases.users.delete.DeleteForm import be.simplenotes.domain.usecases.users.delete.DeleteForm
import be.simplenotes.domain.usecases.users.login.InvalidLoginForm import be.simplenotes.domain.usecases.users.login.InvalidLoginForm
import be.simplenotes.domain.usecases.users.login.LoginForm import be.simplenotes.domain.usecases.users.login.LoginForm
import be.simplenotes.domain.usecases.users.register.InvalidRegisterForm import be.simplenotes.domain.usecases.users.register.InvalidRegisterForm
import be.simplenotes.domain.usecases.users.register.RegisterForm import be.simplenotes.domain.usecases.users.register.RegisterForm
import be.simplenotes.types.User
import io.konform.validation.Validation import io.konform.validation.Validation
import io.konform.validation.jsonschema.maxLength import io.konform.validation.jsonschema.maxLength
import io.konform.validation.jsonschema.minLength import io.konform.validation.jsonschema.minLength

View File

@ -1,7 +1,7 @@
package be.simplenotes.domain.security package be.simplenotes.domain.security
import be.simplenotes.domain.usecases.users.login.Token
import be.simplenotes.config.JwtConfig import be.simplenotes.config.JwtConfig
import be.simplenotes.domain.usecases.users.login.Token
import be.simplenotes.types.LoggedInUser import be.simplenotes.types.LoggedInUser
import com.auth0.jwt.JWT import com.auth0.jwt.JWT
import com.auth0.jwt.algorithms.Algorithm import com.auth0.jwt.algorithms.Algorithm

View File

@ -1,12 +1,12 @@
package be.simplenotes.domain.usecases.users.login package be.simplenotes.domain.usecases.users.login
import be.simplenotes.types.PersistedUser import be.simplenotes.config.JwtConfig
import be.simplenotes.domain.security.BcryptPasswordHash import be.simplenotes.domain.security.BcryptPasswordHash
import be.simplenotes.domain.security.SimpleJwt import be.simplenotes.domain.security.SimpleJwt
import be.simplenotes.persistance.repositories.UserRepository
import be.simplenotes.config.JwtConfig
import be.simplenotes.domain.testutils.isLeftOfType import be.simplenotes.domain.testutils.isLeftOfType
import be.simplenotes.domain.testutils.isRight import be.simplenotes.domain.testutils.isRight
import be.simplenotes.persistance.repositories.UserRepository
import be.simplenotes.types.PersistedUser
import com.natpryce.hamkrest.assertion.assertThat import com.natpryce.hamkrest.assertion.assertThat
import io.mockk.* import io.mockk.*
import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.BeforeEach

View File

@ -1,10 +1,10 @@
package be.simplenotes.domain.usecases.users.register package be.simplenotes.domain.usecases.users.register
import be.simplenotes.types.PersistedUser
import be.simplenotes.domain.security.BcryptPasswordHash import be.simplenotes.domain.security.BcryptPasswordHash
import be.simplenotes.domain.testutils.isLeftOfType import be.simplenotes.domain.testutils.isLeftOfType
import be.simplenotes.domain.testutils.isRight import be.simplenotes.domain.testutils.isRight
import be.simplenotes.persistance.repositories.UserRepository import be.simplenotes.persistance.repositories.UserRepository
import be.simplenotes.types.PersistedUser
import com.natpryce.hamkrest.assertion.assertThat import com.natpryce.hamkrest.assertion.assertThat
import com.natpryce.hamkrest.equalTo import com.natpryce.hamkrest.equalTo
import io.mockk.* import io.mockk.*

View File

@ -1,8 +1,8 @@
package be.simplenotes.persistance package be.simplenotes.persistance
import be.simplenotes.config.DataSourceConfig
import be.simplenotes.persistance.utils.DbType import be.simplenotes.persistance.utils.DbType
import be.simplenotes.persistance.utils.type import be.simplenotes.persistance.utils.type
import be.simplenotes.config.DataSourceConfig
import me.liuwj.ktorm.database.Database import me.liuwj.ktorm.database.Database
import me.liuwj.ktorm.database.asIterable import me.liuwj.ktorm.database.asIterable
import me.liuwj.ktorm.database.use import me.liuwj.ktorm.database.use

View File

@ -1,8 +1,8 @@
package be.simplenotes.persistance package be.simplenotes.persistance
import be.simplenotes.config.DataSourceConfig
import be.simplenotes.persistance.utils.DbType import be.simplenotes.persistance.utils.DbType
import be.simplenotes.persistance.utils.type import be.simplenotes.persistance.utils.type
import be.simplenotes.config.DataSourceConfig
import org.flywaydb.core.Flyway import org.flywaydb.core.Flyway
import javax.sql.DataSource import javax.sql.DataSource

View File

@ -10,7 +10,6 @@ import org.mapstruct.ReportingPolicy
import java.time.LocalDateTime import java.time.LocalDateTime
import java.util.* import java.util.*
/** /**
* This is an abstract class because kotlin default methods in interface are not seen as default in kapt * This is an abstract class because kotlin default methods in interface are not seen as default in kapt
* @see [KT-25960](https://youtrack.jetbrains.com/issue/KT-25960) * @see [KT-25960](https://youtrack.jetbrains.com/issue/KT-25960)
@ -35,7 +34,11 @@ internal abstract class NoteConverter {
fun toPersistedNote(entity: NoteEntity, tags: Tags) = PersistedNote( fun toPersistedNote(entity: NoteEntity, tags: Tags) = PersistedNote(
NoteMetadata(title = entity.title, tags = tags), NoteMetadata(title = entity.title, tags = tags),
entity.markdown, entity.html, entity.updatedAt, entity.uuid, entity.public entity.markdown,
entity.html,
entity.updatedAt,
entity.uuid,
entity.public
) )
@Mappings( @Mappings(
@ -46,15 +49,15 @@ internal abstract class NoteConverter {
abstract fun toExportedNote(entity: NoteEntity, tags: Tags): ExportedNote abstract fun toExportedNote(entity: NoteEntity, tags: Tags): ExportedNote
fun toEntity(note: Note, uuid: UUID, userId: Int, updatedAt: LocalDateTime) = NoteEntity { fun toEntity(note: Note, uuid: UUID, userId: Int, updatedAt: LocalDateTime) = NoteEntity {
this.title = note.meta.title this.title = note.meta.title
this.markdown = note.markdown this.markdown = note.markdown
this.html = note.html this.html = note.html
this.uuid = uuid this.uuid = uuid
this.deleted = false this.deleted = false
this.public = false this.public = false
this.user.id = userId this.user.id = userId
this.updatedAt = updatedAt this.updatedAt = updatedAt
} }
@Mappings( @Mappings(
Mapping(target = ".", source = "note"), Mapping(target = ".", source = "note"),
@ -73,7 +76,6 @@ internal abstract class NoteConverter {
@Mapping(target = "deleted", source = "trash") @Mapping(target = "deleted", source = "trash")
abstract fun toEntity(exportedNote: ExportedNote): NoteEntity abstract fun toEntity(exportedNote: ExportedNote): NoteEntity
} }
typealias Tags = List<String> typealias Tags = List<String>

View File

@ -1,11 +1,11 @@
package be.simplenotes.persistance.notes package be.simplenotes.persistance.notes
import be.simplenotes.persistance.converters.NoteConverter
import be.simplenotes.persistance.repositories.NoteRepository
import be.simplenotes.types.ExportedNote import be.simplenotes.types.ExportedNote
import be.simplenotes.types.Note import be.simplenotes.types.Note
import be.simplenotes.types.PersistedNote import be.simplenotes.types.PersistedNote
import be.simplenotes.types.PersistedNoteMetadata import be.simplenotes.types.PersistedNoteMetadata
import be.simplenotes.persistance.converters.NoteConverter
import be.simplenotes.persistance.repositories.NoteRepository
import me.liuwj.ktorm.database.Database import me.liuwj.ktorm.database.Database
import me.liuwj.ktorm.dsl.* import me.liuwj.ktorm.dsl.*
import me.liuwj.ktorm.entity.* import me.liuwj.ktorm.entity.*
@ -211,5 +211,4 @@ internal class NoteRepositoryImpl(private val db: Database, private val converte
.filter { it.noteUuid inList map { note -> note.uuid } } .filter { it.noteUuid inList map { note -> note.uuid } }
.groupByTo(HashMap(), { it.note.uuid }, { it.name }) .groupByTo(HashMap(), { it.note.uuid }, { it.name })
} }
} }

View File

@ -1,9 +1,9 @@
package be.simplenotes.persistance.users package be.simplenotes.persistance.users
import be.simplenotes.types.PersistedUser
import be.simplenotes.types.User
import be.simplenotes.persistance.converters.UserConverter import be.simplenotes.persistance.converters.UserConverter
import be.simplenotes.persistance.repositories.UserRepository import be.simplenotes.persistance.repositories.UserRepository
import be.simplenotes.types.PersistedUser
import be.simplenotes.types.User
import me.liuwj.ktorm.database.Database import me.liuwj.ktorm.database.Database
import me.liuwj.ktorm.dsl.* import me.liuwj.ktorm.dsl.*
import me.liuwj.ktorm.entity.any import me.liuwj.ktorm.entity.any

View File

@ -26,10 +26,14 @@ internal class NoteConverterTest {
} }
val tags = listOf("a", "b") val tags = listOf("a", "b")
val note = converter.toNote(entity, tags) val note = converter.toNote(entity, tags)
val expectedNote = Note(NoteMetadata( val expectedNote = Note(
title = "title", NoteMetadata(
tags = tags, title = "title",
), markdown = "md", html = "html") tags = tags,
),
markdown = "md",
html = "html"
)
assertThat(note).isEqualTo(expectedNote) assertThat(note).isEqualTo(expectedNote)
} }
@ -77,7 +81,6 @@ internal class NoteConverterTest {
) )
assertThat(note).isEqualTo(expectedNote) assertThat(note).isEqualTo(expectedNote)
} }
} }
@Nested @Nested
@ -162,7 +165,5 @@ internal class NoteConverterTest {
.hasFieldOrPropertyWithValue("updatedAt", exportedNote.updatedAt) .hasFieldOrPropertyWithValue("updatedAt", exportedNote.updatedAt)
.hasFieldOrPropertyWithValue("deleted", true) .hasFieldOrPropertyWithValue("deleted", true)
} }
} }
} }

View File

@ -1,8 +1,8 @@
package be.simplenotes.persistance.converters package be.simplenotes.persistance.converters
import be.simplenotes.persistance.users.UserEntity
import be.simplenotes.types.PersistedUser import be.simplenotes.types.PersistedUser
import be.simplenotes.types.User import be.simplenotes.types.User
import be.simplenotes.persistance.users.UserEntity
import org.assertj.core.api.Assertions.assertThat import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.Test import org.junit.jupiter.api.Test
import org.mapstruct.factory.Mappers import org.mapstruct.factory.Mappers

View File

@ -1,14 +1,13 @@
package be.simplenotes.persistance.notes package be.simplenotes.persistance.notes
import be.simplenotes.config.DataSourceConfig
import be.simplenotes.persistance.DbMigrations import be.simplenotes.persistance.DbMigrations
import be.simplenotes.persistance.converters.NoteConverter import be.simplenotes.persistance.converters.NoteConverter
import be.simplenotes.persistance.migrationModule import be.simplenotes.persistance.migrationModule
import be.simplenotes.persistance.persistanceModule import be.simplenotes.persistance.persistanceModule
import be.simplenotes.config.DataSourceConfig
import be.simplenotes.persistance.repositories.NoteRepository import be.simplenotes.persistance.repositories.NoteRepository
import be.simplenotes.persistance.repositories.UserRepository import be.simplenotes.persistance.repositories.UserRepository
import be.simplenotes.types.* import be.simplenotes.types.*
import be.simplenotes.types.*
import me.liuwj.ktorm.database.Database import me.liuwj.ktorm.database.Database
import me.liuwj.ktorm.dsl.eq import me.liuwj.ktorm.dsl.eq
import me.liuwj.ktorm.entity.filter import me.liuwj.ktorm.entity.filter

View File

@ -1,11 +1,11 @@
package be.simplenotes.persistance.users package be.simplenotes.persistance.users
import be.simplenotes.types.User import be.simplenotes.config.DataSourceConfig
import be.simplenotes.persistance.repositories.UserRepository
import be.simplenotes.persistance.DbMigrations import be.simplenotes.persistance.DbMigrations
import be.simplenotes.persistance.migrationModule import be.simplenotes.persistance.migrationModule
import be.simplenotes.persistance.persistanceModule import be.simplenotes.persistance.persistanceModule
import be.simplenotes.config.DataSourceConfig import be.simplenotes.persistance.repositories.UserRepository
import be.simplenotes.types.User
import me.liuwj.ktorm.database.* import me.liuwj.ktorm.database.*
import me.liuwj.ktorm.dsl.* import me.liuwj.ktorm.dsl.*
import me.liuwj.ktorm.entity.* import me.liuwj.ktorm.entity.*

View File

@ -1,7 +1,7 @@
package be.simplenotes.search package be.simplenotes.search
import be.simplenotes.types.PersistedNote
import be.simplenotes.search.utils.rmdir import be.simplenotes.search.utils.rmdir
import be.simplenotes.types.PersistedNote
import org.apache.lucene.analysis.standard.StandardAnalyzer import org.apache.lucene.analysis.standard.StandardAnalyzer
import org.apache.lucene.document.Document import org.apache.lucene.document.Document
import org.apache.lucene.index.* import org.apache.lucene.index.*

View File

@ -24,12 +24,14 @@ internal class NoteSearcherImplTest {
content: String = "", content: String = "",
uuid: UUID = UUID.randomUUID(), uuid: UUID = UUID.randomUUID(),
): PersistedNote { ): PersistedNote {
val note = PersistedNote(NoteMetadata(title, tags), val note = PersistedNote(
NoteMetadata(title, tags),
markdown = content, markdown = content,
html = "", html = "",
LocalDateTime.MIN, LocalDateTime.MIN,
uuid, uuid,
public = false) public = false
)
searcher.indexNote(1, note) searcher.indexNote(1, note)
return note return note
} }

View File

@ -1,7 +1,6 @@
package be.simplenotes.views package be.simplenotes.views
import be.simplenotes.types.LoggedInUser import be.simplenotes.types.LoggedInUser
import be.simplenotes.views.components.noteListHeader
import be.simplenotes.types.PersistedNote import be.simplenotes.types.PersistedNote
import be.simplenotes.types.PersistedNoteMetadata import be.simplenotes.types.PersistedNoteMetadata
import be.simplenotes.views.components.* import be.simplenotes.views.components.*
@ -38,7 +37,9 @@ class NoteView(styles: String) : View(styles) {
|tags: [] |tags: []
|--- |---
| |
""".trimMargin("|") """.trimMargin(
"|"
)
} }
submitButton("Save") submitButton("Save")
} }
@ -128,7 +129,7 @@ class NoteView(styles: String) : View(styles) {
+"You are viewing a public note " +"You are viewing a public note "
} }
hr { } hr { }
} }
div("flex items-center justify-between mb-4") { div("flex items-center justify-between mb-4") {
@ -151,7 +152,7 @@ class NoteView(styles: String) : View(styles) {
+"/notes/public/${note.uuid}" +"/notes/public/${note.uuid}"
} }
} }
hr { } hr { }
} }
} }
@ -182,8 +183,9 @@ class NoteView(styles: String) : View(styles) {
button( button(
type = ButtonType.submit, type = ButtonType.submit,
name = if (note.public) "private" else "public", name = if (note.public) "private" else "public",
classes = "font-semibold border-b-4 ${if (!note.public) "border-teal-200" else "border-green-500"}" + classes = "font-semibold border-b-4 " +
" p-2 rounded-r bg-teal-200 text-gray-800" if (!note.public) "border-teal-200" else "border-green-500" +
" p-2 rounded-r bg-teal-200 text-gray-800"
) { ) {
+"Public" +"Public"
} }

View File

@ -28,9 +28,11 @@ class SettingView(styles: String) : View(styles) {
section("m-4 p-2 bg-gray-800 rounded flex flex-wrap justify-around items-end") { section("m-4 p-2 bg-gray-800 rounded flex flex-wrap justify-around items-end") {
form(classes = "m-2", method = FormMethod.post, action = "/export") { form(classes = "m-2", method = FormMethod.post, action = "/export") {
button(name = "display", button(
name = "display",
classes = "inline btn btn-teal block", classes = "inline btn btn-teal block",
type = submit) { +"Display my data" } type = submit
) { +"Display my data" }
} }
form(classes = "m-2", method = FormMethod.post, action = "/export") { form(classes = "m-2", method = FormMethod.post, action = "/export") {

View File

@ -22,7 +22,7 @@ abstract class View(private val styles: String) {
meta(name = "viewport", content = "width=device-width, initial-scale=1") meta(name = "viewport", content = "width=device-width, initial-scale=1")
title("$title - SimpleNotes") title("$title - SimpleNotes")
description?.let { meta(name = "description", content = it) } description?.let { meta(name = "description", content = it) }
link(rel = "preload", href = "/recursive-0.0.1.woff2"){ link(rel = "preload", href = "/recursive-0.0.1.woff2") {
attributes["as"] = "font" attributes["as"] = "font"
attributes["type"] = "font/woff2" attributes["type"] = "font/woff2"
attributes["crossorigin"] = "anonymous" attributes["crossorigin"] = "anonymous"

View File

@ -4,7 +4,9 @@ import kotlinx.html.*
internal class SUMMARY(consumer: TagConsumer<*>) : internal class SUMMARY(consumer: TagConsumer<*>) :
HTMLTag( HTMLTag(
"summary", consumer, emptyMap(), "summary",
consumer,
emptyMap(),
inlineTag = true, inlineTag = true,
emptyTag = false emptyTag = false
), ),

View File

@ -7,4 +7,6 @@ import java.util.*
private val prettyTime = PrettyTime() private val prettyTime = PrettyTime()
internal fun LocalDateTime.toTimeAgo(): String = prettyTime.format(Date.from(atZone(ZoneId.systemDefault()).toInstant())) internal fun LocalDateTime.toTimeAgo(): String = prettyTime.format(
Date.from(atZone(ZoneId.systemDefault()).toInstant())
)