Compare commits
23 Commits
develop
...
logger-ins
| Author | SHA1 | Date |
|---|---|---|
|
|
a7ec9241ab | |
|
|
a84cbeb155 | |
|
|
285c8ab334 | |
|
|
40781f56e7 | |
|
|
973d18a552 | |
|
|
78238d427a | |
|
|
1433a7aecf | |
|
|
b42577e3ad | |
|
|
493829b3ee | |
|
|
7ce4a26970 | |
|
|
1f79cd1760 | |
|
|
8e55285e48 | |
|
|
198d38431a | |
|
|
c8fe7b337e | |
|
|
a7e3f6c1a9 | |
|
|
670d509696 | |
|
|
ec914d9f0c | |
|
|
18f13cea98 | |
|
|
d803ec3e3e | |
|
|
d84a5767bf | |
|
|
84a6877f57 | |
|
|
c9ff8d0624 | |
|
|
f7e8862d28 |
|
|
@ -1,223 +0,0 @@
|
||||||
#━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
||||||
# Misskey configuration
|
|
||||||
#━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
||||||
|
|
||||||
# ┌────────────────────────┐
|
|
||||||
#───┘ Initial Setup Password └─────────────────────────────────────────────────────
|
|
||||||
|
|
||||||
# Password to initiate setting up admin account.
|
|
||||||
# It will not be used after the initial setup is complete.
|
|
||||||
#
|
|
||||||
# Be sure to change this when you set up Misskey via the Internet.
|
|
||||||
#
|
|
||||||
# The provider of the service who sets up Misskey on behalf of the customer should
|
|
||||||
# set this value to something unique when generating the Misskey config file,
|
|
||||||
# and provide it to the customer.
|
|
||||||
setupPassword: example_password_please_change_this_or_you_will_get_hacked
|
|
||||||
|
|
||||||
# ┌─────┐
|
|
||||||
#───┘ URL └─────────────────────────────────────────────────────
|
|
||||||
|
|
||||||
# Final accessible URL seen by a user.
|
|
||||||
url: 'http://misskey.local'
|
|
||||||
|
|
||||||
# ONCE YOU HAVE STARTED THE INSTANCE, DO NOT CHANGE THE
|
|
||||||
# URL SETTINGS AFTER THAT!
|
|
||||||
|
|
||||||
# ┌───────────────────────┐
|
|
||||||
#───┘ Port and TLS settings └───────────────────────────────────
|
|
||||||
|
|
||||||
#
|
|
||||||
# Misskey requires a reverse proxy to support HTTPS connections.
|
|
||||||
#
|
|
||||||
# +----- https://example.tld/ ------------+
|
|
||||||
# +------+ |+-------------+ +----------------+|
|
|
||||||
# | User | ---> || Proxy (443) | ---> | Misskey (3000) ||
|
|
||||||
# +------+ |+-------------+ +----------------+|
|
|
||||||
# +---------------------------------------+
|
|
||||||
#
|
|
||||||
# You need to set up a reverse proxy. (e.g. nginx)
|
|
||||||
# An encrypted connection with HTTPS is highly recommended
|
|
||||||
# because tokens may be transferred in GET requests.
|
|
||||||
|
|
||||||
# The port that your Misskey server should listen on.
|
|
||||||
port: 61812
|
|
||||||
|
|
||||||
# ┌──────────────────────────┐
|
|
||||||
#───┘ PostgreSQL configuration └────────────────────────────────
|
|
||||||
|
|
||||||
db:
|
|
||||||
host: db
|
|
||||||
port: 5432
|
|
||||||
|
|
||||||
# Database name
|
|
||||||
db: misskey
|
|
||||||
|
|
||||||
# Auth
|
|
||||||
user: postgres
|
|
||||||
pass: postgres
|
|
||||||
|
|
||||||
# Whether disable Caching queries
|
|
||||||
#disableCache: true
|
|
||||||
|
|
||||||
# Extra Connection options
|
|
||||||
#extra:
|
|
||||||
# ssl: true
|
|
||||||
|
|
||||||
dbReplications: false
|
|
||||||
|
|
||||||
# You can configure any number of replicas here
|
|
||||||
#dbSlaves:
|
|
||||||
# -
|
|
||||||
# host:
|
|
||||||
# port:
|
|
||||||
# db:
|
|
||||||
# user:
|
|
||||||
# pass:
|
|
||||||
# -
|
|
||||||
# host:
|
|
||||||
# port:
|
|
||||||
# db:
|
|
||||||
# user:
|
|
||||||
# pass:
|
|
||||||
|
|
||||||
# ┌─────────────────────┐
|
|
||||||
#───┘ Redis configuration └─────────────────────────────────────
|
|
||||||
|
|
||||||
redis:
|
|
||||||
host: redis
|
|
||||||
port: 6379
|
|
||||||
#family: 0 # 0=Both, 4=IPv4, 6=IPv6
|
|
||||||
#pass: example-pass
|
|
||||||
#prefix: example-prefix
|
|
||||||
#db: 1
|
|
||||||
|
|
||||||
#redisForPubsub:
|
|
||||||
# host: redis
|
|
||||||
# port: 6379
|
|
||||||
# #family: 0 # 0=Both, 4=IPv4, 6=IPv6
|
|
||||||
# #pass: example-pass
|
|
||||||
# #prefix: example-prefix
|
|
||||||
# #db: 1
|
|
||||||
|
|
||||||
#redisForJobQueue:
|
|
||||||
# host: redis
|
|
||||||
# port: 6379
|
|
||||||
# #family: 0 # 0=Both, 4=IPv4, 6=IPv6
|
|
||||||
# #pass: example-pass
|
|
||||||
# #prefix: example-prefix
|
|
||||||
# #db: 1
|
|
||||||
|
|
||||||
#redisForTimelines:
|
|
||||||
# host: redis
|
|
||||||
# port: 6379
|
|
||||||
# #family: 0 # 0=Both, 4=IPv4, 6=IPv6
|
|
||||||
# #pass: example-pass
|
|
||||||
# #prefix: example-prefix
|
|
||||||
# #db: 1
|
|
||||||
|
|
||||||
#redisForReactions:
|
|
||||||
# host: redis
|
|
||||||
# port: 6379
|
|
||||||
# #family: 0 # 0=Both, 4=IPv4, 6=IPv6
|
|
||||||
# #pass: example-pass
|
|
||||||
# #prefix: example-prefix
|
|
||||||
# #db: 1
|
|
||||||
|
|
||||||
# ┌───────────────────────────┐
|
|
||||||
#───┘ MeiliSearch configuration └─────────────────────────────
|
|
||||||
|
|
||||||
#meilisearch:
|
|
||||||
# host: meilisearch
|
|
||||||
# port: 7700
|
|
||||||
# apiKey: ''
|
|
||||||
# ssl: true
|
|
||||||
# index: ''
|
|
||||||
|
|
||||||
# ┌───────────────┐
|
|
||||||
#───┘ ID generation └───────────────────────────────────────────
|
|
||||||
|
|
||||||
# You can select the ID generation method.
|
|
||||||
# You don't usually need to change this setting, but you can
|
|
||||||
# change it according to your preferences.
|
|
||||||
|
|
||||||
# Available methods:
|
|
||||||
# aid ... Short, Millisecond accuracy
|
|
||||||
# aidx ... Millisecond accuracy
|
|
||||||
# meid ... Similar to ObjectID, Millisecond accuracy
|
|
||||||
# ulid ... Millisecond accuracy
|
|
||||||
# objectid ... This is left for backward compatibility
|
|
||||||
|
|
||||||
# ONCE YOU HAVE STARTED THE INSTANCE, DO NOT CHANGE THE
|
|
||||||
# ID SETTINGS AFTER THAT!
|
|
||||||
|
|
||||||
id: 'aidx'
|
|
||||||
|
|
||||||
# ┌────────────────┐
|
|
||||||
#───┘ Error tracking └──────────────────────────────────────────
|
|
||||||
|
|
||||||
# Sentry is available for error tracking.
|
|
||||||
# See the Sentry documentation for more details on options.
|
|
||||||
|
|
||||||
#sentryForBackend:
|
|
||||||
# enableNodeProfiling: true
|
|
||||||
# options:
|
|
||||||
# dsn: 'https://examplePublicKey@o0.ingest.sentry.io/0'
|
|
||||||
|
|
||||||
#sentryForFrontend:
|
|
||||||
# vueIntegration:
|
|
||||||
# tracingOptions:
|
|
||||||
# trackComponents: true
|
|
||||||
# browserTracingIntegration:
|
|
||||||
# replayIntegration:
|
|
||||||
# options:
|
|
||||||
# dsn: 'https://examplePublicKey@o0.ingest.sentry.io/0'
|
|
||||||
|
|
||||||
# ┌─────────────────────┐
|
|
||||||
#───┘ Other configuration └─────────────────────────────────────
|
|
||||||
|
|
||||||
# Whether disable HSTS
|
|
||||||
#disableHsts: true
|
|
||||||
|
|
||||||
# Number of worker processes
|
|
||||||
#clusterLimit: 1
|
|
||||||
|
|
||||||
# Job concurrency per worker
|
|
||||||
# deliverJobConcurrency: 128
|
|
||||||
# inboxJobConcurrency: 16
|
|
||||||
|
|
||||||
# Job rate limiter
|
|
||||||
# deliverJobPerSec: 128
|
|
||||||
# inboxJobPerSec: 32
|
|
||||||
|
|
||||||
# Job attempts
|
|
||||||
# deliverJobMaxAttempts: 12
|
|
||||||
# inboxJobMaxAttempts: 8
|
|
||||||
|
|
||||||
# IP address family used for outgoing request (ipv4, ipv6 or dual)
|
|
||||||
#outgoingAddressFamily: ipv4
|
|
||||||
|
|
||||||
# Proxy for HTTP/HTTPS
|
|
||||||
#proxy: http://127.0.0.1:3128
|
|
||||||
|
|
||||||
proxyBypassHosts:
|
|
||||||
- api.deepl.com
|
|
||||||
- api-free.deepl.com
|
|
||||||
- www.recaptcha.net
|
|
||||||
- hcaptcha.com
|
|
||||||
- challenges.cloudflare.com
|
|
||||||
|
|
||||||
# Proxy for SMTP/SMTPS
|
|
||||||
#proxySmtp: http://127.0.0.1:3128 # use HTTP/1.1 CONNECT
|
|
||||||
#proxySmtp: socks4://127.0.0.1:1080 # use SOCKS4
|
|
||||||
#proxySmtp: socks5://127.0.0.1:1080 # use SOCKS5
|
|
||||||
|
|
||||||
# Media Proxy
|
|
||||||
#mediaProxy: https://example.com/proxy
|
|
||||||
|
|
||||||
allowedPrivateNetworks: [
|
|
||||||
'127.0.0.1/32'
|
|
||||||
]
|
|
||||||
|
|
||||||
# Upload or download file size limits (bytes)
|
|
||||||
#maxFileSize: 262144000
|
|
||||||
|
|
@ -1,11 +1,5 @@
|
||||||
# misskey settings
|
|
||||||
# MISSKEY_URL=https://example.tld/
|
|
||||||
|
|
||||||
# db settings
|
# db settings
|
||||||
POSTGRES_PASSWORD=example-misskey-pass
|
POSTGRES_PASSWORD=example-misskey-pass
|
||||||
# DATABASE_PASSWORD=${POSTGRES_PASSWORD}
|
|
||||||
POSTGRES_USER=example-misskey-user
|
POSTGRES_USER=example-misskey-user
|
||||||
# DATABASE_USER=${POSTGRES_USER}
|
|
||||||
POSTGRES_DB=misskey
|
POSTGRES_DB=misskey
|
||||||
# DATABASE_DB=${POSTGRES_DB}
|
|
||||||
DATABASE_URL="postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@db:5432/${POSTGRES_DB}"
|
DATABASE_URL="postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@db:5432/${POSTGRES_DB}"
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,6 @@
|
||||||
#───┘ URL └─────────────────────────────────────────────────────
|
#───┘ URL └─────────────────────────────────────────────────────
|
||||||
|
|
||||||
# Final accessible URL seen by a user.
|
# Final accessible URL seen by a user.
|
||||||
# You can set url from an environment variable instead.
|
|
||||||
url: https://example.tld/
|
url: https://example.tld/
|
||||||
|
|
||||||
# ONCE YOU HAVE STARTED THE INSTANCE, DO NOT CHANGE THE
|
# ONCE YOU HAVE STARTED THE INSTANCE, DO NOT CHANGE THE
|
||||||
|
|
@ -39,11 +38,9 @@ db:
|
||||||
port: 5432
|
port: 5432
|
||||||
|
|
||||||
# Database name
|
# Database name
|
||||||
# You can set db from an environment variable instead.
|
|
||||||
db: misskey
|
db: misskey
|
||||||
|
|
||||||
# Auth
|
# Auth
|
||||||
# You can set user and pass from environment variables instead.
|
|
||||||
user: example-misskey-user
|
user: example-misskey-user
|
||||||
pass: example-misskey-pass
|
pass: example-misskey-pass
|
||||||
|
|
||||||
|
|
@ -106,35 +103,9 @@ redis:
|
||||||
# #prefix: example-prefix
|
# #prefix: example-prefix
|
||||||
# #db: 1
|
# #db: 1
|
||||||
|
|
||||||
#redisForReactions:
|
# ┌───────────────────────────┐
|
||||||
# host: redis
|
#───┘ MeiliSearch configuration └─────────────────────────────
|
||||||
# port: 6379
|
|
||||||
# #family: 0 # 0=Both, 4=IPv4, 6=IPv6
|
|
||||||
# #pass: example-pass
|
|
||||||
# #prefix: example-prefix
|
|
||||||
# #db: 1
|
|
||||||
|
|
||||||
# ┌───────────────────────────────┐
|
|
||||||
#───┘ Fulltext search configuration └─────────────────────────────
|
|
||||||
|
|
||||||
# These are the setting items for the full-text search provider.
|
|
||||||
fulltextSearch:
|
|
||||||
# You can select the ID generation method.
|
|
||||||
# - sqlLike (default)
|
|
||||||
# Use SQL-like search.
|
|
||||||
# This is a standard feature of PostgreSQL, so no special extensions are required.
|
|
||||||
# - sqlPgroonga
|
|
||||||
# Use pgroonga.
|
|
||||||
# You need to install pgroonga and configure it as a PostgreSQL extension.
|
|
||||||
# In addition to the above, you need to create a pgroonga index on the text column of the note table.
|
|
||||||
# see: https://pgroonga.github.io/tutorial/
|
|
||||||
# - meilisearch
|
|
||||||
# Use Meilisearch.
|
|
||||||
# You need to install Meilisearch and configure.
|
|
||||||
provider: sqlLike
|
|
||||||
|
|
||||||
# For Meilisearch settings.
|
|
||||||
# If you select "meilisearch" for "fulltextSearch.provider", it must be set.
|
|
||||||
# You can set scope to local (default value) or global
|
# You can set scope to local (default value) or global
|
||||||
# (include notes from remote).
|
# (include notes from remote).
|
||||||
|
|
||||||
|
|
@ -165,26 +136,6 @@ fulltextSearch:
|
||||||
|
|
||||||
id: 'aidx'
|
id: 'aidx'
|
||||||
|
|
||||||
# ┌────────────────┐
|
|
||||||
#───┘ Error tracking └──────────────────────────────────────────
|
|
||||||
|
|
||||||
# Sentry is available for error tracking.
|
|
||||||
# See the Sentry documentation for more details on options.
|
|
||||||
|
|
||||||
#sentryForBackend:
|
|
||||||
# enableNodeProfiling: true
|
|
||||||
# options:
|
|
||||||
# dsn: 'https://examplePublicKey@o0.ingest.sentry.io/0'
|
|
||||||
|
|
||||||
#sentryForFrontend:
|
|
||||||
# vueIntegration:
|
|
||||||
# tracingOptions:
|
|
||||||
# trackComponents: true
|
|
||||||
# browserTracingIntegration:
|
|
||||||
# replayIntegration:
|
|
||||||
# options:
|
|
||||||
# dsn: 'https://examplePublicKey@o0.ingest.sentry.io/0'
|
|
||||||
|
|
||||||
# ┌─────────────────────┐
|
# ┌─────────────────────┐
|
||||||
#───┘ Other configuration └─────────────────────────────────────
|
#───┘ Other configuration └─────────────────────────────────────
|
||||||
|
|
||||||
|
|
@ -227,6 +178,12 @@ proxyBypassHosts:
|
||||||
# Media Proxy
|
# Media Proxy
|
||||||
#mediaProxy: https://example.com/proxy
|
#mediaProxy: https://example.com/proxy
|
||||||
|
|
||||||
|
# Proxy remote files (default: true)
|
||||||
|
proxyRemoteFiles: true
|
||||||
|
|
||||||
|
# Sign to ActivityPub GET request (default: true)
|
||||||
|
signToActivityPubGet: true
|
||||||
|
|
||||||
# For security reasons, uploading attachments from the intranet is prohibited,
|
# For security reasons, uploading attachments from the intranet is prohibited,
|
||||||
# but exceptions can be made from the following settings. Default value is "undefined".
|
# but exceptions can be made from the following settings. Default value is "undefined".
|
||||||
# Read changelog to learn more (Improvements of 12.90.0 (2021/09/04)).
|
# Read changelog to learn more (Improvements of 12.90.0 (2021/09/04)).
|
||||||
|
|
@ -236,13 +193,3 @@ proxyBypassHosts:
|
||||||
|
|
||||||
# Upload or download file size limits (bytes)
|
# Upload or download file size limits (bytes)
|
||||||
#maxFileSize: 262144000
|
#maxFileSize: 262144000
|
||||||
|
|
||||||
# Log settings
|
|
||||||
# logging:
|
|
||||||
# sql:
|
|
||||||
# # Outputs query parameters during SQL execution to the log.
|
|
||||||
# # default: false
|
|
||||||
# enableQueryParamLogging: false
|
|
||||||
# # Disable query truncation. If set to true, the full text of the query will be output to the log.
|
|
||||||
# # default: false
|
|
||||||
# disableQueryTruncation: false
|
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,7 @@
|
||||||
# Option 3: If neither of the above applies to you.
|
# Option 3: If neither of the above applies to you.
|
||||||
# (In this case, the source code should be published
|
# (In this case, the source code should be published
|
||||||
# on the Misskey interface. IT IS NOT ENOUGH TO
|
# on the Misskey interface. IT IS NOT ENOUGH TO
|
||||||
# DISCLOSE THE SOURCE CODE WHEN A USER REQUESTS IT BY
|
# DISCLOSE THE SOURCE CODE WEHN A USER REQUESTS IT BY
|
||||||
# E-MAIL OR OTHER MEANS. If you are not satisfied
|
# E-MAIL OR OTHER MEANS. If you are not satisfied
|
||||||
# with this, it is recommended that you read the
|
# with this, it is recommended that you read the
|
||||||
# license again carefully. Anyway, enabling this
|
# license again carefully. Anyway, enabling this
|
||||||
|
|
@ -59,20 +59,6 @@
|
||||||
#
|
#
|
||||||
# publishTarballInsteadOfProvideRepositoryUrl: true
|
# publishTarballInsteadOfProvideRepositoryUrl: true
|
||||||
|
|
||||||
# ┌────────────────────────┐
|
|
||||||
#───┘ Initial Setup Password └─────────────────────────────────────────────────────
|
|
||||||
|
|
||||||
# Password to initiate setting up admin account.
|
|
||||||
# It will not be used after the initial setup is complete.
|
|
||||||
#
|
|
||||||
# Be sure to change this when you set up Misskey via the Internet.
|
|
||||||
#
|
|
||||||
# The provider of the service who sets up Misskey on behalf of the customer should
|
|
||||||
# set this value to something unique when generating the Misskey config file,
|
|
||||||
# and provide it to the customer.
|
|
||||||
#
|
|
||||||
# setupPassword: example_password_please_change_this_or_you_will_get_hacked
|
|
||||||
|
|
||||||
# ┌─────┐
|
# ┌─────┐
|
||||||
#───┘ URL └─────────────────────────────────────────────────────
|
#───┘ URL └─────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
|
@ -105,54 +91,6 @@ port: 3000
|
||||||
# socket: /path/to/misskey.sock
|
# socket: /path/to/misskey.sock
|
||||||
# chmodSocket: '777'
|
# chmodSocket: '777'
|
||||||
|
|
||||||
# Proxy trust settings
|
|
||||||
#
|
|
||||||
# Specifies the IP addresses that Misskey will use as trusted
|
|
||||||
# reverse proxies (e.g., nginx, Cloudflare). This affects how
|
|
||||||
# Misskey determines the source IP for each request and is used
|
|
||||||
# for important rate limiting and security features. If the value
|
|
||||||
# is not set correctly, Misskey may use the IP address of the
|
|
||||||
# reverse proxy instead of the actual source IP, which may lead to
|
|
||||||
# unintended rate limiting or security vulnerabilities.
|
|
||||||
# By default, the loopback network and private network address
|
|
||||||
# ranges shown below are trusted.
|
|
||||||
# If you are using a single reverse proxy and it is on the same
|
|
||||||
# machine or the same private network as Misskey, it is unlikely you
|
|
||||||
# need to change this setting, and the default setting is fine.
|
|
||||||
# Also, if you are using multiple reverse proxy servers and they are
|
|
||||||
# all on the same private network as Misskey, the default setting
|
|
||||||
# is fine.
|
|
||||||
# However, if you are using a reverse proxy server that accesses
|
|
||||||
# Misskey web servers and streaming servers via public IP addresses
|
|
||||||
# (for example, Cloudflare), you must set this variable.
|
|
||||||
# When changing this setting, you can use one of the following values:
|
|
||||||
#
|
|
||||||
# - true: Trust all proxies
|
|
||||||
# - false: Do not trust any proxies
|
|
||||||
# - IP address, IP address range, or array of them: Trust hops that
|
|
||||||
# match the specified criteria.
|
|
||||||
# - Integer: Trust the nth hop from the front-facing proxy server as
|
|
||||||
# the client.
|
|
||||||
# For more information on how to configure this setting, please refer
|
|
||||||
# to the Fastify documentation:
|
|
||||||
# https://fastify.dev/docs/latest/Reference/Server/#trustproxy
|
|
||||||
#
|
|
||||||
# Note that if this variable is set, it overrides the default range,
|
|
||||||
# so if you have both an external reverse proxy and a proxy on the
|
|
||||||
# local host, you must include both IPs (or IP ranges).
|
|
||||||
#
|
|
||||||
#trustProxy:
|
|
||||||
# - '10.0.0.0/8'
|
|
||||||
# - '172.16.0.0/12'
|
|
||||||
# - '192.168.0.0/16'
|
|
||||||
# - '127.0.0.1/32'
|
|
||||||
# - '::1/128'
|
|
||||||
# - 'fc00::/7'
|
|
||||||
# # Example: If you are using some external reverse proxies like CDNs,
|
|
||||||
# # you may need to add the CDN IP ranges here.
|
|
||||||
# # If you're using Cloudflare, you can find IP Ranges at:
|
|
||||||
# # https://www.cloudflare.com/ips/
|
|
||||||
|
|
||||||
# ┌──────────────────────────┐
|
# ┌──────────────────────────┐
|
||||||
#───┘ PostgreSQL configuration └────────────────────────────────
|
#───┘ PostgreSQL configuration └────────────────────────────────
|
||||||
|
|
||||||
|
|
@ -234,37 +172,9 @@ redis:
|
||||||
# # You can specify more ioredis options...
|
# # You can specify more ioredis options...
|
||||||
# #username: example-username
|
# #username: example-username
|
||||||
|
|
||||||
#redisForReactions:
|
# ┌───────────────────────────┐
|
||||||
# host: localhost
|
#───┘ MeiliSearch configuration └─────────────────────────────
|
||||||
# port: 6379
|
|
||||||
# #family: 0 # 0=Both, 4=IPv4, 6=IPv6
|
|
||||||
# #pass: example-pass
|
|
||||||
# #prefix: example-prefix
|
|
||||||
# #db: 1
|
|
||||||
# # You can specify more ioredis options...
|
|
||||||
# #username: example-username
|
|
||||||
|
|
||||||
# ┌───────────────────────────────┐
|
|
||||||
#───┘ Fulltext search configuration └─────────────────────────────
|
|
||||||
|
|
||||||
# These are the setting items for the full-text search provider.
|
|
||||||
fulltextSearch:
|
|
||||||
# You can select the ID generation method.
|
|
||||||
# - sqlLike (default)
|
|
||||||
# Use SQL-like search.
|
|
||||||
# This is a standard feature of PostgreSQL, so no special extensions are required.
|
|
||||||
# - sqlPgroonga
|
|
||||||
# Use pgroonga.
|
|
||||||
# You need to install pgroonga and configure it as a PostgreSQL extension.
|
|
||||||
# In addition to the above, you need to create a pgroonga index on the text column of the note table.
|
|
||||||
# see: https://pgroonga.github.io/tutorial/
|
|
||||||
# - meilisearch
|
|
||||||
# Use Meilisearch.
|
|
||||||
# You need to install Meilisearch and configure.
|
|
||||||
provider: sqlLike
|
|
||||||
|
|
||||||
# For Meilisearch settings.
|
|
||||||
# If you select "meilisearch" for "fulltextSearch.provider", it must be set.
|
|
||||||
# You can set scope to local (default value) or global
|
# You can set scope to local (default value) or global
|
||||||
# (include notes from remote).
|
# (include notes from remote).
|
||||||
|
|
||||||
|
|
@ -295,36 +205,12 @@ fulltextSearch:
|
||||||
|
|
||||||
id: 'aidx'
|
id: 'aidx'
|
||||||
|
|
||||||
# ┌────────────────┐
|
|
||||||
#───┘ Error tracking └──────────────────────────────────────────
|
|
||||||
|
|
||||||
# Sentry is available for error tracking.
|
|
||||||
# See the Sentry documentation for more details on options.
|
|
||||||
|
|
||||||
#sentryForBackend:
|
|
||||||
# enableNodeProfiling: true
|
|
||||||
# options:
|
|
||||||
# dsn: 'https://examplePublicKey@o0.ingest.sentry.io/0'
|
|
||||||
|
|
||||||
#sentryForFrontend:
|
|
||||||
# vueIntegration:
|
|
||||||
# tracingOptions:
|
|
||||||
# trackComponents: true
|
|
||||||
# browserTracingIntegration:
|
|
||||||
# replayIntegration:
|
|
||||||
# options:
|
|
||||||
# dsn: 'https://examplePublicKey@o0.ingest.sentry.io/0'
|
|
||||||
|
|
||||||
# ┌─────────────────────┐
|
# ┌─────────────────────┐
|
||||||
#───┘ Other configuration └─────────────────────────────────────
|
#───┘ Other configuration └─────────────────────────────────────
|
||||||
|
|
||||||
# Whether disable HSTS
|
# Whether disable HSTS
|
||||||
#disableHsts: true
|
#disableHsts: true
|
||||||
|
|
||||||
# Enable internal IP-based rate limiting (default: true)
|
|
||||||
# To configure them in reverse proxy instead, set this to false.
|
|
||||||
#enableIpRateLimit: true
|
|
||||||
|
|
||||||
# Number of worker processes
|
# Number of worker processes
|
||||||
#clusterLimit: 1
|
#clusterLimit: 1
|
||||||
|
|
||||||
|
|
@ -371,12 +257,19 @@ proxyBypassHosts:
|
||||||
# * Perform image compression (on a different server resource than the main process)
|
# * Perform image compression (on a different server resource than the main process)
|
||||||
#mediaProxy: https://example.com/proxy
|
#mediaProxy: https://example.com/proxy
|
||||||
|
|
||||||
|
# Proxy remote files (default: true)
|
||||||
|
# Proxy remote files by this instance or mediaProxy to prevent remote files from running in remote domains.
|
||||||
|
proxyRemoteFiles: true
|
||||||
|
|
||||||
# Movie Thumbnail Generation URL
|
# Movie Thumbnail Generation URL
|
||||||
# There is no reference implementation.
|
# There is no reference implementation.
|
||||||
# For example, Misskey will point to the following URL:
|
# For example, Misskey will point to the following URL:
|
||||||
# https://example.com/thumbnail.webp?thumbnail=1&url=https%3A%2F%2Fstorage.example.com%2Fpath%2Fto%2Fvideo.mp4
|
# https://example.com/thumbnail.webp?thumbnail=1&url=https%3A%2F%2Fstorage.example.com%2Fpath%2Fto%2Fvideo.mp4
|
||||||
#videoThumbnailGenerator: https://example.com
|
#videoThumbnailGenerator: https://example.com
|
||||||
|
|
||||||
|
# Sign to ActivityPub GET request (default: true)
|
||||||
|
signToActivityPubGet: true
|
||||||
|
|
||||||
# For security reasons, uploading attachments from the intranet is prohibited,
|
# For security reasons, uploading attachments from the intranet is prohibited,
|
||||||
# but exceptions can be made from the following settings. Default value is "undefined".
|
# but exceptions can be made from the following settings. Default value is "undefined".
|
||||||
# Read changelog to learn more (Improvements of 12.90.0 (2021/09/04)).
|
# Read changelog to learn more (Improvements of 12.90.0 (2021/09/04)).
|
||||||
|
|
@ -389,13 +282,3 @@ proxyBypassHosts:
|
||||||
|
|
||||||
# PID File of master process
|
# PID File of master process
|
||||||
#pidFile: /tmp/misskey.pid
|
#pidFile: /tmp/misskey.pid
|
||||||
|
|
||||||
# Log settings
|
|
||||||
# logging:
|
|
||||||
# sql:
|
|
||||||
# # Outputs query parameters during SQL execution to the log.
|
|
||||||
# # default: false
|
|
||||||
# enableQueryParamLogging: false
|
|
||||||
# # Disable query truncation. If set to true, the full text of the query will be output to the log.
|
|
||||||
# # default: false
|
|
||||||
# disableQueryTruncation: false
|
|
||||||
|
|
|
||||||
|
|
@ -1 +1 @@
|
||||||
FROM mcr.microsoft.com/devcontainers/javascript-node:4.0.3-24-trixie
|
FROM mcr.microsoft.com/devcontainers/javascript-node:0-18
|
||||||
|
|
|
||||||
|
|
@ -1,24 +1,25 @@
|
||||||
{
|
{
|
||||||
"name": "Misskey",
|
"name": "Misskey",
|
||||||
"dockerComposeFile": "compose.yml",
|
"dockerComposeFile": "docker-compose.yml",
|
||||||
"service": "app",
|
"service": "app",
|
||||||
"workspaceFolder": "/workspace",
|
"workspaceFolder": "/workspace",
|
||||||
"features": {
|
"features": {
|
||||||
"ghcr.io/devcontainers/features/node:1": {
|
"ghcr.io/devcontainers-contrib/features/pnpm:2": {
|
||||||
"version": "22.15.0"
|
"version": "8.9.2"
|
||||||
},
|
},
|
||||||
"ghcr.io/devcontainers-extra/features/pnpm:2": {
|
"ghcr.io/devcontainers/features/node:1": {
|
||||||
"version": "10.10.0"
|
"version": "20.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"forwardPorts": [3000],
|
"forwardPorts": [3000],
|
||||||
"postCreateCommand": "/bin/bash .devcontainer/init.sh",
|
"postCreateCommand": "sudo chmod 755 .devcontainer/init.sh && .devcontainer/init.sh",
|
||||||
"customizations": {
|
"customizations": {
|
||||||
"vscode": {
|
"vscode": {
|
||||||
"extensions": [
|
"extensions": [
|
||||||
"editorconfig.editorconfig",
|
"editorconfig.editorconfig",
|
||||||
"dbaeumer.vscode-eslint",
|
"dbaeumer.vscode-eslint",
|
||||||
"Vue.volar",
|
"Vue.volar",
|
||||||
|
"Vue.vscode-typescript-vue-plugin",
|
||||||
"Orta.vscode-jest",
|
"Orta.vscode-jest",
|
||||||
"dbaeumer.vscode-eslint",
|
"dbaeumer.vscode-eslint",
|
||||||
"mrmlnc.vscode-json5"
|
"mrmlnc.vscode-json5"
|
||||||
|
|
|
||||||
|
|
@ -103,14 +103,6 @@ redis:
|
||||||
# #prefix: example-prefix
|
# #prefix: example-prefix
|
||||||
# #db: 1
|
# #db: 1
|
||||||
|
|
||||||
#redisForReactions:
|
|
||||||
# host: redis
|
|
||||||
# port: 6379
|
|
||||||
# #family: 0 # 0=Both, 4=IPv4, 6=IPv6
|
|
||||||
# #pass: example-pass
|
|
||||||
# #prefix: example-prefix
|
|
||||||
# #db: 1
|
|
||||||
|
|
||||||
# ┌───────────────────────────┐
|
# ┌───────────────────────────┐
|
||||||
#───┘ MeiliSearch configuration └─────────────────────────────
|
#───┘ MeiliSearch configuration └─────────────────────────────
|
||||||
|
|
||||||
|
|
@ -140,26 +132,6 @@ redis:
|
||||||
|
|
||||||
id: 'aidx'
|
id: 'aidx'
|
||||||
|
|
||||||
# ┌────────────────┐
|
|
||||||
#───┘ Error tracking └──────────────────────────────────────────
|
|
||||||
|
|
||||||
# Sentry is available for error tracking.
|
|
||||||
# See the Sentry documentation for more details on options.
|
|
||||||
|
|
||||||
#sentryForBackend:
|
|
||||||
# enableNodeProfiling: true
|
|
||||||
# options:
|
|
||||||
# dsn: 'https://examplePublicKey@o0.ingest.sentry.io/0'
|
|
||||||
|
|
||||||
#sentryForFrontend:
|
|
||||||
# vueIntegration:
|
|
||||||
# tracingOptions:
|
|
||||||
# trackComponents: true
|
|
||||||
# browserTracingIntegration:
|
|
||||||
# replayIntegration:
|
|
||||||
# options:
|
|
||||||
# dsn: 'https://examplePublicKey@o0.ingest.sentry.io/0'
|
|
||||||
|
|
||||||
# ┌─────────────────────┐
|
# ┌─────────────────────┐
|
||||||
#───┘ Other configuration └─────────────────────────────────────
|
#───┘ Other configuration └─────────────────────────────────────
|
||||||
|
|
||||||
|
|
@ -202,6 +174,12 @@ proxyBypassHosts:
|
||||||
# Media Proxy
|
# Media Proxy
|
||||||
#mediaProxy: https://example.com/proxy
|
#mediaProxy: https://example.com/proxy
|
||||||
|
|
||||||
|
# Proxy remote files (default: true)
|
||||||
|
proxyRemoteFiles: true
|
||||||
|
|
||||||
|
# Sign to ActivityPub GET request (default: true)
|
||||||
|
signToActivityPubGet: true
|
||||||
|
|
||||||
allowedPrivateNetworks: [
|
allowedPrivateNetworks: [
|
||||||
'127.0.0.1/32'
|
'127.0.0.1/32'
|
||||||
]
|
]
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
version: '3.8'
|
||||||
|
|
||||||
services:
|
services:
|
||||||
app:
|
app:
|
||||||
build:
|
build:
|
||||||
|
|
@ -6,7 +8,6 @@ services:
|
||||||
|
|
||||||
volumes:
|
volumes:
|
||||||
- ../:/workspace:cached
|
- ../:/workspace:cached
|
||||||
- node_modules:/workspace/node_modules
|
|
||||||
|
|
||||||
command: sleep infinity
|
command: sleep infinity
|
||||||
|
|
||||||
|
|
@ -28,7 +29,7 @@ services:
|
||||||
|
|
||||||
db:
|
db:
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
image: postgres:18-alpine
|
image: postgres:15-alpine
|
||||||
networks:
|
networks:
|
||||||
- internal_network
|
- internal_network
|
||||||
environment:
|
environment:
|
||||||
|
|
@ -45,7 +46,6 @@ services:
|
||||||
volumes:
|
volumes:
|
||||||
postgres-data:
|
postgres-data:
|
||||||
redis-data:
|
redis-data:
|
||||||
node_modules:
|
|
||||||
|
|
||||||
networks:
|
networks:
|
||||||
internal_network:
|
internal_network:
|
||||||
|
|
@ -2,14 +2,10 @@
|
||||||
|
|
||||||
set -xe
|
set -xe
|
||||||
|
|
||||||
sudo chown node node_modules
|
sudo chown -R node /workspace
|
||||||
sudo apt-get update
|
|
||||||
sudo apt-get -y install libgtk2.0-0 libgtk-3-0 libgbm-dev libnotify-dev libnss3 libxss1 libasound2 libxtst6 xauth xvfb
|
|
||||||
git config --global --add safe.directory /workspace
|
|
||||||
git submodule update --init
|
git submodule update --init
|
||||||
pnpm config set store-dir /home/node/.local/share/pnpm/store
|
pnpm config set store-dir /home/node/.local/share/pnpm/store
|
||||||
pnpm install --frozen-lockfile
|
pnpm install --frozen-lockfile
|
||||||
cp .devcontainer/devcontainer.yml .config/default.yml
|
cp .devcontainer/devcontainer.yml .config/default.yml
|
||||||
pnpm build
|
pnpm build
|
||||||
pnpm migrate
|
pnpm migrate
|
||||||
pnpm exec cypress install
|
|
||||||
|
|
|
||||||
|
|
@ -6,13 +6,13 @@
|
||||||
Dockerfile
|
Dockerfile
|
||||||
build/
|
build/
|
||||||
built/
|
built/
|
||||||
src-js/
|
|
||||||
db/
|
db/
|
||||||
.devcontainer/compose.yml
|
docker-compose.yml
|
||||||
node_modules/
|
node_modules/
|
||||||
packages/*/node_modules
|
packages/*/node_modules
|
||||||
redis/
|
redis/
|
||||||
files/
|
files/
|
||||||
|
misskey-assets/
|
||||||
fluent-emojis/
|
fluent-emojis/
|
||||||
.pnp.*
|
.pnp.*
|
||||||
|
|
||||||
|
|
@ -28,4 +28,4 @@ fluent-emojis/
|
||||||
|
|
||||||
.idea/
|
.idea/
|
||||||
packages/*/.vscode/
|
packages/*/.vscode/
|
||||||
packages/backend/test/compose.yml
|
packages/backend/test/docker-compose.yml
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,3 @@ trim_trailing_whitespace = false
|
||||||
|
|
||||||
[*.{yml,yaml}]
|
[*.{yml,yaml}]
|
||||||
indent_style = space
|
indent_style = space
|
||||||
|
|
||||||
[packages/backend/migration/*.js]
|
|
||||||
indent_style = space
|
|
||||||
indent_size = 4
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
# These are supported funding model platforms
|
||||||
|
|
||||||
|
patreon: syuilo
|
||||||
|
|
@ -53,8 +53,8 @@ body:
|
||||||
Examples:
|
Examples:
|
||||||
* Model and OS of the device(s): MacBook Pro (14inch, 2021), macOS Ventura 13.4
|
* Model and OS of the device(s): MacBook Pro (14inch, 2021), macOS Ventura 13.4
|
||||||
* Browser: Chrome 113.0.5672.126
|
* Browser: Chrome 113.0.5672.126
|
||||||
* Server URL: misskey.example.com
|
* Server URL: misskey.io
|
||||||
* Misskey: 2026.x.x
|
* Misskey: 13.x.x
|
||||||
value: |
|
value: |
|
||||||
* Model and OS of the device(s):
|
* Model and OS of the device(s):
|
||||||
* Browser:
|
* Browser:
|
||||||
|
|
@ -74,11 +74,11 @@ body:
|
||||||
|
|
||||||
Examples:
|
Examples:
|
||||||
* Installation Method or Hosting Service: docker compose, k8s/docker, systemd, "Misskey install shell script", development environment
|
* Installation Method or Hosting Service: docker compose, k8s/docker, systemd, "Misskey install shell script", development environment
|
||||||
* Misskey: 2026.x.x
|
* Misskey: 13.x.x
|
||||||
* Node: 20.x.x
|
* Node: 20.x.x
|
||||||
* PostgreSQL: 18.x.x
|
* PostgreSQL: 15.x.x
|
||||||
* Redis: 7.x.x
|
* Redis: 7.x.x
|
||||||
* OS and Architecture: Ubuntu 24.04.2 LTS aarch64
|
* OS and Architecture: Ubuntu 22.04.2 LTS aarch64
|
||||||
value: |
|
value: |
|
||||||
* Installation Method or Hosting Service:
|
* Installation Method or Hosting Service:
|
||||||
* Misskey:
|
* Misskey:
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,3 @@ contact_links:
|
||||||
- name: 💬 Misskey official Discord
|
- name: 💬 Misskey official Discord
|
||||||
url: https://discord.gg/Wp8gVStHW3
|
url: https://discord.gg/Wp8gVStHW3
|
||||||
about: Chat freely about Misskey
|
about: Chat freely about Misskey
|
||||||
# 仮
|
|
||||||
- name: 💬 Start discussion
|
|
||||||
url: https://github.com/misskey-dev/misskey/discussions
|
|
||||||
about: The official forum to join conversation and ask question
|
|
||||||
|
|
|
||||||
|
|
@ -1,3 +0,0 @@
|
||||||
# Copilot Instructions for Misskey
|
|
||||||
|
|
||||||
- en-US.yml を編集しないでください。
|
|
||||||
|
|
@ -9,7 +9,7 @@ updates:
|
||||||
directory: "/"
|
directory: "/"
|
||||||
schedule:
|
schedule:
|
||||||
interval: daily
|
interval: daily
|
||||||
open-pull-requests-limit: 0
|
open-pull-requests-limit: 100
|
||||||
|
|
||||||
# Add only the root, not each workspace item
|
# Add only the root, not each workspace item
|
||||||
# https://github.com/dependabot/dependabot-core/issues/4993#issuecomment-1289133027
|
# https://github.com/dependabot/dependabot-core/issues/4993#issuecomment-1289133027
|
||||||
|
|
@ -17,13 +17,16 @@ updates:
|
||||||
directory: "/"
|
directory: "/"
|
||||||
schedule:
|
schedule:
|
||||||
interval: daily
|
interval: daily
|
||||||
open-pull-requests-limit: 0
|
open-pull-requests-limit: 10
|
||||||
# List dependencies required to be updated together, sharing the same version numbers.
|
# List dependencies required to be updated together, sharing the same version numbers.
|
||||||
# Those who simply have the common owner (e.g. @fastify) don't need to be listed.
|
# Those who simply have the common owner (e.g. @fastify) don't need to be listed.
|
||||||
groups:
|
groups:
|
||||||
aws-sdk:
|
aws-sdk:
|
||||||
patterns:
|
patterns:
|
||||||
- "@aws-sdk/*"
|
- "@aws-sdk/*"
|
||||||
|
bull-board:
|
||||||
|
patterns:
|
||||||
|
- "@bull-board/*"
|
||||||
nestjs:
|
nestjs:
|
||||||
patterns:
|
patterns:
|
||||||
- "@nestjs/*"
|
- "@nestjs/*"
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
'packages/backend:test':
|
'packages/backend:test':
|
||||||
- any:
|
- any:
|
||||||
- changed-files:
|
- changed-files:
|
||||||
- any-glob-to-any-file: ['packages/backend/test/**/*', 'packages/backend/test-federation/**/*']
|
- any-glob-to-any-file: ['packages/backend/test/**/*']
|
||||||
|
|
||||||
'packages/frontend':
|
'packages/frontend':
|
||||||
- any:
|
- any:
|
||||||
|
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
22.15.0
|
|
||||||
|
|
@ -1,7 +1,5 @@
|
||||||
url: 'http://misskey.local'
|
url: 'http://misskey.local'
|
||||||
|
|
||||||
setupPassword: example_password_please_change_this_or_you_will_get_hacked
|
|
||||||
|
|
||||||
# ローカルでテストするときにポートを被らないようにするためデフォルトのものとは変える(以下同じ)
|
# ローカルでテストするときにポートを被らないようにするためデフォルトのものとは変える(以下同じ)
|
||||||
port: 61812
|
port: 61812
|
||||||
|
|
||||||
|
|
@ -15,5 +13,3 @@ redis:
|
||||||
host: 127.0.0.1
|
host: 127.0.0.1
|
||||||
port: 56312
|
port: 56312
|
||||||
id: aidx
|
id: aidx
|
||||||
|
|
||||||
proxyRemoteFiles: true
|
|
||||||
|
|
|
||||||
|
|
@ -4,11 +4,10 @@ on:
|
||||||
push:
|
push:
|
||||||
paths:
|
paths:
|
||||||
- packages/misskey-js/**
|
- packages/misskey-js/**
|
||||||
- .github/workflows/api-misskey-js.yml
|
|
||||||
pull_request:
|
pull_request:
|
||||||
paths:
|
paths:
|
||||||
- packages/misskey-js/**
|
- packages/misskey-js/**
|
||||||
- .github/workflows/api-misskey-js.yml
|
|
||||||
jobs:
|
jobs:
|
||||||
report:
|
report:
|
||||||
|
|
||||||
|
|
@ -16,13 +15,12 @@ jobs:
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v6.0.1
|
uses: actions/checkout@v4.1.1
|
||||||
|
|
||||||
- name: Setup pnpm
|
- run: corepack enable
|
||||||
uses: pnpm/action-setup@v4.2.0
|
|
||||||
|
|
||||||
- name: Setup Node.js
|
- name: Setup Node.js
|
||||||
uses: actions/setup-node@v6.1.0
|
uses: actions/setup-node@v4.0.2
|
||||||
with:
|
with:
|
||||||
node-version-file: '.node-version'
|
node-version-file: '.node-version'
|
||||||
cache: 'pnpm'
|
cache: 'pnpm'
|
||||||
|
|
|
||||||
|
|
@ -12,9 +12,9 @@ jobs:
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout head
|
- name: Checkout head
|
||||||
uses: actions/checkout@v6.0.1
|
uses: actions/checkout@v4.1.1
|
||||||
- name: Setup Node.js
|
- name: Setup Node.js
|
||||||
uses: actions/setup-node@v6.1.0
|
uses: actions/setup-node@v4.0.2
|
||||||
with:
|
with:
|
||||||
node-version-file: '.node-version'
|
node-version-file: '.node-version'
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,31 +5,33 @@ on:
|
||||||
branches:
|
branches:
|
||||||
- master
|
- master
|
||||||
- develop
|
- develop
|
||||||
- improve-misskey-js-autogen-check
|
|
||||||
paths:
|
paths:
|
||||||
- packages/backend/**
|
- packages/backend/**
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
# pull_request_target safety: permissions: read-all, and there are no secrets used in this job
|
check-misskey-js-autogen:
|
||||||
generate-misskey-js:
|
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
permissions:
|
permissions:
|
||||||
contents: read
|
pull-requests: write
|
||||||
if: ${{ github.event.pull_request.mergeable == null || github.event.pull_request.mergeable == true }}
|
|
||||||
|
env:
|
||||||
|
api_json_name: "api-head.json"
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: checkout
|
- name: checkout
|
||||||
uses: actions/checkout@v6.0.1
|
uses: actions/checkout@v4.1.1
|
||||||
with:
|
with:
|
||||||
submodules: true
|
submodules: true
|
||||||
persist-credentials: false
|
ref: ${{ github.event.pull_request.head.sha }}
|
||||||
ref: refs/pull/${{ github.event.pull_request.number }}/merge
|
|
||||||
|
|
||||||
- name: setup pnpm
|
- name: setup pnpm
|
||||||
uses: pnpm/action-setup@v4
|
uses: pnpm/action-setup@v3
|
||||||
|
with:
|
||||||
|
version: 8
|
||||||
|
|
||||||
- name: setup node
|
- name: setup node
|
||||||
id: setup-node
|
id: setup-node
|
||||||
uses: actions/setup-node@v6.1.0
|
uses: actions/setup-node@v4.0.2
|
||||||
with:
|
with:
|
||||||
node-version-file: '.node-version'
|
node-version-file: '.node-version'
|
||||||
cache: pnpm
|
cache: pnpm
|
||||||
|
|
@ -37,85 +39,82 @@ jobs:
|
||||||
- name: install dependencies
|
- name: install dependencies
|
||||||
run: pnpm i --frozen-lockfile
|
run: pnpm i --frozen-lockfile
|
||||||
|
|
||||||
# generate api.json
|
- name: wait get-api-diff
|
||||||
- name: Copy Config
|
uses: lewagon/wait-on-check-action@v1.3.3
|
||||||
run: cp .config/example.yml .config/default.yml
|
with:
|
||||||
- name: Build
|
ref: ${{ github.event.pull_request.head.sha }}
|
||||||
run: pnpm build
|
check-regexp: get-from-misskey .+
|
||||||
- name: Generate API JSON
|
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
run: pnpm --filter backend generate-api-json
|
wait-interval: 30
|
||||||
|
|
||||||
# build misskey js
|
- name: Download artifact
|
||||||
- name: Build misskey-js
|
uses: actions/github-script@v7.0.1
|
||||||
|
with:
|
||||||
|
script: |
|
||||||
|
const fs = require('fs');
|
||||||
|
|
||||||
|
const workflows = await github.rest.actions.listWorkflowRunsForRepo({
|
||||||
|
owner: context.repo.owner,
|
||||||
|
repo: context.repo.repo,
|
||||||
|
head_sha: `${{ github.event.pull_request.head.sha }}`
|
||||||
|
}).then(x => x.data.workflow_runs);
|
||||||
|
|
||||||
|
console.log(workflows.map(x => ({name: x.name, title: x.display_title})));
|
||||||
|
|
||||||
|
const run_id = workflows.find(x => x.name.includes("Get api.json from Misskey")).id;
|
||||||
|
|
||||||
|
let allArtifacts = await github.rest.actions.listWorkflowRunArtifacts({
|
||||||
|
owner: context.repo.owner,
|
||||||
|
repo: context.repo.repo,
|
||||||
|
run_id: run_id,
|
||||||
|
});
|
||||||
|
|
||||||
|
let matchArtifacts = allArtifacts.data.artifacts.filter((artifact) => {
|
||||||
|
return artifact.name.startsWith("api-artifact-") || artifact.name == "api-artifact"
|
||||||
|
});
|
||||||
|
|
||||||
|
await Promise.all(matchArtifacts.map(async (artifact) => {
|
||||||
|
let download = await github.rest.actions.downloadArtifact({
|
||||||
|
owner: context.repo.owner,
|
||||||
|
repo: context.repo.repo,
|
||||||
|
artifact_id: artifact.id,
|
||||||
|
archive_format: 'zip',
|
||||||
|
});
|
||||||
|
await fs.promises.writeFile(`${process.env.GITHUB_WORKSPACE}/${artifact.name}.zip`, Buffer.from(download.data));
|
||||||
|
}));
|
||||||
|
|
||||||
|
- name: unzip artifacts
|
||||||
run: |-
|
run: |-
|
||||||
cp packages/backend/built/api.json packages/misskey-js/generator/api.json
|
find . -mindepth 1 -maxdepth 1 -type f -name '*.zip' -exec unzip {} -d . ';'
|
||||||
pnpm run --filter misskey-js-type-generator generate
|
ls -la
|
||||||
|
|
||||||
# packages/misskey-js/generator/built/autogen
|
- name: get head checksum
|
||||||
- name: Upload Generated
|
run: |-
|
||||||
uses: actions/upload-artifact@v6
|
checksum=$(realpath head_checksum)
|
||||||
with:
|
|
||||||
name: generated-misskey-js
|
|
||||||
path: packages/misskey-js/generator/built/autogen
|
|
||||||
|
|
||||||
# pull_request_target safety: permissions: read-all, and no user codes are executed
|
cd packages/misskey-js/src
|
||||||
get-actual-misskey-js:
|
find autogen -type f -exec sh -c 'echo $(sed -E "s/^\s+\*\s+generatedAt:.+$//" {} | sha256sum | cut -d" " -f 1) {}' \; > $checksum
|
||||||
runs-on: ubuntu-latest
|
cd ../../..
|
||||||
permissions:
|
|
||||||
contents: read
|
|
||||||
if: ${{ github.event.pull_request.mergeable == null || github.event.pull_request.mergeable == true }}
|
|
||||||
steps:
|
|
||||||
- name: checkout
|
|
||||||
uses: actions/checkout@v6.0.1
|
|
||||||
with:
|
|
||||||
submodules: true
|
|
||||||
persist-credentials: false
|
|
||||||
ref: refs/pull/${{ github.event.pull_request.number }}/merge
|
|
||||||
|
|
||||||
- name: Upload From Merged
|
- name: build autogen
|
||||||
uses: actions/upload-artifact@v6
|
run: |-
|
||||||
with:
|
checksum=$(realpath ${api_json_name}_checksum)
|
||||||
name: actual-misskey-js
|
mv $api_json_name packages/misskey-js/generator/api.json
|
||||||
path: packages/misskey-js/src/autogen
|
|
||||||
|
|
||||||
# pull_request_target safety: nothing is cloned from repository
|
cd packages/misskey-js/generator
|
||||||
comment-misskey-js-autogen:
|
pnpm run generate
|
||||||
runs-on: ubuntu-latest
|
cd built
|
||||||
needs: [generate-misskey-js, get-actual-misskey-js]
|
find autogen -type f -exec sh -c 'echo $(sed -E "s/^\s+\*\s+generatedAt:.+$//" {} | sha256sum | cut -d" " -f 1) {}' \; > $checksum
|
||||||
permissions:
|
cd ../../../..
|
||||||
pull-requests: write
|
|
||||||
steps:
|
|
||||||
- name: download generated-misskey-js
|
|
||||||
uses: actions/download-artifact@v7
|
|
||||||
with:
|
|
||||||
name: generated-misskey-js
|
|
||||||
path: misskey-js-generated
|
|
||||||
|
|
||||||
- name: download actual-misskey-js
|
- name: check update for type definitions
|
||||||
uses: actions/download-artifact@v7
|
run: diff head_checksum ${api_json_name}_checksum
|
||||||
with:
|
|
||||||
name: actual-misskey-js
|
|
||||||
path: misskey-js-actual
|
|
||||||
|
|
||||||
- name: check misskey-js changes
|
|
||||||
id: check-changes
|
|
||||||
run: |
|
|
||||||
diff -r -u --label=generated --label=on-tree ./misskey-js-generated ./misskey-js-actual > misskey-js.diff || true
|
|
||||||
|
|
||||||
if [ -s misskey-js.diff ]; then
|
|
||||||
echo "changes=true" >> $GITHUB_OUTPUT
|
|
||||||
else
|
|
||||||
echo "changes=false" >> $GITHUB_OUTPUT
|
|
||||||
fi
|
|
||||||
|
|
||||||
- name: Print full diff
|
|
||||||
run: cat ./misskey-js.diff
|
|
||||||
|
|
||||||
- name: send message
|
- name: send message
|
||||||
if: steps.check-changes.outputs.changes == 'true'
|
if: failure()
|
||||||
uses: thollander/actions-comment-pull-request@v3
|
uses: thollander/actions-comment-pull-request@v2
|
||||||
with:
|
with:
|
||||||
comment-tag: check-misskey-js-autogen
|
comment_tag: check-misskey-js-autogen
|
||||||
message: |-
|
message: |-
|
||||||
Thank you for sending us a great Pull Request! 👍
|
Thank you for sending us a great Pull Request! 👍
|
||||||
Please regenerate misskey-js type definitions! 🙏
|
Please regenerate misskey-js type definitions! 🙏
|
||||||
|
|
@ -126,14 +125,10 @@ jobs:
|
||||||
```
|
```
|
||||||
|
|
||||||
- name: send message
|
- name: send message
|
||||||
if: steps.check-changes.outputs.changes == 'false'
|
if: success()
|
||||||
uses: thollander/actions-comment-pull-request@v3
|
uses: thollander/actions-comment-pull-request@v2
|
||||||
with:
|
with:
|
||||||
comment-tag: check-misskey-js-autogen
|
comment_tag: check-misskey-js-autogen
|
||||||
mode: delete
|
mode: delete
|
||||||
message: "Thank you!"
|
message: "Thank you!"
|
||||||
create_if_not_exists: false
|
create_if_not_exists: false
|
||||||
|
|
||||||
- name: Make failure if changes are detected
|
|
||||||
if: steps.check-changes.outputs.changes == 'true'
|
|
||||||
run: exit 1
|
|
||||||
|
|
|
||||||
|
|
@ -6,13 +6,12 @@ on:
|
||||||
paths:
|
paths:
|
||||||
- packages/misskey-js/package.json
|
- packages/misskey-js/package.json
|
||||||
- package.json
|
- package.json
|
||||||
- .github/workflows/check-misskey-js-version.yml
|
|
||||||
pull_request:
|
pull_request:
|
||||||
branches: [ develop ]
|
branches: [ develop ]
|
||||||
paths:
|
paths:
|
||||||
- packages/misskey-js/package.json
|
- packages/misskey-js/package.json
|
||||||
- package.json
|
- package.json
|
||||||
- .github/workflows/check-misskey-js-version.yml
|
|
||||||
jobs:
|
jobs:
|
||||||
check-version:
|
check-version:
|
||||||
# ルートの package.json と packages/misskey-js/package.json のバージョンが一致しているかを確認する
|
# ルートの package.json と packages/misskey-js/package.json のバージョンが一致しているかを確認する
|
||||||
|
|
@ -20,7 +19,7 @@ jobs:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v6.0.1
|
uses: actions/checkout@v4.1.1
|
||||||
- name: Check version
|
- name: Check version
|
||||||
run: |
|
run: |
|
||||||
if [ "$(jq -r '.version' package.json)" != "$(jq -r '.version' packages/misskey-js/package.json)" ]; then
|
if [ "$(jq -r '.version' package.json)" != "$(jq -r '.version' packages/misskey-js/package.json)" ]; then
|
||||||
|
|
|
||||||
|
|
@ -1,81 +0,0 @@
|
||||||
name: Check SPDX-License-Identifier
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- master
|
|
||||||
- develop
|
|
||||||
pull_request:
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
check-spdx-license-id:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@v6.0.1
|
|
||||||
- name: Check
|
|
||||||
run: |
|
|
||||||
counter=0
|
|
||||||
|
|
||||||
search() {
|
|
||||||
local directory="$1"
|
|
||||||
find "$directory" -type f \
|
|
||||||
'(' \
|
|
||||||
-name "*.cjs" -and -not -name '*.config.cjs' -o \
|
|
||||||
-name "*.html" -o \
|
|
||||||
-name "*.js" -and -not -name '*.config.js' -o \
|
|
||||||
-name "*.mjs" -and -not -name '*.config.mjs' -o \
|
|
||||||
-name "*.scss" -o \
|
|
||||||
-name "*.ts" -and -not -name '*.config.ts' -o \
|
|
||||||
-name "*.vue" \
|
|
||||||
')' -and \
|
|
||||||
-not -name '*eslint*'
|
|
||||||
}
|
|
||||||
|
|
||||||
check() {
|
|
||||||
local file="$1"
|
|
||||||
if ! (
|
|
||||||
grep -q "SPDX-FileCopyrightText: syuilo and misskey-project" "$file" ||
|
|
||||||
grep -q "SPDX-License-Identifier: AGPL-3.0-only" "$file"
|
|
||||||
); then
|
|
||||||
echo "Missing: $file"
|
|
||||||
((counter++))
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
directories=(
|
|
||||||
"cypress/e2e"
|
|
||||||
"packages/backend/migration"
|
|
||||||
"packages/backend/src"
|
|
||||||
"packages/backend/test"
|
|
||||||
"packages/frontend-shared/@types"
|
|
||||||
"packages/frontend-shared/js"
|
|
||||||
"packages/frontend-builder"
|
|
||||||
"packages/frontend/.storybook"
|
|
||||||
"packages/frontend/@types"
|
|
||||||
"packages/frontend/lib"
|
|
||||||
"packages/frontend/public"
|
|
||||||
"packages/frontend/src"
|
|
||||||
"packages/frontend/test"
|
|
||||||
"packages/frontend-embed/@types"
|
|
||||||
"packages/frontend-embed/src"
|
|
||||||
"packages/icons-subsetter/src"
|
|
||||||
"packages/misskey-bubble-game/src"
|
|
||||||
"packages/misskey-reversi/src"
|
|
||||||
"packages/sw/src"
|
|
||||||
"scripts"
|
|
||||||
)
|
|
||||||
|
|
||||||
for directory in "${directories[@]}"; do
|
|
||||||
for file in $(search $directory); do
|
|
||||||
check "$file"
|
|
||||||
done
|
|
||||||
done
|
|
||||||
|
|
||||||
if [ $counter -gt 0 ]; then
|
|
||||||
echo "SPDX-License-Identifier is missing in $counter files."
|
|
||||||
exit 1
|
|
||||||
else
|
|
||||||
echo "SPDX-License-Identifier is certainly described in all target files!"
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
@ -10,7 +10,7 @@ jobs:
|
||||||
check_copyright_year:
|
check_copyright_year:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v6.0.1
|
- uses: actions/checkout@v4.1.1
|
||||||
- run: |
|
- run: |
|
||||||
if [ "$(grep Copyright COPYING | sed -e 's/.*2014-\([0-9]*\) .*/\1/g')" -ne "$(date +%Y)" ]; then
|
if [ "$(grep Copyright COPYING | sed -e 's/.*2014-\([0-9]*\) .*/\1/g')" -ne "$(date +%Y)" ]; then
|
||||||
echo "Please change copyright year!"
|
echo "Please change copyright year!"
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@ jobs:
|
||||||
wait_time: ${{ steps.get-wait-time.outputs.wait_time }}
|
wait_time: ${{ steps.get-wait-time.outputs.wait_time }}
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v6.0.1
|
uses: actions/checkout@v4.1.1
|
||||||
|
|
||||||
- name: Check allowed users
|
- name: Check allowed users
|
||||||
id: check-allowed-users
|
id: check-allowed-users
|
||||||
|
|
@ -50,9 +50,12 @@ jobs:
|
||||||
|
|
||||||
- name: Get PR ref
|
- name: Get PR ref
|
||||||
id: get-ref
|
id: get-ref
|
||||||
|
env:
|
||||||
|
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
run: |
|
run: |
|
||||||
PR_REF="refs/pull/${{ github.event.issue.number }}/head"
|
PR_NUMBER=$(jq --raw-output .issue.number $GITHUB_EVENT_PATH)
|
||||||
echo "pr-ref=$PR_REF" >> $GITHUB_OUTPUT
|
PR_REF=$(gh pr view $PR_NUMBER --json headRefName -q '.headRefName')
|
||||||
|
echo "pr-ref=$PR_REF" > $GITHUB_OUTPUT
|
||||||
|
|
||||||
- name: Extract wait time
|
- name: Extract wait time
|
||||||
id: get-wait-time
|
id: get-wait-time
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@ jobs:
|
||||||
platform=${{ matrix.platform }}
|
platform=${{ matrix.platform }}
|
||||||
echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV
|
echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV
|
||||||
- name: Check out the repo
|
- name: Check out the repo
|
||||||
uses: actions/checkout@v6.0.1
|
uses: actions/checkout@v4.1.1
|
||||||
- name: Set up Docker Buildx
|
- name: Set up Docker Buildx
|
||||||
uses: docker/setup-buildx-action@v3
|
uses: docker/setup-buildx-action@v3
|
||||||
- name: Log in to Docker Hub
|
- name: Log in to Docker Hub
|
||||||
|
|
@ -37,7 +37,7 @@ jobs:
|
||||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||||
- name: Build and push by digest
|
- name: Build and push by digest
|
||||||
id: build
|
id: build
|
||||||
uses: docker/build-push-action@v6
|
uses: docker/build-push-action@v5
|
||||||
with:
|
with:
|
||||||
context: .
|
context: .
|
||||||
push: true
|
push: true
|
||||||
|
|
@ -53,7 +53,7 @@ jobs:
|
||||||
digest="${{ steps.build.outputs.digest }}"
|
digest="${{ steps.build.outputs.digest }}"
|
||||||
touch "/tmp/digests/${digest#sha256:}"
|
touch "/tmp/digests/${digest#sha256:}"
|
||||||
- name: Upload digest
|
- name: Upload digest
|
||||||
uses: actions/upload-artifact@v6
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: digests-${{ env.PLATFORM_PAIR }}
|
name: digests-${{ env.PLATFORM_PAIR }}
|
||||||
path: /tmp/digests/*
|
path: /tmp/digests/*
|
||||||
|
|
@ -66,7 +66,7 @@ jobs:
|
||||||
- build
|
- build
|
||||||
steps:
|
steps:
|
||||||
- name: Download digests
|
- name: Download digests
|
||||||
uses: actions/download-artifact@v7
|
uses: actions/download-artifact@v4
|
||||||
with:
|
with:
|
||||||
path: /tmp/digests
|
path: /tmp/digests
|
||||||
pattern: digests-*
|
pattern: digests-*
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@ jobs:
|
||||||
platform=${{ matrix.platform }}
|
platform=${{ matrix.platform }}
|
||||||
echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV
|
echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV
|
||||||
- name: Check out the repo
|
- name: Check out the repo
|
||||||
uses: actions/checkout@v6.0.1
|
uses: actions/checkout@v4.1.1
|
||||||
- name: Set up Docker Buildx
|
- name: Set up Docker Buildx
|
||||||
uses: docker/setup-buildx-action@v3
|
uses: docker/setup-buildx-action@v3
|
||||||
- name: Docker meta
|
- name: Docker meta
|
||||||
|
|
@ -48,7 +48,7 @@ jobs:
|
||||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||||
- name: Build and Push to Docker Hub
|
- name: Build and Push to Docker Hub
|
||||||
id: build
|
id: build
|
||||||
uses: docker/build-push-action@v6
|
uses: docker/build-push-action@v5
|
||||||
with:
|
with:
|
||||||
context: .
|
context: .
|
||||||
push: true
|
push: true
|
||||||
|
|
@ -64,7 +64,7 @@ jobs:
|
||||||
digest="${{ steps.build.outputs.digest }}"
|
digest="${{ steps.build.outputs.digest }}"
|
||||||
touch "/tmp/digests/${digest#sha256:}"
|
touch "/tmp/digests/${digest#sha256:}"
|
||||||
- name: Upload digest
|
- name: Upload digest
|
||||||
uses: actions/upload-artifact@v6
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: digests-${{ env.PLATFORM_PAIR }}
|
name: digests-${{ env.PLATFORM_PAIR }}
|
||||||
path: /tmp/digests/*
|
path: /tmp/digests/*
|
||||||
|
|
@ -77,7 +77,7 @@ jobs:
|
||||||
- build
|
- build
|
||||||
steps:
|
steps:
|
||||||
- name: Download digests
|
- name: Download digests
|
||||||
uses: actions/download-artifact@v7
|
uses: actions/download-artifact@v4
|
||||||
with:
|
with:
|
||||||
path: /tmp/digests
|
path: /tmp/digests
|
||||||
pattern: digests-*
|
pattern: digests-*
|
||||||
|
|
|
||||||
|
|
@ -11,43 +11,20 @@ on:
|
||||||
jobs:
|
jobs:
|
||||||
dockle:
|
dockle:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
env:
|
env:
|
||||||
DOCKER_CONTENT_TRUST: 1
|
DOCKER_CONTENT_TRUST: 1
|
||||||
DOCKLE_VERSION: 0.4.15
|
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v6.0.1
|
- uses: actions/checkout@v4.1.1
|
||||||
|
- run: |
|
||||||
- name: Download and install dockle v${{ env.DOCKLE_VERSION }}
|
curl -L -o dockle.deb "https://github.com/goodwithtech/dockle/releases/download/v0.4.10/dockle_0.4.10_Linux-64bit.deb"
|
||||||
run: |
|
|
||||||
set -eux
|
|
||||||
curl -L -o dockle.deb "https://github.com/goodwithtech/dockle/releases/download/v${DOCKLE_VERSION}/dockle_${DOCKLE_VERSION}_Linux-64bit.deb"
|
|
||||||
sudo dpkg -i dockle.deb
|
sudo dpkg -i dockle.deb
|
||||||
|
- run: |
|
||||||
- name: Build web image (docker build)
|
cp .config/docker_example.env .config/docker.env
|
||||||
run: |
|
cp ./docker-compose_example.yml ./docker-compose.yml
|
||||||
set -eux
|
- run: |
|
||||||
docker build -t "misskey-web:ci" .
|
docker compose up -d web
|
||||||
docker image ls
|
docker tag "$(docker compose images web | awk 'OFS=":" {print $4}' | tail -n +2)" misskey-web:latest
|
||||||
|
- run: |
|
||||||
- name: Mount tmpfs for Dockle tar
|
cmd="dockle --exit-code 1 misskey-web:latest ${image_name}"
|
||||||
env:
|
echo "> ${cmd}"
|
||||||
TMPFS_SIZE: 8G
|
eval "${cmd}"
|
||||||
run: |
|
|
||||||
set -eux
|
|
||||||
sudo mkdir -p /mnt/dockle-tmp
|
|
||||||
sudo mount -t tmpfs -o size=${{ env.TMPFS_SIZE }} tmpfs /mnt/dockle-tmp
|
|
||||||
free -h
|
|
||||||
df -h
|
|
||||||
|
|
||||||
- name: Save image tar into tmpfs
|
|
||||||
run: |
|
|
||||||
set -eux
|
|
||||||
docker save misskey-web:ci -o /mnt/dockle-tmp/misskey-web.tar
|
|
||||||
ls -lh /mnt/dockle-tmp/misskey-web.tar
|
|
||||||
|
|
||||||
- name: Run Dockle Scan (tar input)
|
|
||||||
run: |
|
|
||||||
set -eux
|
|
||||||
dockle --exit-code 1 --input /mnt/dockle-tmp/misskey-web.tar
|
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ on:
|
||||||
paths:
|
paths:
|
||||||
- packages/backend/**
|
- packages/backend/**
|
||||||
- .github/workflows/get-api-diff.yml
|
- .github/workflows/get-api-diff.yml
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
get-from-misskey:
|
get-from-misskey:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
@ -17,6 +18,7 @@ jobs:
|
||||||
|
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
|
node-version: [20.10.0]
|
||||||
api-json-name: [api-base.json, api-head.json]
|
api-json-name: [api-base.json, api-head.json]
|
||||||
include:
|
include:
|
||||||
- api-json-name: api-base.json
|
- api-json-name: api-base.json
|
||||||
|
|
@ -25,17 +27,21 @@ jobs:
|
||||||
ref: refs/pull/${{ github.event.number }}/merge
|
ref: refs/pull/${{ github.event.number }}/merge
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v6.0.1
|
- uses: actions/checkout@v4.1.1
|
||||||
with:
|
with:
|
||||||
ref: ${{ matrix.ref }}
|
ref: ${{ matrix.ref }}
|
||||||
submodules: true
|
submodules: true
|
||||||
- name: Setup pnpm
|
- name: Install pnpm
|
||||||
uses: pnpm/action-setup@v4.2.0
|
uses: pnpm/action-setup@v3
|
||||||
- name: Use Node.js
|
|
||||||
uses: actions/setup-node@v6.1.0
|
|
||||||
with:
|
with:
|
||||||
node-version-file: '.node-version'
|
version: 8
|
||||||
|
run_install: false
|
||||||
|
- name: Use Node.js ${{ matrix.node-version }}
|
||||||
|
uses: actions/setup-node@v4.0.2
|
||||||
|
with:
|
||||||
|
node-version: ${{ matrix.node-version }}
|
||||||
cache: 'pnpm'
|
cache: 'pnpm'
|
||||||
|
- run: corepack enable
|
||||||
- run: pnpm i --frozen-lockfile
|
- run: pnpm i --frozen-lockfile
|
||||||
- name: Check pnpm-lock.yaml
|
- name: Check pnpm-lock.yaml
|
||||||
run: git diff --exit-code pnpm-lock.yaml
|
run: git diff --exit-code pnpm-lock.yaml
|
||||||
|
|
@ -48,7 +54,7 @@ jobs:
|
||||||
- name: Copy API.json
|
- name: Copy API.json
|
||||||
run: cp packages/backend/built/api.json ${{ matrix.api-json-name }}
|
run: cp packages/backend/built/api.json ${{ matrix.api-json-name }}
|
||||||
- name: Upload Artifact
|
- name: Upload Artifact
|
||||||
uses: actions/upload-artifact@v6
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: api-artifact-${{ matrix.api-json-name }}
|
name: api-artifact-${{ matrix.api-json-name }}
|
||||||
path: ${{ matrix.api-json-name }}
|
path: ${{ matrix.api-json-name }}
|
||||||
|
|
@ -61,7 +67,7 @@ jobs:
|
||||||
PR_NUMBER: ${{ github.event.number }}
|
PR_NUMBER: ${{ github.event.number }}
|
||||||
run: |
|
run: |
|
||||||
echo "$PR_NUMBER" > ./pr_number
|
echo "$PR_NUMBER" > ./pr_number
|
||||||
- uses: actions/upload-artifact@v6
|
- uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: api-artifact-pr-number
|
name: api-artifact-pr-number
|
||||||
path: pr_number
|
path: pr_number
|
||||||
|
|
|
||||||
|
|
@ -1,87 +0,0 @@
|
||||||
# this name is used in report-backend-memory.yml so be careful when change name
|
|
||||||
name: Get backend memory usage
|
|
||||||
|
|
||||||
on:
|
|
||||||
pull_request:
|
|
||||||
branches:
|
|
||||||
- master
|
|
||||||
- develop
|
|
||||||
paths:
|
|
||||||
- packages/backend/**
|
|
||||||
- packages/misskey-js/**
|
|
||||||
- .github/workflows/get-backend-memory.yml
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
get-memory-usage:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
permissions:
|
|
||||||
contents: read
|
|
||||||
|
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
memory-json-name: [memory-base.json, memory-head.json]
|
|
||||||
include:
|
|
||||||
- memory-json-name: memory-base.json
|
|
||||||
ref: ${{ github.base_ref }}
|
|
||||||
- memory-json-name: memory-head.json
|
|
||||||
ref: refs/pull/${{ github.event.number }}/merge
|
|
||||||
|
|
||||||
services:
|
|
||||||
postgres:
|
|
||||||
image: postgres:18
|
|
||||||
ports:
|
|
||||||
- 54312:5432
|
|
||||||
env:
|
|
||||||
POSTGRES_DB: test-misskey
|
|
||||||
POSTGRES_HOST_AUTH_METHOD: trust
|
|
||||||
redis:
|
|
||||||
image: redis:7
|
|
||||||
ports:
|
|
||||||
- 56312:6379
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v6.0.1
|
|
||||||
with:
|
|
||||||
ref: ${{ matrix.ref }}
|
|
||||||
submodules: true
|
|
||||||
- name: Setup pnpm
|
|
||||||
uses: pnpm/action-setup@v4.2.0
|
|
||||||
- name: Use Node.js
|
|
||||||
uses: actions/setup-node@v6.1.0
|
|
||||||
with:
|
|
||||||
node-version-file: '.node-version'
|
|
||||||
cache: 'pnpm'
|
|
||||||
- run: pnpm i --frozen-lockfile
|
|
||||||
- name: Check pnpm-lock.yaml
|
|
||||||
run: git diff --exit-code pnpm-lock.yaml
|
|
||||||
- name: Copy Configure
|
|
||||||
run: cp .github/misskey/test.yml .config/default.yml
|
|
||||||
- name: Compile Configure
|
|
||||||
run: pnpm compile-config
|
|
||||||
- name: Build
|
|
||||||
run: pnpm build
|
|
||||||
- name: Run migrations
|
|
||||||
run: pnpm --filter backend migrate
|
|
||||||
- name: Measure memory usage
|
|
||||||
run: |
|
|
||||||
# Start the server and measure memory usage
|
|
||||||
node packages/backend/scripts/measure-memory.mjs > ${{ matrix.memory-json-name }}
|
|
||||||
- name: Upload Artifact
|
|
||||||
uses: actions/upload-artifact@v6
|
|
||||||
with:
|
|
||||||
name: memory-artifact-${{ matrix.memory-json-name }}
|
|
||||||
path: ${{ matrix.memory-json-name }}
|
|
||||||
|
|
||||||
save-pr-number:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
permissions: {}
|
|
||||||
steps:
|
|
||||||
- name: Save PR number
|
|
||||||
env:
|
|
||||||
PR_NUMBER: ${{ github.event.number }}
|
|
||||||
run: |
|
|
||||||
echo "$PR_NUMBER" > ./pr_number
|
|
||||||
- uses: actions/upload-artifact@v6
|
|
||||||
with:
|
|
||||||
name: memory-artifact-pr-number
|
|
||||||
path: pr_number
|
|
||||||
|
|
@ -11,6 +11,6 @@ jobs:
|
||||||
pull-requests: write
|
pull-requests: write
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/labeler@v6
|
- uses: actions/labeler@v5
|
||||||
with:
|
with:
|
||||||
repo-token: "${{ secrets.GITHUB_TOKEN }}"
|
repo-token: "${{ secrets.GITHUB_TOKEN }}"
|
||||||
|
|
|
||||||
|
|
@ -8,44 +8,34 @@ on:
|
||||||
paths:
|
paths:
|
||||||
- packages/backend/**
|
- packages/backend/**
|
||||||
- packages/frontend/**
|
- packages/frontend/**
|
||||||
- packages/frontend-shared/**
|
|
||||||
- packages/frontend-builder/**
|
|
||||||
- packages/frontend-embed/**
|
|
||||||
- packages/icons-subsetter/**
|
|
||||||
- packages/sw/**
|
- packages/sw/**
|
||||||
- packages/misskey-js/**
|
- packages/misskey-js/**
|
||||||
- packages/misskey-bubble-game/**
|
- packages/shared/.eslintrc.js
|
||||||
- packages/misskey-reversi/**
|
|
||||||
- packages/shared/eslint.config.js
|
|
||||||
- .github/workflows/lint.yml
|
|
||||||
pull_request:
|
pull_request:
|
||||||
paths:
|
paths:
|
||||||
- packages/backend/**
|
- packages/backend/**
|
||||||
- packages/frontend/**
|
- packages/frontend/**
|
||||||
- packages/frontend-shared/**
|
|
||||||
- packages/frontend-builder/**
|
|
||||||
- packages/frontend-embed/**
|
|
||||||
- packages/icons-subsetter/**
|
|
||||||
- packages/sw/**
|
- packages/sw/**
|
||||||
- packages/misskey-js/**
|
- packages/misskey-js/**
|
||||||
- packages/misskey-bubble-game/**
|
- packages/shared/.eslintrc.js
|
||||||
- packages/misskey-reversi/**
|
|
||||||
- packages/shared/eslint.config.js
|
|
||||||
- .github/workflows/lint.yml
|
|
||||||
jobs:
|
jobs:
|
||||||
pnpm_install:
|
pnpm_install:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v6.0.1
|
- uses: actions/checkout@v4.1.1
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
submodules: true
|
submodules: true
|
||||||
- name: Setup pnpm
|
- uses: pnpm/action-setup@v3
|
||||||
uses: pnpm/action-setup@v4.2.0
|
with:
|
||||||
- uses: actions/setup-node@v6.1.0
|
version: 8
|
||||||
|
run_install: false
|
||||||
|
- uses: actions/setup-node@v4.0.2
|
||||||
with:
|
with:
|
||||||
node-version-file: '.node-version'
|
node-version-file: '.node-version'
|
||||||
cache: 'pnpm'
|
cache: 'pnpm'
|
||||||
|
- run: corepack enable
|
||||||
- run: pnpm i --frozen-lockfile
|
- run: pnpm i --frozen-lockfile
|
||||||
|
|
||||||
lint:
|
lint:
|
||||||
|
|
@ -57,36 +47,24 @@ jobs:
|
||||||
workspace:
|
workspace:
|
||||||
- backend
|
- backend
|
||||||
- frontend
|
- frontend
|
||||||
- frontend-shared
|
|
||||||
- frontend-builder
|
|
||||||
- frontend-embed
|
|
||||||
- icons-subsetter
|
|
||||||
- sw
|
- sw
|
||||||
- misskey-js
|
- misskey-js
|
||||||
- misskey-bubble-game
|
|
||||||
- misskey-reversi
|
|
||||||
env:
|
|
||||||
eslint-cache-version: v1
|
|
||||||
eslint-cache-path: ${{ github.workspace }}/node_modules/.cache/eslint-${{ matrix.workspace }}
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v6.0.1
|
- uses: actions/checkout@v4.1.1
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
submodules: true
|
submodules: true
|
||||||
- name: Setup pnpm
|
- uses: pnpm/action-setup@v3
|
||||||
uses: pnpm/action-setup@v4.2.0
|
with:
|
||||||
- uses: actions/setup-node@v6.1.0
|
version: 7
|
||||||
|
run_install: false
|
||||||
|
- uses: actions/setup-node@v4.0.2
|
||||||
with:
|
with:
|
||||||
node-version-file: '.node-version'
|
node-version-file: '.node-version'
|
||||||
cache: 'pnpm'
|
cache: 'pnpm'
|
||||||
|
- run: corepack enable
|
||||||
- run: pnpm i --frozen-lockfile
|
- run: pnpm i --frozen-lockfile
|
||||||
- name: Restore eslint cache
|
- run: pnpm --filter ${{ matrix.workspace }} run eslint
|
||||||
uses: actions/cache@v4.3.0
|
|
||||||
with:
|
|
||||||
path: ${{ env.eslint-cache-path }}
|
|
||||||
key: eslint-${{ env.eslint-cache-version }}-${{ matrix.workspace }}-${{ hashFiles('**/pnpm-lock.yaml') }}-${{ github.ref_name }}-${{ github.sha }}
|
|
||||||
restore-keys: eslint-${{ env.eslint-cache-version }}-${{ matrix.workspace }}-${{ hashFiles('**/pnpm-lock.yaml') }}-
|
|
||||||
- run: pnpm --filter ${{ matrix.workspace }} run eslint --cache --cache-location ${{ env.eslint-cache-path }} --cache-strategy content
|
|
||||||
|
|
||||||
typecheck:
|
typecheck:
|
||||||
needs: [pnpm_install]
|
needs: [pnpm_install]
|
||||||
|
|
@ -96,20 +74,24 @@ jobs:
|
||||||
matrix:
|
matrix:
|
||||||
workspace:
|
workspace:
|
||||||
- backend
|
- backend
|
||||||
- frontend
|
|
||||||
- sw
|
|
||||||
- misskey-js
|
- misskey-js
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v6.0.1
|
- uses: actions/checkout@v4.1.1
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
submodules: true
|
submodules: true
|
||||||
- name: Setup pnpm
|
- uses: pnpm/action-setup@v3
|
||||||
uses: pnpm/action-setup@v4.2.0
|
with:
|
||||||
- uses: actions/setup-node@v6.1.0
|
version: 7
|
||||||
|
run_install: false
|
||||||
|
- uses: actions/setup-node@v4.0.2
|
||||||
with:
|
with:
|
||||||
node-version-file: '.node-version'
|
node-version-file: '.node-version'
|
||||||
cache: 'pnpm'
|
cache: 'pnpm'
|
||||||
|
- run: corepack enable
|
||||||
- run: pnpm i --frozen-lockfile
|
- run: pnpm i --frozen-lockfile
|
||||||
- run: pnpm --filter "${{ matrix.workspace }}^..." run build
|
- run: pnpm --filter misskey-js run build
|
||||||
|
if: ${{ matrix.workspace == 'backend' }}
|
||||||
|
- run: pnpm --filter misskey-reversi run build:tsc
|
||||||
|
if: ${{ matrix.workspace == 'backend' }}
|
||||||
- run: pnpm --filter ${{ matrix.workspace }} run typecheck
|
- run: pnpm --filter ${{ matrix.workspace }} run typecheck
|
||||||
|
|
|
||||||
|
|
@ -1,33 +0,0 @@
|
||||||
name: Lint
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
paths:
|
|
||||||
- packages/i18n/**
|
|
||||||
- locales/**
|
|
||||||
- .github/workflows/locale.yml
|
|
||||||
pull_request:
|
|
||||||
paths:
|
|
||||||
- packages/i18n/**
|
|
||||||
- locales/**
|
|
||||||
- .github/workflows/locale.yml
|
|
||||||
jobs:
|
|
||||||
locale_verify:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
continue-on-error: true
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v6.0.1
|
|
||||||
with:
|
|
||||||
fetch-depth: 0
|
|
||||||
submodules: true
|
|
||||||
- name: Setup pnpm
|
|
||||||
uses: pnpm/action-setup@v4.2.0
|
|
||||||
- uses: actions/setup-node@v6.1.0
|
|
||||||
with:
|
|
||||||
node-version-file: ".node-version"
|
|
||||||
cache: "pnpm"
|
|
||||||
- run: pnpm i --frozen-lockfile
|
|
||||||
- run: pnpm --filter i18n build
|
|
||||||
- name: Verify Locales
|
|
||||||
working-directory: ./packages/i18n
|
|
||||||
run: pnpm run verify
|
|
||||||
|
|
@ -0,0 +1,36 @@
|
||||||
|
# If someone with write access comments "/ok-to-test" on a pull request, emit a repository_dispatch event
|
||||||
|
name: Ok To Test
|
||||||
|
|
||||||
|
on:
|
||||||
|
issue_comment:
|
||||||
|
types: [created]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
ok-to-test:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
# Only run for PRs, not issue comments
|
||||||
|
if: ${{ github.event.issue.pull_request }}
|
||||||
|
steps:
|
||||||
|
# Generate a GitHub App installation access token from an App ID and private key
|
||||||
|
# To create a new GitHub App:
|
||||||
|
# https://developer.github.com/apps/building-github-apps/creating-a-github-app/
|
||||||
|
# See app.yml for an example app manifest
|
||||||
|
- name: Generate token
|
||||||
|
id: generate_token
|
||||||
|
uses: tibdex/github-app-token@v2
|
||||||
|
with:
|
||||||
|
app_id: ${{ secrets.DEPLOYBOT_APP_ID }}
|
||||||
|
private_key: ${{ secrets.DEPLOYBOT_PRIVATE_KEY }}
|
||||||
|
|
||||||
|
- name: Slash Command Dispatch
|
||||||
|
uses: peter-evans/slash-command-dispatch@v4
|
||||||
|
env:
|
||||||
|
TOKEN: ${{ steps.generate_token.outputs.token }}
|
||||||
|
with:
|
||||||
|
token: ${{ env.TOKEN }} # GitHub App installation access token
|
||||||
|
# token: ${{ secrets.PERSONAL_ACCESS_TOKEN }} # PAT or OAuth token will also work
|
||||||
|
reaction-token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
issue-type: pull-request
|
||||||
|
commands: deploy
|
||||||
|
named-args: true
|
||||||
|
permission: write
|
||||||
|
|
@ -15,21 +15,28 @@ jobs:
|
||||||
contents: read
|
contents: read
|
||||||
id-token: write
|
id-token: write
|
||||||
|
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
node-version: [20.10.0]
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v6.0.1
|
- uses: actions/checkout@v4.1.1
|
||||||
with:
|
with:
|
||||||
submodules: true
|
submodules: true
|
||||||
- name: Setup pnpm
|
- name: Install pnpm
|
||||||
uses: pnpm/action-setup@v4.2.0
|
uses: pnpm/action-setup@v3
|
||||||
- name: Use Node.js
|
|
||||||
uses: actions/setup-node@v6.1.0
|
|
||||||
with:
|
with:
|
||||||
node-version-file: '.node-version'
|
version: 8
|
||||||
|
run_install: false
|
||||||
|
- name: Use Node.js ${{ matrix.node-version }}
|
||||||
|
uses: actions/setup-node@v4.0.2
|
||||||
|
with:
|
||||||
|
node-version: ${{ matrix.node-version }}
|
||||||
cache: 'pnpm'
|
cache: 'pnpm'
|
||||||
# see https://docs.github.com/actions/use-cases-and-examples/publishing-packages/publishing-nodejs-packages#publishing-packages-to-the-npm-registry
|
|
||||||
registry-url: 'https://registry.npmjs.org'
|
registry-url: 'https://registry.npmjs.org'
|
||||||
- name: Publish package
|
- name: Publish package
|
||||||
run: |
|
run: |
|
||||||
|
corepack enable
|
||||||
pnpm i --frozen-lockfile
|
pnpm i --frozen-lockfile
|
||||||
pnpm build
|
pnpm build
|
||||||
pnpm --filter misskey-js publish --access public --no-git-checks --provenance
|
pnpm --filter misskey-js publish --access public --no-git-checks --provenance
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,92 @@
|
||||||
|
# Run secret-dependent integration tests only after /deploy approval
|
||||||
|
on:
|
||||||
|
repository_dispatch:
|
||||||
|
types: [deploy-command]
|
||||||
|
|
||||||
|
name: Deploy preview environment
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
# Repo owner has commented /deploy on a (fork-based) pull request
|
||||||
|
deploy-preview-environment:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
if:
|
||||||
|
github.event.client_payload.slash_command.sha != '' &&
|
||||||
|
contains(github.event.client_payload.pull_request.head.sha, github.event.client_payload.slash_command.sha)
|
||||||
|
steps:
|
||||||
|
- uses: actions/github-script@v7.0.1
|
||||||
|
id: check-id
|
||||||
|
env:
|
||||||
|
number: ${{ github.event.client_payload.pull_request.number }}
|
||||||
|
job: ${{ github.job }}
|
||||||
|
with:
|
||||||
|
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
result-encoding: string
|
||||||
|
script: |
|
||||||
|
const { data: pull } = await github.rest.pulls.get({
|
||||||
|
...context.repo,
|
||||||
|
pull_number: process.env.number
|
||||||
|
});
|
||||||
|
const ref = pull.head.sha;
|
||||||
|
|
||||||
|
const { data: checks } = await github.rest.checks.listForRef({
|
||||||
|
...context.repo,
|
||||||
|
ref
|
||||||
|
});
|
||||||
|
|
||||||
|
const check = checks.check_runs.filter(c => c.name === process.env.job);
|
||||||
|
|
||||||
|
return check[0].id;
|
||||||
|
|
||||||
|
- uses: actions/github-script@v7.0.1
|
||||||
|
env:
|
||||||
|
check_id: ${{ steps.check-id.outputs.result }}
|
||||||
|
details_url: ${{ github.server_url }}/${{ github.repository }}/runs/${{ github.run_id }}
|
||||||
|
with:
|
||||||
|
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
script: |
|
||||||
|
await github.rest.checks.update({
|
||||||
|
...context.repo,
|
||||||
|
check_run_id: process.env.check_id,
|
||||||
|
status: 'in_progress',
|
||||||
|
details_url: process.env.details_url
|
||||||
|
});
|
||||||
|
|
||||||
|
# Check out merge commit
|
||||||
|
- name: Fork based /deploy checkout
|
||||||
|
uses: actions/checkout@v4.1.1
|
||||||
|
with:
|
||||||
|
ref: 'refs/pull/${{ github.event.client_payload.pull_request.number }}/merge'
|
||||||
|
|
||||||
|
# <insert integration tests needing secrets>
|
||||||
|
- name: Context
|
||||||
|
uses: okteto/context@latest
|
||||||
|
with:
|
||||||
|
token: ${{ secrets.OKTETO_TOKEN }}
|
||||||
|
|
||||||
|
- name: Deploy preview environment
|
||||||
|
uses: ikuradon/deploy-preview@latest
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
with:
|
||||||
|
name: pr-${{ github.event.client_payload.pull_request.number }}-syuilo
|
||||||
|
timeout: 15m
|
||||||
|
|
||||||
|
# Update check run called "integration-fork"
|
||||||
|
- uses: actions/github-script@v7.0.1
|
||||||
|
id: update-check-run
|
||||||
|
if: ${{ always() }}
|
||||||
|
env:
|
||||||
|
# Conveniently, job.status maps to https://developer.github.com/v3/checks/runs/#update-a-check-run
|
||||||
|
conclusion: ${{ job.status }}
|
||||||
|
check_id: ${{ steps.check-id.outputs.result }}
|
||||||
|
with:
|
||||||
|
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
script: |
|
||||||
|
const { data: result } = await github.rest.checks.update({
|
||||||
|
...context.repo,
|
||||||
|
check_run_id: process.env.check_id,
|
||||||
|
status: 'completed',
|
||||||
|
conclusion: process.env.conclusion
|
||||||
|
});
|
||||||
|
|
||||||
|
return result;
|
||||||
|
|
@ -0,0 +1,54 @@
|
||||||
|
# file: .github/workflows/preview-closed.yaml
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
types:
|
||||||
|
- closed
|
||||||
|
|
||||||
|
name: Destroy preview environment
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
destroy-preview-environment:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/github-script@v7.0.1
|
||||||
|
id: check-conclusion
|
||||||
|
env:
|
||||||
|
number: ${{ github.event.number }}
|
||||||
|
with:
|
||||||
|
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
result-encoding: string
|
||||||
|
script: |
|
||||||
|
const { data: pull } = await github.rest.pulls.get({
|
||||||
|
...context.repo,
|
||||||
|
pull_number: process.env.number
|
||||||
|
});
|
||||||
|
const ref = pull.head.sha;
|
||||||
|
|
||||||
|
const { data: checks } = await github.rest.checks.listForRef({
|
||||||
|
...context.repo,
|
||||||
|
ref
|
||||||
|
});
|
||||||
|
|
||||||
|
const check = checks.check_runs.filter(c => c.name === 'deploy-preview-environment');
|
||||||
|
|
||||||
|
if (check.length === 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const { data: result } = await github.rest.checks.get({
|
||||||
|
...context.repo,
|
||||||
|
check_run_id: check[0].id,
|
||||||
|
});
|
||||||
|
|
||||||
|
return result.conclusion;
|
||||||
|
- name: Context
|
||||||
|
if: steps.check-conclusion.outputs.result == 'success'
|
||||||
|
uses: okteto/context@latest
|
||||||
|
with:
|
||||||
|
token: ${{ secrets.OKTETO_TOKEN }}
|
||||||
|
|
||||||
|
- name: Destroy preview environment
|
||||||
|
if: steps.check-conclusion.outputs.result == 'success'
|
||||||
|
uses: okteto/destroy-preview@latest
|
||||||
|
with:
|
||||||
|
name: pr-${{ github.event.number }}-syuilo
|
||||||
|
|
@ -3,7 +3,7 @@ name: "Release Manager: sync changelog with PR"
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- develop
|
- release/**
|
||||||
paths:
|
paths:
|
||||||
- 'CHANGELOG.md'
|
- 'CHANGELOG.md'
|
||||||
|
|
||||||
|
|
@ -19,30 +19,22 @@ jobs:
|
||||||
edit:
|
edit:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v6
|
- uses: actions/checkout@v4
|
||||||
# headが$GITHUB_REF_NAME, baseが$STABLE_BRANCHかつopenのPRを1つ取得
|
# headがrelease/かつopenのPRを1つ取得
|
||||||
- name: Get PR
|
- name: Get PR
|
||||||
run: |
|
run: |
|
||||||
echo "pr_number=$(gh pr list --limit 1 --search "head:$GITHUB_REF_NAME base:$STABLE_BRANCH is:open" --json number --jq '.[] | .number')" >> $GITHUB_OUTPUT
|
echo "pr_number=$(gh pr list --limit 1 --head "${{ github.ref_name }}" --json number --jq '.[] | .number')" >> $GITHUB_OUTPUT
|
||||||
id: get_pr
|
id: get_pr
|
||||||
env:
|
|
||||||
STABLE_BRANCH: ${{ vars.STABLE_BRANCH }}
|
|
||||||
- name: Get target version
|
- name: Get target version
|
||||||
if: steps.get_pr.outputs.pr_number != ''
|
uses: misskey-dev/release-manager-actions/.github/actions/get-target-version@v1
|
||||||
uses: misskey-dev/release-manager-actions/.github/actions/get-target-version@v2
|
|
||||||
id: v
|
id: v
|
||||||
# CHANGELOG.mdの内容を取得
|
# CHANGELOG.mdの内容を取得
|
||||||
- name: Get changelog
|
- name: Get changelog
|
||||||
if: steps.get_pr.outputs.pr_number != ''
|
uses: misskey-dev/release-manager-actions/.github/actions/get-changelog@v1
|
||||||
uses: misskey-dev/release-manager-actions/.github/actions/get-changelog@v2
|
|
||||||
with:
|
with:
|
||||||
version: ${{ steps.v.outputs.target_version }}
|
version: ${{ steps.v.outputs.target_version }}
|
||||||
id: changelog
|
id: changelog
|
||||||
# PRのnotesを更新
|
# PRのnotesを更新
|
||||||
- name: Update PR
|
- name: Update PR
|
||||||
if: steps.get_pr.outputs.pr_number != ''
|
|
||||||
run: |
|
run: |
|
||||||
gh pr edit "$PR_NUMBER" --body "$CHANGELOG"
|
gh pr edit ${{ steps.get_pr.outputs.pr_number }} --body "${{ steps.changelog.outputs.changelog }}"
|
||||||
env:
|
|
||||||
PR_NUMBER: ${{ steps.get_pr.outputs.pr_number }}
|
|
||||||
CHANGELOG: ${{ steps.changelog.outputs.changelog }}
|
|
||||||
|
|
|
||||||
|
|
@ -17,10 +17,6 @@ on:
|
||||||
type: boolean
|
type: boolean
|
||||||
description: 'MERGE RELEASE BRANCH TO MAIN'
|
description: 'MERGE RELEASE BRANCH TO MAIN'
|
||||||
default: false
|
default: false
|
||||||
start-rc:
|
|
||||||
type: boolean
|
|
||||||
description: 'Start Release Candidate'
|
|
||||||
default: false
|
|
||||||
|
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
@ -36,22 +32,19 @@ jobs:
|
||||||
outputs:
|
outputs:
|
||||||
pr_number: ${{ steps.get_pr.outputs.pr_number }}
|
pr_number: ${{ steps.get_pr.outputs.pr_number }}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v6
|
- uses: actions/checkout@v4
|
||||||
# headが$GITHUB_REF_NAME, baseが$STABLE_BRANCHかつopenのPRを1つ取得
|
# headがrelease/かつopenのPRを1つ取得
|
||||||
- name: Get PRs
|
- name: Get PRs
|
||||||
run: |
|
run: |
|
||||||
echo "pr_number=$(gh pr list --limit 1 --search "head:$GITHUB_REF_NAME base:$STABLE_BRANCH is:open" --json number --jq '.[] | .number')" >> $GITHUB_OUTPUT
|
echo "pr_number=$(gh pr list --limit 1 --search "head:release/ is:open" --json number --jq '.[] | .number')" >> $GITHUB_OUTPUT
|
||||||
id: get_pr
|
id: get_pr
|
||||||
env:
|
|
||||||
STABLE_BRANCH: ${{ vars.STABLE_BRANCH }}
|
|
||||||
|
|
||||||
merge:
|
merge:
|
||||||
uses: misskey-dev/release-manager-actions/.github/workflows/merge.yml@v2
|
uses: misskey-dev/release-manager-actions/.github/workflows/merge.yml@v1
|
||||||
needs: get-pr
|
needs: get-pr
|
||||||
if: ${{ needs.get-pr.outputs.pr_number != '' && inputs.merge == true }}
|
if: ${{ needs.get-pr.outputs.pr_number != '' && inputs.merge == true }}
|
||||||
with:
|
with:
|
||||||
pr_number: ${{ needs.get-pr.outputs.pr_number }}
|
pr_number: ${{ needs.get-pr.outputs.pr_number }}
|
||||||
user: 'github-actions[bot]'
|
|
||||||
package_jsons_to_rewrite: ${{ vars.PACKAGE_JSONS_TO_REWRITE }}
|
package_jsons_to_rewrite: ${{ vars.PACKAGE_JSONS_TO_REWRITE }}
|
||||||
# Text to prepend to the changelog
|
# Text to prepend to the changelog
|
||||||
# The first line must be `## Unreleased`
|
# The first line must be `## Unreleased`
|
||||||
|
|
@ -68,35 +61,29 @@ jobs:
|
||||||
-
|
-
|
||||||
|
|
||||||
use_external_app_to_release: ${{ vars.USE_RELEASE_APP == 'true' }}
|
use_external_app_to_release: ${{ vars.USE_RELEASE_APP == 'true' }}
|
||||||
indent: ${{ vars.INDENT }}
|
|
||||||
secrets:
|
secrets:
|
||||||
RELEASE_APP_ID: ${{ secrets.RELEASE_APP_ID }}
|
RELEASE_APP_ID: ${{ secrets.RELEASE_APP_ID }}
|
||||||
RELEASE_APP_PRIVATE_KEY: ${{ secrets.RELEASE_APP_PRIVATE_KEY }}
|
RELEASE_APP_PRIVATE_KEY: ${{ secrets.RELEASE_APP_PRIVATE_KEY }}
|
||||||
|
RULESET_EDIT_APP_ID: ${{ secrets.RULESET_EDIT_APP_ID }}
|
||||||
|
RULESET_EDIT_APP_PRIVATE_KEY: ${{ secrets.RULESET_EDIT_APP_PRIVATE_KEY }}
|
||||||
|
|
||||||
create-prerelease:
|
create-prerelease:
|
||||||
uses: misskey-dev/release-manager-actions/.github/workflows/create-prerelease.yml@v2
|
uses: misskey-dev/release-manager-actions/.github/workflows/create-prerelease.yml@v1
|
||||||
needs: get-pr
|
needs: get-pr
|
||||||
if: ${{ needs.get-pr.outputs.pr_number != '' && inputs.merge != true }}
|
if: ${{ needs.get-pr.outputs.pr_number != '' && inputs.merge != true }}
|
||||||
with:
|
with:
|
||||||
pr_number: ${{ needs.get-pr.outputs.pr_number }}
|
pr_number: ${{ needs.get-pr.outputs.pr_number }}
|
||||||
user: 'github-actions[bot]'
|
|
||||||
package_jsons_to_rewrite: ${{ vars.PACKAGE_JSONS_TO_REWRITE }}
|
package_jsons_to_rewrite: ${{ vars.PACKAGE_JSONS_TO_REWRITE }}
|
||||||
use_external_app_to_release: ${{ vars.USE_RELEASE_APP == 'true' }}
|
use_external_app_to_release: ${{ vars.USE_RELEASE_APP == 'true' }}
|
||||||
indent: ${{ vars.INDENT }}
|
|
||||||
draft_prerelease_channel: alpha
|
|
||||||
ready_start_prerelease_channel: beta
|
|
||||||
prerelease_channel: ${{ inputs.start-rc && 'rc' || '' }}
|
|
||||||
reset_number_on_channel_change: true
|
|
||||||
secrets:
|
secrets:
|
||||||
RELEASE_APP_ID: ${{ secrets.RELEASE_APP_ID }}
|
RELEASE_APP_ID: ${{ secrets.RELEASE_APP_ID }}
|
||||||
RELEASE_APP_PRIVATE_KEY: ${{ secrets.RELEASE_APP_PRIVATE_KEY }}
|
RELEASE_APP_PRIVATE_KEY: ${{ secrets.RELEASE_APP_PRIVATE_KEY }}
|
||||||
|
|
||||||
create-target:
|
create-target:
|
||||||
uses: misskey-dev/release-manager-actions/.github/workflows/create-target.yml@v2
|
uses: misskey-dev/release-manager-actions/.github/workflows/create-target.yml@v1
|
||||||
needs: get-pr
|
needs: get-pr
|
||||||
if: ${{ needs.get-pr.outputs.pr_number == '' }}
|
if: ${{ needs.get-pr.outputs.pr_number == '' }}
|
||||||
with:
|
with:
|
||||||
user: 'github-actions[bot]'
|
|
||||||
# The script for version increment.
|
# The script for version increment.
|
||||||
# process.env.CURRENT_VERSION: The current version.
|
# process.env.CURRENT_VERSION: The current version.
|
||||||
#
|
#
|
||||||
|
|
@ -128,9 +115,8 @@ jobs:
|
||||||
# }
|
# }
|
||||||
package_jsons_to_rewrite: ${{ vars.PACKAGE_JSONS_TO_REWRITE }}
|
package_jsons_to_rewrite: ${{ vars.PACKAGE_JSONS_TO_REWRITE }}
|
||||||
use_external_app_to_release: ${{ vars.USE_RELEASE_APP == 'true' }}
|
use_external_app_to_release: ${{ vars.USE_RELEASE_APP == 'true' }}
|
||||||
indent: ${{ vars.INDENT }}
|
|
||||||
stable_branch: ${{ vars.STABLE_BRANCH }}
|
|
||||||
draft_prerelease_channel: alpha
|
|
||||||
secrets:
|
secrets:
|
||||||
RELEASE_APP_ID: ${{ secrets.RELEASE_APP_ID }}
|
RELEASE_APP_ID: ${{ secrets.RELEASE_APP_ID }}
|
||||||
RELEASE_APP_PRIVATE_KEY: ${{ secrets.RELEASE_APP_PRIVATE_KEY }}
|
RELEASE_APP_PRIVATE_KEY: ${{ secrets.RELEASE_APP_PRIVATE_KEY }}
|
||||||
|
RULESET_EDIT_APP_ID: ${{ secrets.RULESET_EDIT_APP_ID }}
|
||||||
|
RULESET_EDIT_APP_PRIVATE_KEY: ${{ secrets.RULESET_EDIT_APP_PRIVATE_KEY }}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,38 @@
|
||||||
|
name: "Release Manager: release RC when ready for review"
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
types: [ready_for_review]
|
||||||
|
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
issues: write
|
||||||
|
pull-requests: write
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
check:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
outputs:
|
||||||
|
ref: ${{ steps.get_pr.outputs.ref }}
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
# PR情報を取得
|
||||||
|
- name: Get PR
|
||||||
|
run: |
|
||||||
|
pr_json=$(gh pr view ${{ github.event.pull_request.number }} --json isDraft,headRefName)
|
||||||
|
echo "ref=$(echo $pr_json | jq -r '.headRefName')" >> $GITHUB_OUTPUT
|
||||||
|
id: get_pr
|
||||||
|
release:
|
||||||
|
uses: misskey-dev/release-manager-actions/.github/workflows/create-prerelease.yml@v1
|
||||||
|
needs: check
|
||||||
|
if: startsWith(needs.check.outputs.ref, 'release/')
|
||||||
|
with:
|
||||||
|
pr_number: ${{ github.event.pull_request.number }}
|
||||||
|
package_jsons_to_rewrite: ${{ vars.PACKAGE_JSONS_TO_REWRITE }}
|
||||||
|
use_external_app_to_release: ${{ vars.USE_RELEASE_APP == 'true' }}
|
||||||
|
secrets:
|
||||||
|
RELEASE_APP_ID: ${{ secrets.RELEASE_APP_ID }}
|
||||||
|
RELEASE_APP_PRIVATE_KEY: ${{ secrets.RELEASE_APP_PRIVATE_KEY }}
|
||||||
|
|
@ -16,7 +16,7 @@ jobs:
|
||||||
# api-artifact
|
# api-artifact
|
||||||
steps:
|
steps:
|
||||||
- name: Download artifact
|
- name: Download artifact
|
||||||
uses: actions/github-script@v8.0.0
|
uses: actions/github-script@v7.0.1
|
||||||
with:
|
with:
|
||||||
script: |
|
script: |
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
|
|
@ -60,7 +60,7 @@ jobs:
|
||||||
- name: Echo full diff
|
- name: Echo full diff
|
||||||
run: cat ./api-full.json.diff
|
run: cat ./api-full.json.diff
|
||||||
- name: Upload full diff to Artifact
|
- name: Upload full diff to Artifact
|
||||||
uses: actions/upload-artifact@v6
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: api-artifact
|
name: api-artifact
|
||||||
path: |
|
path: |
|
||||||
|
|
@ -70,35 +70,28 @@ jobs:
|
||||||
- id: out-diff
|
- id: out-diff
|
||||||
name: Build diff Comment
|
name: Build diff Comment
|
||||||
run: |
|
run: |
|
||||||
HEADER="このPRによるapi.jsonの差分"
|
cat <<- EOF > ./output.md
|
||||||
FOOTER="[Get diff files from Workflow Page](https://github.com/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID})"
|
このPRによるapi.jsonの差分
|
||||||
DIFF_BYTES="$(stat ./api.json.diff -c '%s' | tr -d '\n')"
|
<details>
|
||||||
|
<summary>差分はこちら</summary>
|
||||||
|
|
||||||
echo "$HEADER" > ./output.md
|
\`\`\`diff
|
||||||
|
$(cat ./api.json.diff)
|
||||||
|
\`\`\`
|
||||||
|
</details>
|
||||||
|
|
||||||
if (( "$DIFF_BYTES" <= 1 )); then
|
[Get diff files from Workflow Page](https://github.com/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID})
|
||||||
echo '差分はありません。' >> ./output.md
|
EOF
|
||||||
else
|
- uses: thollander/actions-comment-pull-request@v2
|
||||||
echo '<details>' >> ./output.md
|
|
||||||
echo '<summary>差分はこちら</summary>' >> ./output.md
|
|
||||||
echo >> ./output.md
|
|
||||||
echo '```diff' >> ./output.md
|
|
||||||
cat ./api.json.diff >> ./output.md
|
|
||||||
echo '```' >> ./output.md
|
|
||||||
echo '</details>' >> .output.md
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "$FOOTER" >> ./output.md
|
|
||||||
- uses: thollander/actions-comment-pull-request@v3
|
|
||||||
with:
|
with:
|
||||||
pr-number: ${{ steps.load-pr-num.outputs.pr-number }}
|
pr_number: ${{ steps.load-pr-num.outputs.pr-number }}
|
||||||
comment-tag: show_diff
|
comment_tag: show_diff
|
||||||
file-path: ./output.md
|
filePath: ./output.md
|
||||||
- name: Tell error to PR
|
- name: Tell error to PR
|
||||||
uses: thollander/actions-comment-pull-request@v3
|
uses: thollander/actions-comment-pull-request@v2
|
||||||
if: failure() && steps.load-pr-num.outputs.pr-number
|
if: failure() && steps.load-pr-num.outputs.pr-number
|
||||||
with:
|
with:
|
||||||
pr-number: ${{ steps.load-pr-num.outputs.pr-number }}
|
pr_number: ${{ steps.load-pr-num.outputs.pr-number }}
|
||||||
comment-tag: show_diff_error
|
comment_tag: show_diff_error
|
||||||
message: |
|
message: |
|
||||||
api.jsonの差分作成中にエラーが発生しました。詳細は[Workflowのログ](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }})を確認してください。
|
api.jsonの差分作成中にエラーが発生しました。詳細は[Workflowのログ](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }})を確認してください。
|
||||||
|
|
|
||||||
|
|
@ -1,177 +0,0 @@
|
||||||
name: Report backend memory
|
|
||||||
|
|
||||||
on:
|
|
||||||
workflow_run:
|
|
||||||
types: [completed]
|
|
||||||
workflows:
|
|
||||||
- Get backend memory usage # get-backend-memory.yml
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
compare-memory:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
if: ${{ github.event.workflow_run.conclusion == 'success' }}
|
|
||||||
permissions:
|
|
||||||
pull-requests: write
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: Download artifact
|
|
||||||
uses: actions/github-script@v8.0.0
|
|
||||||
with:
|
|
||||||
script: |
|
|
||||||
const fs = require('fs');
|
|
||||||
let allArtifacts = await github.rest.actions.listWorkflowRunArtifacts({
|
|
||||||
owner: context.repo.owner,
|
|
||||||
repo: context.repo.repo,
|
|
||||||
run_id: context.payload.workflow_run.id,
|
|
||||||
});
|
|
||||||
let matchArtifacts = allArtifacts.data.artifacts.filter((artifact) => {
|
|
||||||
return artifact.name.startsWith("memory-artifact-") || artifact.name == "memory-artifact"
|
|
||||||
});
|
|
||||||
await Promise.all(matchArtifacts.map(async (artifact) => {
|
|
||||||
let download = await github.rest.actions.downloadArtifact({
|
|
||||||
owner: context.repo.owner,
|
|
||||||
repo: context.repo.repo,
|
|
||||||
artifact_id: artifact.id,
|
|
||||||
archive_format: 'zip',
|
|
||||||
});
|
|
||||||
await fs.promises.writeFile(`${process.env.GITHUB_WORKSPACE}/${artifact.name}.zip`, Buffer.from(download.data));
|
|
||||||
}));
|
|
||||||
- name: Extract all artifacts
|
|
||||||
run: |
|
|
||||||
find . -mindepth 1 -maxdepth 1 -type f -name '*.zip' -exec unzip {} -d artifacts ';'
|
|
||||||
ls -la artifacts/
|
|
||||||
- name: Load PR Number
|
|
||||||
id: load-pr-num
|
|
||||||
run: echo "pr-number=$(cat artifacts/pr_number)" >> "$GITHUB_OUTPUT"
|
|
||||||
|
|
||||||
- name: Output base
|
|
||||||
run: cat ./artifacts/memory-base.json
|
|
||||||
- name: Output head
|
|
||||||
run: cat ./artifacts/memory-head.json
|
|
||||||
- name: Compare memory usage
|
|
||||||
id: compare
|
|
||||||
run: |
|
|
||||||
BASE_MEMORY=$(cat ./artifacts/memory-base.json)
|
|
||||||
HEAD_MEMORY=$(cat ./artifacts/memory-head.json)
|
|
||||||
|
|
||||||
variation() {
|
|
||||||
calc() {
|
|
||||||
BASE=$(echo "$BASE_MEMORY" | jq -r ".${1}.${2} // 0")
|
|
||||||
HEAD=$(echo "$HEAD_MEMORY" | jq -r ".${1}.${2} // 0")
|
|
||||||
|
|
||||||
DIFF=$((HEAD - BASE))
|
|
||||||
if [ "$BASE" -gt 0 ]; then
|
|
||||||
DIFF_PERCENT=$(echo "scale=2; ($DIFF * 100) / $BASE" | bc)
|
|
||||||
else
|
|
||||||
DIFF_PERCENT=0
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Convert KB to MB for readability
|
|
||||||
BASE_MB=$(echo "scale=2; $BASE / 1024" | bc)
|
|
||||||
HEAD_MB=$(echo "scale=2; $HEAD / 1024" | bc)
|
|
||||||
DIFF_MB=$(echo "scale=2; $DIFF / 1024" | bc)
|
|
||||||
|
|
||||||
JSON=$(jq -c -n \
|
|
||||||
--argjson base "$BASE_MB" \
|
|
||||||
--argjson head "$HEAD_MB" \
|
|
||||||
--argjson diff "$DIFF_MB" \
|
|
||||||
--argjson diff_percent "$DIFF_PERCENT" \
|
|
||||||
'{base: $base, head: $head, diff: $diff, diff_percent: $diff_percent}')
|
|
||||||
|
|
||||||
echo "$JSON"
|
|
||||||
}
|
|
||||||
|
|
||||||
JSON=$(jq -c -n \
|
|
||||||
--argjson VmRSS "$(calc $1 VmRSS)" \
|
|
||||||
--argjson VmHWM "$(calc $1 VmHWM)" \
|
|
||||||
--argjson VmSize "$(calc $1 VmSize)" \
|
|
||||||
--argjson VmData "$(calc $1 VmData)" \
|
|
||||||
'{VmRSS: $VmRSS, VmHWM: $VmHWM, VmSize: $VmSize, VmData: $VmData}')
|
|
||||||
|
|
||||||
echo "$JSON"
|
|
||||||
}
|
|
||||||
|
|
||||||
JSON=$(jq -c -n \
|
|
||||||
--argjson beforeGc "$(variation beforeGc)" \
|
|
||||||
--argjson afterGc "$(variation afterGc)" \
|
|
||||||
--argjson afterRequest "$(variation afterRequest)" \
|
|
||||||
'{beforeGc: $beforeGc, afterGc: $afterGc, afterRequest: $afterRequest}')
|
|
||||||
|
|
||||||
echo "res=$JSON" >> "$GITHUB_OUTPUT"
|
|
||||||
- id: build-comment
|
|
||||||
name: Build memory comment
|
|
||||||
env:
|
|
||||||
RES: ${{ steps.compare.outputs.res }}
|
|
||||||
run: |
|
|
||||||
HEADER="## Backend memory usage comparison"
|
|
||||||
FOOTER="[See workflow logs for details](https://github.com/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID})"
|
|
||||||
|
|
||||||
echo "$HEADER" > ./output.md
|
|
||||||
echo >> ./output.md
|
|
||||||
|
|
||||||
table() {
|
|
||||||
echo "| Metric | base (MB) | head (MB) | Diff (MB) | Diff (%) |" >> ./output.md
|
|
||||||
echo "|--------|------:|------:|------:|------:|" >> ./output.md
|
|
||||||
|
|
||||||
line() {
|
|
||||||
METRIC=$2
|
|
||||||
BASE=$(echo "$RES" | jq -r ".${1}.${2}.base")
|
|
||||||
HEAD=$(echo "$RES" | jq -r ".${1}.${2}.head")
|
|
||||||
DIFF=$(echo "$RES" | jq -r ".${1}.${2}.diff")
|
|
||||||
DIFF_PERCENT=$(echo "$RES" | jq -r ".${1}.${2}.diff_percent")
|
|
||||||
|
|
||||||
if (( $(echo "$DIFF_PERCENT > 0" | bc -l) )); then
|
|
||||||
DIFF="+$DIFF"
|
|
||||||
DIFF_PERCENT="+$DIFF_PERCENT"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# highlight VmRSS
|
|
||||||
if [ "$2" = "VmRSS" ]; then
|
|
||||||
METRIC="**${METRIC}**"
|
|
||||||
BASE="**${BASE}**"
|
|
||||||
HEAD="**${HEAD}**"
|
|
||||||
DIFF="**${DIFF}**"
|
|
||||||
DIFF_PERCENT="**${DIFF_PERCENT}**"
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "| ${METRIC} | ${BASE} MB | ${HEAD} MB | ${DIFF} MB | ${DIFF_PERCENT}% |" >> ./output.md
|
|
||||||
}
|
|
||||||
|
|
||||||
line $1 VmRSS
|
|
||||||
line $1 VmHWM
|
|
||||||
line $1 VmSize
|
|
||||||
line $1 VmData
|
|
||||||
}
|
|
||||||
|
|
||||||
echo "### Before GC" >> ./output.md
|
|
||||||
table beforeGc
|
|
||||||
echo >> ./output.md
|
|
||||||
|
|
||||||
echo "### After GC" >> ./output.md
|
|
||||||
table afterGc
|
|
||||||
echo >> ./output.md
|
|
||||||
|
|
||||||
echo "### After Request" >> ./output.md
|
|
||||||
table afterRequest
|
|
||||||
echo >> ./output.md
|
|
||||||
|
|
||||||
# Determine if this is a significant change (more than 5% increase)
|
|
||||||
if [ "$(echo "$RES" | jq -r '.afterGc.VmRSS.diff_percent | tonumber > 5')" = "true" ]; then
|
|
||||||
echo "⚠️ **Warning**: Memory usage has increased by more than 5%. Please verify this is not an unintended change." >> ./output.md
|
|
||||||
echo >> ./output.md
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "$FOOTER" >> ./output.md
|
|
||||||
- uses: thollander/actions-comment-pull-request@v3
|
|
||||||
with:
|
|
||||||
pr-number: ${{ steps.load-pr-num.outputs.pr-number }}
|
|
||||||
comment-tag: show_memory_diff
|
|
||||||
file-path: ./output.md
|
|
||||||
- name: Tell error to PR
|
|
||||||
uses: thollander/actions-comment-pull-request@v3
|
|
||||||
if: failure() && steps.load-pr-num.outputs.pr-number
|
|
||||||
with:
|
|
||||||
pr-number: ${{ steps.load-pr-num.outputs.pr-number }}
|
|
||||||
comment-tag: show_memory_diff_error
|
|
||||||
message: |
|
|
||||||
An error occurred while comparing backend memory usage. See [workflow logs](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}) for details.
|
|
||||||
|
|
@ -1,51 +0,0 @@
|
||||||
name: Request release review
|
|
||||||
|
|
||||||
on:
|
|
||||||
issue_comment:
|
|
||||||
types: [created]
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
reply:
|
|
||||||
if: github.event.comment.body == '/request-release-review'
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
permissions:
|
|
||||||
contents: read
|
|
||||||
issues: write
|
|
||||||
pull-requests: write
|
|
||||||
steps:
|
|
||||||
- name: Reply
|
|
||||||
uses: actions/github-script@v8
|
|
||||||
with:
|
|
||||||
script: |
|
|
||||||
const body = `To dev team (@misskey-dev/dev):
|
|
||||||
|
|
||||||
リリースが提案されています :rocket:
|
|
||||||
|
|
||||||
GOの場合はapprove、NO GOの場合はその旨コメントをお願いいたします。
|
|
||||||
|
|
||||||
判断にあたって考慮すべき観点は、
|
|
||||||
|
|
||||||
- やり残したことはないか?
|
|
||||||
- CHANGELOGは過不足ないか?
|
|
||||||
- バージョンに問題はないか?(月跨いでいるのに更新忘れているなど)
|
|
||||||
- 再考すべき仕様・実装はないか?
|
|
||||||
- ベータ版を検証したサーバーから不具合の報告等は上がってないか?
|
|
||||||
- (セキュリティの修正や重要なバグ修正などのため)リリースを急いだ方が良いか?そうではないか?
|
|
||||||
- Actionsが落ちていないか?
|
|
||||||
|
|
||||||
などが挙げられます。
|
|
||||||
|
|
||||||
ご協力ありがとうございます :sparkles:
|
|
||||||
`
|
|
||||||
|
|
||||||
const issue_number = context.payload.issue ? context.payload.issue.number : (context.payload.pull_request && context.payload.pull_request.number)
|
|
||||||
if (!issue_number) {
|
|
||||||
console.log('No issue or PR number found in payload; skipping')
|
|
||||||
} else {
|
|
||||||
await github.rest.issues.createComment({
|
|
||||||
owner: context.repo.owner,
|
|
||||||
repo: context.repo.repo,
|
|
||||||
issue_number,
|
|
||||||
body,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
@ -5,29 +5,23 @@ on:
|
||||||
branches:
|
branches:
|
||||||
- master
|
- master
|
||||||
- develop
|
- develop
|
||||||
|
- dev/storybook8 # for testing
|
||||||
pull_request_target:
|
pull_request_target:
|
||||||
branches-ignore:
|
|
||||||
# Since pull requests targets master mostly is the "develop" branch.
|
|
||||||
# Storybook CI is checked on the "push" event of "develop" branch so it would cause a duplicate build.
|
|
||||||
# This is a waste of chromatic build quota, so we don't run storybook CI on pull requests targets master.
|
|
||||||
- master
|
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
# Chromatic is not likely to be available for fork repositories, so we disable for fork repositories.
|
|
||||||
if: github.repository == 'misskey-dev/misskey'
|
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
env:
|
env:
|
||||||
NODE_OPTIONS: "--max_old_space_size=7168"
|
NODE_OPTIONS: "--max_old_space_size=7168"
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v6.0.1
|
- uses: actions/checkout@v4.1.1
|
||||||
if: github.event_name != 'pull_request_target'
|
if: github.event_name != 'pull_request_target'
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
submodules: true
|
submodules: true
|
||||||
- uses: actions/checkout@v6.0.1
|
- uses: actions/checkout@v4.1.1
|
||||||
if: github.event_name == 'pull_request_target'
|
if: github.event_name == 'pull_request_target'
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
|
|
@ -35,19 +29,26 @@ jobs:
|
||||||
ref: "refs/pull/${{ github.event.number }}/merge"
|
ref: "refs/pull/${{ github.event.number }}/merge"
|
||||||
- name: Checkout actual HEAD
|
- name: Checkout actual HEAD
|
||||||
if: github.event_name == 'pull_request_target'
|
if: github.event_name == 'pull_request_target'
|
||||||
run: git checkout "$(git rev-list --parents -n1 HEAD | cut -d" " -f3)"
|
id: rev
|
||||||
- name: Setup pnpm
|
run: |
|
||||||
uses: pnpm/action-setup@v4.2.0
|
echo "base=$(git rev-list --parents -n1 HEAD | cut -d" " -f2)" >> $GITHUB_OUTPUT
|
||||||
- name: Use Node.js
|
git checkout $(git rev-list --parents -n1 HEAD | cut -d" " -f3)
|
||||||
uses: actions/setup-node@v6.1.0
|
- name: Install pnpm
|
||||||
|
uses: pnpm/action-setup@v3
|
||||||
|
with:
|
||||||
|
version: 8
|
||||||
|
run_install: false
|
||||||
|
- name: Use Node.js 20.x
|
||||||
|
uses: actions/setup-node@v4.0.2
|
||||||
with:
|
with:
|
||||||
node-version-file: '.node-version'
|
node-version-file: '.node-version'
|
||||||
cache: 'pnpm'
|
cache: 'pnpm'
|
||||||
|
- run: corepack enable
|
||||||
- run: pnpm i --frozen-lockfile
|
- run: pnpm i --frozen-lockfile
|
||||||
- name: Check pnpm-lock.yaml
|
- name: Check pnpm-lock.yaml
|
||||||
run: git diff --exit-code pnpm-lock.yaml
|
run: git diff --exit-code pnpm-lock.yaml
|
||||||
- name: Build dependent packages
|
- name: Build misskey-js
|
||||||
run: pnpm -F misskey-js -F misskey-bubble-game -F misskey-reversi build
|
run: pnpm --filter misskey-js build
|
||||||
- name: Build storybook
|
- name: Build storybook
|
||||||
run: pnpm --filter frontend build-storybook
|
run: pnpm --filter frontend build-storybook
|
||||||
- name: Publish to Chromatic
|
- name: Publish to Chromatic
|
||||||
|
|
@ -78,19 +79,23 @@ jobs:
|
||||||
if: github.event_name == 'pull_request_target'
|
if: github.event_name == 'pull_request_target'
|
||||||
id: chromatic_pull_request
|
id: chromatic_pull_request
|
||||||
run: |
|
run: |
|
||||||
CHROMATIC_PARAMETER="$(node packages/frontend/.storybook/changes.js $(git diff --name-only origin/${GITHUB_BASE_REF}...origin/${GITHUB_HEAD_REF} | xargs))"
|
DIFF="${{ steps.rev.outputs.base }} HEAD"
|
||||||
|
if [ "$DIFF" = "0000000000000000000000000000000000000000 HEAD" ]; then
|
||||||
|
DIFF="HEAD"
|
||||||
|
fi
|
||||||
|
CHROMATIC_PARAMETER="$(node packages/frontend/.storybook/changes.js $(git diff-tree --no-commit-id --name-only -r $(echo "$DIFF") | xargs))"
|
||||||
if [ "$CHROMATIC_PARAMETER" = " --skip" ]; then
|
if [ "$CHROMATIC_PARAMETER" = " --skip" ]; then
|
||||||
echo "skip=true" >> $GITHUB_OUTPUT
|
echo "skip=true" >> $GITHUB_OUTPUT
|
||||||
fi
|
fi
|
||||||
BRANCH="${{ github.event.pull_request.head.user.login }}:$GITHUB_HEAD_REF"
|
BRANCH="${{ github.event.pull_request.head.user.login }}:${{ github.event.pull_request.head.ref }}"
|
||||||
if [ "$BRANCH" = "misskey-dev:$GITHUB_HEAD_REF" ]; then
|
if [ "$BRANCH" = "misskey-dev:${{ github.event.pull_request.head.ref }}" ]; then
|
||||||
BRANCH="$GITHUB_HEAD_REF"
|
BRANCH="${{ github.event.pull_request.head.ref }}"
|
||||||
fi
|
fi
|
||||||
pnpm --filter frontend chromatic --exit-once-uploaded -d storybook-static --branch-name "$BRANCH" $(echo "$CHROMATIC_PARAMETER")
|
pnpm --filter frontend chromatic --exit-once-uploaded -d storybook-static --branch-name $BRANCH $(echo "$CHROMATIC_PARAMETER")
|
||||||
env:
|
env:
|
||||||
CHROMATIC_PROJECT_TOKEN: ${{ secrets.CHROMATIC_PROJECT_TOKEN }}
|
CHROMATIC_PROJECT_TOKEN: ${{ secrets.CHROMATIC_PROJECT_TOKEN }}
|
||||||
- name: Notify that Chromatic detects changes
|
- name: Notify that Chromatic detects changes
|
||||||
uses: actions/github-script@v8.0.0
|
uses: actions/github-script@v7.0.1
|
||||||
if: github.event_name != 'pull_request_target' && steps.chromatic_push.outputs.success == 'false'
|
if: github.event_name != 'pull_request_target' && steps.chromatic_push.outputs.success == 'false'
|
||||||
with:
|
with:
|
||||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
@ -102,7 +107,7 @@ jobs:
|
||||||
body: 'Chromatic detects changes. Please [review the changes on Chromatic](https://www.chromatic.com/builds?appId=6428f7d7b962f0b79f97d6e4).'
|
body: 'Chromatic detects changes. Please [review the changes on Chromatic](https://www.chromatic.com/builds?appId=6428f7d7b962f0b79f97d6e4).'
|
||||||
})
|
})
|
||||||
- name: Upload Artifacts
|
- name: Upload Artifacts
|
||||||
uses: actions/upload-artifact@v6
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: storybook
|
name: storybook
|
||||||
path: packages/frontend/storybook-static
|
path: packages/frontend/storybook-static
|
||||||
|
|
|
||||||
|
|
@ -9,36 +9,23 @@ on:
|
||||||
- packages/backend/**
|
- packages/backend/**
|
||||||
# for permissions
|
# for permissions
|
||||||
- packages/misskey-js/**
|
- packages/misskey-js/**
|
||||||
- .github/workflows/test-backend.yml
|
|
||||||
- .github/misskey/test.yml
|
|
||||||
pull_request:
|
pull_request:
|
||||||
paths:
|
paths:
|
||||||
- packages/backend/**
|
- packages/backend/**
|
||||||
# for permissions
|
# for permissions
|
||||||
- packages/misskey-js/**
|
- packages/misskey-js/**
|
||||||
- .github/workflows/test-backend.yml
|
|
||||||
- .github/misskey/test.yml
|
|
||||||
workflow_dispatch:
|
|
||||||
inputs:
|
|
||||||
force_ffmpeg_cache_update:
|
|
||||||
description: 'Force update ffmpeg cache'
|
|
||||||
required: false
|
|
||||||
default: false
|
|
||||||
type: boolean
|
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
unit:
|
unit:
|
||||||
name: Unit tests (backend)
|
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
node-version-file:
|
node-version: [20.10.0]
|
||||||
- .node-version
|
|
||||||
- .github/min.node-version
|
|
||||||
|
|
||||||
services:
|
services:
|
||||||
postgres:
|
postgres:
|
||||||
image: postgres:18
|
image: postgres:15
|
||||||
ports:
|
ports:
|
||||||
- 54312:5432
|
- 54312:5432
|
||||||
env:
|
env:
|
||||||
|
|
@ -48,55 +35,22 @@ jobs:
|
||||||
image: redis:7
|
image: redis:7
|
||||||
ports:
|
ports:
|
||||||
- 56312:6379
|
- 56312:6379
|
||||||
meilisearch:
|
|
||||||
image: getmeili/meilisearch:v1.3.4
|
|
||||||
ports:
|
|
||||||
- 57712:7700
|
|
||||||
env:
|
|
||||||
MEILI_NO_ANALYTICS: true
|
|
||||||
MEILI_ENV: development
|
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v6.0.1
|
- uses: actions/checkout@v4.1.1
|
||||||
with:
|
with:
|
||||||
submodules: true
|
submodules: true
|
||||||
- name: Setup pnpm
|
- name: Install pnpm
|
||||||
uses: pnpm/action-setup@v4.2.0
|
uses: pnpm/action-setup@v3
|
||||||
- name: Get current date
|
|
||||||
id: current-date
|
|
||||||
run: echo "today=$(date +'%Y-%m-%d')" >> $GITHUB_OUTPUT
|
|
||||||
- name: Setup and Restore ffmpeg/ffprobe Cache
|
|
||||||
id: cache-ffmpeg
|
|
||||||
uses: actions/cache@v4
|
|
||||||
with:
|
with:
|
||||||
path: |
|
version: 8
|
||||||
/usr/local/bin/ffmpeg
|
run_install: false
|
||||||
/usr/local/bin/ffprobe
|
- name: Use Node.js ${{ matrix.node-version }}
|
||||||
# daily cache
|
uses: actions/setup-node@v4.0.2
|
||||||
key: ${{ runner.os }}-ffmpeg-${{ steps.current-date.outputs.today }}
|
|
||||||
restore-keys: |
|
|
||||||
${{ runner.os }}-ffmpeg-${{ steps.current-date.outputs.today }}
|
|
||||||
- name: Install FFmpeg
|
|
||||||
if: steps.cache-ffmpeg.outputs.cache-hit != 'true' || github.event.inputs.force_ffmpeg_cache_update == true
|
|
||||||
run: |
|
|
||||||
for i in {1..3}; do
|
|
||||||
echo "Attempt $i: Installing FFmpeg..."
|
|
||||||
curl -s -L https://johnvansickle.com/ffmpeg/releases/ffmpeg-release-amd64-static.tar.xz -o ffmpeg.tar.xz && \
|
|
||||||
tar -xf ffmpeg.tar.xz && \
|
|
||||||
mv ffmpeg-*-static/ffmpeg /usr/local/bin/ && \
|
|
||||||
mv ffmpeg-*-static/ffprobe /usr/local/bin/ && \
|
|
||||||
rm -rf ffmpeg.tar.xz ffmpeg-*-static/ && \
|
|
||||||
break || sleep 10
|
|
||||||
if [ $i -eq 3 ]; then
|
|
||||||
echo "Failed to install FFmpeg after 3 attempts"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
- name: Use Node.js
|
|
||||||
uses: actions/setup-node@v6.1.0
|
|
||||||
with:
|
with:
|
||||||
node-version-file: ${{ matrix.node-version-file }}
|
node-version: ${{ matrix.node-version }}
|
||||||
cache: 'pnpm'
|
cache: 'pnpm'
|
||||||
|
- run: corepack enable
|
||||||
- run: pnpm i --frozen-lockfile
|
- run: pnpm i --frozen-lockfile
|
||||||
- name: Check pnpm-lock.yaml
|
- name: Check pnpm-lock.yaml
|
||||||
run: git diff --exit-code pnpm-lock.yaml
|
run: git diff --exit-code pnpm-lock.yaml
|
||||||
|
|
@ -107,24 +61,21 @@ jobs:
|
||||||
- name: Test
|
- name: Test
|
||||||
run: pnpm --filter backend test-and-coverage
|
run: pnpm --filter backend test-and-coverage
|
||||||
- name: Upload to Codecov
|
- name: Upload to Codecov
|
||||||
uses: codecov/codecov-action@v5
|
uses: codecov/codecov-action@v4
|
||||||
with:
|
with:
|
||||||
token: ${{ secrets.CODECOV_TOKEN }}
|
token: ${{ secrets.CODECOV_TOKEN }}
|
||||||
files: ./packages/backend/coverage/coverage-final.json
|
files: ./packages/backend/coverage/coverage-final.json
|
||||||
|
|
||||||
e2e:
|
e2e:
|
||||||
name: E2E tests (backend)
|
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
|
||||||
matrix:
|
matrix:
|
||||||
node-version-file:
|
node-version: [20.10.0]
|
||||||
- .node-version
|
|
||||||
- .github/min.node-version
|
|
||||||
|
|
||||||
services:
|
services:
|
||||||
postgres:
|
postgres:
|
||||||
image: postgres:18
|
image: postgres:15
|
||||||
ports:
|
ports:
|
||||||
- 54312:5432
|
- 54312:5432
|
||||||
env:
|
env:
|
||||||
|
|
@ -136,16 +87,20 @@ jobs:
|
||||||
- 56312:6379
|
- 56312:6379
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v6.0.1
|
- uses: actions/checkout@v4.1.1
|
||||||
with:
|
with:
|
||||||
submodules: true
|
submodules: true
|
||||||
- name: Setup pnpm
|
- name: Install pnpm
|
||||||
uses: pnpm/action-setup@v4.2.0
|
uses: pnpm/action-setup@v3
|
||||||
- name: Use Node.js
|
|
||||||
uses: actions/setup-node@v6.1.0
|
|
||||||
with:
|
with:
|
||||||
node-version-file: ${{ matrix.node-version-file }}
|
version: 8
|
||||||
|
run_install: false
|
||||||
|
- name: Use Node.js ${{ matrix.node-version }}
|
||||||
|
uses: actions/setup-node@v4.0.2
|
||||||
|
with:
|
||||||
|
node-version: ${{ matrix.node-version }}
|
||||||
cache: 'pnpm'
|
cache: 'pnpm'
|
||||||
|
- run: corepack enable
|
||||||
- run: pnpm i --frozen-lockfile
|
- run: pnpm i --frozen-lockfile
|
||||||
- name: Check pnpm-lock.yaml
|
- name: Check pnpm-lock.yaml
|
||||||
run: git diff --exit-code pnpm-lock.yaml
|
run: git diff --exit-code pnpm-lock.yaml
|
||||||
|
|
@ -156,51 +111,7 @@ jobs:
|
||||||
- name: Test
|
- name: Test
|
||||||
run: pnpm --filter backend test-and-coverage:e2e
|
run: pnpm --filter backend test-and-coverage:e2e
|
||||||
- name: Upload to Codecov
|
- name: Upload to Codecov
|
||||||
uses: codecov/codecov-action@v5
|
uses: codecov/codecov-action@v4
|
||||||
with:
|
with:
|
||||||
token: ${{ secrets.CODECOV_TOKEN }}
|
token: ${{ secrets.CODECOV_TOKEN }}
|
||||||
files: ./packages/backend/coverage/coverage-final.json
|
files: ./packages/backend/coverage/coverage-final.json
|
||||||
|
|
||||||
migration:
|
|
||||||
name: Migration tests (backend)
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
node-version-file:
|
|
||||||
- .node-version
|
|
||||||
#- .github/min.node-version
|
|
||||||
|
|
||||||
services:
|
|
||||||
postgres:
|
|
||||||
image: postgres:18
|
|
||||||
ports:
|
|
||||||
- 54312:5432
|
|
||||||
env:
|
|
||||||
POSTGRES_DB: test-misskey
|
|
||||||
POSTGRES_HOST_AUTH_METHOD: trust
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v6.0.1
|
|
||||||
with:
|
|
||||||
submodules: true
|
|
||||||
- name: Setup pnpm
|
|
||||||
uses: pnpm/action-setup@v4.2.0
|
|
||||||
- name: Get current date
|
|
||||||
id: current-date
|
|
||||||
run: echo "today=$(date +'%Y-%m-%d')" >> $GITHUB_OUTPUT
|
|
||||||
- name: Use Node.js
|
|
||||||
uses: actions/setup-node@v6.1.0
|
|
||||||
with:
|
|
||||||
node-version-file: ${{ matrix.node-version-file }}
|
|
||||||
cache: 'pnpm'
|
|
||||||
- run: pnpm i --frozen-lockfile
|
|
||||||
- name: Check pnpm-lock.yaml
|
|
||||||
run: git diff --exit-code pnpm-lock.yaml
|
|
||||||
- name: Copy Configure
|
|
||||||
run: cp .github/misskey/test.yml .config
|
|
||||||
- name: Build
|
|
||||||
run: pnpm build
|
|
||||||
- name: Run migrations
|
|
||||||
run: MISSKEY_CONFIG_YML=test.yml pnpm --filter backend migrate
|
|
||||||
- name: Check no migrations are remaining
|
|
||||||
run: MISSKEY_CONFIG_YML=test.yml pnpm --filter backend check-migrations
|
|
||||||
|
|
|
||||||
|
|
@ -1,111 +0,0 @@
|
||||||
name: Test (federation)
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- master
|
|
||||||
- develop
|
|
||||||
paths:
|
|
||||||
- packages/backend/**
|
|
||||||
- packages/misskey-js/**
|
|
||||||
- .github/workflows/test-federation.yml
|
|
||||||
pull_request:
|
|
||||||
paths:
|
|
||||||
- packages/backend/**
|
|
||||||
- packages/misskey-js/**
|
|
||||||
- .github/workflows/test-federation.yml
|
|
||||||
workflow_dispatch:
|
|
||||||
inputs:
|
|
||||||
force_ffmpeg_cache_update:
|
|
||||||
description: 'Force update ffmpeg cache'
|
|
||||||
required: false
|
|
||||||
default: false
|
|
||||||
type: boolean
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
test:
|
|
||||||
name: Federation test
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
node-version-file:
|
|
||||||
- .node-version
|
|
||||||
- .github/min.node-version
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v6
|
|
||||||
with:
|
|
||||||
submodules: true
|
|
||||||
- name: Setup pnpm
|
|
||||||
uses: pnpm/action-setup@v4.2.0
|
|
||||||
- name: Get current date
|
|
||||||
id: current-date
|
|
||||||
run: echo "today=$(date +'%Y-%m-%d')" >> $GITHUB_OUTPUT
|
|
||||||
- name: Setup and Restore ffmpeg/ffprobe Cache
|
|
||||||
id: cache-ffmpeg
|
|
||||||
uses: actions/cache@v4
|
|
||||||
with:
|
|
||||||
path: |
|
|
||||||
/usr/local/bin/ffmpeg
|
|
||||||
/usr/local/bin/ffprobe
|
|
||||||
# daily cache
|
|
||||||
key: ${{ runner.os }}-ffmpeg-${{ steps.current-date.outputs.today }}
|
|
||||||
restore-keys: |
|
|
||||||
${{ runner.os }}-ffmpeg-${{ steps.current-date.outputs.today }}
|
|
||||||
- name: Install FFmpeg
|
|
||||||
if: steps.cache-ffmpeg.outputs.cache-hit != 'true' || github.event.inputs.force_ffmpeg_cache_update == true
|
|
||||||
run: |
|
|
||||||
for i in {1..3}; do
|
|
||||||
echo "Attempt $i: Installing FFmpeg..."
|
|
||||||
curl -s -L https://johnvansickle.com/ffmpeg/releases/ffmpeg-release-amd64-static.tar.xz -o ffmpeg.tar.xz && \
|
|
||||||
tar -xf ffmpeg.tar.xz && \
|
|
||||||
mv ffmpeg-*-static/ffmpeg /usr/local/bin/ && \
|
|
||||||
mv ffmpeg-*-static/ffprobe /usr/local/bin/ && \
|
|
||||||
rm -rf ffmpeg.tar.xz ffmpeg-*-static/ && \
|
|
||||||
break || sleep 10
|
|
||||||
if [ $i -eq 3 ]; then
|
|
||||||
echo "Failed to install FFmpeg after 3 attempts"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
- name: Use Node.js
|
|
||||||
uses: actions/setup-node@v6.1.0
|
|
||||||
with:
|
|
||||||
node-version-file: ${{ matrix.node-version-file }}
|
|
||||||
cache: 'pnpm'
|
|
||||||
- name: Build Misskey
|
|
||||||
run: |
|
|
||||||
pnpm i --frozen-lockfile
|
|
||||||
pnpm build
|
|
||||||
- name: Setup
|
|
||||||
run: |
|
|
||||||
echo "NODE_VERSION=$(cat ${{ matrix.node-version-file }})" >> $GITHUB_ENV
|
|
||||||
cd packages/backend/test-federation
|
|
||||||
bash ./setup.sh
|
|
||||||
sudo chmod 644 ./certificates/*.test.key
|
|
||||||
- name: Start servers
|
|
||||||
id: start_servers
|
|
||||||
continue-on-error: true
|
|
||||||
# https://github.com/docker/compose/issues/1294#issuecomment-374847206
|
|
||||||
run: |
|
|
||||||
cd packages/backend/test-federation
|
|
||||||
docker compose up -d --scale tester=0
|
|
||||||
- name: Print start_servers error
|
|
||||||
if: ${{ steps.start_servers.outcome == 'failure' }}
|
|
||||||
run: |
|
|
||||||
cd packages/backend/test-federation
|
|
||||||
docker compose logs | tail -n 300
|
|
||||||
exit 1
|
|
||||||
- name: Test
|
|
||||||
run: |
|
|
||||||
cd packages/backend/test-federation
|
|
||||||
docker compose run --no-deps tester
|
|
||||||
- name: Log
|
|
||||||
if: always()
|
|
||||||
run: |
|
|
||||||
cd packages/backend/test-federation
|
|
||||||
docker compose logs
|
|
||||||
- name: Stop servers
|
|
||||||
if: always()
|
|
||||||
run: |
|
|
||||||
cd packages/backend/test-federation
|
|
||||||
docker compose down
|
|
||||||
|
|
@ -11,8 +11,7 @@ on:
|
||||||
- packages/misskey-js/**
|
- packages/misskey-js/**
|
||||||
# for e2e
|
# for e2e
|
||||||
- packages/backend/**
|
- packages/backend/**
|
||||||
- .github/workflows/test-frontend.yml
|
|
||||||
- .github/misskey/test.yml
|
|
||||||
pull_request:
|
pull_request:
|
||||||
paths:
|
paths:
|
||||||
- packages/frontend/**
|
- packages/frontend/**
|
||||||
|
|
@ -20,24 +19,30 @@ on:
|
||||||
- packages/misskey-js/**
|
- packages/misskey-js/**
|
||||||
# for e2e
|
# for e2e
|
||||||
- packages/backend/**
|
- packages/backend/**
|
||||||
- .github/workflows/test-frontend.yml
|
|
||||||
- .github/misskey/test.yml
|
|
||||||
jobs:
|
jobs:
|
||||||
vitest:
|
vitest:
|
||||||
name: Unit tests (frontend)
|
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
node-version: [20.10.0]
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v6.0.1
|
- uses: actions/checkout@v4.1.1
|
||||||
with:
|
with:
|
||||||
submodules: true
|
submodules: true
|
||||||
- name: Setup pnpm
|
- name: Install pnpm
|
||||||
uses: pnpm/action-setup@v4.2.0
|
uses: pnpm/action-setup@v3
|
||||||
- name: Use Node.js
|
|
||||||
uses: actions/setup-node@v6.1.0
|
|
||||||
with:
|
with:
|
||||||
node-version-file: '.node-version'
|
version: 8
|
||||||
|
run_install: false
|
||||||
|
- name: Use Node.js ${{ matrix.node-version }}
|
||||||
|
uses: actions/setup-node@v4.0.2
|
||||||
|
with:
|
||||||
|
node-version: ${{ matrix.node-version }}
|
||||||
cache: 'pnpm'
|
cache: 'pnpm'
|
||||||
|
- run: corepack enable
|
||||||
- run: pnpm i --frozen-lockfile
|
- run: pnpm i --frozen-lockfile
|
||||||
- name: Check pnpm-lock.yaml
|
- name: Check pnpm-lock.yaml
|
||||||
run: git diff --exit-code pnpm-lock.yaml
|
run: git diff --exit-code pnpm-lock.yaml
|
||||||
|
|
@ -48,23 +53,23 @@ jobs:
|
||||||
- name: Test
|
- name: Test
|
||||||
run: pnpm --filter frontend test-and-coverage
|
run: pnpm --filter frontend test-and-coverage
|
||||||
- name: Upload Coverage
|
- name: Upload Coverage
|
||||||
uses: codecov/codecov-action@v5
|
uses: codecov/codecov-action@v4
|
||||||
with:
|
with:
|
||||||
token: ${{ secrets.CODECOV_TOKEN }}
|
token: ${{ secrets.CODECOV_TOKEN }}
|
||||||
files: ./packages/frontend/coverage/coverage-final.json
|
files: ./packages/frontend/coverage/coverage-final.json
|
||||||
|
|
||||||
e2e:
|
e2e:
|
||||||
name: E2E tests (frontend)
|
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
|
node-version: [20.10.0]
|
||||||
browser: [chrome]
|
browser: [chrome]
|
||||||
|
|
||||||
services:
|
services:
|
||||||
postgres:
|
postgres:
|
||||||
image: postgres:18
|
image: postgres:15
|
||||||
ports:
|
ports:
|
||||||
- 54312:5432
|
- 54312:5432
|
||||||
env:
|
env:
|
||||||
|
|
@ -76,7 +81,7 @@ jobs:
|
||||||
- 56312:6379
|
- 56312:6379
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v6.0.1
|
- uses: actions/checkout@v4.1.1
|
||||||
with:
|
with:
|
||||||
submodules: true
|
submodules: true
|
||||||
# https://github.com/cypress-io/cypress-docker-images/issues/150
|
# https://github.com/cypress-io/cypress-docker-images/issues/150
|
||||||
|
|
@ -85,13 +90,17 @@ jobs:
|
||||||
# if: ${{ matrix.browser == 'firefox' }}
|
# if: ${{ matrix.browser == 'firefox' }}
|
||||||
#- uses: browser-actions/setup-firefox@latest
|
#- uses: browser-actions/setup-firefox@latest
|
||||||
# if: ${{ matrix.browser == 'firefox' }}
|
# if: ${{ matrix.browser == 'firefox' }}
|
||||||
- name: Setup pnpm
|
- name: Install pnpm
|
||||||
uses: pnpm/action-setup@v4.2.0
|
uses: pnpm/action-setup@v3
|
||||||
- name: Use Node.js
|
|
||||||
uses: actions/setup-node@v6.1.0
|
|
||||||
with:
|
with:
|
||||||
node-version-file: '.node-version'
|
version: 7
|
||||||
|
run_install: false
|
||||||
|
- name: Use Node.js ${{ matrix.node-version }}
|
||||||
|
uses: actions/setup-node@v4.0.2
|
||||||
|
with:
|
||||||
|
node-version: ${{ matrix.node-version }}
|
||||||
cache: 'pnpm'
|
cache: 'pnpm'
|
||||||
|
- run: corepack enable
|
||||||
- run: pnpm i --frozen-lockfile
|
- run: pnpm i --frozen-lockfile
|
||||||
- name: Copy Configure
|
- name: Copy Configure
|
||||||
run: cp .github/misskey/test.yml .config
|
run: cp .github/misskey/test.yml .config
|
||||||
|
|
@ -113,12 +122,12 @@ jobs:
|
||||||
wait-on: 'http://localhost:61812'
|
wait-on: 'http://localhost:61812'
|
||||||
headed: true
|
headed: true
|
||||||
browser: ${{ matrix.browser }}
|
browser: ${{ matrix.browser }}
|
||||||
- uses: actions/upload-artifact@v6
|
- uses: actions/upload-artifact@v4
|
||||||
if: failure()
|
if: failure()
|
||||||
with:
|
with:
|
||||||
name: ${{ matrix.browser }}-cypress-screenshots
|
name: ${{ matrix.browser }}-cypress-screenshots
|
||||||
path: cypress/screenshots
|
path: cypress/screenshots
|
||||||
- uses: actions/upload-artifact@v6
|
- uses: actions/upload-artifact@v4
|
||||||
if: always()
|
if: always()
|
||||||
with:
|
with:
|
||||||
name: ${{ matrix.browser }}-cypress-videos
|
name: ${{ matrix.browser }}-cypress-videos
|
||||||
|
|
|
||||||
|
|
@ -8,29 +8,31 @@ on:
|
||||||
branches: [ develop ]
|
branches: [ develop ]
|
||||||
paths:
|
paths:
|
||||||
- packages/misskey-js/**
|
- packages/misskey-js/**
|
||||||
- .github/workflows/test-misskey-js.yml
|
|
||||||
pull_request:
|
pull_request:
|
||||||
branches: [ develop ]
|
branches: [ develop ]
|
||||||
paths:
|
paths:
|
||||||
- packages/misskey-js/**
|
- packages/misskey-js/**
|
||||||
- .github/workflows/test-misskey-js.yml
|
|
||||||
jobs:
|
jobs:
|
||||||
test:
|
test:
|
||||||
name: Unit tests (misskey.js)
|
|
||||||
|
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
node-version: [20.10.0]
|
||||||
|
# See supported Node.js release schedule at https://nodejs.org/en/about/releases/
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v6.0.1
|
uses: actions/checkout@v4.1.1
|
||||||
|
|
||||||
- name: Setup pnpm
|
- run: corepack enable
|
||||||
uses: pnpm/action-setup@v4.2.0
|
|
||||||
|
|
||||||
- name: Setup Node.js
|
- name: Setup Node.js ${{ matrix.node-version }}
|
||||||
uses: actions/setup-node@v6.1.0
|
uses: actions/setup-node@v4.0.2
|
||||||
with:
|
with:
|
||||||
node-version-file: '.node-version'
|
node-version: ${{ matrix.node-version }}
|
||||||
cache: 'pnpm'
|
cache: 'pnpm'
|
||||||
|
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
|
|
@ -48,7 +50,7 @@ jobs:
|
||||||
CI: true
|
CI: true
|
||||||
|
|
||||||
- name: Upload Coverage
|
- name: Upload Coverage
|
||||||
uses: codecov/codecov-action@v5
|
uses: codecov/codecov-action@v4
|
||||||
with:
|
with:
|
||||||
token: ${{ secrets.CODECOV_TOKEN }}
|
token: ${{ secrets.CODECOV_TOKEN }}
|
||||||
files: ./packages/misskey-js/coverage/coverage-final.json
|
files: ./packages/misskey-js/coverage/coverage-final.json
|
||||||
|
|
|
||||||
|
|
@ -12,20 +12,27 @@ env:
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
production:
|
production:
|
||||||
name: Production build
|
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
node-version: [20.10.0]
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v6.0.1
|
- uses: actions/checkout@v4.1.1
|
||||||
with:
|
with:
|
||||||
submodules: true
|
submodules: true
|
||||||
- name: Setup pnpm
|
- name: Install pnpm
|
||||||
uses: pnpm/action-setup@v4.2.0
|
uses: pnpm/action-setup@v3
|
||||||
- name: Use Node.js
|
|
||||||
uses: actions/setup-node@v6.1.0
|
|
||||||
with:
|
with:
|
||||||
node-version-file: '.node-version'
|
version: 8
|
||||||
|
run_install: false
|
||||||
|
- name: Use Node.js ${{ matrix.node-version }}
|
||||||
|
uses: actions/setup-node@v4.0.2
|
||||||
|
with:
|
||||||
|
node-version: ${{ matrix.node-version }}
|
||||||
cache: 'pnpm'
|
cache: 'pnpm'
|
||||||
|
- run: corepack enable
|
||||||
- run: pnpm i --frozen-lockfile
|
- run: pnpm i --frozen-lockfile
|
||||||
- name: Check pnpm-lock.yaml
|
- name: Check pnpm-lock.yaml
|
||||||
run: git diff --exit-code pnpm-lock.yaml
|
run: git diff --exit-code pnpm-lock.yaml
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
name: api.json validation
|
name: Test (backend)
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
|
|
@ -7,28 +7,35 @@ on:
|
||||||
- develop
|
- develop
|
||||||
paths:
|
paths:
|
||||||
- packages/backend/**
|
- packages/backend/**
|
||||||
- .github/workflows/validate-api-json.yml
|
|
||||||
pull_request:
|
pull_request:
|
||||||
paths:
|
paths:
|
||||||
- packages/backend/**
|
- packages/backend/**
|
||||||
- .github/workflows/validate-api-json.yml
|
|
||||||
jobs:
|
jobs:
|
||||||
validate-api-json:
|
validate-api-json:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
node-version: [20.10.0]
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v6.0.1
|
- uses: actions/checkout@v4.1.1
|
||||||
with:
|
with:
|
||||||
submodules: true
|
submodules: true
|
||||||
- name: Setup pnpm
|
- name: Install pnpm
|
||||||
uses: pnpm/action-setup@v4.2.0
|
uses: pnpm/action-setup@v3
|
||||||
- name: Use Node.js
|
|
||||||
uses: actions/setup-node@v6.1.0
|
|
||||||
with:
|
with:
|
||||||
node-version-file: '.node-version'
|
version: 8
|
||||||
|
run_install: false
|
||||||
|
- name: Use Node.js ${{ matrix.node-version }}
|
||||||
|
uses: actions/setup-node@v4.0.2
|
||||||
|
with:
|
||||||
|
node-version: ${{ matrix.node-version }}
|
||||||
cache: 'pnpm'
|
cache: 'pnpm'
|
||||||
- name: Install Redocly CLI
|
- name: Install Redocly CLI
|
||||||
run: npm i -g @redocly/cli
|
run: npm i -g @redocly/cli
|
||||||
|
- run: corepack enable
|
||||||
- run: pnpm i --frozen-lockfile
|
- run: pnpm i --frozen-lockfile
|
||||||
- name: Check pnpm-lock.yaml
|
- name: Check pnpm-lock.yaml
|
||||||
run: git diff --exit-code pnpm-lock.yaml
|
run: git diff --exit-code pnpm-lock.yaml
|
||||||
|
|
|
||||||
|
|
@ -35,18 +35,13 @@ coverage
|
||||||
!/.config/example.yml
|
!/.config/example.yml
|
||||||
!/.config/docker_example.yml
|
!/.config/docker_example.yml
|
||||||
!/.config/docker_example.env
|
!/.config/docker_example.env
|
||||||
!/.config/cypress-devcontainer.yml
|
|
||||||
docker-compose.yml
|
docker-compose.yml
|
||||||
./compose.yml
|
!/.devcontainer/docker-compose.yml
|
||||||
.devcontainer/compose.yml
|
|
||||||
!/.devcontainer/compose.yml
|
|
||||||
|
|
||||||
# misskey
|
# misskey
|
||||||
/build
|
/build
|
||||||
built
|
built
|
||||||
built-test
|
built-test
|
||||||
js-built
|
|
||||||
src-js
|
|
||||||
/data
|
/data
|
||||||
/.cache-loader
|
/.cache-loader
|
||||||
/db
|
/db
|
||||||
|
|
@ -64,13 +59,6 @@ ormconfig.json
|
||||||
temp
|
temp
|
||||||
/packages/frontend/src/**/*.stories.ts
|
/packages/frontend/src/**/*.stories.ts
|
||||||
tsdoc-metadata.json
|
tsdoc-metadata.json
|
||||||
misskey-assets
|
|
||||||
|
|
||||||
# Vite temporary files
|
|
||||||
vite.config.js.timestamp-*
|
|
||||||
vite.config.ts.timestamp-*
|
|
||||||
vite.config.local-dev.js.timestamp-*
|
|
||||||
vite.config.local-dev.ts.timestamp-*
|
|
||||||
|
|
||||||
# blender backups
|
# blender backups
|
||||||
*.blend1
|
*.blend1
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,6 @@
|
||||||
|
[submodule "misskey-assets"]
|
||||||
|
path = misskey-assets
|
||||||
|
url = https://github.com/misskey-dev/assets.git
|
||||||
[submodule "fluent-emojis"]
|
[submodule "fluent-emojis"]
|
||||||
path = fluent-emojis
|
path = fluent-emojis
|
||||||
url = https://github.com/misskey-dev/emojis.git
|
url = https://github.com/misskey-dev/emojis.git
|
||||||
|
|
|
||||||
|
|
@ -1 +1 @@
|
||||||
22.15.0
|
20.10.0
|
||||||
|
|
|
||||||
2
.npmrc
2
.npmrc
|
|
@ -1,3 +1 @@
|
||||||
engine-strict = true
|
engine-strict = true
|
||||||
save-exact = true
|
|
||||||
shell-emulator = true
|
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,9 @@
|
||||||
"editorconfig.editorconfig",
|
"editorconfig.editorconfig",
|
||||||
"dbaeumer.vscode-eslint",
|
"dbaeumer.vscode-eslint",
|
||||||
"Vue.volar",
|
"Vue.volar",
|
||||||
|
"Vue.vscode-typescript-vue-plugin",
|
||||||
"Orta.vscode-jest",
|
"Orta.vscode-jest",
|
||||||
|
"dbaeumer.vscode-eslint",
|
||||||
"mrmlnc.vscode-json5"
|
"mrmlnc.vscode-json5"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,16 +3,11 @@
|
||||||
"**/node_modules": true
|
"**/node_modules": true
|
||||||
},
|
},
|
||||||
"typescript.tsdk": "node_modules/typescript/lib",
|
"typescript.tsdk": "node_modules/typescript/lib",
|
||||||
"typescript.enablePromptUseWorkspaceTsdk": true,
|
|
||||||
"files.associations": {
|
"files.associations": {
|
||||||
"*.test.ts": "typescript"
|
"*.test.ts": "typescript"
|
||||||
},
|
},
|
||||||
"jest.runMode": "on-demand",
|
"jest.jestCommandLine": "pnpm run jest",
|
||||||
"jest.virtualFolders": [
|
"jest.autoRun": "off",
|
||||||
{ "name": "backend unit", "jestCommandLine": "pnpm -F backend run test" },
|
|
||||||
{ "name": "backend e2e", "jestCommandLine": "pnpm -F backend run test:e2e"},
|
|
||||||
{ "name": "misskey-js", "jestCommandLine": "pnpm -F misskey-js run jest" }
|
|
||||||
],
|
|
||||||
"editor.codeActionsOnSave": {
|
"editor.codeActionsOnSave": {
|
||||||
"source.fixAll": "explicit"
|
"source.fixAll": "explicit"
|
||||||
},
|
},
|
||||||
|
|
|
||||||
1251
CHANGELOG.md
1251
CHANGELOG.md
File diff suppressed because it is too large
Load Diff
345
CONTRIBUTING.md
345
CONTRIBUTING.md
|
|
@ -1,7 +1,7 @@
|
||||||
# Contribution guide
|
# Contribution guide
|
||||||
We're glad you're interested in contributing Misskey! In this document you will find the information you need to contribute to the project.
|
We're glad you're interested in contributing Misskey! In this document you will find the information you need to contribute to the project.
|
||||||
|
|
||||||
> [!NOTE]
|
> **Note**
|
||||||
> This project uses Japanese as its major language, **but you do not need to translate and write the Issues/PRs in Japanese.**
|
> This project uses Japanese as its major language, **but you do not need to translate and write the Issues/PRs in Japanese.**
|
||||||
> Also, you might receive comments on your Issue/PR in Japanese, but you do not need to reply to them in Japanese as well.\
|
> Also, you might receive comments on your Issue/PR in Japanese, but you do not need to reply to them in Japanese as well.\
|
||||||
> The accuracy of machine translation into Japanese is not high, so it will be easier for us to understand if you write it in the original language.
|
> The accuracy of machine translation into Japanese is not high, so it will be easier for us to understand if you write it in the original language.
|
||||||
|
|
@ -17,31 +17,16 @@ Before creating an issue, please check the following:
|
||||||
- Issues should only be used to feature requests, suggestions, and bug tracking.
|
- Issues should only be used to feature requests, suggestions, and bug tracking.
|
||||||
- Please ask questions or troubleshooting in [GitHub Discussions](https://github.com/misskey-dev/misskey/discussions) or [Discord](https://discord.gg/Wp8gVStHW3).
|
- Please ask questions or troubleshooting in [GitHub Discussions](https://github.com/misskey-dev/misskey/discussions) or [Discord](https://discord.gg/Wp8gVStHW3).
|
||||||
|
|
||||||
> [!WARNING]
|
> **Warning**
|
||||||
> Do not close issues that are about to be resolved. It should remain open until a commit that actually resolves it is merged.
|
> Do not close issues that are about to be resolved. It should remain open until a commit that actually resolves it is merged.
|
||||||
|
|
||||||
### Recommended discussing before implementation
|
## Before implementation
|
||||||
We welcome your proposal.
|
|
||||||
|
|
||||||
When you want to add a feature or fix a bug, **first have the design and policy reviewed in an Issue** (if it is not there, please make one). Without this step, there is a high possibility that the PR will not be merged even if it is implemented.
|
When you want to add a feature or fix a bug, **first have the design and policy reviewed in an Issue** (if it is not there, please make one). Without this step, there is a high possibility that the PR will not be merged even if it is implemented.
|
||||||
|
|
||||||
At this point, you also need to clarify the goals of the PR you will create, and make sure that the other members of the team are aware of them.
|
At this point, you also need to clarify the goals of the PR you will create, and make sure that the other members of the team are aware of them.
|
||||||
PRs that do not have a clear set of do's and don'ts tend to be bloated and difficult to review.
|
PRs that do not have a clear set of do's and don'ts tend to be bloated and difficult to review.
|
||||||
|
|
||||||
Also, when you start implementation, assign yourself to the Issue (if you cannot do it yourself, ask Committer to assign you).
|
Also, when you start implementation, assign yourself to the Issue (if you cannot do it yourself, ask another member to assign you). By expressing your intention to work the Issue, you can prevent conflicts in the work.
|
||||||
By expressing your intention to work on the Issue, you can prevent conflicts in the work.
|
|
||||||
|
|
||||||
To the Committers: you should not assign someone on it before the Final Decision.
|
|
||||||
|
|
||||||
### How issues are triaged
|
|
||||||
|
|
||||||
The Committers may:
|
|
||||||
* close an issue that is not reproducible on latest stable release,
|
|
||||||
* merge an issue into another issue,
|
|
||||||
* split an issue into multiple issues,
|
|
||||||
* or re-open that has been closed for some reason which is not applicable anymore.
|
|
||||||
|
|
||||||
@syuilo reserves the Final Decision rights including whether the project will implement feature and how to implement, these rights are not always exercised.
|
|
||||||
|
|
||||||
## Well-known branches
|
## Well-known branches
|
||||||
- **`master`** branch is tracking the latest release and used for production purposes.
|
- **`master`** branch is tracking the latest release and used for production purposes.
|
||||||
|
|
@ -52,45 +37,25 @@ The Committers may:
|
||||||
## Creating a PR
|
## Creating a PR
|
||||||
Thank you for your PR! Before creating a PR, please check the following:
|
Thank you for your PR! Before creating a PR, please check the following:
|
||||||
- If possible, prefix the title with a keyword that identifies the type of this PR, as shown below.
|
- If possible, prefix the title with a keyword that identifies the type of this PR, as shown below.
|
||||||
- `fix` / `refactor` / `feat` / `enhance` / `perf` / `chore` etc
|
- `fix` / `refactor` / `feat` / `enhance` / `perf` / `chore` etc
|
||||||
- Also, make sure that the granularity of this PR is appropriate. Please do not include more than one type of change or interest in a single PR.
|
- Also, make sure that the granularity of this PR is appropriate. Please do not include more than one type of change or interest in a single PR.
|
||||||
- If there is an Issue which will be resolved by this PR, please include a reference to the Issue in the text.
|
- If there is an Issue which will be resolved by this PR, please include a reference to the Issue in the text.
|
||||||
- Please add the summary of the changes to [`CHANGELOG.md`](/CHANGELOG.md). However, this is not necessary for changes that do not affect the users, such as refactoring.
|
- Please add the summary of the changes to [`CHANGELOG.md`](/CHANGELOG.md). However, this is not necessary for changes that do not affect the users, such as refactoring.
|
||||||
- Check if there are any documents that need to be created or updated due to this change.
|
- Check if there are any documents that need to be created or updated due to this change.
|
||||||
- If you have added a feature or fixed a bug, please add a test case if possible.
|
- If you have added a feature or fixed a bug, please add a test case if possible.
|
||||||
- Please make sure that tests and Lint are passed in advance.
|
- Please make sure that tests and Lint are passed in advance.
|
||||||
- You can run it with `pnpm test` and `pnpm lint`. [See more info](#testing)
|
- You can run it with `pnpm test` and `pnpm lint`. [See more info](#testing)
|
||||||
- If this PR includes UI changes, please attach a screenshot in the text.
|
- If this PR includes UI changes, please attach a screenshot in the text.
|
||||||
|
|
||||||
Thanks for your cooperation 🤗
|
Thanks for your cooperation 🤗
|
||||||
|
|
||||||
### Additional things for ActivityPub payload changes
|
|
||||||
*This section is specific to misskey-dev implementation. Other fork or implementation may take different way. A significant difference is that non-"misskey-dev" extension is not described in the misskey-hub's document.*
|
|
||||||
|
|
||||||
If PR includes changes to ActivityPub payload, please reflect it in [misskey-hub's document](https://github.com/misskey-dev/misskey-hub-next/blob/master/content/ns.md) by sending PR.
|
|
||||||
|
|
||||||
The name of purporsed extension property (referred as "extended property" in later) to ActivityPub shall be prefixed by `_misskey_`. (i.e. `_misskey_quote`)
|
|
||||||
|
|
||||||
The extended property in `packages/backend/src/core/activitypub/type.ts` **must** be declared as optional because ActivityPub payloads that comes from older Misskey or other implementation may not contain it.
|
|
||||||
|
|
||||||
The extended property must be included in the context definition. Context is defined in `packages/backend/src/core/activitypub/misc/contexts.ts`.
|
|
||||||
The key shall be same as the name of extended property, and the value shall be same as "short IRI".
|
|
||||||
|
|
||||||
"Short IRI" is defined in misskey-hub's document, but usually takes form of `misskey:<name of extended property>`. (i.e. `misskey:_misskey_quote`)
|
|
||||||
|
|
||||||
One should not add property that has defined before by other implementation, or add custom variant value to "well-known" property.
|
|
||||||
|
|
||||||
## Reviewers guide
|
## Reviewers guide
|
||||||
Be willing to comment on the good points and not just the things you want fixed 💯
|
Be willing to comment on the good points and not just the things you want fixed 💯
|
||||||
|
|
||||||
読んでおくといいやつ
|
|
||||||
- https://blog.lacolaco.net/posts/1e2cf439b3c2/
|
|
||||||
- https://konifar-zatsu.hatenadiary.jp/entry/2024/11/05/192421
|
|
||||||
|
|
||||||
### Review perspective
|
### Review perspective
|
||||||
- Scope
|
- Scope
|
||||||
- Are the goals of the PR clear?
|
- Are the goals of the PR clear?
|
||||||
- Is the granularity of the PR appropriate?
|
- Is the granularity of the PR appropriate?
|
||||||
- Security
|
- Security
|
||||||
- Does merging this PR create a vulnerability?
|
- Does merging this PR create a vulnerability?
|
||||||
- Performance
|
- Performance
|
||||||
|
|
@ -101,22 +66,6 @@ Be willing to comment on the good points and not just the things you want fixed
|
||||||
- Are there any omissions or gaps?
|
- Are there any omissions or gaps?
|
||||||
- Does it check for anomalies?
|
- Does it check for anomalies?
|
||||||
|
|
||||||
## Security Advisory
|
|
||||||
### For reporter
|
|
||||||
Thank you for your reporting!
|
|
||||||
|
|
||||||
If you can also create a patch to fix the vulnerability, please create a PR on the private fork.
|
|
||||||
|
|
||||||
> [!note]
|
|
||||||
> There is a GitHub bug that prevents merging if a PR not following the develop branch of upstream, so please keep follow the develop branch.
|
|
||||||
|
|
||||||
### For misskey-dev member
|
|
||||||
修正PRがdevelopに追従されていないとマージできないので、マージできなかったら
|
|
||||||
|
|
||||||
> Could you merge or rebase onto upstream develop branch?
|
|
||||||
|
|
||||||
などと伝える。
|
|
||||||
|
|
||||||
## Deploy
|
## Deploy
|
||||||
The `/deploy` command by issue comment can be used to deploy the contents of a PR to the preview environment.
|
The `/deploy` command by issue comment can be used to deploy the contents of a PR to the preview environment.
|
||||||
```
|
```
|
||||||
|
|
@ -128,7 +77,7 @@ An actual domain will be assigned so you can test the federation.
|
||||||
|
|
||||||
## Release
|
## Release
|
||||||
### Release Instructions
|
### Release Instructions
|
||||||
1. Commit version changes in the `develop` branch ([package.json](package.json))
|
1. Commit version changes in the `develop` branch ([package.json](https://github.com/misskey-dev/misskey/blob/develop/package.json))
|
||||||
2. Create a release PR.
|
2. Create a release PR.
|
||||||
- Into `master` from `develop` branch.
|
- Into `master` from `develop` branch.
|
||||||
- The title must be in the format `Release: x.y.z`.
|
- The title must be in the format `Release: x.y.z`.
|
||||||
|
|
@ -139,7 +88,7 @@ An actual domain will be assigned so you can test the federation.
|
||||||
- The target branch must be `master`
|
- The target branch must be `master`
|
||||||
- The tag name must be the version
|
- The tag name must be the version
|
||||||
|
|
||||||
> [!NOTE]
|
> **Note**
|
||||||
> Why this instruction is necessary:
|
> Why this instruction is necessary:
|
||||||
> - To perform final QA checks
|
> - To perform final QA checks
|
||||||
> - To distribute responsibility
|
> - To distribute responsibility
|
||||||
|
|
@ -152,28 +101,41 @@ You can improve our translations with your Crowdin account.
|
||||||
Your changes in Crowdin are automatically submitted as a PR (with the title "New Crowdin translations") to the repository.
|
Your changes in Crowdin are automatically submitted as a PR (with the title "New Crowdin translations") to the repository.
|
||||||
The owner [@syuilo](https://github.com/syuilo) merges the PR into the develop branch before the next release.
|
The owner [@syuilo](https://github.com/syuilo) merges the PR into the develop branch before the next release.
|
||||||
|
|
||||||
If your language is not listed in Crowdin, please open an issue. We will add it to Crowdin.
|
If your language is not listed in Crowdin, please open an issue.
|
||||||
For newly added languages, once the translation progress per language exceeds 70%, it will be officially introduced into Misskey and made available to users.
|
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
## Development
|
## Development
|
||||||
### Setup
|
During development, it is useful to use the
|
||||||
Before developing, you have to set up environment. Misskey requires Redis, PostgreSQL, and FFmpeg.
|
|
||||||
|
|
||||||
You would want to install Meilisearch to experiment related features. Technically, meilisearch is not strict requirement, but some features and tests require it.
|
```
|
||||||
|
pnpm dev
|
||||||
|
```
|
||||||
|
|
||||||
There are a few ways to proceed.
|
command.
|
||||||
|
|
||||||
#### Use system-wide software
|
- Server-side source files and automatically builds them if they are modified. Automatically start the server process(es).
|
||||||
You could install them in system-wide (such as from package manager).
|
- Vite HMR (just the `vite` command) is available. The behavior may be different from production.
|
||||||
|
- Service Worker is watched by esbuild.
|
||||||
|
- The front end can be viewed by accessing `http://localhost:5173`.
|
||||||
|
- The backend listens on the port configured with `port` in .config/default.yml.
|
||||||
|
If you have not changed it from the default, it will be "http://localhost:3000".
|
||||||
|
If "port" in .config/default.yml is set to something other than 3000, you need to change the proxy settings in packages/frontend/vite.config.local-dev.ts.
|
||||||
|
|
||||||
#### Use `docker compose`
|
### `MK_DEV_PREFER=backend pnpm dev`
|
||||||
You could obtain middleware container by typing `docker compose -f $PROJECT_ROOT/compose.local-db.yml up -d`.
|
pnpm dev has another mode with `MK_DEV_PREFER=backend`.
|
||||||
|
|
||||||
#### Use Devcontainer
|
```
|
||||||
Devcontainer also has necessary setting. This method can be done by connecting from VSCode.
|
MK_DEV_PREFER=backend pnpm dev
|
||||||
|
```
|
||||||
|
|
||||||
|
- This mode is closer to the production environment than the default mode.
|
||||||
|
- Vite runs behind the backend (the backend will proxy Vite at /vite).
|
||||||
|
- You can see Misskey by accessing `http://localhost:3000` (Replace `3000` with the port configured with `port` in .config/default.yml).
|
||||||
|
- To change the port of Vite, specify with `VITE_PORT` environment variable.
|
||||||
|
- HMR may not work in some environments such as Windows.
|
||||||
|
|
||||||
|
### Dev Container
|
||||||
Instead of running `pnpm` locally, you can use Dev Container to set up your development environment.
|
Instead of running `pnpm` locally, you can use Dev Container to set up your development environment.
|
||||||
To use Dev Container, open the project directory on VSCode with Dev Containers installed.
|
To use Dev Container, open the project directory on VSCode with Dev Containers installed.
|
||||||
**Note:** If you are using Windows, please clone the repository with WSL. Using Git for Windows will result in broken files due to the difference in how newlines are handled.
|
**Note:** If you are using Windows, please clone the repository with WSL. Using Git for Windows will result in broken files due to the difference in how newlines are handled.
|
||||||
|
|
@ -187,61 +149,38 @@ pnpm build
|
||||||
pnpm migrate
|
pnpm migrate
|
||||||
```
|
```
|
||||||
|
|
||||||
After finishing the migration, you can proceed.
|
After finishing the migration, run the `pnpm dev` command to start the development server.
|
||||||
|
|
||||||
### Start developing
|
``` bash
|
||||||
During development, it is useful to use the
|
|
||||||
```
|
|
||||||
pnpm dev
|
pnpm dev
|
||||||
```
|
```
|
||||||
command.
|
|
||||||
|
|
||||||
- Server-side source files and automatically builds them if they are modified. Automatically start the server process(es).
|
|
||||||
- Service Worker is watched by esbuild.
|
|
||||||
- Vite HMR (just the `vite` command) is available. The behavior may be different from production.
|
|
||||||
- Vite runs behind the backend (the backend will proxy Vite at /vite and /embed_vite except for websocket used for HMR).
|
|
||||||
- You can see Misskey by accessing `http://localhost:3000` (Replace `3000` with the port configured with `port` in .config/default.yml).
|
|
||||||
|
|
||||||
## Testing
|
## Testing
|
||||||
You can run non-backend tests by executing following commands:
|
- Test codes are located in [`/packages/backend/test`](/packages/backend/test).
|
||||||
```sh
|
|
||||||
pnpm --filter frontend test
|
### Run test
|
||||||
pnpm --filter misskey-js test
|
Create a config file.
|
||||||
```
|
```
|
||||||
|
|
||||||
Backend tests require manual preparation of servers. See the next section for more on this.
|
|
||||||
|
|
||||||
### Backend
|
|
||||||
There are three types of test codes for the backend:
|
|
||||||
- Unit tests: [`/packages/backend/test/unit`](/packages/backend/test/unit)
|
|
||||||
- Single-server E2E tests: [`/packages/backend/test/e2e`](/packages/backend/test/e2e)
|
|
||||||
- Multiple-server E2E tests: [`/packages/backend/test-federation`](/packages/backend/test-federation)
|
|
||||||
|
|
||||||
#### Running Unit Tests or Single-server E2E Tests
|
|
||||||
1. Create a config file:
|
|
||||||
```sh
|
|
||||||
cp .github/misskey/test.yml .config/
|
cp .github/misskey/test.yml .config/
|
||||||
```
|
```
|
||||||
|
Prepare DB/Redis for testing.
|
||||||
2. Start DB and Redis servers for testing:
|
|
||||||
```sh
|
|
||||||
docker compose -f packages/backend/test/compose.yml up
|
|
||||||
```
|
```
|
||||||
Instead, you can prepare an empty (data can be erased) DB and edit `.config/test.yml` appropriately.
|
docker compose -f packages/backend/test/docker-compose.yml up
|
||||||
|
|
||||||
3. Run all tests:
|
|
||||||
```sh
|
|
||||||
pnpm --filter backend test # unit tests
|
|
||||||
pnpm --filter backend test:e2e # single-server E2E tests
|
|
||||||
```
|
```
|
||||||
If you want to run a specific test, run as a following command:
|
Alternatively, prepare an empty (data can be erased) DB and edit `.config/test.yml`.
|
||||||
```sh
|
|
||||||
pnpm --filter backend test -- packages/backend/test/unit/activitypub.ts
|
Run all test.
|
||||||
pnpm --filter backend test:e2e -- packages/backend/test/e2e/nodeinfo.ts
|
```
|
||||||
|
pnpm test
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Running Multiple-server E2E Tests
|
#### Run specify test
|
||||||
See [`/packages/backend/test-federation/README.md`](/packages/backend/test-federation/README.md).
|
```
|
||||||
|
pnpm jest -- foo.ts
|
||||||
|
```
|
||||||
|
|
||||||
|
### e2e tests
|
||||||
|
TODO
|
||||||
|
|
||||||
## Environment Variable
|
## Environment Variable
|
||||||
|
|
||||||
|
|
@ -258,12 +197,6 @@ Misskey uses Vue(v3) as its front-end framework.
|
||||||
- **When creating a new component, please use the Composition API (with [setup sugar](https://v3.vuejs.org/api/sfc-script-setup.html) and [ref sugar](https://github.com/vuejs/rfcs/discussions/369)) instead of the Options API.**
|
- **When creating a new component, please use the Composition API (with [setup sugar](https://v3.vuejs.org/api/sfc-script-setup.html) and [ref sugar](https://github.com/vuejs/rfcs/discussions/369)) instead of the Options API.**
|
||||||
- Some of the existing components are implemented in the Options API, but it is an old implementation. Refactors that migrate those components to the Composition API are also welcome.
|
- Some of the existing components are implemented in the Options API, but it is an old implementation. Refactors that migrate those components to the Composition API are also welcome.
|
||||||
|
|
||||||
## Tabler Icons
|
|
||||||
アイコンは、Production Build時に使用されていないものが削除されるようになっています。
|
|
||||||
|
|
||||||
**アイコンを動的に設定する際には、 `ti-${someVal}` のような、アイコン名のみを動的に変化させる実装を行わないでください。**
|
|
||||||
必ず `ti-xxx` のような完全なクラス名を含めるようにしてください。
|
|
||||||
|
|
||||||
## nirax
|
## nirax
|
||||||
niraxは、Misskeyで使用しているオリジナルのフロントエンドルーティングシステムです。
|
niraxは、Misskeyで使用しているオリジナルのフロントエンドルーティングシステムです。
|
||||||
**vue-routerから影響を多大に受けているので、まずはvue-routerについて学ぶことをお勧めします。**
|
**vue-routerから影響を多大に受けているので、まずはvue-routerについて学ぶことをお勧めします。**
|
||||||
|
|
@ -271,7 +204,7 @@ niraxは、Misskeyで使用しているオリジナルのフロントエンド
|
||||||
### ルート定義
|
### ルート定義
|
||||||
ルート定義は、以下の形式のオブジェクトの配列です。
|
ルート定義は、以下の形式のオブジェクトの配列です。
|
||||||
|
|
||||||
```ts
|
``` ts
|
||||||
{
|
{
|
||||||
name?: string;
|
name?: string;
|
||||||
path: string;
|
path: string;
|
||||||
|
|
@ -279,11 +212,12 @@ niraxは、Misskeyで使用しているオリジナルのフロントエンド
|
||||||
query?: Record<string, string>;
|
query?: Record<string, string>;
|
||||||
loginRequired?: boolean;
|
loginRequired?: boolean;
|
||||||
hash?: string;
|
hash?: string;
|
||||||
|
globalCacheKey?: string;
|
||||||
children?: RouteDef[];
|
children?: RouteDef[];
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
> [!WARNING]
|
> **Warning**
|
||||||
> 現状、ルートは定義された順に評価されます。
|
> 現状、ルートは定義された順に評価されます。
|
||||||
> たとえば、`/foo/:id`ルート定義の次に`/foo/bar`ルート定義がされていた場合、後者がマッチすることはありません。
|
> たとえば、`/foo/:id`ルート定義の次に`/foo/bar`ルート定義がされていた場合、後者がマッチすることはありません。
|
||||||
|
|
||||||
|
|
@ -345,7 +279,7 @@ export const Default = {
|
||||||
parameters: {
|
parameters: {
|
||||||
layout: 'centered',
|
layout: 'centered',
|
||||||
},
|
},
|
||||||
} satisfies StoryObj<typeof MyComponent>;
|
} satisfies StoryObj<typeof MkAvatar>;
|
||||||
```
|
```
|
||||||
|
|
||||||
If you want to opt-out from the automatic generation, create a `MyComponent.stories.impl.ts` file and add the following line to the file.
|
If you want to opt-out from the automatic generation, create a `MyComponent.stories.impl.ts` file and add the following line to the file.
|
||||||
|
|
@ -382,98 +316,6 @@ export const handlers = [
|
||||||
|
|
||||||
Don't forget to re-run the `.storybook/generate.js` script after adding, editing, or removing the above files.
|
Don't forget to re-run the `.storybook/generate.js` script after adding, editing, or removing the above files.
|
||||||
|
|
||||||
## Nest
|
|
||||||
|
|
||||||
### Nest Service Circular dependency / Nestでサービスの循環参照でエラーが起きた場合
|
|
||||||
|
|
||||||
#### forwardRef
|
|
||||||
まずは簡単に`forwardRef`を試してみる
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
export class FooService {
|
|
||||||
constructor(
|
|
||||||
@Inject(forwardRef(() => BarService))
|
|
||||||
private barService: BarService
|
|
||||||
) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
#### OnModuleInit
|
|
||||||
できなければ`OnModuleInit`を使う
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
import { Injectable, OnModuleInit } from '@nestjs/common';
|
|
||||||
import { ModuleRef } from '@nestjs/core';
|
|
||||||
import { BarService } from '@/core/BarService';
|
|
||||||
|
|
||||||
@Injectable()
|
|
||||||
export class FooService implements OnModuleInit {
|
|
||||||
private barService: BarService // constructorから移動してくる
|
|
||||||
|
|
||||||
constructor(
|
|
||||||
private moduleRef: ModuleRef,
|
|
||||||
) {
|
|
||||||
}
|
|
||||||
|
|
||||||
async onModuleInit() {
|
|
||||||
this.barService = this.moduleRef.get(BarService.name);
|
|
||||||
}
|
|
||||||
|
|
||||||
public async niceMethod() {
|
|
||||||
return await this.barService.incredibleMethod({ hoge: 'fuga' });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
##### Service Unit Test
|
|
||||||
テストで`onModuleInit`を呼び出す必要がある
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
// import ...
|
|
||||||
|
|
||||||
describe('test', () => {
|
|
||||||
let app: TestingModule;
|
|
||||||
let fooService: FooService; // for test case
|
|
||||||
let barService: BarService; // for test case
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
|
||||||
app = await Test.createTestingModule({
|
|
||||||
imports: ...,
|
|
||||||
providers: [
|
|
||||||
FooService,
|
|
||||||
{ // mockする (mockは必須ではないかもしれない)
|
|
||||||
provide: BarService,
|
|
||||||
useFactory: () => ({
|
|
||||||
incredibleMethod: jest.fn(),
|
|
||||||
}),
|
|
||||||
},
|
|
||||||
{ // Provideにする
|
|
||||||
provide: BarService.name,
|
|
||||||
useExisting: BarService,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
})
|
|
||||||
.useMocker(...
|
|
||||||
.compile();
|
|
||||||
|
|
||||||
fooService = app.get<FooService>(FooService);
|
|
||||||
barService = app.get<BarService>(BarService) as jest.Mocked<BarService>;
|
|
||||||
|
|
||||||
// onModuleInitを実行する
|
|
||||||
await fooService.onModuleInit();
|
|
||||||
});
|
|
||||||
|
|
||||||
test('nice', () => {
|
|
||||||
await fooService.niceMethod();
|
|
||||||
|
|
||||||
expect(barService.incredibleMethod).toHaveBeenCalled();
|
|
||||||
expect(barService.incredibleMethod.mock.lastCall![0])
|
|
||||||
.toEqual({ hoge: 'fuga' });
|
|
||||||
});
|
|
||||||
})
|
|
||||||
```
|
|
||||||
|
|
||||||
## Notes
|
## Notes
|
||||||
|
|
||||||
### Misskeyのドメイン固有の概念は`Mi`をprefixする
|
### Misskeyのドメイン固有の概念は`Mi`をprefixする
|
||||||
|
|
@ -481,11 +323,6 @@ describe('test', () => {
|
||||||
コード上でMisskeyのドメイン固有の概念には`Mi`をprefixすることで、他のドメインの同様の概念と区別できるほか、名前の衝突を防ぐ。
|
コード上でMisskeyのドメイン固有の概念には`Mi`をprefixすることで、他のドメインの同様の概念と区別できるほか、名前の衝突を防ぐ。
|
||||||
ただし、文脈上Misskeyのものを指すことが明らかであり、名前の衝突の恐れがない場合は、一時的なローカル変数に限って`Mi`を省略してもよい。
|
ただし、文脈上Misskeyのものを指すことが明らかであり、名前の衝突の恐れがない場合は、一時的なローカル変数に限って`Mi`を省略してもよい。
|
||||||
|
|
||||||
### Misskey.jsの型生成
|
|
||||||
```bash
|
|
||||||
pnpm build-misskey-js-with-types
|
|
||||||
```
|
|
||||||
|
|
||||||
### How to resolve conflictions occurred at pnpm-lock.yaml?
|
### How to resolve conflictions occurred at pnpm-lock.yaml?
|
||||||
|
|
||||||
Just execute `pnpm` to fix it.
|
Just execute `pnpm` to fix it.
|
||||||
|
|
@ -581,6 +418,27 @@ pnpm dlx typeorm migration:generate -d ormconfig.js -o <migration name>
|
||||||
- 生成後、ファイルをmigration下に移してください
|
- 生成後、ファイルをmigration下に移してください
|
||||||
- 作成されたスクリプトは不必要な変更を含むため除去してください
|
- 作成されたスクリプトは不必要な変更を含むため除去してください
|
||||||
|
|
||||||
|
### JSON SchemaのobjectでanyOfを使うとき
|
||||||
|
JSON Schemaで、objectに対してanyOfを使う場合、anyOfの中でpropertiesを定義しないこと。
|
||||||
|
バリデーションが効かないため。(SchemaTypeもそのように作られており、objectのanyOf内のpropertiesは捨てられます)
|
||||||
|
https://github.com/misskey-dev/misskey/pull/10082
|
||||||
|
|
||||||
|
テキストhogeおよびfugaについて、片方を必須としつつ両方の指定もありうる場合:
|
||||||
|
|
||||||
|
```
|
||||||
|
export const paramDef = {
|
||||||
|
type: 'object',
|
||||||
|
properties: {
|
||||||
|
hoge: { type: 'string', minLength: 1 },
|
||||||
|
fuga: { type: 'string', minLength: 1 },
|
||||||
|
},
|
||||||
|
anyOf: [
|
||||||
|
{ required: ['hoge'] },
|
||||||
|
{ required: ['fuga'] },
|
||||||
|
],
|
||||||
|
} as const;
|
||||||
|
```
|
||||||
|
|
||||||
### コネクションには`markRaw`せよ
|
### コネクションには`markRaw`せよ
|
||||||
**Vueのコンポーネントのdataオプションとして**misskey.jsのコネクションを設定するとき、必ず`markRaw`でラップしてください。インスタンスが不必要にリアクティブ化されることで、misskey.js内の処理で不具合が発生するとともに、パフォーマンス上の問題にも繋がる。なお、Composition APIを使う場合はこの限りではない(リアクティブ化はマニュアルなため)。
|
**Vueのコンポーネントのdataオプションとして**misskey.jsのコネクションを設定するとき、必ず`markRaw`でラップしてください。インスタンスが不必要にリアクティブ化されることで、misskey.js内の処理で不具合が発生するとともに、パフォーマンス上の問題にも繋がる。なお、Composition APIを使う場合はこの限りではない(リアクティブ化はマニュアルなため)。
|
||||||
|
|
||||||
|
|
@ -597,44 +455,3 @@ marginはそのコンポーネントを使う側が設定する
|
||||||
|
|
||||||
### indexというファイル名を使うな
|
### indexというファイル名を使うな
|
||||||
ESMではディレクトリインポートは廃止されているのと、ディレクトリインポートせずともファイル名が index だと何故か一部のライブラリ?でディレクトリインポートだと見做されてエラーになる
|
ESMではディレクトリインポートは廃止されているのと、ディレクトリインポートせずともファイル名が index だと何故か一部のライブラリ?でディレクトリインポートだと見做されてエラーになる
|
||||||
|
|
||||||
## CSS Recipe
|
|
||||||
|
|
||||||
### Lighten CSS vars
|
|
||||||
|
|
||||||
``` css
|
|
||||||
color: hsl(from var(--MI_THEME-accent) h s calc(l + 10));
|
|
||||||
```
|
|
||||||
|
|
||||||
### Darken CSS vars
|
|
||||||
|
|
||||||
``` css
|
|
||||||
color: hsl(from var(--MI_THEME-accent) h s calc(l - 10));
|
|
||||||
```
|
|
||||||
|
|
||||||
### Add alpha to CSS vars
|
|
||||||
|
|
||||||
``` css
|
|
||||||
color: color(from var(--MI_THEME-accent) srgb r g b / 0.5);
|
|
||||||
```
|
|
||||||
|
|
||||||
## 考え方
|
|
||||||
### DRYに囚われるな
|
|
||||||
必要なのは一般化ではなく抽象化と考えます。
|
|
||||||
盲信せず、誤った・不必要な共通化は避け、それが自然だと感じる場合は重複させる勇気を持ちましょう。
|
|
||||||
|
|
||||||
### Misskeyを複雑にしない実装
|
|
||||||
それがいくら複雑であっても、Misskey固有のコンテキストと関心が分離されている(もしくは事実上分離されていると見做すことができる)実装であれば、それはMisskeyのコードベースに対する複雑性に影響を与えないと考えます。
|
|
||||||
|
|
||||||
例えるなら、VueやAiScriptといったMisskeyが使用しているライブラリの内部実装がいくら複雑だったとしても、「それを使用しているからMisskeyの実装は複雑である」ということにはならないのと同じです。
|
|
||||||
|
|
||||||
Misskeyのドメイン知識から関心が分離されているということは、Misskeyの実装について考える時にそれらの内部実装を考慮する必要が無く、認知負荷を増やさないからです。
|
|
||||||
|
|
||||||
また重要な点は、その実装が、Misskeyリポジトリの外部にあるか・内部にあるかということや、Misskeyがメンテナンスするものか・第三者がメンテナンスするものかといったことは複雑性を考える上ではほとんど無視できるという点です。
|
|
||||||
|
|
||||||
もちろんその実装がMisskeyリポジトリにあり、Misskeyがメンテナンスしなければならないものは、保守のコストはかかります。
|
|
||||||
しかし、Misskeyの本質的な設計・実装という観点で見たときは、その実装は実質的に外部ライブラリのように振る舞います。
|
|
||||||
換言すれば「たまたまMisskeyの開発者と同じ人たちがメンテナンスしているし、たまたまMisskeyのリポジトリ内に置いてあるだけの外部ライブラリ」です。
|
|
||||||
|
|
||||||
そのため、実装をなるべくMisskeyのドメイン知識から独立したものにすれば、Misskeyのコードベースの複雑性を上げることなく機能実装を行うことができ、お得であると言えます。
|
|
||||||
もちろんそれにこだわって、些細な実装でもそのように分離してしまうとかえって認知負荷が増えたり、実装量が増えてメリットをデメリットが上回る場合もあるので、ケースバイケースではあります。
|
|
||||||
|
|
|
||||||
2
COPYING
2
COPYING
|
|
@ -1,5 +1,5 @@
|
||||||
Unless otherwise stated this repository is
|
Unless otherwise stated this repository is
|
||||||
Copyright © 2014-2026 syuilo and contributors
|
Copyright © 2014-2024 syuilo and contributors
|
||||||
|
|
||||||
And is distributed under The GNU Affero General Public License Version 3, you should have received a copy of the license file as LICENSE.
|
And is distributed under The GNU Affero General Public License Version 3, you should have received a copy of the license file as LICENSE.
|
||||||
|
|
||||||
|
|
|
||||||
26
Dockerfile
26
Dockerfile
|
|
@ -1,6 +1,6 @@
|
||||||
# syntax = docker/dockerfile:1.20
|
# syntax = docker/dockerfile:1.4
|
||||||
|
|
||||||
ARG NODE_VERSION=22.21.1-bookworm
|
ARG NODE_VERSION=20.10.0-bullseye
|
||||||
|
|
||||||
# build assets & compile TypeScript
|
# build assets & compile TypeScript
|
||||||
|
|
||||||
|
|
@ -14,18 +14,14 @@ RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
|
||||||
&& apt-get install -yqq --no-install-recommends \
|
&& apt-get install -yqq --no-install-recommends \
|
||||||
build-essential
|
build-essential
|
||||||
|
|
||||||
|
RUN corepack enable
|
||||||
|
|
||||||
WORKDIR /misskey
|
WORKDIR /misskey
|
||||||
|
|
||||||
COPY --link ["pnpm-lock.yaml", "pnpm-workspace.yaml", "package.json", "./"]
|
COPY --link ["pnpm-lock.yaml", "pnpm-workspace.yaml", "package.json", "./"]
|
||||||
COPY --link ["scripts", "./scripts"]
|
COPY --link ["scripts", "./scripts"]
|
||||||
COPY --link ["patches", "./patches"]
|
|
||||||
COPY --link ["packages/backend/package.json", "./packages/backend/"]
|
COPY --link ["packages/backend/package.json", "./packages/backend/"]
|
||||||
COPY --link ["packages/frontend-shared/package.json", "./packages/frontend-shared/"]
|
|
||||||
COPY --link ["packages/frontend/package.json", "./packages/frontend/"]
|
COPY --link ["packages/frontend/package.json", "./packages/frontend/"]
|
||||||
COPY --link ["packages/frontend-embed/package.json", "./packages/frontend-embed/"]
|
|
||||||
COPY --link ["packages/frontend-builder/package.json", "./packages/frontend-builder/"]
|
|
||||||
COPY --link ["packages/i18n/package.json", "./packages/i18n/"]
|
|
||||||
COPY --link ["packages/icons-subsetter/package.json", "./packages/icons-subsetter/"]
|
|
||||||
COPY --link ["packages/sw/package.json", "./packages/sw/"]
|
COPY --link ["packages/sw/package.json", "./packages/sw/"]
|
||||||
COPY --link ["packages/misskey-js/package.json", "./packages/misskey-js/"]
|
COPY --link ["packages/misskey-js/package.json", "./packages/misskey-js/"]
|
||||||
COPY --link ["packages/misskey-reversi/package.json", "./packages/misskey-reversi/"]
|
COPY --link ["packages/misskey-reversi/package.json", "./packages/misskey-reversi/"]
|
||||||
|
|
@ -33,8 +29,6 @@ COPY --link ["packages/misskey-bubble-game/package.json", "./packages/misskey-bu
|
||||||
|
|
||||||
ARG NODE_ENV=production
|
ARG NODE_ENV=production
|
||||||
|
|
||||||
RUN node -e "console.log(JSON.parse(require('node:fs').readFileSync('./package.json')).packageManager)" | xargs npm install -g
|
|
||||||
|
|
||||||
RUN --mount=type=cache,target=/root/.local/share/pnpm/store,sharing=locked \
|
RUN --mount=type=cache,target=/root/.local/share/pnpm/store,sharing=locked \
|
||||||
pnpm i --frozen-lockfile --aggregate-output
|
pnpm i --frozen-lockfile --aggregate-output
|
||||||
|
|
||||||
|
|
@ -52,11 +46,12 @@ RUN apt-get update \
|
||||||
&& apt-get install -yqq --no-install-recommends \
|
&& apt-get install -yqq --no-install-recommends \
|
||||||
build-essential
|
build-essential
|
||||||
|
|
||||||
|
RUN corepack enable
|
||||||
|
|
||||||
WORKDIR /misskey
|
WORKDIR /misskey
|
||||||
|
|
||||||
COPY --link ["pnpm-lock.yaml", "pnpm-workspace.yaml", "package.json", "./"]
|
COPY --link ["pnpm-lock.yaml", "pnpm-workspace.yaml", "package.json", "./"]
|
||||||
COPY --link ["scripts", "./scripts"]
|
COPY --link ["scripts", "./scripts"]
|
||||||
COPY --link ["patches", "./patches"]
|
|
||||||
COPY --link ["packages/backend/package.json", "./packages/backend/"]
|
COPY --link ["packages/backend/package.json", "./packages/backend/"]
|
||||||
COPY --link ["packages/misskey-js/package.json", "./packages/misskey-js/"]
|
COPY --link ["packages/misskey-js/package.json", "./packages/misskey-js/"]
|
||||||
COPY --link ["packages/misskey-reversi/package.json", "./packages/misskey-reversi/"]
|
COPY --link ["packages/misskey-reversi/package.json", "./packages/misskey-reversi/"]
|
||||||
|
|
@ -64,8 +59,6 @@ COPY --link ["packages/misskey-bubble-game/package.json", "./packages/misskey-bu
|
||||||
|
|
||||||
ARG NODE_ENV=production
|
ARG NODE_ENV=production
|
||||||
|
|
||||||
RUN node -e "console.log(JSON.parse(require('node:fs').readFileSync('./package.json')).packageManager)" | xargs npm install -g
|
|
||||||
|
|
||||||
RUN --mount=type=cache,target=/root/.local/share/pnpm/store,sharing=locked \
|
RUN --mount=type=cache,target=/root/.local/share/pnpm/store,sharing=locked \
|
||||||
pnpm i --frozen-lockfile --aggregate-output
|
pnpm i --frozen-lockfile --aggregate-output
|
||||||
|
|
||||||
|
|
@ -78,6 +71,7 @@ RUN apt-get update \
|
||||||
&& apt-get install -y --no-install-recommends \
|
&& apt-get install -y --no-install-recommends \
|
||||||
ffmpeg tini curl libjemalloc-dev libjemalloc2 \
|
ffmpeg tini curl libjemalloc-dev libjemalloc2 \
|
||||||
&& ln -s /usr/lib/$(uname -m)-linux-gnu/libjemalloc.so.2 /usr/local/lib/libjemalloc.so \
|
&& ln -s /usr/lib/$(uname -m)-linux-gnu/libjemalloc.so.2 /usr/local/lib/libjemalloc.so \
|
||||||
|
&& corepack enable \
|
||||||
&& groupadd -g "${GID}" misskey \
|
&& groupadd -g "${GID}" misskey \
|
||||||
&& useradd -l -u "${UID}" -g "${GID}" -m -d /misskey misskey \
|
&& useradd -l -u "${UID}" -g "${GID}" -m -d /misskey misskey \
|
||||||
&& find / -type d -path /sys -prune -o -type d -path /proc -prune -o -type f -perm /u+s -ignore_readdir_race -exec chmod u-s {} \; \
|
&& find / -type d -path /sys -prune -o -type d -path /proc -prune -o -type f -perm /u+s -ignore_readdir_race -exec chmod u-s {} \; \
|
||||||
|
|
@ -85,10 +79,6 @@ RUN apt-get update \
|
||||||
&& apt-get clean \
|
&& apt-get clean \
|
||||||
&& rm -rf /var/lib/apt/lists
|
&& rm -rf /var/lib/apt/lists
|
||||||
|
|
||||||
# add package.json to add pnpm
|
|
||||||
COPY ./package.json ./package.json
|
|
||||||
RUN node -e "console.log(JSON.parse(require('node:fs').readFileSync('./package.json')).packageManager)" | xargs npm install -g
|
|
||||||
|
|
||||||
USER misskey
|
USER misskey
|
||||||
WORKDIR /misskey
|
WORKDIR /misskey
|
||||||
|
|
||||||
|
|
@ -102,8 +92,6 @@ COPY --chown=misskey:misskey --from=native-builder /misskey/packages/misskey-js/
|
||||||
COPY --chown=misskey:misskey --from=native-builder /misskey/packages/misskey-reversi/built ./packages/misskey-reversi/built
|
COPY --chown=misskey:misskey --from=native-builder /misskey/packages/misskey-reversi/built ./packages/misskey-reversi/built
|
||||||
COPY --chown=misskey:misskey --from=native-builder /misskey/packages/misskey-bubble-game/built ./packages/misskey-bubble-game/built
|
COPY --chown=misskey:misskey --from=native-builder /misskey/packages/misskey-bubble-game/built ./packages/misskey-bubble-game/built
|
||||||
COPY --chown=misskey:misskey --from=native-builder /misskey/packages/backend/built ./packages/backend/built
|
COPY --chown=misskey:misskey --from=native-builder /misskey/packages/backend/built ./packages/backend/built
|
||||||
COPY --chown=misskey:misskey --from=native-builder /misskey/packages/backend/src-js ./packages/backend/src-js
|
|
||||||
COPY --chown=misskey:misskey --from=native-builder /misskey/packages/i18n/built ./packages/i18n/built
|
|
||||||
COPY --chown=misskey:misskey --from=native-builder /misskey/fluent-emojis /misskey/fluent-emojis
|
COPY --chown=misskey:misskey --from=native-builder /misskey/fluent-emojis /misskey/fluent-emojis
|
||||||
COPY --chown=misskey:misskey . ./
|
COPY --chown=misskey:misskey . ./
|
||||||
|
|
||||||
|
|
|
||||||
18
README.md
18
README.md
|
|
@ -24,18 +24,10 @@
|
||||||
<a href="https://www.patreon.com/syuilo">
|
<a href="https://www.patreon.com/syuilo">
|
||||||
<img src="https://custom-icon-badges.herokuapp.com/badge/become_a-patron-F96854?logoColor=F96854&style=for-the-badge&logo=patreon&labelColor=363B40" alt="become a patron"/></a>
|
<img src="https://custom-icon-badges.herokuapp.com/badge/become_a-patron-F96854?logoColor=F96854&style=for-the-badge&logo=patreon&labelColor=363B40" alt="become a patron"/></a>
|
||||||
|
|
||||||
[](https://deepwiki.com/misskey-dev/misskey)
|
|
||||||
|
|
||||||
<a href="https://flatt.tech/oss/gmo/trampoline" target="_blank"><img src="https://flatt.tech/assets/images/badges/gmo-oss.svg" height="24px"/></a>
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
## Thanks
|
## Thanks
|
||||||
|
|
||||||
<a href="https://sentry.io/"><img src="https://github.com/misskey-dev/misskey/assets/4439005/98576556-222f-467a-94be-e98dbda1d852" height="30" alt="Sentry" /></a>
|
|
||||||
|
|
||||||
Thanks to [Sentry](https://sentry.io/) for providing the error tracking platform that helps us catch unexpected errors.
|
|
||||||
|
|
||||||
<a href="https://www.chromatic.com/"><img src="https://user-images.githubusercontent.com/321738/84662277-e3db4f80-af1b-11ea-88f5-91d67a5e59f6.png" height="30" alt="Chromatic" /></a>
|
<a href="https://www.chromatic.com/"><img src="https://user-images.githubusercontent.com/321738/84662277-e3db4f80-af1b-11ea-88f5-91d67a5e59f6.png" height="30" alt="Chromatic" /></a>
|
||||||
|
|
||||||
Thanks to [Chromatic](https://www.chromatic.com/) for providing the visual testing platform that helps us review UI changes and catch visual regressions.
|
Thanks to [Chromatic](https://www.chromatic.com/) for providing the visual testing platform that helps us review UI changes and catch visual regressions.
|
||||||
|
|
@ -51,13 +43,3 @@ Thanks to [Crowdin](https://crowdin.com/) for providing the localization platfor
|
||||||
<a href="https://hub.docker.com/"><img src="https://user-images.githubusercontent.com/20679825/230148221-f8e73a32-a49b-47c3-9029-9a15c3824f92.png" height="30" alt="Docker" /></a>
|
<a href="https://hub.docker.com/"><img src="https://user-images.githubusercontent.com/20679825/230148221-f8e73a32-a49b-47c3-9029-9a15c3824f92.png" height="30" alt="Docker" /></a>
|
||||||
|
|
||||||
Thanks to [Docker](https://hub.docker.com/) for providing the container platform that helps us run Misskey in production.
|
Thanks to [Docker](https://hub.docker.com/) for providing the container platform that helps us run Misskey in production.
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
<div align="center">
|
|
||||||
|
|
||||||
Support us with a ⭐ !
|
|
||||||
|
|
||||||
[](https://star-history.com/#misskey-dev/misskey&Date)
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ Also, the later tasks are more indefinite and are subject to change as developme
|
||||||
This is the phase we are at now. We need to make a high-maintenance environment that can withstand future development.
|
This is the phase we are at now. We need to make a high-maintenance environment that can withstand future development.
|
||||||
|
|
||||||
- ~~Make the number of type errors zero (backend)~~ → Done ✔️
|
- ~~Make the number of type errors zero (backend)~~ → Done ✔️
|
||||||
- ~~Make the number of type errors zero (frontend)~~ → Done ✔️
|
- Make the number of type errors zero (frontend)
|
||||||
- Improve CI
|
- Improve CI
|
||||||
- ~~Fix tests~~ → Done ✔️
|
- ~~Fix tests~~ → Done ✔️
|
||||||
- Fix random test failures - https://github.com/misskey-dev/misskey/issues/7985 and https://github.com/misskey-dev/misskey/issues/7986
|
- Fix random test failures - https://github.com/misskey-dev/misskey/issues/7985 and https://github.com/misskey-dev/misskey/issues/7986
|
||||||
|
|
|
||||||
12
SECURITY.md
12
SECURITY.md
|
|
@ -6,15 +6,3 @@ This will allow us to assess the risk, and make a fix available before we add a
|
||||||
bug report to the GitHub repository.
|
bug report to the GitHub repository.
|
||||||
|
|
||||||
Thanks for helping make Misskey safe for everyone.
|
Thanks for helping make Misskey safe for everyone.
|
||||||
|
|
||||||
> [!note]
|
|
||||||
> CNA [requires](https://www.cve.org/ResourcesSupport/AllResources/CNARules#section_5-2_Description) that CVEs include a description in English for inclusion in the CVE Catalog.
|
|
||||||
>
|
|
||||||
> When creating a security advisory, all content must be written in English (it is acceptable to include a non-English description along with the English one).
|
|
||||||
|
|
||||||
## When create a patch
|
|
||||||
|
|
||||||
If you can also create a patch to fix the vulnerability, please create a PR on the private fork.
|
|
||||||
|
|
||||||
> [!note]
|
|
||||||
> There is a GitHub bug that prevents merging if a PR not following the develop branch of upstream, so please keep follow the develop branch.
|
|
||||||
|
|
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 94 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 317 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 24 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 95 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 238 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 148 KiB |
Binary file not shown.
|
|
@ -124,14 +124,6 @@ redis:
|
||||||
# #prefix: example-prefix
|
# #prefix: example-prefix
|
||||||
# #db: 1
|
# #db: 1
|
||||||
|
|
||||||
#redisForReactions:
|
|
||||||
# host: redis
|
|
||||||
# port: 6379
|
|
||||||
# #family: 0 # 0=Both, 4=IPv4, 6=IPv6
|
|
||||||
# #pass: example-pass
|
|
||||||
# #prefix: example-prefix
|
|
||||||
# #db: 1
|
|
||||||
|
|
||||||
# ┌───────────────────────────┐
|
# ┌───────────────────────────┐
|
||||||
#───┘ MeiliSearch configuration └─────────────────────────────
|
#───┘ MeiliSearch configuration └─────────────────────────────
|
||||||
|
|
||||||
|
|
@ -160,27 +152,6 @@ redis:
|
||||||
# ID SETTINGS AFTER THAT!
|
# ID SETTINGS AFTER THAT!
|
||||||
|
|
||||||
id: "aidx"
|
id: "aidx"
|
||||||
|
|
||||||
# ┌────────────────┐
|
|
||||||
#───┘ Error tracking └──────────────────────────────────────────
|
|
||||||
|
|
||||||
# Sentry is available for error tracking.
|
|
||||||
# See the Sentry documentation for more details on options.
|
|
||||||
|
|
||||||
#sentryForBackend:
|
|
||||||
# enableNodeProfiling: true
|
|
||||||
# options:
|
|
||||||
# dsn: 'https://examplePublicKey@o0.ingest.sentry.io/0'
|
|
||||||
|
|
||||||
#sentryForFrontend:
|
|
||||||
# vueIntegration:
|
|
||||||
# tracingOptions:
|
|
||||||
# trackComponents: true
|
|
||||||
# browserTracingIntegration:
|
|
||||||
# replayIntegration:
|
|
||||||
# options:
|
|
||||||
# dsn: 'https://examplePublicKey@o0.ingest.sentry.io/0'
|
|
||||||
|
|
||||||
# ┌─────────────────────┐
|
# ┌─────────────────────┐
|
||||||
#───┘ Other configuration └─────────────────────────────────────
|
#───┘ Other configuration └─────────────────────────────────────
|
||||||
|
|
||||||
|
|
@ -221,6 +192,9 @@ id: "aidx"
|
||||||
# Media Proxy
|
# Media Proxy
|
||||||
#mediaProxy: https://example.com/proxy
|
#mediaProxy: https://example.com/proxy
|
||||||
|
|
||||||
|
# Sign to ActivityPub GET request (default: true)
|
||||||
|
signToActivityPubGet: true
|
||||||
|
|
||||||
#allowedPrivateNetworks: [
|
#allowedPrivateNetworks: [
|
||||||
# '127.0.0.1/32'
|
# '127.0.0.1/32'
|
||||||
#]
|
#]
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@ spec:
|
||||||
ports:
|
ports:
|
||||||
- containerPort: 3000
|
- containerPort: 3000
|
||||||
- name: postgres
|
- name: postgres
|
||||||
image: postgres:18-alpine
|
image: postgres:15-alpine
|
||||||
env:
|
env:
|
||||||
- name: POSTGRES_USER
|
- name: POSTGRES_USER
|
||||||
value: "example-misskey-user"
|
value: "example-misskey-user"
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,11 @@ import { defineConfig } from 'cypress'
|
||||||
|
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
e2e: {
|
e2e: {
|
||||||
|
// We've imported your old cypress plugins here.
|
||||||
|
// You may want to clean this up later by importing these.
|
||||||
|
setupNodeEvents(on, config) {
|
||||||
|
return require('./cypress/plugins/index.js')(on, config)
|
||||||
|
},
|
||||||
baseUrl: 'http://localhost:61812',
|
baseUrl: 'http://localhost:61812',
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,3 @@
|
||||||
/*
|
|
||||||
* SPDX-FileCopyrightText: syuilo and misskey-project
|
|
||||||
* SPDX-License-Identifier: AGPL-3.0-only
|
|
||||||
*/
|
|
||||||
|
|
||||||
describe('Before setup instance', () => {
|
describe('Before setup instance', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
cy.resetState();
|
cy.resetState();
|
||||||
|
|
@ -23,7 +18,6 @@ describe('Before setup instance', () => {
|
||||||
|
|
||||||
cy.intercept('POST', '/api/admin/accounts/create').as('signup');
|
cy.intercept('POST', '/api/admin/accounts/create').as('signup');
|
||||||
|
|
||||||
cy.get('[data-cy-admin-initial-password] input').type('example_password_please_change_this_or_you_will_get_hacked');
|
|
||||||
cy.get('[data-cy-admin-username] input').type('admin');
|
cy.get('[data-cy-admin-username] input').type('admin');
|
||||||
cy.get('[data-cy-admin-password] input').type('admin1234');
|
cy.get('[data-cy-admin-password] input').type('admin1234');
|
||||||
cy.get('[data-cy-admin-ok]').click();
|
cy.get('[data-cy-admin-ok]').click();
|
||||||
|
|
@ -31,14 +25,6 @@ describe('Before setup instance', () => {
|
||||||
// なぜか動かない
|
// なぜか動かない
|
||||||
//cy.wait('@signup').should('have.property', 'response.statusCode');
|
//cy.wait('@signup').should('have.property', 'response.statusCode');
|
||||||
cy.wait('@signup');
|
cy.wait('@signup');
|
||||||
|
|
||||||
cy.intercept('POST', '/api/admin/update-meta').as('update-meta');
|
|
||||||
|
|
||||||
cy.get('[data-cy-next]').click();
|
|
||||||
cy.get('[data-cy-server-name] input').type('Testskey');
|
|
||||||
cy.get('[data-cy-server-setup-wizard-apply]').click();
|
|
||||||
|
|
||||||
cy.wait('@update-meta');
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -78,8 +64,6 @@ describe('After setup instance', () => {
|
||||||
cy.get('[data-cy-signup-password] input').type('alice1234');
|
cy.get('[data-cy-signup-password] input').type('alice1234');
|
||||||
cy.get('[data-cy-signup-submit]').should('be.disabled');
|
cy.get('[data-cy-signup-submit]').should('be.disabled');
|
||||||
cy.get('[data-cy-signup-password-retype] input').type('alice1234');
|
cy.get('[data-cy-signup-password-retype] input').type('alice1234');
|
||||||
cy.get('[data-cy-signup-submit]').should('be.disabled');
|
|
||||||
cy.get('[data-cy-signup-invitation-code] input').type('test-invitation-code');
|
|
||||||
cy.get('[data-cy-signup-submit]').should('not.be.disabled');
|
cy.get('[data-cy-signup-submit]').should('not.be.disabled');
|
||||||
cy.get('[data-cy-signup-submit]').click();
|
cy.get('[data-cy-signup-submit]').click();
|
||||||
|
|
||||||
|
|
@ -130,16 +114,11 @@ describe('After user signup', () => {
|
||||||
it('signin', () => {
|
it('signin', () => {
|
||||||
cy.visitHome();
|
cy.visitHome();
|
||||||
|
|
||||||
cy.intercept('POST', '/api/signin-flow').as('signin');
|
cy.intercept('POST', '/api/signin').as('signin');
|
||||||
|
|
||||||
cy.get('[data-cy-signin]').click();
|
cy.get('[data-cy-signin]').click();
|
||||||
|
cy.get('[data-cy-signin-username] input').type('alice');
|
||||||
cy.get('[data-cy-signin-page-input]').should('be.visible', { timeout: 1000 });
|
// Enterキーでサインインできるかの確認も兼ねる
|
||||||
// Enterキーで続行できるかの確認も兼ねる
|
|
||||||
cy.get('[data-cy-signin-username] input').type('alice{enter}');
|
|
||||||
|
|
||||||
cy.get('[data-cy-signin-page-password]').should('be.visible', { timeout: 10000 });
|
|
||||||
// Enterキーで続行できるかの確認も兼ねる
|
|
||||||
cy.get('[data-cy-signin-password] input').type('alice1234{enter}');
|
cy.get('[data-cy-signin-password] input').type('alice1234{enter}');
|
||||||
|
|
||||||
cy.wait('@signin');
|
cy.wait('@signin');
|
||||||
|
|
@ -154,9 +133,8 @@ describe('After user signup', () => {
|
||||||
cy.visitHome();
|
cy.visitHome();
|
||||||
|
|
||||||
cy.get('[data-cy-signin]').click();
|
cy.get('[data-cy-signin]').click();
|
||||||
|
cy.get('[data-cy-signin-username] input').type('alice');
|
||||||
cy.get('[data-cy-signin-page-input]').should('be.visible', { timeout: 1000 });
|
cy.get('[data-cy-signin-password] input').type('alice1234{enter}');
|
||||||
cy.get('[data-cy-signin-username] input').type('alice{enter}');
|
|
||||||
|
|
||||||
// TODO: cypressにブラウザの言語指定できる機能が実装され次第英語のみテストするようにする
|
// TODO: cypressにブラウザの言語指定できる機能が実装され次第英語のみテストするようにする
|
||||||
cy.contains(/アカウントが凍結されています|This account has been suspended due to/gi);
|
cy.contains(/アカウントが凍結されています|This account has been suspended due to/gi);
|
||||||
|
|
@ -243,7 +221,7 @@ describe('After user setup', () => {
|
||||||
cy.get('[data-cy-post-form-text]').type('Hello, Misskey!');
|
cy.get('[data-cy-post-form-text]').type('Hello, Misskey!');
|
||||||
cy.get('[data-cy-open-post-form-submit]').click();
|
cy.get('[data-cy-open-post-form-submit]').click();
|
||||||
|
|
||||||
cy.contains('Hello, Misskey!', { timeout: 15000 });
|
cy.contains('Hello, Misskey!');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('open note form with hotkey', () => {
|
it('open note form with hotkey', () => {
|
||||||
|
|
@ -1,8 +1,3 @@
|
||||||
/*
|
|
||||||
* SPDX-FileCopyrightText: syuilo and misskey-project
|
|
||||||
* SPDX-License-Identifier: AGPL-3.0-only
|
|
||||||
*/
|
|
||||||
|
|
||||||
describe('Router transition', () => {
|
describe('Router transition', () => {
|
||||||
describe('Redirect', () => {
|
describe('Redirect', () => {
|
||||||
// サーバの初期化。ルートのテストに関しては各describeごとに1度だけ実行で十分だと思う(使いまわした方が早い)
|
// サーバの初期化。ルートのテストに関しては各describeごとに1度だけ実行で十分だと思う(使いまわした方が早い)
|
||||||
|
|
@ -1,8 +1,3 @@
|
||||||
/*
|
|
||||||
* SPDX-FileCopyrightText: syuilo and misskey-project
|
|
||||||
* SPDX-License-Identifier: AGPL-3.0-only
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* flaky
|
/* flaky
|
||||||
describe('After user signed in', () => {
|
describe('After user signed in', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
/// <reference types="cypress" />
|
||||||
|
// ***********************************************************
|
||||||
|
// This example plugins/index.js can be used to load plugins
|
||||||
|
//
|
||||||
|
// You can change the location of this file or turn off loading
|
||||||
|
// the plugins file with the 'pluginsFile' configuration option.
|
||||||
|
//
|
||||||
|
// You can read more here:
|
||||||
|
// https://on.cypress.io/plugins-guide
|
||||||
|
// ***********************************************************
|
||||||
|
|
||||||
|
// This function is called when a project is opened or re-opened (e.g. due to
|
||||||
|
// the project's config changing)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @type {Cypress.PluginConfig}
|
||||||
|
*/
|
||||||
|
// eslint-disable-next-line no-unused-vars
|
||||||
|
module.exports = (on, config) => {
|
||||||
|
// `on` is used to hook into various events Cypress emits
|
||||||
|
// `config` is the resolved Cypress config
|
||||||
|
}
|
||||||
|
|
@ -30,13 +30,9 @@ Cypress.Commands.add('visitHome', () => {
|
||||||
})
|
})
|
||||||
|
|
||||||
Cypress.Commands.add('resetState', () => {
|
Cypress.Commands.add('resetState', () => {
|
||||||
// iframe.contentWindow.indexedDB.deleteDatabase() がchromeのバグで使用できないため、indexedDBを無効化している。
|
cy.window(win => {
|
||||||
// see https://github.com/misskey-dev/misskey/issues/13605#issuecomment-2053652123
|
|
||||||
/*
|
|
||||||
cy.window().then(win => {
|
|
||||||
win.indexedDB.deleteDatabase('keyval-store');
|
win.indexedDB.deleteDatabase('keyval-store');
|
||||||
});
|
});
|
||||||
*/
|
|
||||||
cy.request('POST', '/api/reset-db', {}).as('reset');
|
cy.request('POST', '/api/reset-db', {}).as('reset');
|
||||||
cy.get('@reset').its('status').should('equal', 204);
|
cy.get('@reset').its('status').should('equal', 204);
|
||||||
cy.reload(true);
|
cy.reload(true);
|
||||||
|
|
@ -48,19 +44,16 @@ Cypress.Commands.add('registerUser', (username, password, isAdmin = false) => {
|
||||||
cy.request('POST', route, {
|
cy.request('POST', route, {
|
||||||
username: username,
|
username: username,
|
||||||
password: password,
|
password: password,
|
||||||
...(isAdmin ? { setupPassword: 'example_password_please_change_this_or_you_will_get_hacked' } : {}),
|
|
||||||
}).its('body').as(username);
|
}).its('body').as(username);
|
||||||
});
|
});
|
||||||
|
|
||||||
Cypress.Commands.add('login', (username, password) => {
|
Cypress.Commands.add('login', (username, password) => {
|
||||||
cy.visitHome();
|
cy.visitHome();
|
||||||
|
|
||||||
cy.intercept('POST', '/api/signin-flow').as('signin');
|
cy.intercept('POST', '/api/signin').as('signin');
|
||||||
|
|
||||||
cy.get('[data-cy-signin]').click();
|
cy.get('[data-cy-signin]').click();
|
||||||
cy.get('[data-cy-signin-page-input]').should('be.visible', { timeout: 1000 });
|
cy.get('[data-cy-signin-username] input').type(username);
|
||||||
cy.get('[data-cy-signin-username] input').type(`${username}{enter}`);
|
|
||||||
cy.get('[data-cy-signin-page-password]').should('be.visible', { timeout: 10000 });
|
|
||||||
cy.get('[data-cy-signin-password] input').type(`${password}{enter}`);
|
cy.get('[data-cy-signin-password] input').type(`${password}{enter}`);
|
||||||
|
|
||||||
cy.wait('@signin').as('signedIn');
|
cy.wait('@signin').as('signedIn');
|
||||||
|
|
@ -1,19 +0,0 @@
|
||||||
declare global {
|
|
||||||
namespace Cypress {
|
|
||||||
interface Chainable {
|
|
||||||
login(username: string, password: string): Chainable<void>;
|
|
||||||
|
|
||||||
registerUser(
|
|
||||||
username: string,
|
|
||||||
password: string,
|
|
||||||
isAdmin?: boolean
|
|
||||||
): Chainable<void>;
|
|
||||||
|
|
||||||
resetState(): Chainable<void>;
|
|
||||||
|
|
||||||
visitHome(): Chainable<void>;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export {}
|
|
||||||
|
|
@ -1,8 +0,0 @@
|
||||||
{
|
|
||||||
"compilerOptions": {
|
|
||||||
"lib": ["dom", "es5"],
|
|
||||||
"target": "es5",
|
|
||||||
"types": ["cypress", "node"]
|
|
||||||
},
|
|
||||||
"include": ["./**/*.ts"]
|
|
||||||
}
|
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
version: "3"
|
||||||
|
|
||||||
# このconfigは、 dockerでMisskey本体を起動せず、 redisとpostgresql などだけを起動します
|
# このconfigは、 dockerでMisskey本体を起動せず、 redisとpostgresql などだけを起動します
|
||||||
|
|
||||||
services:
|
services:
|
||||||
|
|
@ -15,13 +17,13 @@ services:
|
||||||
|
|
||||||
db:
|
db:
|
||||||
restart: always
|
restart: always
|
||||||
image: postgres:18-alpine
|
image: postgres:15-alpine
|
||||||
ports:
|
ports:
|
||||||
- "5432:5432"
|
- "5432:5432"
|
||||||
env_file:
|
env_file:
|
||||||
- .config/docker.env
|
- .config/docker.env
|
||||||
volumes:
|
volumes:
|
||||||
- ./db:/var/lib/postgresql
|
- ./db:/var/lib/postgresql/data
|
||||||
healthcheck:
|
healthcheck:
|
||||||
test: "pg_isready -U $$POSTGRES_USER -d $$POSTGRES_DB"
|
test: "pg_isready -U $$POSTGRES_USER -d $$POSTGRES_DB"
|
||||||
interval: 5s
|
interval: 5s
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
version: "3"
|
||||||
|
|
||||||
services:
|
services:
|
||||||
web:
|
web:
|
||||||
build: .
|
build: .
|
||||||
|
|
@ -17,8 +19,6 @@ services:
|
||||||
networks:
|
networks:
|
||||||
- internal_network
|
- internal_network
|
||||||
- external_network
|
- external_network
|
||||||
# env_file:
|
|
||||||
# - .config/docker.env
|
|
||||||
volumes:
|
volumes:
|
||||||
- ./files:/misskey/files
|
- ./files:/misskey/files
|
||||||
- ./.config:/misskey/.config:ro
|
- ./.config:/misskey/.config:ro
|
||||||
|
|
@ -37,13 +37,13 @@ services:
|
||||||
|
|
||||||
db:
|
db:
|
||||||
restart: always
|
restart: always
|
||||||
image: postgres:18-alpine
|
image: postgres:15-alpine
|
||||||
networks:
|
networks:
|
||||||
- internal_network
|
- internal_network
|
||||||
env_file:
|
env_file:
|
||||||
- .config/docker.env
|
- .config/docker.env
|
||||||
volumes:
|
volumes:
|
||||||
- ./db:/var/lib/postgresql
|
- ./db:/var/lib/postgresql/data
|
||||||
healthcheck:
|
healthcheck:
|
||||||
test: "pg_isready -U $$POSTGRES_USER -d $$POSTGRES_DB"
|
test: "pg_isready -U $$POSTGRES_USER -d $$POSTGRES_DB"
|
||||||
interval: 5s
|
interval: 5s
|
||||||
|
|
@ -4,4 +4,4 @@
|
||||||
# SPDX-License-Identifier: AGPL-3.0-only
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
PORT=$(grep '^port:' /misskey/.config/default.yml | awk 'NR==1{print $2; exit}')
|
PORT=$(grep '^port:' /misskey/.config/default.yml | awk 'NR==1{print $2; exit}')
|
||||||
curl -Sfso/dev/null "http://localhost:${PORT}/healthz"
|
curl -s -S -o /dev/null "http://localhost:${PORT}"
|
||||||
|
|
|
||||||
|
|
@ -1,232 +0,0 @@
|
||||||
<!--
|
|
||||||
SPDX-FileCopyrightText: syuilo and misskey-project
|
|
||||||
SPDX-License-Identifier: AGPL-3.0-only
|
|
||||||
-->
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<canvas ref="canvasEl" style="display: block; width: 100%; height: 100%; pointer-events: none;"></canvas>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script lang="ts" setup>
|
|
||||||
import { onMounted, onUnmounted, useTemplateRef } from 'vue';
|
|
||||||
import isChromatic from 'chromatic/isChromatic';
|
|
||||||
import { initShaderProgram } from '@/utility/webgl.js';
|
|
||||||
|
|
||||||
const VERTEX_SHADER = `#version 300 es
|
|
||||||
in vec2 position;
|
|
||||||
out vec2 in_uv;
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
in_uv = (position + 1.0) / 2.0;
|
|
||||||
gl_Position = vec4(position, 0.0, 1.0);
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
|
|
||||||
const FRAGMENT_SHADER = `#version 300 es
|
|
||||||
precision mediump float;
|
|
||||||
|
|
||||||
const float PI = 3.141592653589793;
|
|
||||||
const float TWO_PI = 6.283185307179586;
|
|
||||||
const float HALF_PI = 1.5707963267948966;
|
|
||||||
|
|
||||||
in vec2 in_uv;
|
|
||||||
uniform vec2 in_resolution;
|
|
||||||
uniform float u_scale;
|
|
||||||
uniform float u_time;
|
|
||||||
uniform float u_seed;
|
|
||||||
uniform float u_angle;
|
|
||||||
uniform float u_radius;
|
|
||||||
uniform vec3 u_color;
|
|
||||||
uniform vec2 u_ripplePositions[16];
|
|
||||||
uniform float u_rippleRadiuses[16];
|
|
||||||
out vec4 out_color;
|
|
||||||
|
|
||||||
float getRipple(vec2 uv) {
|
|
||||||
float strength = 0.0;
|
|
||||||
float thickness = 0.05;
|
|
||||||
for (int i = 0; i < 16; i++) {
|
|
||||||
if (u_rippleRadiuses[i] <= 0.0) continue;
|
|
||||||
|
|
||||||
float d = distance(uv, u_ripplePositions[i]);
|
|
||||||
|
|
||||||
// フチ
|
|
||||||
if (d < u_rippleRadiuses[i] + thickness && d > u_rippleRadiuses[i] - thickness) {
|
|
||||||
float gradate = abs(d - u_rippleRadiuses[i] + thickness) / thickness;
|
|
||||||
strength += (1.0 - u_rippleRadiuses[i]) * gradate;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 内側
|
|
||||||
if (d < u_rippleRadiuses[i] + thickness) {
|
|
||||||
strength += 0.25 * (1.0 - u_rippleRadiuses[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return strength;
|
|
||||||
}
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
float x_ratio = min(in_resolution.x / in_resolution.y, 1.0);
|
|
||||||
float y_ratio = min(in_resolution.y / in_resolution.x, 1.0);
|
|
||||||
|
|
||||||
float angle = -(u_angle * PI);
|
|
||||||
vec2 centeredUv = (in_uv - vec2(0.5, 0.5)) * vec2(x_ratio, y_ratio);
|
|
||||||
vec2 rotatedUV = vec2(
|
|
||||||
centeredUv.x * cos(angle) - centeredUv.y * sin(angle),
|
|
||||||
centeredUv.x * sin(angle) + centeredUv.y * cos(angle)
|
|
||||||
);
|
|
||||||
vec2 uv = rotatedUV;
|
|
||||||
|
|
||||||
float time = u_time * 0.00025;
|
|
||||||
|
|
||||||
float size = 1.0 / u_scale;
|
|
||||||
float size_half = size / 2.0;
|
|
||||||
float modX = mod(uv.x, size);
|
|
||||||
float modY = mod(uv.y, size);
|
|
||||||
|
|
||||||
vec2 pixelated_uv = vec2(
|
|
||||||
(size * (floor((uv.x - 0.5 - size) / size) + 0.5)),
|
|
||||||
(size * (floor((uv.y - 0.5 - size) / size) + 0.5))
|
|
||||||
) + vec2(0.5 + size, 0.5 + size);
|
|
||||||
|
|
||||||
float strength = getRipple(pixelated_uv);
|
|
||||||
|
|
||||||
float opacity = min(max(strength, 0.0), 1.0);
|
|
||||||
|
|
||||||
float threshold = ((u_radius / 2.0) / u_scale);
|
|
||||||
if (length(vec2(modX - size_half, modY - size_half)) < threshold) {
|
|
||||||
out_color = vec4(u_color.r, u_color.g, u_color.b, opacity);
|
|
||||||
//out_color = vec4(1.0);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// debug
|
|
||||||
//float a = min(max(getRipple(uv), 0.0), 1.0);
|
|
||||||
//out_color = vec4(u_color.r, u_color.g, u_color.b, (opacity + a) / 2.0);
|
|
||||||
|
|
||||||
out_color = vec4(0.0, 0.0, 0.0, 0.0);
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
|
|
||||||
const canvasEl = useTemplateRef('canvasEl');
|
|
||||||
|
|
||||||
const props = withDefaults(defineProps<{
|
|
||||||
scale?: number;
|
|
||||||
}>(), {
|
|
||||||
scale: 48,
|
|
||||||
});
|
|
||||||
|
|
||||||
let handle: ReturnType<typeof window['requestAnimationFrame']> | null = null;
|
|
||||||
|
|
||||||
onMounted(() => {
|
|
||||||
const canvas = canvasEl.value!;
|
|
||||||
let width = canvas.offsetWidth;
|
|
||||||
let height = canvas.offsetHeight;
|
|
||||||
canvas.width = width;
|
|
||||||
canvas.height = height;
|
|
||||||
|
|
||||||
const maybeGl = canvas.getContext('webgl2', { preserveDrawingBuffer: false, alpha: true, premultipliedAlpha: false, antialias: true });
|
|
||||||
if (maybeGl == null) return;
|
|
||||||
|
|
||||||
const gl = maybeGl;
|
|
||||||
|
|
||||||
const VERTICES = new Float32Array([-1, -1, -1, 1, 1, 1, -1, -1, 1, 1, 1, -1]);
|
|
||||||
const vertexBuffer = gl.createBuffer();
|
|
||||||
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
|
|
||||||
gl.bufferData(gl.ARRAY_BUFFER, VERTICES, gl.STATIC_DRAW);
|
|
||||||
|
|
||||||
//gl.clearColor(0.0, 0.0, 0.0, 0.0);
|
|
||||||
//gl.clear(gl.COLOR_BUFFER_BIT);
|
|
||||||
|
|
||||||
const shaderProgram = initShaderProgram(gl, VERTEX_SHADER, FRAGMENT_SHADER);
|
|
||||||
|
|
||||||
gl.useProgram(shaderProgram);
|
|
||||||
|
|
||||||
const positionLocation = gl.getAttribLocation(shaderProgram, 'position');
|
|
||||||
gl.vertexAttribPointer(positionLocation, 2, gl.FLOAT, false, 0, 0);
|
|
||||||
gl.enableVertexAttribArray(positionLocation);
|
|
||||||
|
|
||||||
const in_resolution = gl.getUniformLocation(shaderProgram, 'in_resolution');
|
|
||||||
gl.uniform2fv(in_resolution, [canvas.width, canvas.height]);
|
|
||||||
|
|
||||||
const u_time = gl.getUniformLocation(shaderProgram, 'u_time');
|
|
||||||
const u_seed = gl.getUniformLocation(shaderProgram, 'u_seed');
|
|
||||||
const u_scale = gl.getUniformLocation(shaderProgram, 'u_scale');
|
|
||||||
const u_angle = gl.getUniformLocation(shaderProgram, 'u_angle');
|
|
||||||
const u_radius = gl.getUniformLocation(shaderProgram, 'u_radius');
|
|
||||||
const u_color = gl.getUniformLocation(shaderProgram, 'u_color');
|
|
||||||
gl.uniform1f(u_seed, Math.random() * 1000);
|
|
||||||
gl.uniform1f(u_scale, props.scale);
|
|
||||||
gl.uniform1f(u_angle, 0.0);
|
|
||||||
gl.uniform1f(u_radius, 0.15);
|
|
||||||
gl.uniform3fv(u_color, [0.5, 1.0, 0]);
|
|
||||||
|
|
||||||
if (isChromatic()) {
|
|
||||||
gl.uniform1f(u_time, 0);
|
|
||||||
gl.drawArrays(gl.TRIANGLES, 0, 6);
|
|
||||||
} else {
|
|
||||||
let ripples = [] as { position: [number, number]; startTime: number; }[];
|
|
||||||
const LIFE_TIME = 1000 * 4;
|
|
||||||
|
|
||||||
function render(timeStamp: number) {
|
|
||||||
let sizeChanged = false;
|
|
||||||
if (Math.abs(height - canvas.offsetHeight) > 2) {
|
|
||||||
height = canvas.offsetHeight;
|
|
||||||
canvas.height = height;
|
|
||||||
sizeChanged = true;
|
|
||||||
}
|
|
||||||
if (Math.abs(width - canvas.offsetWidth) > 2) {
|
|
||||||
width = canvas.offsetWidth;
|
|
||||||
canvas.width = width;
|
|
||||||
sizeChanged = true;
|
|
||||||
}
|
|
||||||
if (sizeChanged && gl) {
|
|
||||||
gl.uniform2fv(in_resolution, [width, height]);
|
|
||||||
gl.viewport(0, 0, width, height);
|
|
||||||
}
|
|
||||||
|
|
||||||
gl.uniform1f(u_time, timeStamp);
|
|
||||||
|
|
||||||
if (Math.random() < 0.01 && ripples.length < 16) {
|
|
||||||
ripples.push({ position: [(Math.random() * 2) - 1, (Math.random() * 2) - 1], startTime: timeStamp });
|
|
||||||
}
|
|
||||||
|
|
||||||
for (let i = 0; i < 16; i++) {
|
|
||||||
const o = gl.getUniformLocation(shaderProgram, `u_ripplePositions[${i.toString()}]`);
|
|
||||||
const r = gl.getUniformLocation(shaderProgram, `u_rippleRadiuses[${i.toString()}]`);
|
|
||||||
const ripple = ripples[i];
|
|
||||||
if (ripple == null) {
|
|
||||||
gl.uniform2f(o, 0, 0);
|
|
||||||
gl.uniform1f(r, 0.0);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
const delta = timeStamp - ripple.startTime;
|
|
||||||
|
|
||||||
gl.uniform2f(o, ripple.position[0], ripple.position[1]);
|
|
||||||
gl.uniform1f(r, delta / LIFE_TIME);
|
|
||||||
}
|
|
||||||
|
|
||||||
ripples = ripples.filter(r => (timeStamp - r.startTime) < LIFE_TIME);
|
|
||||||
if (ripples.length === 0) {
|
|
||||||
ripples.push({ position: [(Math.random() * 2) - 1, (Math.random() * 2) - 1], startTime: timeStamp });
|
|
||||||
}
|
|
||||||
|
|
||||||
gl.drawArrays(gl.TRIANGLES, 0, 6);
|
|
||||||
|
|
||||||
handle = window.requestAnimationFrame(render);
|
|
||||||
}
|
|
||||||
|
|
||||||
handle = window.requestAnimationFrame(render);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
onUnmounted(() => {
|
|
||||||
if (handle) {
|
|
||||||
window.cancelAnimationFrame(handle);
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: WebGLリソースの解放
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" module>
|
|
||||||
</style>
|
|
||||||
|
|
@ -1,190 +0,0 @@
|
||||||
<!--
|
|
||||||
SPDX-FileCopyrightText: syuilo and misskey-project
|
|
||||||
SPDX-License-Identifier: AGPL-3.0-only
|
|
||||||
-->
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<canvas ref="canvasEl" style="display: block; width: 100%; height: 100%; pointer-events: none;"></canvas>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script lang="ts" setup>
|
|
||||||
import { onMounted, onUnmounted, useTemplateRef } from 'vue';
|
|
||||||
import isChromatic from 'chromatic/isChromatic';
|
|
||||||
import { GLSL_LIB_SNOISE, initShaderProgram } from '@/utility/webgl.js';
|
|
||||||
|
|
||||||
const VERTEX_SHADER = `#version 300 es
|
|
||||||
in vec2 position;
|
|
||||||
out vec2 in_uv;
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
in_uv = (position + 1.0) / 2.0;
|
|
||||||
gl_Position = vec4(position, 0.0, 1.0);
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
|
|
||||||
const FRAGMENT_SHADER = `#version 300 es
|
|
||||||
precision mediump float;
|
|
||||||
|
|
||||||
const float PI = 3.141592653589793;
|
|
||||||
const float TWO_PI = 6.283185307179586;
|
|
||||||
const float HALF_PI = 1.5707963267948966;
|
|
||||||
|
|
||||||
${GLSL_LIB_SNOISE}
|
|
||||||
|
|
||||||
in vec2 in_uv;
|
|
||||||
uniform vec2 in_resolution;
|
|
||||||
uniform float u_scale;
|
|
||||||
uniform float u_time;
|
|
||||||
uniform float u_seed;
|
|
||||||
uniform float u_angle;
|
|
||||||
uniform float u_radius;
|
|
||||||
uniform vec3 u_color;
|
|
||||||
out vec4 out_color;
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
float x_ratio = min(in_resolution.x / in_resolution.y, 1.0);
|
|
||||||
float y_ratio = min(in_resolution.y / in_resolution.x, 1.0);
|
|
||||||
|
|
||||||
float size = 1.0 / u_scale;
|
|
||||||
float size_half = size / 2.0;
|
|
||||||
|
|
||||||
float angle = -(u_angle * PI);
|
|
||||||
vec2 centeredUv = (in_uv - vec2(0.5, 0.5)) * vec2(x_ratio, y_ratio);
|
|
||||||
vec2 rotatedUV = vec2(
|
|
||||||
centeredUv.x * cos(angle) - centeredUv.y * sin(angle),
|
|
||||||
centeredUv.x * sin(angle) + centeredUv.y * cos(angle)
|
|
||||||
);
|
|
||||||
vec2 uv = rotatedUV;
|
|
||||||
|
|
||||||
float modX = mod(uv.x, size);
|
|
||||||
float modY = mod(uv.y, size);
|
|
||||||
|
|
||||||
vec2 pixelated_uv = vec2(
|
|
||||||
(size * (floor((uv.x - 0.5 - size) / size) + 0.5)),
|
|
||||||
(size * (floor((uv.y - 0.5 - size) / size) + 0.5))
|
|
||||||
) + vec2(0.5 + size, 0.5 + size);
|
|
||||||
|
|
||||||
float time = u_time * 0.00025;
|
|
||||||
|
|
||||||
float noiseAScale = 1.0;
|
|
||||||
float noiseAX = (pixelated_uv.x + u_seed) * (u_scale / noiseAScale);
|
|
||||||
float noiseAY = (pixelated_uv.y + u_seed) * (u_scale / noiseAScale);
|
|
||||||
float noiseA = snoise(vec3(noiseAX, noiseAY, time * 2.0));
|
|
||||||
|
|
||||||
float noiseBScale = 32.0;
|
|
||||||
float noiseBX = (pixelated_uv.x + u_seed) * (u_scale / noiseBScale);
|
|
||||||
float noiseBY = (pixelated_uv.y + u_seed) * (u_scale / noiseBScale);
|
|
||||||
float noiseB = snoise(vec3(noiseBX, noiseBY, time));
|
|
||||||
|
|
||||||
float strength = 0.0;
|
|
||||||
strength += noiseA * 0.2;
|
|
||||||
strength += noiseB * 0.8;
|
|
||||||
|
|
||||||
float opacity = min(max(strength, 0.0), 1.0);
|
|
||||||
|
|
||||||
float threshold = ((u_radius / 2.0) / u_scale);
|
|
||||||
if (length(vec2(modX - size_half, modY - size_half)) < threshold) {
|
|
||||||
out_color = vec4(u_color.r, u_color.g, u_color.b, opacity);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
out_color = vec4(0.0, 0.0, 0.0, 0.0);
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
|
|
||||||
const canvasEl = useTemplateRef('canvasEl');
|
|
||||||
|
|
||||||
const props = withDefaults(defineProps<{
|
|
||||||
scale?: number;
|
|
||||||
}>(), {
|
|
||||||
scale: 48,
|
|
||||||
});
|
|
||||||
|
|
||||||
let handle: ReturnType<typeof window['requestAnimationFrame']> | null = null;
|
|
||||||
|
|
||||||
onMounted(() => {
|
|
||||||
const canvas = canvasEl.value!;
|
|
||||||
let width = canvas.offsetWidth;
|
|
||||||
let height = canvas.offsetHeight;
|
|
||||||
canvas.width = width;
|
|
||||||
canvas.height = height;
|
|
||||||
|
|
||||||
const maybeGl = canvas.getContext('webgl2', { preserveDrawingBuffer: false, alpha: true, premultipliedAlpha: false, antialias: true });
|
|
||||||
if (maybeGl == null) return;
|
|
||||||
|
|
||||||
const gl = maybeGl;
|
|
||||||
|
|
||||||
const VERTICES = new Float32Array([-1, -1, -1, 1, 1, 1, -1, -1, 1, 1, 1, -1]);
|
|
||||||
const vertexBuffer = gl.createBuffer();
|
|
||||||
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
|
|
||||||
gl.bufferData(gl.ARRAY_BUFFER, VERTICES, gl.STATIC_DRAW);
|
|
||||||
|
|
||||||
//gl.clearColor(0.0, 0.0, 0.0, 0.0);
|
|
||||||
//gl.clear(gl.COLOR_BUFFER_BIT);
|
|
||||||
|
|
||||||
const shaderProgram = initShaderProgram(gl, VERTEX_SHADER, FRAGMENT_SHADER);
|
|
||||||
|
|
||||||
gl.useProgram(shaderProgram);
|
|
||||||
|
|
||||||
const positionLocation = gl.getAttribLocation(shaderProgram, 'position');
|
|
||||||
gl.vertexAttribPointer(positionLocation, 2, gl.FLOAT, false, 0, 0);
|
|
||||||
gl.enableVertexAttribArray(positionLocation);
|
|
||||||
|
|
||||||
const in_resolution = gl.getUniformLocation(shaderProgram, 'in_resolution');
|
|
||||||
gl.uniform2fv(in_resolution, [canvas.width, canvas.height]);
|
|
||||||
|
|
||||||
const u_time = gl.getUniformLocation(shaderProgram, 'u_time');
|
|
||||||
const u_seed = gl.getUniformLocation(shaderProgram, 'u_seed');
|
|
||||||
const u_scale = gl.getUniformLocation(shaderProgram, 'u_scale');
|
|
||||||
const u_angle = gl.getUniformLocation(shaderProgram, 'u_angle');
|
|
||||||
const u_radius = gl.getUniformLocation(shaderProgram, 'u_radius');
|
|
||||||
const u_color = gl.getUniformLocation(shaderProgram, 'u_color');
|
|
||||||
gl.uniform1f(u_seed, Math.random() * 1000);
|
|
||||||
gl.uniform1f(u_scale, props.scale);
|
|
||||||
gl.uniform1f(u_angle, 0.0);
|
|
||||||
gl.uniform1f(u_radius, 0.15);
|
|
||||||
gl.uniform3fv(u_color, [0.5, 1.0, 0]);
|
|
||||||
|
|
||||||
if (isChromatic()) {
|
|
||||||
gl.uniform1f(u_time, 0);
|
|
||||||
gl.drawArrays(gl.TRIANGLES, 0, 6);
|
|
||||||
} else {
|
|
||||||
function render(timeStamp: number) {
|
|
||||||
let sizeChanged = false;
|
|
||||||
if (Math.abs(height - canvas.offsetHeight) > 2) {
|
|
||||||
height = canvas.offsetHeight;
|
|
||||||
canvas.height = height;
|
|
||||||
sizeChanged = true;
|
|
||||||
}
|
|
||||||
if (Math.abs(width - canvas.offsetWidth) > 2) {
|
|
||||||
width = canvas.offsetWidth;
|
|
||||||
canvas.width = width;
|
|
||||||
sizeChanged = true;
|
|
||||||
}
|
|
||||||
if (sizeChanged && gl) {
|
|
||||||
gl.uniform2fv(in_resolution, [width, height]);
|
|
||||||
gl.viewport(0, 0, width, height);
|
|
||||||
}
|
|
||||||
|
|
||||||
gl.uniform1f(u_time, timeStamp);
|
|
||||||
|
|
||||||
gl.drawArrays(gl.TRIANGLES, 0, 6);
|
|
||||||
|
|
||||||
handle = window.requestAnimationFrame(render);
|
|
||||||
}
|
|
||||||
|
|
||||||
handle = window.requestAnimationFrame(render);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
onUnmounted(() => {
|
|
||||||
if (handle) {
|
|
||||||
window.cancelAnimationFrame(handle);
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: WebGLリソースの解放
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" module>
|
|
||||||
</style>
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
使われなくなったけど消すのは勿体ない(将来使えるかもしれない)コードを入れておくとこ
|
|
||||||
|
|
@ -68,7 +68,7 @@ receiveFollowRequest: "تلقيت طلب متابعة"
|
||||||
followRequestAccepted: "قُبل طلب المتابعة"
|
followRequestAccepted: "قُبل طلب المتابعة"
|
||||||
mention: "أشر الى"
|
mention: "أشر الى"
|
||||||
mentions: "الإشارات"
|
mentions: "الإشارات"
|
||||||
directNotes: "رسالة خاصة"
|
directNotes: "الملاحظات المباشرة"
|
||||||
importAndExport: "إستورد / صدر"
|
importAndExport: "إستورد / صدر"
|
||||||
import: "استيراد"
|
import: "استيراد"
|
||||||
export: "تصدير"
|
export: "تصدير"
|
||||||
|
|
@ -123,7 +123,6 @@ reactions: "التفاعلات"
|
||||||
reactionSettingDescription2: "اسحب لترتيب ، انقر للحذف ، استخدم \"+\" للإضافة."
|
reactionSettingDescription2: "اسحب لترتيب ، انقر للحذف ، استخدم \"+\" للإضافة."
|
||||||
rememberNoteVisibility: "تذكر إعدادت مدى رؤية الملاحظات"
|
rememberNoteVisibility: "تذكر إعدادت مدى رؤية الملاحظات"
|
||||||
attachCancel: "أزل المرفق"
|
attachCancel: "أزل المرفق"
|
||||||
deleteFile: "حُذف الملف"
|
|
||||||
markAsSensitive: "علّمه كمحتوى حساس"
|
markAsSensitive: "علّمه كمحتوى حساس"
|
||||||
unmarkAsSensitive: "ألغ تعيينه كمحتوى حساس"
|
unmarkAsSensitive: "ألغ تعيينه كمحتوى حساس"
|
||||||
enterFileName: "ادخل اسم الملف"
|
enterFileName: "ادخل اسم الملف"
|
||||||
|
|
@ -215,6 +214,7 @@ noUsers: "ليس هناك مستخدمون"
|
||||||
editProfile: "تعديل الملف التعريفي"
|
editProfile: "تعديل الملف التعريفي"
|
||||||
noteDeleteConfirm: "هل تريد حذف هذه الملاحظة؟"
|
noteDeleteConfirm: "هل تريد حذف هذه الملاحظة؟"
|
||||||
pinLimitExceeded: "لا يمكنك تثبيت الملاحظات بعد الآن."
|
pinLimitExceeded: "لا يمكنك تثبيت الملاحظات بعد الآن."
|
||||||
|
intro: "لقد انتهت عملية تنصيب Misskey. الرجاء إنشاء حساب إداري."
|
||||||
done: "تمّ"
|
done: "تمّ"
|
||||||
processing: "المعالجة جارية"
|
processing: "المعالجة جارية"
|
||||||
preview: "معاينة"
|
preview: "معاينة"
|
||||||
|
|
@ -250,6 +250,7 @@ removeAreYouSure: "متأكد من أنك تريد حذف {x}؟"
|
||||||
deleteAreYouSure: "متأكد من أنك تريد حذف {x}؟"
|
deleteAreYouSure: "متأكد من أنك تريد حذف {x}؟"
|
||||||
resetAreYouSure: "هل تريد إعادة التعيين؟"
|
resetAreYouSure: "هل تريد إعادة التعيين؟"
|
||||||
saved: "حُفظ"
|
saved: "حُفظ"
|
||||||
|
messaging: "المحادثة"
|
||||||
upload: "ارفع"
|
upload: "ارفع"
|
||||||
keepOriginalUploading: "ابق الصورة الأصلية"
|
keepOriginalUploading: "ابق الصورة الأصلية"
|
||||||
keepOriginalUploadingDescription: "يحفظ الصور المرفوعة على حالتها الأصلية، وان عطّل ستولد نسخة مخصصة من الصورة."
|
keepOriginalUploadingDescription: "يحفظ الصور المرفوعة على حالتها الأصلية، وان عطّل ستولد نسخة مخصصة من الصورة."
|
||||||
|
|
@ -262,6 +263,7 @@ uploadFromUrlMayTakeTime: "سيستغرق بعض الوقت لاتمام الر
|
||||||
explore: "استكشاف"
|
explore: "استكشاف"
|
||||||
messageRead: "مقروءة"
|
messageRead: "مقروءة"
|
||||||
noMoreHistory: "لا يوجد المزيد من التاريخ"
|
noMoreHistory: "لا يوجد المزيد من التاريخ"
|
||||||
|
startMessaging: "ابدأ محادثة"
|
||||||
nUsersRead: "قرأه {n}"
|
nUsersRead: "قرأه {n}"
|
||||||
agreeTo: "اوافق على {0}"
|
agreeTo: "اوافق على {0}"
|
||||||
agree: "أقبل"
|
agree: "أقبل"
|
||||||
|
|
@ -340,6 +342,7 @@ enableLocalTimeline: "تفعيل الخيط المحلي"
|
||||||
enableGlobalTimeline: "تفعيل الخيط الزمني الشامل"
|
enableGlobalTimeline: "تفعيل الخيط الزمني الشامل"
|
||||||
disablingTimelinesInfo: "سيتمكن المديرون والمشرفون من الوصول إلى كل الخيوط الزمنية حتى وإن لم تفعّل."
|
disablingTimelinesInfo: "سيتمكن المديرون والمشرفون من الوصول إلى كل الخيوط الزمنية حتى وإن لم تفعّل."
|
||||||
registration: "إنشاء حساب"
|
registration: "إنشاء حساب"
|
||||||
|
enableRegistration: "تفعيل إنشاء الحسابات الجديدة"
|
||||||
invite: "دعوة"
|
invite: "دعوة"
|
||||||
driveCapacityPerLocalAccount: "حصة التخزين لكل مستخدم محلي"
|
driveCapacityPerLocalAccount: "حصة التخزين لكل مستخدم محلي"
|
||||||
driveCapacityPerRemoteAccount: "حصة التخزين لكل مستخدم بعيد"
|
driveCapacityPerRemoteAccount: "حصة التخزين لكل مستخدم بعيد"
|
||||||
|
|
@ -433,6 +436,8 @@ retype: "أعد الكتابة"
|
||||||
noteOf: "ملاحظات {user}"
|
noteOf: "ملاحظات {user}"
|
||||||
quoteAttached: "اِقتُبسَ"
|
quoteAttached: "اِقتُبسَ"
|
||||||
quoteQuestion: "أتريد تضمينها كاقتباس"
|
quoteQuestion: "أتريد تضمينها كاقتباس"
|
||||||
|
noMessagesYet: "ليس هناك رسائل بعد"
|
||||||
|
newMessageExists: "لقد تلقيت رسالة جديدة"
|
||||||
onlyOneFileCanBeAttached: "يمكنك إرفاق ملف واحد بالرسالة"
|
onlyOneFileCanBeAttached: "يمكنك إرفاق ملف واحد بالرسالة"
|
||||||
signinRequired: "رجاءً لِج"
|
signinRequired: "رجاءً لِج"
|
||||||
invitations: "دعوة"
|
invitations: "دعوة"
|
||||||
|
|
@ -620,7 +625,10 @@ abuseReported: "أُرسل البلاغ، شكرًا لك"
|
||||||
reporter: "المُبلّغ"
|
reporter: "المُبلّغ"
|
||||||
reporteeOrigin: "أصل البلاغ"
|
reporteeOrigin: "أصل البلاغ"
|
||||||
reporterOrigin: "أصل المُبلّغ"
|
reporterOrigin: "أصل المُبلّغ"
|
||||||
|
forwardReport: "وجّه البلاغ إلى المثيل البعيد"
|
||||||
|
forwardReportIsAnonymous: "في المثيل البعيد سيظهر المبلّغ كحساب مجهول."
|
||||||
send: "أرسل"
|
send: "أرسل"
|
||||||
|
abuseMarkAsResolved: "علّم البلاغ كمحلول"
|
||||||
openInNewTab: "افتح في لسان جديد"
|
openInNewTab: "افتح في لسان جديد"
|
||||||
defaultNavigationBehaviour: "سلوك الملاحة الافتراضي"
|
defaultNavigationBehaviour: "سلوك الملاحة الافتراضي"
|
||||||
editTheseSettingsMayBreakAccount: "تعديل هذه الإعدادات قد يسبب عطبًا لحسابك"
|
editTheseSettingsMayBreakAccount: "تعديل هذه الإعدادات قد يسبب عطبًا لحسابك"
|
||||||
|
|
@ -675,6 +683,7 @@ experimental: "اختباري"
|
||||||
developer: "المطور"
|
developer: "المطور"
|
||||||
makeExplorable: "أظهر الحساب في صفحة \"استكشاف\""
|
makeExplorable: "أظهر الحساب في صفحة \"استكشاف\""
|
||||||
makeExplorableDescription: "بتعطيل هذا الخيار لن يظهر حسابك في صفحة \"استكشاف\""
|
makeExplorableDescription: "بتعطيل هذا الخيار لن يظهر حسابك في صفحة \"استكشاف\""
|
||||||
|
showGapBetweenNotesInTimeline: "أظهر فجوات بين المشاركات في الخيط الزمني"
|
||||||
left: "يسار"
|
left: "يسار"
|
||||||
center: "وسط"
|
center: "وسط"
|
||||||
wide: "عريض"
|
wide: "عريض"
|
||||||
|
|
@ -1006,27 +1015,6 @@ sourceCode: "الشفرة المصدرية"
|
||||||
flip: "اقلب"
|
flip: "اقلب"
|
||||||
lastNDays: "آخر {n} أيام"
|
lastNDays: "آخر {n} أيام"
|
||||||
surrender: "ألغِ"
|
surrender: "ألغِ"
|
||||||
postForm: "أنشئ ملاحظة"
|
|
||||||
information: "عن"
|
|
||||||
inMinutes: "د"
|
|
||||||
inDays: "ي"
|
|
||||||
widgets: "التطبيقات المُصغّرة"
|
|
||||||
presets: "إعدادات مسبقة"
|
|
||||||
_imageEditing:
|
|
||||||
_vars:
|
|
||||||
filename: "اسم الملف"
|
|
||||||
_imageFrameEditor:
|
|
||||||
font: "الخط"
|
|
||||||
fontSerif: "Serif"
|
|
||||||
fontSansSerif: "Sans Serif"
|
|
||||||
_chat:
|
|
||||||
invitations: "دعوة"
|
|
||||||
noHistory: "السجل فارغ"
|
|
||||||
members: "الأعضاء"
|
|
||||||
home: "الرئيسي"
|
|
||||||
send: "أرسل"
|
|
||||||
_delivery:
|
|
||||||
stop: "مُعلّق"
|
|
||||||
_initialAccountSetting:
|
_initialAccountSetting:
|
||||||
accountCreated: "نجح إنشاء حسابك!"
|
accountCreated: "نجح إنشاء حسابك!"
|
||||||
letsStartAccountSetup: "إذا كنت جديدًا لنعدّ حسابك الشخصي."
|
letsStartAccountSetup: "إذا كنت جديدًا لنعدّ حسابك الشخصي."
|
||||||
|
|
@ -1249,6 +1237,7 @@ _theme:
|
||||||
shadow: "الظل"
|
shadow: "الظل"
|
||||||
navBg: "خلفية الشريط الجانبي"
|
navBg: "خلفية الشريط الجانبي"
|
||||||
navFg: "نص الشريط الجانبي"
|
navFg: "نص الشريط الجانبي"
|
||||||
|
navHoverFg: "نص الشريط الجانبي (عند التمرير فوقه)"
|
||||||
link: "رابط"
|
link: "رابط"
|
||||||
hashtag: "وسم"
|
hashtag: "وسم"
|
||||||
mention: "أشر الى"
|
mention: "أشر الى"
|
||||||
|
|
@ -1263,11 +1252,15 @@ _theme:
|
||||||
buttonBg: "خلفية الأزرار"
|
buttonBg: "خلفية الأزرار"
|
||||||
buttonHoverBg: "خلفية الأزرار (عند التمرير فوقها)"
|
buttonHoverBg: "خلفية الأزرار (عند التمرير فوقها)"
|
||||||
inputBorder: "حواف حقل الإدخال"
|
inputBorder: "حواف حقل الإدخال"
|
||||||
|
listItemHoverBg: "خلفية عناصر القائمة (عند التمرير فوقها)"
|
||||||
|
driveFolderBg: "خلفية مجلد قرص التخزين"
|
||||||
messageBg: "خلفية المحادثة"
|
messageBg: "خلفية المحادثة"
|
||||||
_sfx:
|
_sfx:
|
||||||
note: "الملاحظات"
|
note: "الملاحظات"
|
||||||
noteMy: "ملاحظتي"
|
noteMy: "ملاحظتي"
|
||||||
notification: "الإشعارات"
|
notification: "الإشعارات"
|
||||||
|
antenna: "الهوائيات"
|
||||||
|
channel: "إشعارات القنات"
|
||||||
_ago:
|
_ago:
|
||||||
future: "المستقبَل"
|
future: "المستقبَل"
|
||||||
justNow: "اللحظة"
|
justNow: "اللحظة"
|
||||||
|
|
@ -1322,7 +1315,6 @@ _permissions:
|
||||||
"read:gallery": "اعرض المعرض"
|
"read:gallery": "اعرض المعرض"
|
||||||
"write:gallery": "عدّل المعرض"
|
"write:gallery": "عدّل المعرض"
|
||||||
"read:gallery-likes": "يعرض ما أعجبك من مشاركات المعرض"
|
"read:gallery-likes": "يعرض ما أعجبك من مشاركات المعرض"
|
||||||
"write:chat": "اكتب أو احذف رسائل محادثة"
|
|
||||||
_auth:
|
_auth:
|
||||||
shareAccess: "أتريد التفويض لـ \"{name}\" بالوصول لحسابك؟"
|
shareAccess: "أتريد التفويض لـ \"{name}\" بالوصول لحسابك؟"
|
||||||
shareAccessAsk: "هل تخول لهذا التطبيق الوصول لحسابك؟"
|
shareAccessAsk: "هل تخول لهذا التطبيق الوصول لحسابك؟"
|
||||||
|
|
@ -1365,14 +1357,6 @@ _widgets:
|
||||||
userList: "قائمة المستخدمين"
|
userList: "قائمة المستخدمين"
|
||||||
_userList:
|
_userList:
|
||||||
chooseList: "اختر قائمة"
|
chooseList: "اختر قائمة"
|
||||||
_widgetOptions:
|
|
||||||
height: "الإرتفاع"
|
|
||||||
_button:
|
|
||||||
colored: "ملوّن"
|
|
||||||
_clock:
|
|
||||||
size: "الحجم"
|
|
||||||
_birthdayFollowings:
|
|
||||||
period: "المدة"
|
|
||||||
_cw:
|
_cw:
|
||||||
hide: "إخفاء"
|
hide: "إخفاء"
|
||||||
show: "عرض المزيد"
|
show: "عرض المزيد"
|
||||||
|
|
@ -1413,9 +1397,6 @@ _postForm:
|
||||||
replyPlaceholder: "رد على هذه الملاحظة…"
|
replyPlaceholder: "رد على هذه الملاحظة…"
|
||||||
quotePlaceholder: "اقتبس هذه الملاحظة…"
|
quotePlaceholder: "اقتبس هذه الملاحظة…"
|
||||||
channelPlaceholder: "انشر في قناة..."
|
channelPlaceholder: "انشر في قناة..."
|
||||||
_howToUse:
|
|
||||||
visibility_title: "الظهور"
|
|
||||||
menu_title: "القائمة"
|
|
||||||
_placeholders:
|
_placeholders:
|
||||||
a: "ما الذي تنوي فعله؟"
|
a: "ما الذي تنوي فعله؟"
|
||||||
b: "ماذا يحدث حولك ؟"
|
b: "ماذا يحدث حولك ؟"
|
||||||
|
|
@ -1483,6 +1464,9 @@ _pages:
|
||||||
newPage: "أنشئ صفحة جديدة"
|
newPage: "أنشئ صفحة جديدة"
|
||||||
editPage: "عدّل الصفحة"
|
editPage: "عدّل الصفحة"
|
||||||
readPage: "نُشّط عرض المصدر"
|
readPage: "نُشّط عرض المصدر"
|
||||||
|
created: "نجح إنشاء الصفحة"
|
||||||
|
updated: "نجح تعديل الصفحة"
|
||||||
|
deleted: "نجح حذف الصفحة"
|
||||||
pageSetting: "إعدادات الصفحة"
|
pageSetting: "إعدادات الصفحة"
|
||||||
nameAlreadyExists: "رابط الصفحة موجود مسبقًا"
|
nameAlreadyExists: "رابط الصفحة موجود مسبقًا"
|
||||||
invalidNameTitle: "رابط الصفحة ليس صالحًا"
|
invalidNameTitle: "رابط الصفحة ليس صالحًا"
|
||||||
|
|
@ -1548,7 +1532,6 @@ _notification:
|
||||||
reaction: "التفاعل"
|
reaction: "التفاعل"
|
||||||
receiveFollowRequest: "طلبات المتابعة"
|
receiveFollowRequest: "طلبات المتابعة"
|
||||||
followRequestAccepted: "طلبات المتابعة المقبولة"
|
followRequestAccepted: "طلبات المتابعة المقبولة"
|
||||||
login: "لِج"
|
|
||||||
app: "إشعارات التطبيقات المرتبطة"
|
app: "إشعارات التطبيقات المرتبطة"
|
||||||
_actions:
|
_actions:
|
||||||
followBack: "تابعك بالمثل"
|
followBack: "تابعك بالمثل"
|
||||||
|
|
@ -1580,52 +1563,10 @@ _webhookSettings:
|
||||||
active: "مُفعّل"
|
active: "مُفعّل"
|
||||||
_events:
|
_events:
|
||||||
reaction: "عند التفاعل"
|
reaction: "عند التفاعل"
|
||||||
_abuseReport:
|
|
||||||
_notificationRecipient:
|
|
||||||
_recipientType:
|
|
||||||
mail: "البريد الإلكتروني "
|
|
||||||
_moderationLogTypes:
|
_moderationLogTypes:
|
||||||
suspend: "علِق"
|
suspend: "علِق"
|
||||||
deleteDriveFile: "حُذف الملف"
|
|
||||||
deleteNote: "حُذفت الملاحظة"
|
|
||||||
createGlobalAnnouncement: "أُنشئ إعلان عام"
|
|
||||||
createUserAnnouncement: "أُنشئ إعلان مستخدم"
|
|
||||||
updateGlobalAnnouncement: "حُدث إعلان عام"
|
|
||||||
updateUserAnnouncement: "حُدث إعلان مستخدم"
|
|
||||||
resetPassword: "أعد تعيين كلمتك السرية"
|
resetPassword: "أعد تعيين كلمتك السرية"
|
||||||
createInvitation: "ولِّد دعوة"
|
createInvitation: "ولِّد دعوة"
|
||||||
_reversi:
|
_reversi:
|
||||||
total: "المجموع"
|
total: "المجموع"
|
||||||
lookingForPlayer: "يبحث عن خصم..."
|
|
||||||
gameCanceled: "أُلغيت اللعبة."
|
|
||||||
opponentHasSettingsChanged: "غيَر الخصم إعدادته."
|
|
||||||
showBoardLabels: "اعرض ترقيم الصفوف والأعمدة على اللوح"
|
|
||||||
useAvatarAsStone: "حوَل الحجارة إلى صور مستخدمين"
|
|
||||||
_offlineScreen:
|
|
||||||
title: "غير متصل - يتعذر الاتصال بالخادم"
|
|
||||||
header: "يتعذر الاتصال بالخادم"
|
|
||||||
_remoteLookupErrors:
|
|
||||||
_noSuchObject:
|
|
||||||
title: "غير موجود"
|
|
||||||
_search:
|
|
||||||
searchScopeAll: "الكل"
|
|
||||||
searchScopeLocal: "المحلي"
|
|
||||||
searchScopeUser: "مستخدم محدد"
|
|
||||||
_watermarkEditor:
|
|
||||||
opacity: "الشفافية"
|
|
||||||
scale: "الحجم"
|
|
||||||
text: "نص"
|
|
||||||
position: "الموضع"
|
|
||||||
type: "نوع"
|
|
||||||
image: "صور"
|
|
||||||
advanced: "متقدم"
|
|
||||||
_imageEffector:
|
|
||||||
_fxProps:
|
|
||||||
scale: "الحجم"
|
|
||||||
size: "الحجم"
|
|
||||||
offset: "الموضع"
|
|
||||||
color: "اللون"
|
|
||||||
opacity: "الشفافية"
|
|
||||||
_qr:
|
|
||||||
showTabTitle: "المظهر"
|
|
||||||
raw: "نص"
|
|
||||||
|
|
|
||||||
|
|
@ -215,6 +215,7 @@ noUsers: "কোন ব্যাবহারকারী নেই"
|
||||||
editProfile: "প্রোফাইল সম্পাদনা করুন"
|
editProfile: "প্রোফাইল সম্পাদনা করুন"
|
||||||
noteDeleteConfirm: "আপনি কি নোট ডিলিট করার ব্যাপারে নিশ্চিত?"
|
noteDeleteConfirm: "আপনি কি নোট ডিলিট করার ব্যাপারে নিশ্চিত?"
|
||||||
pinLimitExceeded: "আপনি আর কোন নোট পিন করতে পারবেন না"
|
pinLimitExceeded: "আপনি আর কোন নোট পিন করতে পারবেন না"
|
||||||
|
intro: "Misskey এর ইন্সটলেশন সম্পন্ন হয়েছে!দয়া করে অ্যাডমিন ইউজার তৈরি করুন।"
|
||||||
done: "সম্পন্ন"
|
done: "সম্পন্ন"
|
||||||
processing: "প্রক্রিয়াধীন..."
|
processing: "প্রক্রিয়াধীন..."
|
||||||
preview: "পূর্বরূপ দেখুন"
|
preview: "পূর্বরূপ দেখুন"
|
||||||
|
|
@ -251,6 +252,7 @@ removeAreYouSure: "আপনি কি \"{x}\" সরানোর ব্যা
|
||||||
deleteAreYouSure: "আপনি কি \"{x}\" সরানোর ব্যাপারে নিশ্চিত?"
|
deleteAreYouSure: "আপনি কি \"{x}\" সরানোর ব্যাপারে নিশ্চিত?"
|
||||||
resetAreYouSure: "রিসেট করার ব্যাপারে নিশ্চিত?"
|
resetAreYouSure: "রিসেট করার ব্যাপারে নিশ্চিত?"
|
||||||
saved: "সংরক্ষিত হয়েছে"
|
saved: "সংরক্ষিত হয়েছে"
|
||||||
|
messaging: "চ্যাট"
|
||||||
upload: "আপলোড"
|
upload: "আপলোড"
|
||||||
keepOriginalUploading: "আসল ছবি রাখুন"
|
keepOriginalUploading: "আসল ছবি রাখুন"
|
||||||
keepOriginalUploadingDescription: "ছবিটি আপলোড করার সময় আসল সংস্করণটি রাখুন। অপশনটি বন্ধ থাকলে, আপলোডের সময় ওয়েব প্রকাশনার জন্য ছবি ব্রাউজারে তৈরি করা হবে।"
|
keepOriginalUploadingDescription: "ছবিটি আপলোড করার সময় আসল সংস্করণটি রাখুন। অপশনটি বন্ধ থাকলে, আপলোডের সময় ওয়েব প্রকাশনার জন্য ছবি ব্রাউজারে তৈরি করা হবে।"
|
||||||
|
|
@ -263,6 +265,7 @@ uploadFromUrlMayTakeTime: "URL হতে আপলোড হতে কিছু
|
||||||
explore: "ঘুরে দেখুন"
|
explore: "ঘুরে দেখুন"
|
||||||
messageRead: "পড়া"
|
messageRead: "পড়া"
|
||||||
noMoreHistory: "আর কোন ইতিহাস নেই"
|
noMoreHistory: "আর কোন ইতিহাস নেই"
|
||||||
|
startMessaging: "চ্যাট শুরু করুন"
|
||||||
nUsersRead: "{n} জন পড়েছেন"
|
nUsersRead: "{n} জন পড়েছেন"
|
||||||
agreeTo: "{0} এর প্রতি আমি সম্মত"
|
agreeTo: "{0} এর প্রতি আমি সম্মত"
|
||||||
start: "শুরু করুন"
|
start: "শুরু করুন"
|
||||||
|
|
@ -336,6 +339,7 @@ enableLocalTimeline: "স্থানীয় টাইমলাইন চাল
|
||||||
enableGlobalTimeline: "গ্লোবাল টাইমলাইন চালু করুন"
|
enableGlobalTimeline: "গ্লোবাল টাইমলাইন চালু করুন"
|
||||||
disablingTimelinesInfo: "আপনি এই টাইমলাইনগুলি বন্ধ করলেও প্রশাসক এবং মডারেটররা এই টাইমলাইনগুলি ব্যাবহার করতে পারবে"
|
disablingTimelinesInfo: "আপনি এই টাইমলাইনগুলি বন্ধ করলেও প্রশাসক এবং মডারেটররা এই টাইমলাইনগুলি ব্যাবহার করতে পারবে"
|
||||||
registration: "নিবন্ধন"
|
registration: "নিবন্ধন"
|
||||||
|
enableRegistration: "নতুন ব্যাবহারকারী নিবন্ধন চালু করুন"
|
||||||
invite: "আমন্ত্রণ"
|
invite: "আমন্ত্রণ"
|
||||||
driveCapacityPerLocalAccount: "প্রত্যেক স্থানীয় ব্যাবহারকারীর জন্য ড্রাইভের জায়গা"
|
driveCapacityPerLocalAccount: "প্রত্যেক স্থানীয় ব্যাবহারকারীর জন্য ড্রাইভের জায়গা"
|
||||||
driveCapacityPerRemoteAccount: "প্রত্যেক রিমোট ব্যাবহারকারীর জন্য ড্রাইভের জায়গা"
|
driveCapacityPerRemoteAccount: "প্রত্যেক রিমোট ব্যাবহারকারীর জন্য ড্রাইভের জায়গা"
|
||||||
|
|
@ -424,6 +428,8 @@ retype: "পুনঃ প্রবেশ"
|
||||||
noteOf: "{user} এর নোট"
|
noteOf: "{user} এর নোট"
|
||||||
quoteAttached: "উদ্ধৃত"
|
quoteAttached: "উদ্ধৃত"
|
||||||
quoteQuestion: "উদ্ধৃতি হিসাবে সংযুক্ত করবেন?"
|
quoteQuestion: "উদ্ধৃতি হিসাবে সংযুক্ত করবেন?"
|
||||||
|
noMessagesYet: "কোন মেসেজ নেই"
|
||||||
|
newMessageExists: "নতুন মেসেজ পেয়েছেন"
|
||||||
onlyOneFileCanBeAttached: "আপনি মেসেজের সাথে সর্বোচ্চ একটি ফাইল যুক্ত করতে পারবেন"
|
onlyOneFileCanBeAttached: "আপনি মেসেজের সাথে সর্বোচ্চ একটি ফাইল যুক্ত করতে পারবেন"
|
||||||
signinRequired: "দয়া করে লগ ইন করুন"
|
signinRequired: "দয়া করে লগ ইন করুন"
|
||||||
invitations: "আমন্ত্রণ"
|
invitations: "আমন্ত্রণ"
|
||||||
|
|
@ -445,6 +451,7 @@ or: "অথবা"
|
||||||
language: "ভাষা"
|
language: "ভাষা"
|
||||||
uiLanguage: "UI এর ভাষা"
|
uiLanguage: "UI এর ভাষা"
|
||||||
aboutX: "{x} সম্পর্কে"
|
aboutX: "{x} সম্পর্কে"
|
||||||
|
disableDrawer: "ড্রয়ার মেনু প্রদর্শন করবেন না"
|
||||||
noHistory: "কোনো ইতিহাস নেই"
|
noHistory: "কোনো ইতিহাস নেই"
|
||||||
signinHistory: "প্রবেশ করার ইতিহাস"
|
signinHistory: "প্রবেশ করার ইতিহাস"
|
||||||
doing: "প্রক্রিয়া করছে..."
|
doing: "প্রক্রিয়া করছে..."
|
||||||
|
|
@ -618,7 +625,10 @@ abuseReported: "আপনার অভিযোগটি দাখিল কর
|
||||||
reporter: "অভিযোগকারী"
|
reporter: "অভিযোগকারী"
|
||||||
reporteeOrigin: "অভিযোগটির উৎস"
|
reporteeOrigin: "অভিযোগটির উৎস"
|
||||||
reporterOrigin: "অভিযোগকারীর উৎস"
|
reporterOrigin: "অভিযোগকারীর উৎস"
|
||||||
|
forwardReport: "রিমোট ইন্সত্যান্সে অভিযোগটি পাঠান"
|
||||||
|
forwardReportIsAnonymous: "আপনার তথ্য রিমোট ইন্সত্যান্সে পাঠানো হবে না এবং একটি বেনামী সিস্টেম অ্যাকাউন্ট হিসাবে প্রদর্শিত হবে।"
|
||||||
send: "পাঠান"
|
send: "পাঠান"
|
||||||
|
abuseMarkAsResolved: "অভিযোগটিকে সমাধাকৃত হিসাবে চিহ্নিত করুন"
|
||||||
openInNewTab: "নতুন ট্যাবে খুলুন"
|
openInNewTab: "নতুন ট্যাবে খুলুন"
|
||||||
openInSideView: "সাইড ভিউতে খুলুন"
|
openInSideView: "সাইড ভিউতে খুলুন"
|
||||||
defaultNavigationBehaviour: "ডিফল্ট নেভিগেশন"
|
defaultNavigationBehaviour: "ডিফল্ট নেভিগেশন"
|
||||||
|
|
@ -672,6 +682,7 @@ experimentalFeatures: "পরীক্ষামূলক বৈশিষ্ট
|
||||||
developer: "ডেভেলপার"
|
developer: "ডেভেলপার"
|
||||||
makeExplorable: "অ্যাকাউন্ট \"ঘুরে দেখুন\" পৃষ্ঠায় দেখান"
|
makeExplorable: "অ্যাকাউন্ট \"ঘুরে দেখুন\" পৃষ্ঠায় দেখান"
|
||||||
makeExplorableDescription: "আপনি এটি বন্ধ করলে, আপনার অ্যাকাউন্ট \"ঘুরে দেখুন\" পৃষ্ঠায় প্রদর্শিত হবে না।"
|
makeExplorableDescription: "আপনি এটি বন্ধ করলে, আপনার অ্যাকাউন্ট \"ঘুরে দেখুন\" পৃষ্ঠায় প্রদর্শিত হবে না।"
|
||||||
|
showGapBetweenNotesInTimeline: "টাইমলাইন এবং নোটের মাঝে ফাকা জায়গা রাখুন"
|
||||||
duplicate: "প্রতিরূপ"
|
duplicate: "প্রতিরূপ"
|
||||||
left: "বাম"
|
left: "বাম"
|
||||||
center: "মাঝখান"
|
center: "মাঝখান"
|
||||||
|
|
@ -846,29 +857,6 @@ replies: "জবাব"
|
||||||
renotes: "রিনোট"
|
renotes: "রিনোট"
|
||||||
sourceCode: "সোর্স কোড"
|
sourceCode: "সোর্স কোড"
|
||||||
flip: "উল্টান"
|
flip: "উল্টান"
|
||||||
postForm: "নোট লিখুন"
|
|
||||||
information: "আপনার সম্পর্কে"
|
|
||||||
inMinutes: "মিনিট"
|
|
||||||
inDays: "দিন"
|
|
||||||
widgets: "উইজেটগুলি"
|
|
||||||
_imageEditing:
|
|
||||||
_vars:
|
|
||||||
filename: "ফাইলের নাম"
|
|
||||||
_imageFrameEditor:
|
|
||||||
header: "হেডার"
|
|
||||||
font: "ফন্ট"
|
|
||||||
fontSerif: "সেরিফ"
|
|
||||||
fontSansSerif: "স্যান্স সেরিফ"
|
|
||||||
_chat:
|
|
||||||
invitations: "আমন্ত্রণ"
|
|
||||||
noHistory: "কোনো ইতিহাস নেই"
|
|
||||||
members: "সদস্যবৃন্দ"
|
|
||||||
home: "মূল পাতা"
|
|
||||||
send: "পাঠান"
|
|
||||||
_delivery:
|
|
||||||
stop: "স্থগিত করা হয়েছে"
|
|
||||||
_type:
|
|
||||||
none: "প্রকাশ করা হচ্ছে"
|
|
||||||
_role:
|
_role:
|
||||||
priority: "অগ্রাধিকার"
|
priority: "অগ্রাধিকার"
|
||||||
_priority:
|
_priority:
|
||||||
|
|
@ -1007,6 +995,7 @@ _theme:
|
||||||
header: "হেডার"
|
header: "হেডার"
|
||||||
navBg: "সাইডবারের পটভূমি"
|
navBg: "সাইডবারের পটভূমি"
|
||||||
navFg: "সাইডবারের পাঠ্য"
|
navFg: "সাইডবারের পাঠ্য"
|
||||||
|
navHoverFg: "সাইডবারের পাঠ্য (হভার)"
|
||||||
navActive: "সাইডবারের পাঠ্য (অ্যাকটিভ)"
|
navActive: "সাইডবারের পাঠ্য (অ্যাকটিভ)"
|
||||||
navIndicator: "সাইডবারের ইনডিকেটর"
|
navIndicator: "সাইডবারের ইনডিকেটর"
|
||||||
link: "লিংক"
|
link: "লিংক"
|
||||||
|
|
@ -1028,13 +1017,20 @@ _theme:
|
||||||
buttonBg: "বাটনের পটভূমি"
|
buttonBg: "বাটনের পটভূমি"
|
||||||
buttonHoverBg: "বাটনের পটভূমি (হভার)"
|
buttonHoverBg: "বাটনের পটভূমি (হভার)"
|
||||||
inputBorder: "ইনপুট ফিল্ডের বর্ডার"
|
inputBorder: "ইনপুট ফিল্ডের বর্ডার"
|
||||||
|
listItemHoverBg: "লিস্ট আইটেমের পটভূমি (হোভার)"
|
||||||
|
driveFolderBg: "ড্রাইভ ফোল্ডারের পটভূমি"
|
||||||
|
wallpaperOverlay: "ওয়ালপেপার ওভারলে"
|
||||||
badge: "ব্যাজ"
|
badge: "ব্যাজ"
|
||||||
messageBg: "চ্যাটের পটভূমি"
|
messageBg: "চ্যাটের পটভূমি"
|
||||||
|
accentDarken: "অ্যাকসেন্ট (গাঢ়)"
|
||||||
|
accentLighten: "অ্যাকসেন্ট (হাল্কা)"
|
||||||
fgHighlighted: "হাইলাইট করা পাঠ্য"
|
fgHighlighted: "হাইলাইট করা পাঠ্য"
|
||||||
_sfx:
|
_sfx:
|
||||||
note: "নোটগুলি"
|
note: "নোটগুলি"
|
||||||
noteMy: "নোট (আপনার)"
|
noteMy: "নোট (আপনার)"
|
||||||
notification: "বিজ্ঞপ্তি"
|
notification: "বিজ্ঞপ্তি"
|
||||||
|
antenna: "অ্যান্টেনাগুলি"
|
||||||
|
channel: "চ্যানেলের বিজ্ঞপ্তি"
|
||||||
_ago:
|
_ago:
|
||||||
future: "ভবিষ্যৎ"
|
future: "ভবিষ্যৎ"
|
||||||
justNow: "এইমাত্র"
|
justNow: "এইমাত্র"
|
||||||
|
|
@ -1092,7 +1088,6 @@ _permissions:
|
||||||
"write:gallery": "গ্যালারী সম্পাদনা করুন"
|
"write:gallery": "গ্যালারী সম্পাদনা করুন"
|
||||||
"read:gallery-likes": "গ্যালারীর পছন্দগুলি দেখুন"
|
"read:gallery-likes": "গ্যালারীর পছন্দগুলি দেখুন"
|
||||||
"write:gallery-likes": "গ্যালারীর পছন্দগুলি সম্পাদনা করুন"
|
"write:gallery-likes": "গ্যালারীর পছন্দগুলি সম্পাদনা করুন"
|
||||||
"write:chat": "চ্যাটগুলি সম্পাদনা করুন"
|
|
||||||
_auth:
|
_auth:
|
||||||
shareAccess: "\"{name}\" কে অ্যাকাউন্টের অ্যাক্সেস দিবেন?"
|
shareAccess: "\"{name}\" কে অ্যাকাউন্টের অ্যাক্সেস দিবেন?"
|
||||||
shareAccessAsk: "অ্যাপ্লিকেশনটিকে অ্যাকাউন্টের অ্যাক্সেস দিবেন?"
|
shareAccessAsk: "অ্যাপ্লিকেশনটিকে অ্যাকাউন্টের অ্যাক্সেস দিবেন?"
|
||||||
|
|
@ -1137,14 +1132,6 @@ _widgets:
|
||||||
aichan: "আই চান"
|
aichan: "আই চান"
|
||||||
_userList:
|
_userList:
|
||||||
chooseList: "লিস্ট নির্বাচন করুন"
|
chooseList: "লিস্ট নির্বাচন করুন"
|
||||||
_widgetOptions:
|
|
||||||
height: "উচ্চতা"
|
|
||||||
_button:
|
|
||||||
colored: "রঙ্গিন"
|
|
||||||
_clock:
|
|
||||||
size: "আকার"
|
|
||||||
_birthdayFollowings:
|
|
||||||
period: "ব্যাপ্তিকাল"
|
|
||||||
_cw:
|
_cw:
|
||||||
hide: "লুকান"
|
hide: "লুকান"
|
||||||
show: "আরও দেখুন"
|
show: "আরও দেখুন"
|
||||||
|
|
@ -1185,9 +1172,6 @@ _postForm:
|
||||||
replyPlaceholder: "নোটটির জবাব দিন..."
|
replyPlaceholder: "নোটটির জবাব দিন..."
|
||||||
quotePlaceholder: "নোটটিকে উদ্ধৃত করুন..."
|
quotePlaceholder: "নোটটিকে উদ্ধৃত করুন..."
|
||||||
channelPlaceholder: "চ্যানেলে পোস্ট করুন..."
|
channelPlaceholder: "চ্যানেলে পোস্ট করুন..."
|
||||||
_howToUse:
|
|
||||||
visibility_title: "দৃশ্যমানতা"
|
|
||||||
menu_title: "মেনু"
|
|
||||||
_placeholders:
|
_placeholders:
|
||||||
a: "আপনি এখন কি করছেন?"
|
a: "আপনি এখন কি করছেন?"
|
||||||
b: "আপনার আশে পাশে কি হচ্ছে?"
|
b: "আপনার আশে পাশে কি হচ্ছে?"
|
||||||
|
|
@ -1257,6 +1241,9 @@ _pages:
|
||||||
newPage: "নতুন পৃষ্ঠা বানান"
|
newPage: "নতুন পৃষ্ঠা বানান"
|
||||||
editPage: "পৃষ্ঠাটি সম্পাদনা করুন"
|
editPage: "পৃষ্ঠাটি সম্পাদনা করুন"
|
||||||
readPage: "উৎস দেখছেন"
|
readPage: "উৎস দেখছেন"
|
||||||
|
created: "পৃষ্ঠা তৈরি করা হয়েছে"
|
||||||
|
updated: "পৃষ্ঠা সম্পাদনা করা হয়েছে"
|
||||||
|
deleted: "পৃষ্ঠা মুছে ফেলা হয়েছে"
|
||||||
pageSetting: "পৃষ্ঠার সেটিংস"
|
pageSetting: "পৃষ্ঠার সেটিংস"
|
||||||
nameAlreadyExists: "পৃষ্ঠার URLটি ইতিমধ্যেই ব্যাবহার করা হয়েছে"
|
nameAlreadyExists: "পৃষ্ঠার URLটি ইতিমধ্যেই ব্যাবহার করা হয়েছে"
|
||||||
invalidNameTitle: "পৃষ্ঠার URL অবৈধ"
|
invalidNameTitle: "পৃষ্ঠার URL অবৈধ"
|
||||||
|
|
@ -1325,7 +1312,6 @@ _notification:
|
||||||
pollEnded: "পোল শেষ"
|
pollEnded: "পোল শেষ"
|
||||||
receiveFollowRequest: "প্রাপ্ত অনুসরণের অনুরোধসমূহ"
|
receiveFollowRequest: "প্রাপ্ত অনুসরণের অনুরোধসমূহ"
|
||||||
followRequestAccepted: "গৃহীত অনুসরণের অনুরোধসমূহ"
|
followRequestAccepted: "গৃহীত অনুসরণের অনুরোধসমূহ"
|
||||||
login: "প্রবেশ করুন"
|
|
||||||
app: "লিঙ্ক করা অ্যাপ থেকে বিজ্ঞপ্তি"
|
app: "লিঙ্ক করা অ্যাপ থেকে বিজ্ঞপ্তি"
|
||||||
_actions:
|
_actions:
|
||||||
followBack: "ফলো ব্যাক করেছে"
|
followBack: "ফলো ব্যাক করেছে"
|
||||||
|
|
@ -1356,34 +1342,9 @@ _deck:
|
||||||
_webhookSettings:
|
_webhookSettings:
|
||||||
name: "নাম"
|
name: "নাম"
|
||||||
active: "চালু"
|
active: "চালু"
|
||||||
_abuseReport:
|
|
||||||
_notificationRecipient:
|
|
||||||
_recipientType:
|
|
||||||
mail: "ইমেইল"
|
|
||||||
_moderationLogTypes:
|
_moderationLogTypes:
|
||||||
suspend: "স্থগিত করা"
|
suspend: "স্থগিত করা"
|
||||||
resetPassword: "পাসওয়ার্ড রিসেট করুন"
|
resetPassword: "পাসওয়ার্ড রিসেট করুন"
|
||||||
_reversi:
|
_reversi:
|
||||||
total: "মোট"
|
total: "মোট"
|
||||||
_remoteLookupErrors:
|
|
||||||
_noSuchObject:
|
|
||||||
title: "পাওয়া যায়নি"
|
|
||||||
_search:
|
|
||||||
searchScopeAll: "সবগুলো"
|
|
||||||
searchScopeLocal: "স্থানীয়"
|
|
||||||
_watermarkEditor:
|
|
||||||
opacity: "অস্বচ্ছতা"
|
|
||||||
scale: "আকার"
|
|
||||||
text: "লেখা"
|
|
||||||
image: "ছবি"
|
|
||||||
advanced: "উন্নত"
|
|
||||||
_imageEffector:
|
|
||||||
_fxProps:
|
|
||||||
scale: "আকার"
|
|
||||||
size: "আকার"
|
|
||||||
color: "রং"
|
|
||||||
opacity: "অস্বচ্ছতা"
|
|
||||||
lightness: "উজ্জ্বল করুন"
|
|
||||||
_qr:
|
|
||||||
showTabTitle: "প্রদর্শন"
|
|
||||||
raw: "লেখা"
|
|
||||||
|
|
|
||||||
1512
locales/ca-ES.yml
1512
locales/ca-ES.yml
File diff suppressed because it is too large
Load Diff
|
|
@ -1,17 +1,13 @@
|
||||||
---
|
---
|
||||||
_lang_: "Čeština"
|
_lang_: "Čeština"
|
||||||
headlineMisskey: "Síť propojená poznámkami"
|
headlineMisskey: "Síť propojená poznámkami"
|
||||||
introMisskey: "Vítejte! Misskey je otevřená a decentralizovaná microblogovací služba.\n\"Poznámkami\" můžete sdílet co se zrovna děje se všemi ve Vašem okolí. 📡\nPomocí \"reakcí\" můžete sdílet své názory a pocity na ostatní poznámky. 👍\nPojďte objevovat nový svět! 🚀"
|
introMisskey: "Vítejte! Misskey je otevřený a decentralizovaný microblogový servis.\n\"Poznámkami\" můžete sdílet co se zrovna děje se všemi ve Vašem okolí. 📡\nPomocí \"reakcí\" můžete sdílet své názory a pocity na ostatní poznámky. 👍\nPojďte objevovat nový svět! 🚀"
|
||||||
poweredByMisskeyDescription: "{name} je jeden ze serverů využívající open source platformu <b>Misskey<b> (nazývaná \"Misskey instance\")."
|
poweredByMisskeyDescription: "{name} je jeden ze serverů využívající open source platformu <b>Misskey<b> (nazývaná \"Misskey instance\")."
|
||||||
monthAndDay: "{day}. {month}."
|
monthAndDay: "{day}. {month}."
|
||||||
search: "Vyhledávání"
|
search: "Vyhledávání"
|
||||||
reset: "Obnovit"
|
|
||||||
notifications: "Oznámení"
|
notifications: "Oznámení"
|
||||||
username: "Uživatelské jméno"
|
username: "Uživatelské jméno"
|
||||||
password: "Heslo"
|
password: "Heslo"
|
||||||
initialPasswordForSetup: "Počáteční heslo pro nastavení"
|
|
||||||
initialPasswordIsIncorrect: "Počáteční heslo pro nastavení je nesprávné"
|
|
||||||
initialPasswordForSetupDescription: "Použijte heslo, které jste nastavili v konfiguračním souboru, pokud jste Misskey instalovali ručně.\nPokud užíváte Misskey hostovací službu, použijte poskytnuté heslo.\nPokud jste heslo nenastavovali, zanechte prázdné."
|
|
||||||
forgotPassword: "Zapomenuté heslo"
|
forgotPassword: "Zapomenuté heslo"
|
||||||
fetchingAsApObject: "Načítám data z Fediversu..."
|
fetchingAsApObject: "Načítám data z Fediversu..."
|
||||||
ok: "Potvrdit"
|
ok: "Potvrdit"
|
||||||
|
|
@ -19,7 +15,7 @@ gotIt: "Rozumím!"
|
||||||
cancel: "Zrušit"
|
cancel: "Zrušit"
|
||||||
noThankYou: "Ne děkuji"
|
noThankYou: "Ne děkuji"
|
||||||
enterUsername: "Zadej uživatelské jméno"
|
enterUsername: "Zadej uživatelské jméno"
|
||||||
renotedBy: "{user} přeposlal*a"
|
renotedBy: "{user} přeposla/a"
|
||||||
noNotes: "Žádné poznámky"
|
noNotes: "Žádné poznámky"
|
||||||
noNotifications: "Žádná oznámení"
|
noNotifications: "Žádná oznámení"
|
||||||
instance: "Instance"
|
instance: "Instance"
|
||||||
|
|
@ -49,8 +45,6 @@ pin: "Připnout"
|
||||||
unpin: "Odepnout"
|
unpin: "Odepnout"
|
||||||
copyContent: "Zkopírovat obsah"
|
copyContent: "Zkopírovat obsah"
|
||||||
copyLink: "Kopírovat odkaz"
|
copyLink: "Kopírovat odkaz"
|
||||||
copyRemoteLink: "Zkoprírovat vzdálený odkaz"
|
|
||||||
copyLinkRenote: "Zkopírovat odkaz renotu"
|
|
||||||
delete: "Smazat"
|
delete: "Smazat"
|
||||||
deleteAndEdit: "Smazat a upravit"
|
deleteAndEdit: "Smazat a upravit"
|
||||||
deleteAndEditConfirm: "Jste si jistí že chcete smazat tuto poznámku a editovat ji? Ztratíte tím všechny reakce, sdílení a odpovědi na ni."
|
deleteAndEditConfirm: "Jste si jistí že chcete smazat tuto poznámku a editovat ji? Ztratíte tím všechny reakce, sdílení a odpovědi na ni."
|
||||||
|
|
@ -65,7 +59,6 @@ copyFileId: "Kopírovat ID souboru"
|
||||||
copyFolderId: "Kopírovat ID složky"
|
copyFolderId: "Kopírovat ID složky"
|
||||||
copyProfileUrl: "Kopírovat URL profilu"
|
copyProfileUrl: "Kopírovat URL profilu"
|
||||||
searchUser: "Vyhledat uživatele"
|
searchUser: "Vyhledat uživatele"
|
||||||
searchThisUsersNotes: "Prohledat poznámky uživatele"
|
|
||||||
reply: "Odpovědět"
|
reply: "Odpovědět"
|
||||||
loadMore: "Zobrazit více"
|
loadMore: "Zobrazit více"
|
||||||
showMore: "Zobrazit více"
|
showMore: "Zobrazit více"
|
||||||
|
|
@ -175,9 +168,6 @@ addAccount: "Přidat účet"
|
||||||
reloadAccountsList: "Obnovit list účtů"
|
reloadAccountsList: "Obnovit list účtů"
|
||||||
loginFailed: "Přihlášení se nezdařilo."
|
loginFailed: "Přihlášení se nezdařilo."
|
||||||
showOnRemote: "Více na původním profilu"
|
showOnRemote: "Více na původním profilu"
|
||||||
continueOnRemote: "Pokračujte na původní profil"
|
|
||||||
chooseServerOnMisskeyHub: "Vyberete si server z Misskey Hubu"
|
|
||||||
inputHostName: "Zadejte doménu"
|
|
||||||
general: "Obecně"
|
general: "Obecně"
|
||||||
wallpaper: "Obrázek na pozadí"
|
wallpaper: "Obrázek na pozadí"
|
||||||
setWallpaper: "Nastavení obrázku na pozadí"
|
setWallpaper: "Nastavení obrázku na pozadí"
|
||||||
|
|
@ -202,7 +192,6 @@ perHour: "za hodinu"
|
||||||
perDay: "za den"
|
perDay: "za den"
|
||||||
stopActivityDelivery: "Přestat zasílat aktivitu"
|
stopActivityDelivery: "Přestat zasílat aktivitu"
|
||||||
blockThisInstance: "Blokovat tuto instanci"
|
blockThisInstance: "Blokovat tuto instanci"
|
||||||
silenceThisInstance: "Utišit tuto instanci"
|
|
||||||
operations: "Operace"
|
operations: "Operace"
|
||||||
software: "Software"
|
software: "Software"
|
||||||
version: "Verze"
|
version: "Verze"
|
||||||
|
|
@ -229,6 +218,7 @@ noUsers: "Žádní uživatelé"
|
||||||
editProfile: "Upravit můj profil"
|
editProfile: "Upravit můj profil"
|
||||||
noteDeleteConfirm: "Jste si jistí že chcete smazat tuhle poznámku?"
|
noteDeleteConfirm: "Jste si jistí že chcete smazat tuhle poznámku?"
|
||||||
pinLimitExceeded: "Nemůžete připnout další poznámky."
|
pinLimitExceeded: "Nemůžete připnout další poznámky."
|
||||||
|
intro: "Instalace Misskey byla dokončena! Prosím vytvořte admina."
|
||||||
done: "Hotovo"
|
done: "Hotovo"
|
||||||
processing: "Zpracovávám"
|
processing: "Zpracovávám"
|
||||||
preview: "Náhled"
|
preview: "Náhled"
|
||||||
|
|
@ -266,6 +256,7 @@ removeAreYouSure: "Jste si jistí že chcete smazat \"{x}\"?"
|
||||||
deleteAreYouSure: "Jste si jistí že chcete smazat \"{x}\"?"
|
deleteAreYouSure: "Jste si jistí že chcete smazat \"{x}\"?"
|
||||||
resetAreYouSure: "Opravdu resetovat?"
|
resetAreYouSure: "Opravdu resetovat?"
|
||||||
saved: "Uloženo"
|
saved: "Uloženo"
|
||||||
|
messaging: "Zprávy"
|
||||||
upload: "Nahrát soubory"
|
upload: "Nahrát soubory"
|
||||||
keepOriginalUploading: "Ponechat originální obrázek"
|
keepOriginalUploading: "Ponechat originální obrázek"
|
||||||
keepOriginalUploadingDescription: "Uloží původní nahraný obrázek jak je. Pokud je to vypnuté, vygeneruje se zobrazení verze na webu při nahrátí."
|
keepOriginalUploadingDescription: "Uloží původní nahraný obrázek jak je. Pokud je to vypnuté, vygeneruje se zobrazení verze na webu při nahrátí."
|
||||||
|
|
@ -278,6 +269,7 @@ uploadFromUrlMayTakeTime: "Může trvat nějakou dobu, dokud nebude dokončeno n
|
||||||
explore: "Objevovat"
|
explore: "Objevovat"
|
||||||
messageRead: "Přečtené"
|
messageRead: "Přečtené"
|
||||||
noMoreHistory: "To je vše"
|
noMoreHistory: "To je vše"
|
||||||
|
startMessaging: "Zahájit chat"
|
||||||
nUsersRead: "přečteno {n} uživateli"
|
nUsersRead: "přečteno {n} uživateli"
|
||||||
agreeTo: "Souhlasím s {0}"
|
agreeTo: "Souhlasím s {0}"
|
||||||
agree: "Souhlasím"
|
agree: "Souhlasím"
|
||||||
|
|
@ -356,6 +348,7 @@ enableLocalTimeline: "Povolit lokální čas"
|
||||||
enableGlobalTimeline: "Povolit globální čas"
|
enableGlobalTimeline: "Povolit globální čas"
|
||||||
disablingTimelinesInfo: "Administrátoři a Moderátoři budou mít stálý přístup ke všem časovým osám i přes to že nejsou zapnuté."
|
disablingTimelinesInfo: "Administrátoři a Moderátoři budou mít stálý přístup ke všem časovým osám i přes to že nejsou zapnuté."
|
||||||
registration: "Registrace"
|
registration: "Registrace"
|
||||||
|
enableRegistration: "Povolit registraci novým uživatelům"
|
||||||
invite: "Pozvat"
|
invite: "Pozvat"
|
||||||
driveCapacityPerLocalAccount: "Kapacita disku na lokálního uživatele"
|
driveCapacityPerLocalAccount: "Kapacita disku na lokálního uživatele"
|
||||||
driveCapacityPerRemoteAccount: "Kapacita disku na vzdáleného uživatele"
|
driveCapacityPerRemoteAccount: "Kapacita disku na vzdáleného uživatele"
|
||||||
|
|
@ -373,11 +366,8 @@ hcaptcha: "hCaptcha"
|
||||||
enableHcaptcha: "Aktivovat hCaptchu"
|
enableHcaptcha: "Aktivovat hCaptchu"
|
||||||
hcaptchaSiteKey: "Klíč stránky"
|
hcaptchaSiteKey: "Klíč stránky"
|
||||||
hcaptchaSecretKey: "Tajný Klíč (Secret Key)"
|
hcaptchaSecretKey: "Tajný Klíč (Secret Key)"
|
||||||
mcaptcha: "mCaptcha"
|
|
||||||
enableMcaptcha: "Aktivovat mCaptchu"
|
|
||||||
mcaptchaSiteKey: "Klíč stránky"
|
mcaptchaSiteKey: "Klíč stránky"
|
||||||
mcaptchaSecretKey: "Tajný Klíč (Secret Key)"
|
mcaptchaSecretKey: "Tajný Klíč (Secret Key)"
|
||||||
mcaptchaInstanceUrl: "URL mCaptcha serveru"
|
|
||||||
recaptcha: "reCAPTCHA"
|
recaptcha: "reCAPTCHA"
|
||||||
enableRecaptcha: "Zapnout ReCAPTCHu"
|
enableRecaptcha: "Zapnout ReCAPTCHu"
|
||||||
recaptchaSiteKey: "Klíč stránky"
|
recaptchaSiteKey: "Klíč stránky"
|
||||||
|
|
@ -456,6 +446,8 @@ retype: "Zadejte znovu"
|
||||||
noteOf: "{user} poznámky"
|
noteOf: "{user} poznámky"
|
||||||
quoteAttached: "Citace"
|
quoteAttached: "Citace"
|
||||||
quoteQuestion: "Přiložit jako citaci?"
|
quoteQuestion: "Přiložit jako citaci?"
|
||||||
|
noMessagesYet: "Zatím tu nejsou žádné zprávy"
|
||||||
|
newMessageExists: "Máte novou zprávu"
|
||||||
onlyOneFileCanBeAttached: "Ke zprávě můžete přiložit jenom jeden soubor"
|
onlyOneFileCanBeAttached: "Ke zprávě můžete přiložit jenom jeden soubor"
|
||||||
signinRequired: "Přihlašte se, prosím"
|
signinRequired: "Přihlašte se, prosím"
|
||||||
invitations: "Pozvat"
|
invitations: "Pozvat"
|
||||||
|
|
@ -479,8 +471,7 @@ uiLanguage: "Jazyk uživatelského rozhraní"
|
||||||
aboutX: "O {x}"
|
aboutX: "O {x}"
|
||||||
emojiStyle: "Styl emoji"
|
emojiStyle: "Styl emoji"
|
||||||
native: "Výchozí"
|
native: "Výchozí"
|
||||||
style: "Vzhled"
|
disableDrawer: "Nepoužívat šuplíkové menu"
|
||||||
popup: "Vyskakovací okno"
|
|
||||||
showNoteActionsOnlyHover: "Zobrazit akce poznámky jenom při naběhnutí myši"
|
showNoteActionsOnlyHover: "Zobrazit akce poznámky jenom při naběhnutí myši"
|
||||||
noHistory: "Žádná historie"
|
noHistory: "Žádná historie"
|
||||||
signinHistory: "Historie přihlášení"
|
signinHistory: "Historie přihlášení"
|
||||||
|
|
@ -543,7 +534,6 @@ showInPage: "Zobrazit na stránce"
|
||||||
popout: "Pop-out"
|
popout: "Pop-out"
|
||||||
volume: "Hlasitost"
|
volume: "Hlasitost"
|
||||||
masterVolume: "Celková hlasitost"
|
masterVolume: "Celková hlasitost"
|
||||||
notUseSound: "Zakázat zvuk"
|
|
||||||
details: "Detaily"
|
details: "Detaily"
|
||||||
chooseEmoji: "Vybrat emotikon"
|
chooseEmoji: "Vybrat emotikon"
|
||||||
unableToProcess: "Operace nebyla dokončena."
|
unableToProcess: "Operace nebyla dokončena."
|
||||||
|
|
@ -668,7 +658,10 @@ abuseReported: "Nahlášení bylo odesláno. Děkujeme převelice."
|
||||||
reporter: "Nahlásil"
|
reporter: "Nahlásil"
|
||||||
reporteeOrigin: "Původ nahlášení"
|
reporteeOrigin: "Původ nahlášení"
|
||||||
reporterOrigin: "Původ nahlasovače"
|
reporterOrigin: "Původ nahlasovače"
|
||||||
|
forwardReport: "Přeposlat nahlášení do vzdálené instance"
|
||||||
|
forwardReportIsAnonymous: "Místo vašeho účtu se ve vzdálené instanci zobrazí anonymní systémový účet jako nahlašovač."
|
||||||
send: "Odeslat"
|
send: "Odeslat"
|
||||||
|
abuseMarkAsResolved: "Označit nahlášení jako vyřešené"
|
||||||
openInNewTab: "Otevřít v nové kartě"
|
openInNewTab: "Otevřít v nové kartě"
|
||||||
openInSideView: "Otevřít v bočním panelu"
|
openInSideView: "Otevřít v bočním panelu"
|
||||||
defaultNavigationBehaviour: "Výchozí chování navigace"
|
defaultNavigationBehaviour: "Výchozí chování navigace"
|
||||||
|
|
@ -726,6 +719,7 @@ thisIsExperimentalFeature: "Tohle je experimentální funkce. Její funkce se m
|
||||||
developer: "Vývojář"
|
developer: "Vývojář"
|
||||||
makeExplorable: "Udělat účet viditelný v \"Objevit\""
|
makeExplorable: "Udělat účet viditelný v \"Objevit\""
|
||||||
makeExplorableDescription: "Pokud tohle vypnete, tak se účet přestane zobrazovat v sekci \"Objevit\"."
|
makeExplorableDescription: "Pokud tohle vypnete, tak se účet přestane zobrazovat v sekci \"Objevit\"."
|
||||||
|
showGapBetweenNotesInTimeline: "Zobrazit mezeru mezi příspěvkama na časové ose"
|
||||||
duplicate: "Duplikovat"
|
duplicate: "Duplikovat"
|
||||||
left: "Vlevo"
|
left: "Vlevo"
|
||||||
center: "Uprostřed"
|
center: "Uprostřed"
|
||||||
|
|
@ -1105,30 +1099,6 @@ sourceCode: "Zdrojový kód"
|
||||||
flip: "Otočit"
|
flip: "Otočit"
|
||||||
lastNDays: "Posledních {n} dnů"
|
lastNDays: "Posledních {n} dnů"
|
||||||
surrender: "Zrušit"
|
surrender: "Zrušit"
|
||||||
postForm: "Formulář pro odeslání"
|
|
||||||
information: "Informace"
|
|
||||||
inMinutes: "Minut"
|
|
||||||
inDays: "Dnů"
|
|
||||||
widgets: "Widgety"
|
|
||||||
presets: "Předvolba"
|
|
||||||
_imageEditing:
|
|
||||||
_vars:
|
|
||||||
filename: "Název souboru"
|
|
||||||
_imageFrameEditor:
|
|
||||||
header: "Nadpis"
|
|
||||||
font: "Písmo"
|
|
||||||
fontSerif: "Serif"
|
|
||||||
fontSansSerif: "Sans Serif"
|
|
||||||
_chat:
|
|
||||||
invitations: "Pozvat"
|
|
||||||
noHistory: "Žádná historie"
|
|
||||||
members: "Členové"
|
|
||||||
home: "Domů"
|
|
||||||
send: "Odeslat"
|
|
||||||
_delivery:
|
|
||||||
stop: "Suspendováno"
|
|
||||||
_type:
|
|
||||||
none: "Publikuji"
|
|
||||||
_initialAccountSetting:
|
_initialAccountSetting:
|
||||||
accountCreated: "Váš účet byl úspěšně vytvořen!"
|
accountCreated: "Váš účet byl úspěšně vytvořen!"
|
||||||
letsStartAccountSetup: "Pro začátek si nastavte svůj profil."
|
letsStartAccountSetup: "Pro začátek si nastavte svůj profil."
|
||||||
|
|
@ -1637,6 +1607,7 @@ _theme:
|
||||||
header: "Nadpis"
|
header: "Nadpis"
|
||||||
navBg: "Pozadí postranního panelu"
|
navBg: "Pozadí postranního panelu"
|
||||||
navFg: "Text na postranním panelu"
|
navFg: "Text na postranním panelu"
|
||||||
|
navHoverFg: "Text na postranním panelu (Hover)"
|
||||||
navActive: "Text na postranním panelu (Aktivní)"
|
navActive: "Text na postranním panelu (Aktivní)"
|
||||||
navIndicator: "Indikátor na postranním panelu"
|
navIndicator: "Indikátor na postranním panelu"
|
||||||
link: "Odkaz"
|
link: "Odkaz"
|
||||||
|
|
@ -1658,13 +1629,20 @@ _theme:
|
||||||
buttonBg: "Pozadí tlačítka"
|
buttonBg: "Pozadí tlačítka"
|
||||||
buttonHoverBg: "Pozadí tlačítka (Hover)"
|
buttonHoverBg: "Pozadí tlačítka (Hover)"
|
||||||
inputBorder: "Ohraničení vstupního pole"
|
inputBorder: "Ohraničení vstupního pole"
|
||||||
|
listItemHoverBg: "Pozadí položky seznamu (Hover)"
|
||||||
|
driveFolderBg: "Pozadí složky disku"
|
||||||
|
wallpaperOverlay: "Překrytí tapety"
|
||||||
badge: "Odznak"
|
badge: "Odznak"
|
||||||
messageBg: "Pozadí chatu"
|
messageBg: "Pozadí chatu"
|
||||||
|
accentDarken: "Akcent (Ztmavený)"
|
||||||
|
accentLighten: "Akcent (Zesvětlený)"
|
||||||
fgHighlighted: "Zvýrazněný text"
|
fgHighlighted: "Zvýrazněný text"
|
||||||
_sfx:
|
_sfx:
|
||||||
note: "Poznámky"
|
note: "Poznámky"
|
||||||
noteMy: "Moje poznámka"
|
noteMy: "Moje poznámka"
|
||||||
notification: "Oznámení"
|
notification: "Oznámení"
|
||||||
|
antenna: "Antény"
|
||||||
|
channel: "Oznámení kanálu"
|
||||||
_ago:
|
_ago:
|
||||||
future: "Budoucí"
|
future: "Budoucí"
|
||||||
justNow: "Teď"
|
justNow: "Teď"
|
||||||
|
|
@ -1686,6 +1664,7 @@ _2fa:
|
||||||
registerTOTP: "Registrovat aplikaci autentizátoru"
|
registerTOTP: "Registrovat aplikaci autentizátoru"
|
||||||
step1: "Nejprve si do zařízení nainstalujte aplikaci pro ověřování (například {a} nebo {b})."
|
step1: "Nejprve si do zařízení nainstalujte aplikaci pro ověřování (například {a} nebo {b})."
|
||||||
step2: "Poté naskenujte QR kód zobrazený na této obrazovce."
|
step2: "Poté naskenujte QR kód zobrazený na této obrazovce."
|
||||||
|
step2Click: "Kliknutím na tento QR kód můžete zaregistrovat 2FA do bezpečnostního klíče nebo aplikace autentizace telefonu."
|
||||||
step3Title: "Zadejte ověřovací kód"
|
step3Title: "Zadejte ověřovací kód"
|
||||||
step3: "Pro dokončení nastavení zadejte token poskytnutý vaší aplikací."
|
step3: "Pro dokončení nastavení zadejte token poskytnutý vaší aplikací."
|
||||||
step4: "Od této chvíle budou všechny budoucí pokusy o přihlášení vyžadovat tento přihlašovací token."
|
step4: "Od této chvíle budou všechny budoucí pokusy o přihlášení vyžadovat tento přihlašovací token."
|
||||||
|
|
@ -1735,12 +1714,11 @@ _permissions:
|
||||||
"write:gallery": "Upravit galerii"
|
"write:gallery": "Upravit galerii"
|
||||||
"read:gallery-likes": "Zobrazit seznam to se mi líbí příspěvků v galerii"
|
"read:gallery-likes": "Zobrazit seznam to se mi líbí příspěvků v galerii"
|
||||||
"write:gallery-likes": "Upravit seznam to se mi líbí příspěvků v galerii"
|
"write:gallery-likes": "Upravit seznam to se mi líbí příspěvků v galerii"
|
||||||
"write:chat": "Sestavit nebo mazat zprávy chatu"
|
|
||||||
_auth:
|
_auth:
|
||||||
shareAccessTitle: "Udělovat oprávnění k aplikacím"
|
shareAccessTitle: "Udělovat oprávnění k aplikacím"
|
||||||
shareAccess: "Chcete autorizovat \"{name}\" pro přístup k tomuto účtu?"
|
shareAccess: "Chcete autorizovat \"{name}\" pro přístup k tomuto účtu?"
|
||||||
shareAccessAsk: "Opravdu chcete této aplikaci povolit přístup k vašemu účtu?"
|
shareAccessAsk: "Opravdu chcete této aplikaci povolit přístup k vašemu účtu?"
|
||||||
permission: "{name} požaduje tato oprávnění"
|
permission: "{jméno} požaduje tato oprávnění"
|
||||||
permissionAsk: "Tato aplikace požaduje následující oprávnění"
|
permissionAsk: "Tato aplikace požaduje následující oprávnění"
|
||||||
pleaseGoBack: "Vraťte se prosím zpět do aplikace"
|
pleaseGoBack: "Vraťte se prosím zpět do aplikace"
|
||||||
callback: "Návrat k aplikaci"
|
callback: "Návrat k aplikaci"
|
||||||
|
|
@ -1789,14 +1767,6 @@ _widgets:
|
||||||
_userList:
|
_userList:
|
||||||
chooseList: "Vybrat seznam"
|
chooseList: "Vybrat seznam"
|
||||||
clicker: "Clicker"
|
clicker: "Clicker"
|
||||||
_widgetOptions:
|
|
||||||
height: "Výška"
|
|
||||||
_button:
|
|
||||||
colored: "Barevné"
|
|
||||||
_clock:
|
|
||||||
size: "Velikost"
|
|
||||||
_birthdayFollowings:
|
|
||||||
period: "Trvání"
|
|
||||||
_cw:
|
_cw:
|
||||||
hide: "Skrýt"
|
hide: "Skrýt"
|
||||||
show: "Zobrazit více"
|
show: "Zobrazit více"
|
||||||
|
|
@ -1839,9 +1809,6 @@ _postForm:
|
||||||
replyPlaceholder: "Odpovědět na tuto poznámku..."
|
replyPlaceholder: "Odpovědět na tuto poznámku..."
|
||||||
quotePlaceholder: "Citovat tuto poznámku..."
|
quotePlaceholder: "Citovat tuto poznámku..."
|
||||||
channelPlaceholder: "Zveřejnit příspěvek do kanálu..."
|
channelPlaceholder: "Zveřejnit příspěvek do kanálu..."
|
||||||
_howToUse:
|
|
||||||
visibility_title: "Viditelnost"
|
|
||||||
menu_title: "Menu"
|
|
||||||
_placeholders:
|
_placeholders:
|
||||||
a: "Co máte v plánu?"
|
a: "Co máte v plánu?"
|
||||||
b: "Co se děje kolem vás?"
|
b: "Co se děje kolem vás?"
|
||||||
|
|
@ -1921,6 +1888,9 @@ _pages:
|
||||||
newPage: "Vytvořit novou stránku"
|
newPage: "Vytvořit novou stránku"
|
||||||
editPage: "Upravit stránku"
|
editPage: "Upravit stránku"
|
||||||
readPage: "Prohlížení zdroje této stránky"
|
readPage: "Prohlížení zdroje této stránky"
|
||||||
|
created: "Stránka byla úspěšně vytvořena"
|
||||||
|
updated: "Stránka byla úspěšně aktualizována"
|
||||||
|
deleted: "Stránka byla úspěšně smazána"
|
||||||
pageSetting: "Nastavení stránky"
|
pageSetting: "Nastavení stránky"
|
||||||
nameAlreadyExists: "Zadaná adresa URL stránky již existuje"
|
nameAlreadyExists: "Zadaná adresa URL stránky již existuje"
|
||||||
invalidNameTitle: "Zadaná adresa URL stránky je neplatná"
|
invalidNameTitle: "Zadaná adresa URL stránky je neplatná"
|
||||||
|
|
@ -1972,7 +1942,7 @@ _notification:
|
||||||
youGotMention: "{name} vás zmínil"
|
youGotMention: "{name} vás zmínil"
|
||||||
youGotReply: "{name} vám odpověděl"
|
youGotReply: "{name} vám odpověděl"
|
||||||
youGotQuote: "{name} vás citoval"
|
youGotQuote: "{name} vás citoval"
|
||||||
youRenoted: "Poznámka od {name}"
|
youRenoted: "Poznámka od {jméno}"
|
||||||
youWereFollowed: "Máte nového následovníka"
|
youWereFollowed: "Máte nového následovníka"
|
||||||
youReceivedFollowRequest: "Obdrželi jste žádost o sledování"
|
youReceivedFollowRequest: "Obdrželi jste žádost o sledování"
|
||||||
yourFollowRequestAccepted: "Vaše žádost o sledování byla přijata"
|
yourFollowRequestAccepted: "Vaše žádost o sledování byla přijata"
|
||||||
|
|
@ -1992,7 +1962,6 @@ _notification:
|
||||||
receiveFollowRequest: "Obdržené žádosti o sledování"
|
receiveFollowRequest: "Obdržené žádosti o sledování"
|
||||||
followRequestAccepted: "Přijaté žádosti o sledování"
|
followRequestAccepted: "Přijaté žádosti o sledování"
|
||||||
achievementEarned: "Úspěch odemčen"
|
achievementEarned: "Úspěch odemčen"
|
||||||
login: "Přihlásit se"
|
|
||||||
app: "Oznámení z propojených aplikací"
|
app: "Oznámení z propojených aplikací"
|
||||||
_actions:
|
_actions:
|
||||||
followBack: "vás začal sledovat zpět"
|
followBack: "vás začal sledovat zpět"
|
||||||
|
|
@ -2025,7 +1994,7 @@ _deck:
|
||||||
list: "Seznamy"
|
list: "Seznamy"
|
||||||
channel: "Kanály"
|
channel: "Kanály"
|
||||||
mentions: "Zmínění"
|
mentions: "Zmínění"
|
||||||
direct: "Přímé poznámky"
|
direct: "Přímý"
|
||||||
roleTimeline: "Časová osa role"
|
roleTimeline: "Časová osa role"
|
||||||
_dialog:
|
_dialog:
|
||||||
charactersExceeded: "Překročili jste maximální počet znaků! V současné době je na hodnotě {current} z {max}."
|
charactersExceeded: "Překročili jste maximální počet znaků! V současné době je na hodnotě {current} z {max}."
|
||||||
|
|
@ -2040,6 +2009,7 @@ _webhookSettings:
|
||||||
createWebhook: "Vytvořit Webhook"
|
createWebhook: "Vytvořit Webhook"
|
||||||
name: "Jméno"
|
name: "Jméno"
|
||||||
secret: "Tajné"
|
secret: "Tajné"
|
||||||
|
events: "Události Webhook"
|
||||||
active: "Zapnuto"
|
active: "Zapnuto"
|
||||||
_events:
|
_events:
|
||||||
follow: "Při sledování uživatele"
|
follow: "Při sledování uživatele"
|
||||||
|
|
@ -2049,39 +2019,10 @@ _webhookSettings:
|
||||||
renote: "Při renotaci poznámky"
|
renote: "Při renotaci poznámky"
|
||||||
reaction: "Při obdržení reakce"
|
reaction: "Při obdržení reakce"
|
||||||
mention: "Při zmínce"
|
mention: "Při zmínce"
|
||||||
_abuseReport:
|
|
||||||
_notificationRecipient:
|
|
||||||
_recipientType:
|
|
||||||
mail: "Email"
|
|
||||||
_moderationLogTypes:
|
_moderationLogTypes:
|
||||||
suspend: "Zmrazit"
|
suspend: "Zmrazit"
|
||||||
resetPassword: "Resetovat heslo"
|
resetPassword: "Resetovat heslo"
|
||||||
createInvitation: "Vygenerovat pozvánku"
|
createInvitation: "Vygenerovat pozvánku"
|
||||||
_reversi:
|
_reversi:
|
||||||
total: "Celkem"
|
total: "Celkem"
|
||||||
_remoteLookupErrors:
|
|
||||||
_noSuchObject:
|
|
||||||
title: "Nenalezeno"
|
|
||||||
_search:
|
|
||||||
searchScopeAll: "Vše"
|
|
||||||
searchScopeLocal: "Místní"
|
|
||||||
searchScopeUser: "Upřesnit uživatele"
|
|
||||||
_watermarkEditor:
|
|
||||||
opacity: "Průhlednost"
|
|
||||||
scale: "Velikost"
|
|
||||||
text: "Text"
|
|
||||||
position: "Pozice"
|
|
||||||
type: "Typ"
|
|
||||||
image: "Obrázky"
|
|
||||||
advanced: "Pokročilé"
|
|
||||||
_imageEffector:
|
|
||||||
_fxProps:
|
|
||||||
scale: "Velikost"
|
|
||||||
size: "Velikost"
|
|
||||||
offset: "Pozice"
|
|
||||||
color: "Barva"
|
|
||||||
opacity: "Průhlednost"
|
|
||||||
lightness: "Zesvětlit"
|
|
||||||
_qr:
|
|
||||||
showTabTitle: "Zobrazit"
|
|
||||||
raw: "Text"
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
---
|
---
|
||||||
_lang_: "Dansk"
|
_lang_: "Dansk"
|
||||||
headlineMisskey: ""
|
|
||||||
introMisskey: "ようこそ!Misskeyは、オープンソースの分散型マイクロブログサービスです。\n「ノート」を作成して、いま起こっていることを共有したり、あなたについて皆に発信しよう📡\n「リアクション」機能で、皆のノートに素早く反応を追加することもできます👍\n新しい世界を探検しよう🚀"
|
|
||||||
|
|
|
||||||
1048
locales/de-DE.yml
1048
locales/de-DE.yml
File diff suppressed because it is too large
Load Diff
|
|
@ -162,12 +162,14 @@ imageUrl: "URL εικόνας"
|
||||||
remove: "Διαγραφή"
|
remove: "Διαγραφή"
|
||||||
removed: "Η διαγραφή ολοκληρώθηκε επιτυχώς"
|
removed: "Η διαγραφή ολοκληρώθηκε επιτυχώς"
|
||||||
saved: "Αποθηκεύτηκε"
|
saved: "Αποθηκεύτηκε"
|
||||||
|
messaging: "Συνομιλία"
|
||||||
upload: "Ανεβάστε"
|
upload: "Ανεβάστε"
|
||||||
fromDrive: "Από τον Αποθηκευτικό Χώρο"
|
fromDrive: "Από τον Αποθηκευτικό Χώρο"
|
||||||
fromUrl: "Από URL"
|
fromUrl: "Από URL"
|
||||||
uploadFromUrl: "Ανεβάστε από URL"
|
uploadFromUrl: "Ανεβάστε από URL"
|
||||||
explore: "Εξερευνήστε"
|
explore: "Εξερευνήστε"
|
||||||
messageRead: "Διαβάστηκε"
|
messageRead: "Διαβάστηκε"
|
||||||
|
startMessaging: "Ξεκινήστε μία συνομιλία"
|
||||||
nUsersRead: "διαβάστηκε από {n}"
|
nUsersRead: "διαβάστηκε από {n}"
|
||||||
start: "Ας αρχίσουμε"
|
start: "Ας αρχίσουμε"
|
||||||
home: "Κεντρικό"
|
home: "Κεντρικό"
|
||||||
|
|
@ -286,15 +288,6 @@ cannotUploadBecauseNoFreeSpace: "Το ανέβασμα απέτυχε λόγω
|
||||||
icon: "Εικονίδιο"
|
icon: "Εικονίδιο"
|
||||||
replies: "Απάντηση"
|
replies: "Απάντηση"
|
||||||
renotes: "Κοινοποίηση σημειώματος"
|
renotes: "Κοινοποίηση σημειώματος"
|
||||||
postForm: "Φόρμα δημοσίευσης"
|
|
||||||
information: "Πληροφορίες"
|
|
||||||
widgets: "Μαραφέτια"
|
|
||||||
_imageEditing:
|
|
||||||
_vars:
|
|
||||||
filename: "Όνομα αρχείου"
|
|
||||||
_chat:
|
|
||||||
members: "Μέλη"
|
|
||||||
home: "Κεντρικό"
|
|
||||||
_email:
|
_email:
|
||||||
_follow:
|
_follow:
|
||||||
title: "Έχετε ένα νέο ακόλουθο"
|
title: "Έχετε ένα νέο ακόλουθο"
|
||||||
|
|
@ -308,6 +301,8 @@ _theme:
|
||||||
_sfx:
|
_sfx:
|
||||||
note: "Σημειώματα"
|
note: "Σημειώματα"
|
||||||
notification: "Ειδοποιήσεις"
|
notification: "Ειδοποιήσεις"
|
||||||
|
antenna: "Αντένες"
|
||||||
|
channel: "Ειδοποιήσεις καναλιών"
|
||||||
_ago:
|
_ago:
|
||||||
future: "Μελλοντικό"
|
future: "Μελλοντικό"
|
||||||
justNow: "Μόλις τώρα"
|
justNow: "Μόλις τώρα"
|
||||||
|
|
@ -328,7 +323,6 @@ _permissions:
|
||||||
"write:notifications": "Διαχειριστείτε τις ειδοποιήσεις σας"
|
"write:notifications": "Διαχειριστείτε τις ειδοποιήσεις σας"
|
||||||
"read:pages": "Δείτε τις Σελίδες σας"
|
"read:pages": "Δείτε τις Σελίδες σας"
|
||||||
"write:pages": "Επεξεργαστείτε ή διαγράψτε τις σελίδες σας"
|
"write:pages": "Επεξεργαστείτε ή διαγράψτε τις σελίδες σας"
|
||||||
"write:chat": "Γράψτε ή διαγράψτε μηνύματα συνομιλίας"
|
|
||||||
_antennaSources:
|
_antennaSources:
|
||||||
all: "Όλα τα σημειώματα"
|
all: "Όλα τα σημειώματα"
|
||||||
homeTimeline: "Σημειώματα από μέλη που ακολουθείτε"
|
homeTimeline: "Σημειώματα από μέλη που ακολουθείτε"
|
||||||
|
|
@ -357,7 +351,6 @@ _visibility:
|
||||||
home: "Κεντρικό"
|
home: "Κεντρικό"
|
||||||
homeDescription: "Δημοσίευση στο κεντρικό χρονολόγιο μόνο"
|
homeDescription: "Δημοσίευση στο κεντρικό χρονολόγιο μόνο"
|
||||||
followers: "Ακολουθούν"
|
followers: "Ακολουθούν"
|
||||||
specified: "Απευθείας σημειώματα"
|
|
||||||
_profile:
|
_profile:
|
||||||
name: "Όνομα"
|
name: "Όνομα"
|
||||||
username: "Όνομα μέλους"
|
username: "Όνομα μέλους"
|
||||||
|
|
@ -387,7 +380,6 @@ _notification:
|
||||||
renote: "Κοινοποίηση σημειώματος"
|
renote: "Κοινοποίηση σημειώματος"
|
||||||
quote: "Παράθεση"
|
quote: "Παράθεση"
|
||||||
reaction: "Αντιδράσεις"
|
reaction: "Αντιδράσεις"
|
||||||
login: "Σύνδεση"
|
|
||||||
_actions:
|
_actions:
|
||||||
reply: "Απάντηση"
|
reply: "Απάντηση"
|
||||||
renote: "Κοινοποίηση σημειώματος"
|
renote: "Κοινοποίηση σημειώματος"
|
||||||
|
|
@ -400,14 +392,10 @@ _deck:
|
||||||
antenna: "Αντένες"
|
antenna: "Αντένες"
|
||||||
list: "Λίστα"
|
list: "Λίστα"
|
||||||
mentions: "Επισημάνσεις"
|
mentions: "Επισημάνσεις"
|
||||||
direct: "Απευθείας σημειώματα"
|
|
||||||
_webhookSettings:
|
_webhookSettings:
|
||||||
name: "Όνομα"
|
name: "Όνομα"
|
||||||
_moderationLogTypes:
|
_moderationLogTypes:
|
||||||
suspend: "Αποβολή"
|
suspend: "Αποβολή"
|
||||||
_reversi:
|
_reversi:
|
||||||
total: "Σύνολο"
|
total: "Σύνολο"
|
||||||
_search:
|
|
||||||
searchScopeLocal: "Τοπικό"
|
|
||||||
_watermarkEditor:
|
|
||||||
image: "Εικόνες"
|
|
||||||
|
|
|
||||||
1033
locales/en-US.yml
1033
locales/en-US.yml
File diff suppressed because it is too large
Load Diff
1271
locales/es-ES.yml
1271
locales/es-ES.yml
File diff suppressed because it is too large
Load Diff
|
|
@ -5,13 +5,9 @@ introMisskey: "Bienvenue ! Misskey est un service de microblogage décentralis
|
||||||
poweredByMisskeyDescription: "{name} est l'un des services propulsés par la plateforme ouverte <b>Misskey</b> (appelée \"instance Misskey\")."
|
poweredByMisskeyDescription: "{name} est l'un des services propulsés par la plateforme ouverte <b>Misskey</b> (appelée \"instance Misskey\")."
|
||||||
monthAndDay: "{day}/{month}"
|
monthAndDay: "{day}/{month}"
|
||||||
search: "Rechercher"
|
search: "Rechercher"
|
||||||
reset: "Réinitialiser"
|
|
||||||
notifications: "Notifications"
|
notifications: "Notifications"
|
||||||
username: "Nom d’utilisateur·rice"
|
username: "Nom d’utilisateur·rice"
|
||||||
password: "Mot de passe"
|
password: "Mot de passe"
|
||||||
initialPasswordForSetup: "Mot de passe initial pour la configuration"
|
|
||||||
initialPasswordIsIncorrect: "Le mot de passe initial pour la configuration est incorrect"
|
|
||||||
initialPasswordForSetupDescription: "Utilisez le mot de passe que vous avez entré pour le fichier de configuration si vous avez installé Misskey vous-même.\nSi vous utilisez un service d'hébergement Misskey, utilisez le mot de passe fourni.\nSi vous n'avez pas défini de mot de passe, laissez le champ vide pour continuer."
|
|
||||||
forgotPassword: "Mot de passe oublié"
|
forgotPassword: "Mot de passe oublié"
|
||||||
fetchingAsApObject: "Récupération depuis le fédiverse …"
|
fetchingAsApObject: "Récupération depuis le fédiverse …"
|
||||||
ok: "OK"
|
ok: "OK"
|
||||||
|
|
@ -49,7 +45,6 @@ pin: "Épingler sur le profil"
|
||||||
unpin: "Désépingler"
|
unpin: "Désépingler"
|
||||||
copyContent: "Copier le contenu"
|
copyContent: "Copier le contenu"
|
||||||
copyLink: "Copier le lien"
|
copyLink: "Copier le lien"
|
||||||
copyRemoteLink: "Copier le lien de la note"
|
|
||||||
copyLinkRenote: "Copier le lien de la renote"
|
copyLinkRenote: "Copier le lien de la renote"
|
||||||
delete: "Supprimer"
|
delete: "Supprimer"
|
||||||
deleteAndEdit: "Supprimer et réécrire"
|
deleteAndEdit: "Supprimer et réécrire"
|
||||||
|
|
@ -64,8 +59,7 @@ copyNoteId: "Copier l'identifiant de la note"
|
||||||
copyFileId: "Copier l'identifiant du fichier"
|
copyFileId: "Copier l'identifiant du fichier"
|
||||||
copyFolderId: "Copier l'identifiant du dossier"
|
copyFolderId: "Copier l'identifiant du dossier"
|
||||||
copyProfileUrl: "Copier l'URL du profil"
|
copyProfileUrl: "Copier l'URL du profil"
|
||||||
searchUser: "Chercher un utilisateur"
|
searchUser: "Chercher un·e utilisateur·rice"
|
||||||
searchThisUsersNotes: "Cherchez les notes de cet utilisateur"
|
|
||||||
reply: "Répondre"
|
reply: "Répondre"
|
||||||
loadMore: "Afficher plus …"
|
loadMore: "Afficher plus …"
|
||||||
showMore: "Voir plus"
|
showMore: "Voir plus"
|
||||||
|
|
@ -83,8 +77,6 @@ files: "Fichiers"
|
||||||
download: "Télécharger"
|
download: "Télécharger"
|
||||||
driveFileDeleteConfirm: "Êtes-vous sûr·e de vouloir supprimer le fichier « {name} » ? Les notes avec ce fichier joint seront aussi supprimées."
|
driveFileDeleteConfirm: "Êtes-vous sûr·e de vouloir supprimer le fichier « {name} » ? Les notes avec ce fichier joint seront aussi supprimées."
|
||||||
unfollowConfirm: "Désirez-vous vous désabonner de {name} ?"
|
unfollowConfirm: "Désirez-vous vous désabonner de {name} ?"
|
||||||
cancelFollowRequestConfirm: "Est-te vous sur de vouloir annuler la demande de suivi de {name} ?"
|
|
||||||
rejectFollowRequestConfirm: "Refuser la demande de suivi de {name} ?"
|
|
||||||
exportRequested: "Vous avez demandé une exportation. L’opération pourrait prendre un peu de temps. Une fois terminée, le fichier sera ajouté au Drive."
|
exportRequested: "Vous avez demandé une exportation. L’opération pourrait prendre un peu de temps. Une fois terminée, le fichier sera ajouté au Drive."
|
||||||
importRequested: "Vous avez initié un import. Cela pourrait prendre un peu de temps."
|
importRequested: "Vous avez initié un import. Cela pourrait prendre un peu de temps."
|
||||||
lists: "Listes"
|
lists: "Listes"
|
||||||
|
|
@ -116,14 +108,11 @@ enterEmoji: "Insérer un émoji"
|
||||||
renote: "Renoter"
|
renote: "Renoter"
|
||||||
unrenote: "Annuler la Renote"
|
unrenote: "Annuler la Renote"
|
||||||
renoted: "Renoté !"
|
renoted: "Renoté !"
|
||||||
renotedToX: "Renoté en {name}"
|
|
||||||
cantRenote: "Ce message ne peut pas être renoté."
|
cantRenote: "Ce message ne peut pas être renoté."
|
||||||
cantReRenote: "Impossible de renoter une Renote."
|
cantReRenote: "Impossible de renoter une Renote."
|
||||||
quote: "Citer"
|
quote: "Citer"
|
||||||
inChannelRenote: "Renoter dans le canal"
|
inChannelRenote: "Renoter dans le canal"
|
||||||
inChannelQuote: "Citer dans le canal"
|
inChannelQuote: "Citer dans le canal"
|
||||||
renoteToChannel: "Renoter sur le canal"
|
|
||||||
renoteToOtherChannel: "Renoter sur un autre canal"
|
|
||||||
pinnedNote: "Note épinglée"
|
pinnedNote: "Note épinglée"
|
||||||
pinned: "Épingler sur le profil"
|
pinned: "Épingler sur le profil"
|
||||||
you: "Vous"
|
you: "Vous"
|
||||||
|
|
@ -140,7 +129,7 @@ overwriteFromPinnedEmojisForReaction: "Remplacer par les émojis épinglés pour
|
||||||
overwriteFromPinnedEmojis: "Remplacer par les émojis épinglés globalement"
|
overwriteFromPinnedEmojis: "Remplacer par les émojis épinglés globalement"
|
||||||
reactionSettingDescription2: "Déplacer pour réorganiser, cliquer pour effacer, utiliser « + » pour ajouter."
|
reactionSettingDescription2: "Déplacer pour réorganiser, cliquer pour effacer, utiliser « + » pour ajouter."
|
||||||
rememberNoteVisibility: "Se souvenir de la visibilité des notes"
|
rememberNoteVisibility: "Se souvenir de la visibilité des notes"
|
||||||
attachCancel: "Supprimer le fichier joint"
|
attachCancel: "Supprimer le fichier attaché"
|
||||||
deleteFile: "Fichier supprimé"
|
deleteFile: "Fichier supprimé"
|
||||||
markAsSensitive: "Marquer comme sensible"
|
markAsSensitive: "Marquer comme sensible"
|
||||||
unmarkAsSensitive: "Supprimer le marquage comme sensible"
|
unmarkAsSensitive: "Supprimer le marquage comme sensible"
|
||||||
|
|
@ -162,7 +151,6 @@ editList: "Modifier la liste"
|
||||||
selectChannel: "Sélectionner un canal"
|
selectChannel: "Sélectionner un canal"
|
||||||
selectAntenna: "Sélectionner une antenne"
|
selectAntenna: "Sélectionner une antenne"
|
||||||
editAntenna: "Modifier l'antenne"
|
editAntenna: "Modifier l'antenne"
|
||||||
createAntenna: "Créer une antenne"
|
|
||||||
selectWidget: "Sélectionner un widget"
|
selectWidget: "Sélectionner un widget"
|
||||||
editWidgets: "Modifier les widgets"
|
editWidgets: "Modifier les widgets"
|
||||||
editWidgetsExit: "Valider les modifications"
|
editWidgetsExit: "Valider les modifications"
|
||||||
|
|
@ -189,7 +177,6 @@ addAccount: "Ajouter un compte"
|
||||||
reloadAccountsList: "Rafraichir la liste des comptes"
|
reloadAccountsList: "Rafraichir la liste des comptes"
|
||||||
loginFailed: "Échec de la connexion"
|
loginFailed: "Échec de la connexion"
|
||||||
showOnRemote: "Voir sur l’instance distante"
|
showOnRemote: "Voir sur l’instance distante"
|
||||||
continueOnRemote: "Continuer sur l'instance distante"
|
|
||||||
general: "Général"
|
general: "Général"
|
||||||
wallpaper: "Fond d’écran"
|
wallpaper: "Fond d’écran"
|
||||||
setWallpaper: "Définir le fond d’écran"
|
setWallpaper: "Définir le fond d’écran"
|
||||||
|
|
@ -200,7 +187,6 @@ followConfirm: "Êtes-vous sûr·e de vouloir suivre {name} ?"
|
||||||
proxyAccount: "Compte proxy"
|
proxyAccount: "Compte proxy"
|
||||||
proxyAccountDescription: "Un compte proxy se comporte, dans certaines conditions, comme un·e abonné·e distant·e pour les utilisateurs d'autres instances. Par exemple, quand un·e utilisateur·rice ajoute un·e utilisateur·rice distant·e à une liste, ses notes ne seront pas visibles sur l'instance si personne ne suit cet·te utilisateur·rice. Le compte proxy va donc suivre cet·te utilisateur·rice pour que ses notes soient acheminées."
|
proxyAccountDescription: "Un compte proxy se comporte, dans certaines conditions, comme un·e abonné·e distant·e pour les utilisateurs d'autres instances. Par exemple, quand un·e utilisateur·rice ajoute un·e utilisateur·rice distant·e à une liste, ses notes ne seront pas visibles sur l'instance si personne ne suit cet·te utilisateur·rice. Le compte proxy va donc suivre cet·te utilisateur·rice pour que ses notes soient acheminées."
|
||||||
host: "Serveur distant"
|
host: "Serveur distant"
|
||||||
selectSelf: "Sélectionner manuellement"
|
|
||||||
selectUser: "Sélectionner un·e utilisateur·rice"
|
selectUser: "Sélectionner un·e utilisateur·rice"
|
||||||
recipient: "Destinataire"
|
recipient: "Destinataire"
|
||||||
annotation: "Commentaires"
|
annotation: "Commentaires"
|
||||||
|
|
@ -218,7 +204,6 @@ blockThisInstance: "Bloquer cette instance"
|
||||||
silenceThisInstance: "Mettre cette instance en sourdine"
|
silenceThisInstance: "Mettre cette instance en sourdine"
|
||||||
operations: "Opérations"
|
operations: "Opérations"
|
||||||
software: "Logiciel"
|
software: "Logiciel"
|
||||||
softwareName: "Nom du logiciel"
|
|
||||||
version: "Version"
|
version: "Version"
|
||||||
metadata: "Métadonnées"
|
metadata: "Métadonnées"
|
||||||
withNFiles: "{n} fichier(s)"
|
withNFiles: "{n} fichier(s)"
|
||||||
|
|
@ -238,9 +223,6 @@ blockedInstances: "Instances bloquées"
|
||||||
blockedInstancesDescription: "Listez les instances que vous désirez bloquer, une par ligne. Ces instances ne seront plus en capacité d'interagir avec votre instance."
|
blockedInstancesDescription: "Listez les instances que vous désirez bloquer, une par ligne. Ces instances ne seront plus en capacité d'interagir avec votre instance."
|
||||||
silencedInstances: "Instances mises en sourdine"
|
silencedInstances: "Instances mises en sourdine"
|
||||||
silencedInstancesDescription: "Énumérer les noms d'hôte des instances à mettre en sourdine. Tous les comptes des instances énumérées seront traités comme mis en sourdine, ne peuvent faire que des demandes de suivi et ne peuvent pas mentionner les comptes locaux s'ils ne sont pas suivis. Cela n'affectera pas les instances bloquées."
|
silencedInstancesDescription: "Énumérer les noms d'hôte des instances à mettre en sourdine. Tous les comptes des instances énumérées seront traités comme mis en sourdine, ne peuvent faire que des demandes de suivi et ne peuvent pas mentionner les comptes locaux s'ils ne sont pas suivis. Cela n'affectera pas les instances bloquées."
|
||||||
mediaSilencedInstances: "Médias silencieux sur ces instances"
|
|
||||||
mediaSilencedInstancesDescription: "Liste des noms de serveurs où vous voulez que les médias soient silencieux, séparés par un retour à la ligne.\nTous les comptes des instances listées seront considérés comme sensibles, et ne peuvent pas utilisés d'émojis personnalisés. Ceci n'affectera pas les serveurs bloquées."
|
|
||||||
federationAllowedHosts: "Serveurs qui autorisent la fédération"
|
|
||||||
muteAndBlock: "Masqué·e·s / Bloqué·e·s"
|
muteAndBlock: "Masqué·e·s / Bloqué·e·s"
|
||||||
mutedUsers: "Utilisateur·rice·s en sourdine"
|
mutedUsers: "Utilisateur·rice·s en sourdine"
|
||||||
blockedUsers: "Utilisateur·rice·s bloqué·e·s"
|
blockedUsers: "Utilisateur·rice·s bloqué·e·s"
|
||||||
|
|
@ -248,6 +230,7 @@ noUsers: "Il n’y a pas d’utilisateur·rice·s"
|
||||||
editProfile: "Modifier votre profil"
|
editProfile: "Modifier votre profil"
|
||||||
noteDeleteConfirm: "Êtes-vous sûr·e de vouloir supprimer cette note ?"
|
noteDeleteConfirm: "Êtes-vous sûr·e de vouloir supprimer cette note ?"
|
||||||
pinLimitExceeded: "Vous ne pouvez plus épingler d’autres notes."
|
pinLimitExceeded: "Vous ne pouvez plus épingler d’autres notes."
|
||||||
|
intro: "L’installation de Misskey est terminée ! Veuillez créer un compte administrateur."
|
||||||
done: "Terminé"
|
done: "Terminé"
|
||||||
processing: "Traitement en cours"
|
processing: "Traitement en cours"
|
||||||
preview: "Aperçu"
|
preview: "Aperçu"
|
||||||
|
|
@ -286,6 +269,7 @@ deleteAreYouSure: "Êtes-vous sûr·e de vouloir supprimer « {x} » ?"
|
||||||
resetAreYouSure: "Voulez-vous réinitialiser ?"
|
resetAreYouSure: "Voulez-vous réinitialiser ?"
|
||||||
areYouSure: "Êtes-vous sûr·e ?"
|
areYouSure: "Êtes-vous sûr·e ?"
|
||||||
saved: "Enregistré"
|
saved: "Enregistré"
|
||||||
|
messaging: "Discuter"
|
||||||
upload: "Téléverser"
|
upload: "Téléverser"
|
||||||
keepOriginalUploading: "Garder l’image d’origine"
|
keepOriginalUploading: "Garder l’image d’origine"
|
||||||
keepOriginalUploadingDescription: "Conserve la version originale lors du téléchargement d'images. S'il est désactivé, le navigateur génère l'image pour la publication web lors du téléchargement."
|
keepOriginalUploadingDescription: "Conserve la version originale lors du téléchargement d'images. S'il est désactivé, le navigateur génère l'image pour la publication web lors du téléchargement."
|
||||||
|
|
@ -298,6 +282,7 @@ uploadFromUrlMayTakeTime: "Le téléversement de votre fichier peut prendre un c
|
||||||
explore: "Découvrir"
|
explore: "Découvrir"
|
||||||
messageRead: "Lu"
|
messageRead: "Lu"
|
||||||
noMoreHistory: "Il n’y a plus d’historique"
|
noMoreHistory: "Il n’y a plus d’historique"
|
||||||
|
startMessaging: "Commencer à discuter"
|
||||||
nUsersRead: "Lu par {n} personnes"
|
nUsersRead: "Lu par {n} personnes"
|
||||||
agreeTo: "J’accepte {0}"
|
agreeTo: "J’accepte {0}"
|
||||||
agree: "Accepter"
|
agree: "Accepter"
|
||||||
|
|
@ -335,7 +320,6 @@ renameFolder: "Renommer le dossier"
|
||||||
deleteFolder: "Supprimer le dossier"
|
deleteFolder: "Supprimer le dossier"
|
||||||
folder: "Dossier"
|
folder: "Dossier"
|
||||||
addFile: "Ajouter un fichier"
|
addFile: "Ajouter un fichier"
|
||||||
showFile: "Voir les fichiers"
|
|
||||||
emptyDrive: "Le Disque est vide"
|
emptyDrive: "Le Disque est vide"
|
||||||
emptyFolder: "Le dossier est vide"
|
emptyFolder: "Le dossier est vide"
|
||||||
unableToDelete: "Suppression impossible"
|
unableToDelete: "Suppression impossible"
|
||||||
|
|
@ -378,6 +362,7 @@ enableLocalTimeline: "Activer le fil local"
|
||||||
enableGlobalTimeline: "Activer le fil global"
|
enableGlobalTimeline: "Activer le fil global"
|
||||||
disablingTimelinesInfo: "Même si vous désactivez ces fils, les administrateur·rice·s et les modérateur·rice·s pourront toujours y accéder."
|
disablingTimelinesInfo: "Même si vous désactivez ces fils, les administrateur·rice·s et les modérateur·rice·s pourront toujours y accéder."
|
||||||
registration: "S’inscrire"
|
registration: "S’inscrire"
|
||||||
|
enableRegistration: "Autoriser les nouvelles inscriptions"
|
||||||
invite: "Inviter"
|
invite: "Inviter"
|
||||||
driveCapacityPerLocalAccount: "Capacité de stockage du Disque par utilisateur local"
|
driveCapacityPerLocalAccount: "Capacité de stockage du Disque par utilisateur local"
|
||||||
driveCapacityPerRemoteAccount: "Capacité de stockage du Disque par utilisateur distant"
|
driveCapacityPerRemoteAccount: "Capacité de stockage du Disque par utilisateur distant"
|
||||||
|
|
@ -415,7 +400,6 @@ name: "Nom"
|
||||||
antennaSource: "Source de l’antenne"
|
antennaSource: "Source de l’antenne"
|
||||||
antennaKeywords: "Mots clés à recevoir"
|
antennaKeywords: "Mots clés à recevoir"
|
||||||
antennaExcludeKeywords: "Mots clés à exclure"
|
antennaExcludeKeywords: "Mots clés à exclure"
|
||||||
antennaExcludeBots: "Exclure les comptes robot"
|
|
||||||
antennaKeywordsDescription: "Séparer avec des espaces pour la condition AND. Séparer avec un saut de ligne pour une condition OR."
|
antennaKeywordsDescription: "Séparer avec des espaces pour la condition AND. Séparer avec un saut de ligne pour une condition OR."
|
||||||
notifyAntenna: "Me notifier pour les nouvelles notes"
|
notifyAntenna: "Me notifier pour les nouvelles notes"
|
||||||
withFileAntenna: "Notes ayant des fichiers joints uniquement"
|
withFileAntenna: "Notes ayant des fichiers joints uniquement"
|
||||||
|
|
@ -445,11 +429,10 @@ token: "Jeton"
|
||||||
2fa: "Authentification à deux facteurs"
|
2fa: "Authentification à deux facteurs"
|
||||||
setupOf2fa: "Configuration de l’authentification à deux facteurs"
|
setupOf2fa: "Configuration de l’authentification à deux facteurs"
|
||||||
totp: "Application d'authentification"
|
totp: "Application d'authentification"
|
||||||
totpDescription: "Entrer un mot de passe à usage unique à l'aide d'une application d'authentification"
|
totpDescription: "Entrez un mot de passe à usage unique à l'aide d'une application d'authentification"
|
||||||
moderator: "Modérateur·rice·s"
|
moderator: "Modérateur·rice·s"
|
||||||
moderation: "Modérations"
|
moderation: "Modérations"
|
||||||
moderationNote: "Note de modération"
|
moderationNote: "Note de modération"
|
||||||
moderationNoteDescription: "Vous pouvez remplir des notes qui seront partagés seulement entre modérateurs."
|
|
||||||
addModerationNote: "Ajouter une note de modération"
|
addModerationNote: "Ajouter une note de modération"
|
||||||
moderationLogs: "Journal de modération"
|
moderationLogs: "Journal de modération"
|
||||||
nUsersMentioned: "{n} utilisateur·rice·s mentionné·e·s"
|
nUsersMentioned: "{n} utilisateur·rice·s mentionné·e·s"
|
||||||
|
|
@ -484,6 +467,8 @@ retype: "Confirmation"
|
||||||
noteOf: "Notes de {user}"
|
noteOf: "Notes de {user}"
|
||||||
quoteAttached: "Avec citation"
|
quoteAttached: "Avec citation"
|
||||||
quoteQuestion: "Souhaitez-vous ajouter une citation ?"
|
quoteQuestion: "Souhaitez-vous ajouter une citation ?"
|
||||||
|
noMessagesYet: "Pas encore de discussion"
|
||||||
|
newMessageExists: "Vous avez un nouveau message"
|
||||||
onlyOneFileCanBeAttached: "Vous ne pouvez joindre qu’un seul fichier au message"
|
onlyOneFileCanBeAttached: "Vous ne pouvez joindre qu’un seul fichier au message"
|
||||||
signinRequired: "Veuillez vous connecter"
|
signinRequired: "Veuillez vous connecter"
|
||||||
invitations: "Invitations"
|
invitations: "Invitations"
|
||||||
|
|
@ -507,12 +492,8 @@ uiLanguage: "Langue d’affichage de l’interface"
|
||||||
aboutX: "À propos de {x}"
|
aboutX: "À propos de {x}"
|
||||||
emojiStyle: "Style des émojis"
|
emojiStyle: "Style des émojis"
|
||||||
native: "Natif"
|
native: "Natif"
|
||||||
menuStyle: "Style du menu"
|
disableDrawer: "Les menus ne s'affichent pas dans le tiroir"
|
||||||
style: "Style"
|
|
||||||
drawer: "Sélecteur"
|
|
||||||
popup: "Pop-up"
|
|
||||||
showNoteActionsOnlyHover: "Afficher les actions de note uniquement au survol"
|
showNoteActionsOnlyHover: "Afficher les actions de note uniquement au survol"
|
||||||
showReactionsCount: "Afficher le nombre de réactions des notes"
|
|
||||||
noHistory: "Pas d'historique"
|
noHistory: "Pas d'historique"
|
||||||
signinHistory: "Historique de connexion"
|
signinHistory: "Historique de connexion"
|
||||||
enableAdvancedMfm: "Activer la MFM avancée"
|
enableAdvancedMfm: "Activer la MFM avancée"
|
||||||
|
|
@ -560,7 +541,6 @@ objectStorageUseSSLDesc: "Désactivez cette option si vous n'utilisez pas HTTPS
|
||||||
objectStorageUseProxy: "Se connecter via proxy"
|
objectStorageUseProxy: "Se connecter via proxy"
|
||||||
objectStorageUseProxyDesc: "Désactivez cette option si vous n'utilisez pas de proxy pour la connexion API"
|
objectStorageUseProxyDesc: "Désactivez cette option si vous n'utilisez pas de proxy pour la connexion API"
|
||||||
objectStorageSetPublicRead: "Régler sur « public » lors de l'envoi"
|
objectStorageSetPublicRead: "Régler sur « public » lors de l'envoi"
|
||||||
s3ForcePathStyleDesc: "Si s3ForcePathStyle est activé, le nom du compartiment doit être spécifié comme une partie du chemin de l'URL plutôt que le nom d'hôte. Il faudra peut-être l'activer lors de l'utilisation d'une instance de Minio autohébergée, etc."
|
|
||||||
serverLogs: "Journal du serveur"
|
serverLogs: "Journal du serveur"
|
||||||
deleteAll: "Supprimer tout"
|
deleteAll: "Supprimer tout"
|
||||||
showFixedPostForm: "Afficher le formulaire de publication en haut du fil d'actualité"
|
showFixedPostForm: "Afficher le formulaire de publication en haut du fil d'actualité"
|
||||||
|
|
@ -593,7 +573,6 @@ ascendingOrder: "Ascendant"
|
||||||
descendingOrder: "Descendant"
|
descendingOrder: "Descendant"
|
||||||
scratchpad: "ScratchPad"
|
scratchpad: "ScratchPad"
|
||||||
scratchpadDescription: "ScratchPad fournit un environnement expérimental pour AiScript. Vous pouvez vérifier la rédaction de votre code, sa bonne exécution et le résultat de son interaction avec Misskey."
|
scratchpadDescription: "ScratchPad fournit un environnement expérimental pour AiScript. Vous pouvez vérifier la rédaction de votre code, sa bonne exécution et le résultat de son interaction avec Misskey."
|
||||||
uiInspector: "Inspecteur UI"
|
|
||||||
output: "Sortie"
|
output: "Sortie"
|
||||||
script: "Script"
|
script: "Script"
|
||||||
disablePagesScript: "Désactiver AiScript sur les Pages"
|
disablePagesScript: "Désactiver AiScript sur les Pages"
|
||||||
|
|
@ -637,7 +616,7 @@ description: "Description"
|
||||||
describeFile: "Ajouter une description d'image"
|
describeFile: "Ajouter une description d'image"
|
||||||
enterFileDescription: "Saisissez une description"
|
enterFileDescription: "Saisissez une description"
|
||||||
author: "Auteur·rice"
|
author: "Auteur·rice"
|
||||||
leaveConfirm: "Vous avez des modifications non sauvegardées. Voulez-vous les ignorer ?"
|
leaveConfirm: "Vous avez des modifications non-sauvegardées. Voulez-vous les ignorer ?"
|
||||||
manage: "Gestion"
|
manage: "Gestion"
|
||||||
plugins: "Extensions"
|
plugins: "Extensions"
|
||||||
preferencesBackups: "Sauvegarder les paramètres"
|
preferencesBackups: "Sauvegarder les paramètres"
|
||||||
|
|
@ -676,7 +655,7 @@ testEmail: "Tester la distribution de courriel"
|
||||||
wordMute: "Filtre de mots"
|
wordMute: "Filtre de mots"
|
||||||
hardWordMute: "Filtre de mots dur"
|
hardWordMute: "Filtre de mots dur"
|
||||||
regexpError: "Erreur d’expression régulière"
|
regexpError: "Erreur d’expression régulière"
|
||||||
regexpErrorDescription: "Une erreur s'est produite dans l'expression régulière sur la ligne {line} de votre mot muet {tab} :"
|
regexpErrorDescription: "Une erreur s'est produite dans l'expression régulière sur la ligne {ligne} de votre mot muet {tab} :"
|
||||||
instanceMute: "Instance en sourdine"
|
instanceMute: "Instance en sourdine"
|
||||||
userSaysSomething: "{name} a dit quelque chose"
|
userSaysSomething: "{name} a dit quelque chose"
|
||||||
makeActive: "Activer"
|
makeActive: "Activer"
|
||||||
|
|
@ -696,7 +675,6 @@ useGlobalSettingDesc: "S'il est activé, les paramètres de notification de votr
|
||||||
other: "Autre"
|
other: "Autre"
|
||||||
regenerateLoginToken: "Régénérer le jeton de connexion"
|
regenerateLoginToken: "Régénérer le jeton de connexion"
|
||||||
regenerateLoginTokenDescription: "Générer un nouveau jeton d'authentification. Cette opération ne devrait pas être nécessaire ; lors de la génération d'un nouveau jeton, tous les appareils seront déconnectés. "
|
regenerateLoginTokenDescription: "Générer un nouveau jeton d'authentification. Cette opération ne devrait pas être nécessaire ; lors de la génération d'un nouveau jeton, tous les appareils seront déconnectés. "
|
||||||
theKeywordWhenSearchingForCustomEmoji: "Ce mot-clé est utilisé lors de la recherche des émojis personnalisés."
|
|
||||||
setMultipleBySeparatingWithSpace: "Vous pouvez en définir plusieurs, en les séparant par des espaces."
|
setMultipleBySeparatingWithSpace: "Vous pouvez en définir plusieurs, en les séparant par des espaces."
|
||||||
fileIdOrUrl: "ID du fichier ou URL"
|
fileIdOrUrl: "ID du fichier ou URL"
|
||||||
behavior: "Comportement"
|
behavior: "Comportement"
|
||||||
|
|
@ -710,7 +688,10 @@ abuseReported: "Le rapport est envoyé. Merci."
|
||||||
reporter: "Signalé par"
|
reporter: "Signalé par"
|
||||||
reporteeOrigin: "Origine du signalement"
|
reporteeOrigin: "Origine du signalement"
|
||||||
reporterOrigin: "Signalé par"
|
reporterOrigin: "Signalé par"
|
||||||
|
forwardReport: "Transférer le signalement à l’instance distante"
|
||||||
|
forwardReportIsAnonymous: "L'instance distante ne sera pas en mesure de voir vos informations et apparaîtra comme un compte anonyme du système."
|
||||||
send: "Envoyer"
|
send: "Envoyer"
|
||||||
|
abuseMarkAsResolved: "Marquer le signalement comme résolu"
|
||||||
openInNewTab: "Ouvrir dans un nouvel onglet"
|
openInNewTab: "Ouvrir dans un nouvel onglet"
|
||||||
openInSideView: "Ouvrir en vue latérale"
|
openInSideView: "Ouvrir en vue latérale"
|
||||||
defaultNavigationBehaviour: "Navigation par défaut"
|
defaultNavigationBehaviour: "Navigation par défaut"
|
||||||
|
|
@ -769,6 +750,7 @@ thisIsExperimentalFeature: "Ceci est une fonctionnalité expérimentale. Il y a
|
||||||
developer: "Développeur"
|
developer: "Développeur"
|
||||||
makeExplorable: "Rendre le compte visible sur la page \"Découvrir\"."
|
makeExplorable: "Rendre le compte visible sur la page \"Découvrir\"."
|
||||||
makeExplorableDescription: "Si vous désactivez cette option, votre compte n'apparaîtra pas sur la page \"Découvrir\"."
|
makeExplorableDescription: "Si vous désactivez cette option, votre compte n'apparaîtra pas sur la page \"Découvrir\"."
|
||||||
|
showGapBetweenNotesInTimeline: "Afficher un écart entre les notes sur la Timeline"
|
||||||
duplicate: "Duliquer"
|
duplicate: "Duliquer"
|
||||||
left: "Gauche"
|
left: "Gauche"
|
||||||
center: "Centrer"
|
center: "Centrer"
|
||||||
|
|
@ -846,7 +828,6 @@ administration: "Gestion"
|
||||||
accounts: "Comptes"
|
accounts: "Comptes"
|
||||||
switch: "Remplacer"
|
switch: "Remplacer"
|
||||||
noMaintainerInformationWarning: "Informations administrateur non configurées."
|
noMaintainerInformationWarning: "Informations administrateur non configurées."
|
||||||
noInquiryUrlWarning: "L'URL demandé n'est pas définie"
|
|
||||||
noBotProtectionWarning: "La protection contre les bots n'est pas configurée."
|
noBotProtectionWarning: "La protection contre les bots n'est pas configurée."
|
||||||
configure: "Configurer"
|
configure: "Configurer"
|
||||||
postToGallery: "Publier dans la galerie"
|
postToGallery: "Publier dans la galerie"
|
||||||
|
|
@ -911,7 +892,6 @@ followersVisibility: "Visibilité des abonnés"
|
||||||
continueThread: "Afficher la suite du fil"
|
continueThread: "Afficher la suite du fil"
|
||||||
deleteAccountConfirm: "Votre compte sera supprimé. Êtes vous certain ?"
|
deleteAccountConfirm: "Votre compte sera supprimé. Êtes vous certain ?"
|
||||||
incorrectPassword: "Le mot de passe est incorrect."
|
incorrectPassword: "Le mot de passe est incorrect."
|
||||||
incorrectTotp: "Le mot de passe à usage unique est incorrect ou a expiré."
|
|
||||||
voteConfirm: "Confirmez-vous votre vote pour « {choice} » ?"
|
voteConfirm: "Confirmez-vous votre vote pour « {choice} » ?"
|
||||||
hide: "Masquer"
|
hide: "Masquer"
|
||||||
useDrawerReactionPickerForMobile: "Afficher le sélecteur de réactions en tant que panneau sur mobile"
|
useDrawerReactionPickerForMobile: "Afficher le sélecteur de réactions en tant que panneau sur mobile"
|
||||||
|
|
@ -936,9 +916,6 @@ oneHour: "1 heure"
|
||||||
oneDay: "1 jour"
|
oneDay: "1 jour"
|
||||||
oneWeek: "1 semaine"
|
oneWeek: "1 semaine"
|
||||||
oneMonth: "Un mois"
|
oneMonth: "Un mois"
|
||||||
threeMonths: "3 mois"
|
|
||||||
oneYear: "1 an"
|
|
||||||
threeDays: "3 jours"
|
|
||||||
reflectMayTakeTime: "Cela peut prendre un certain temps avant que cela ne se termine."
|
reflectMayTakeTime: "Cela peut prendre un certain temps avant que cela ne se termine."
|
||||||
failedToFetchAccountInformation: "Impossible de récupérer les informations du compte."
|
failedToFetchAccountInformation: "Impossible de récupérer les informations du compte."
|
||||||
rateLimitExceeded: "Limite de taux dépassée"
|
rateLimitExceeded: "Limite de taux dépassée"
|
||||||
|
|
@ -946,7 +923,7 @@ cropImage: "Recadrer l'image"
|
||||||
cropImageAsk: "Voulez-vous recadrer cette image ?"
|
cropImageAsk: "Voulez-vous recadrer cette image ?"
|
||||||
cropYes: "Rogner"
|
cropYes: "Rogner"
|
||||||
cropNo: "Utiliser en l'état"
|
cropNo: "Utiliser en l'état"
|
||||||
file: "Fichier"
|
file: "Fichiers"
|
||||||
recentNHours: "Dernières {n} heures"
|
recentNHours: "Dernières {n} heures"
|
||||||
recentNDays: "Derniers {n} jours"
|
recentNDays: "Derniers {n} jours"
|
||||||
noEmailServerWarning: "Serveur de courrier non configuré."
|
noEmailServerWarning: "Serveur de courrier non configuré."
|
||||||
|
|
@ -1012,7 +989,6 @@ neverShow: "Ne plus afficher"
|
||||||
remindMeLater: "Peut-être plus tard"
|
remindMeLater: "Peut-être plus tard"
|
||||||
didYouLikeMisskey: "Avez-vous aimé Misskey ?"
|
didYouLikeMisskey: "Avez-vous aimé Misskey ?"
|
||||||
pleaseDonate: "Misskey est le logiciel libre utilisé par {host}. Merci de faire un don pour que nous puissions continuer à le développer !"
|
pleaseDonate: "Misskey est le logiciel libre utilisé par {host}. Merci de faire un don pour que nous puissions continuer à le développer !"
|
||||||
correspondingSourceIsAvailable: "Le code source correspondant est disponible à {anchor}"
|
|
||||||
roles: "Rôles"
|
roles: "Rôles"
|
||||||
role: "Rôles"
|
role: "Rôles"
|
||||||
noRole: "Aucun rôle"
|
noRole: "Aucun rôle"
|
||||||
|
|
@ -1027,7 +1003,6 @@ youCannotCreateAnymore: "Vous avez atteint la limite de création."
|
||||||
cannotPerformTemporary: "Temporairement indisponible"
|
cannotPerformTemporary: "Temporairement indisponible"
|
||||||
cannotPerformTemporaryDescription: "Temporairement indisponible puisque le nombre d'opérations dépasse la limite. Veuillez patienter un peu, puis réessayer."
|
cannotPerformTemporaryDescription: "Temporairement indisponible puisque le nombre d'opérations dépasse la limite. Veuillez patienter un peu, puis réessayer."
|
||||||
invalidParamError: "Paramètres invalides"
|
invalidParamError: "Paramètres invalides"
|
||||||
invalidParamErrorDescription: "Les paramètres de la requête sont invalides. Il s'agit généralement d'un bogue, mais cela peut aussi être causé par un excès de caractères ou quelque chose de similaire."
|
|
||||||
permissionDeniedError: "Opération refusée"
|
permissionDeniedError: "Opération refusée"
|
||||||
permissionDeniedErrorDescription: "Ce compte n'a pas la permission d'effectuer cette opération."
|
permissionDeniedErrorDescription: "Ce compte n'a pas la permission d'effectuer cette opération."
|
||||||
preset: "Préréglage"
|
preset: "Préréglage"
|
||||||
|
|
@ -1041,7 +1016,6 @@ thisPostMayBeAnnoyingCancel: "Annuler"
|
||||||
thisPostMayBeAnnoyingIgnore: "Publier quand-même"
|
thisPostMayBeAnnoyingIgnore: "Publier quand-même"
|
||||||
collapseRenotes: "Réduire les renotes déjà vues"
|
collapseRenotes: "Réduire les renotes déjà vues"
|
||||||
internalServerError: "Erreur interne du serveur"
|
internalServerError: "Erreur interne du serveur"
|
||||||
internalServerErrorDescription: "Une erreur inattendue s'est produite sur le serveur."
|
|
||||||
copyErrorInfo: "Copier les détails de l’erreur"
|
copyErrorInfo: "Copier les détails de l’erreur"
|
||||||
joinThisServer: "S'inscrire à cette instance"
|
joinThisServer: "S'inscrire à cette instance"
|
||||||
exploreOtherServers: "Trouver une autre instance"
|
exploreOtherServers: "Trouver une autre instance"
|
||||||
|
|
@ -1061,10 +1035,8 @@ nonSensitiveOnlyForLocalLikeOnlyForRemote: "Non sensibles seulement (mentions j'
|
||||||
rolesAssignedToMe: "Rôles attribués à moi"
|
rolesAssignedToMe: "Rôles attribués à moi"
|
||||||
resetPasswordConfirm: "Souhaitez-vous réinitialiser votre mot de passe ?"
|
resetPasswordConfirm: "Souhaitez-vous réinitialiser votre mot de passe ?"
|
||||||
sensitiveWords: "Mots sensibles"
|
sensitiveWords: "Mots sensibles"
|
||||||
sensitiveWordsDescription: "Définir la visibilité des notes contenant un mot défini ici au fil principal automatiquement. Vous pouvez définir plusieurs valeurs en les séparant par des sauts de ligne."
|
|
||||||
sensitiveWordsDescription2: "Séparer par une espace pour créer une expression AND ; entourer de barres obliques pour créer une expression régulière."
|
sensitiveWordsDescription2: "Séparer par une espace pour créer une expression AND ; entourer de barres obliques pour créer une expression régulière."
|
||||||
prohibitedWords: "Mots interdits"
|
prohibitedWords: "Mots interdits"
|
||||||
prohibitedWordsDescription: "Publier une note contenant un mot défini ici produira une erreur. Vous pouvez définir plusieurs valeurs en les séparant par des sauts de ligne."
|
|
||||||
prohibitedWordsDescription2: "Séparer par une espace pour créer une expression AND ; entourer de barres obliques pour créer une expression régulière."
|
prohibitedWordsDescription2: "Séparer par une espace pour créer une expression AND ; entourer de barres obliques pour créer une expression régulière."
|
||||||
hiddenTags: "Hashtags cachés"
|
hiddenTags: "Hashtags cachés"
|
||||||
hiddenTagsDescription: "Les hashtags définis ne s'afficheront pas dans les tendances. Vous pouvez définir plusieurs hashtags en faisant un saut de ligne."
|
hiddenTagsDescription: "Les hashtags définis ne s'afficheront pas dans les tendances. Vous pouvez définir plusieurs hashtags en faisant un saut de ligne."
|
||||||
|
|
@ -1078,7 +1050,6 @@ retryAllQueuesConfirmTitle: "Vraiment réessayer ?"
|
||||||
retryAllQueuesConfirmText: "Cela peut augmenter temporairement la charge du serveur."
|
retryAllQueuesConfirmText: "Cela peut augmenter temporairement la charge du serveur."
|
||||||
enableChartsForRemoteUser: "Générer les graphiques pour les utilisateurs distants"
|
enableChartsForRemoteUser: "Générer les graphiques pour les utilisateurs distants"
|
||||||
enableChartsForFederatedInstances: "Générer les graphiques pour les instances distantes"
|
enableChartsForFederatedInstances: "Générer les graphiques pour les instances distantes"
|
||||||
enableStatsForFederatedInstances: "Recevoir les statistiques des instances distantes"
|
|
||||||
showClipButtonInNoteFooter: "Ajouter « Clip » au menu d'action de la note"
|
showClipButtonInNoteFooter: "Ajouter « Clip » au menu d'action de la note"
|
||||||
reactionsDisplaySize: "Taille de l'affichage des réactions"
|
reactionsDisplaySize: "Taille de l'affichage des réactions"
|
||||||
limitWidthOfReaction: "Limiter la largeur maximale des réactions et les afficher en taille réduite"
|
limitWidthOfReaction: "Limiter la largeur maximale des réactions et les afficher en taille réduite"
|
||||||
|
|
@ -1111,13 +1082,9 @@ pleaseConfirmBelowBeforeSignup: "Pour vous inscrire sur cette instance, vous dev
|
||||||
pleaseAgreeAllToContinue: "Pour continuer, veuillez accepter tous les champs ci-dessus."
|
pleaseAgreeAllToContinue: "Pour continuer, veuillez accepter tous les champs ci-dessus."
|
||||||
continue: "Continuer"
|
continue: "Continuer"
|
||||||
preservedUsernames: "Noms d'utilisateur·rice réservés"
|
preservedUsernames: "Noms d'utilisateur·rice réservés"
|
||||||
preservedUsernamesDescription: "Énumérez les noms d'utilisateur à réserver, séparés par des nouvelles lignes. Les noms d'utilisateur spécifiés ici ne seront plus utilisables lors de la création d'un compte, sauf la création manuelle par un administrateur. De plus, les comptes existants ne seront pas affectés."
|
|
||||||
createNoteFromTheFile: "Rédiger une note de ce fichier"
|
createNoteFromTheFile: "Rédiger une note de ce fichier"
|
||||||
archive: "Archive"
|
archive: "Archive"
|
||||||
archived: "Archivé"
|
|
||||||
unarchive: "Annuler l'archivage"
|
|
||||||
channelArchiveConfirmTitle: "Voulez-vous vraiment archiver {name} ?"
|
channelArchiveConfirmTitle: "Voulez-vous vraiment archiver {name} ?"
|
||||||
channelArchiveConfirmDescription: "Une fois archivé, le canal n'apparaîtra plus dans la liste des canaux ni dans les résultats de recherche, et la publication des nouvelles notes sera impossible."
|
|
||||||
thisChannelArchived: "Ce canal a été archivé."
|
thisChannelArchived: "Ce canal a été archivé."
|
||||||
displayOfNote: "Affichage de la note"
|
displayOfNote: "Affichage de la note"
|
||||||
initialAccountSetting: "Configuration initiale du profil"
|
initialAccountSetting: "Configuration initiale du profil"
|
||||||
|
|
@ -1126,8 +1093,6 @@ preventAiLearning: "Refuser l'usage dans l'apprentissage automatique d'IA géné
|
||||||
preventAiLearningDescription: "Demander aux robots d'indexation de ne pas utiliser le contenu publié, tel que les notes et les images, dans l'apprentissage automatique d'IA générative. Cela est réalisé en incluant le drapeau « noai » dans la réponse HTML. Une prévention complète n'est toutefois pas possible, car il est au robot d'indexation de respecter cette demande."
|
preventAiLearningDescription: "Demander aux robots d'indexation de ne pas utiliser le contenu publié, tel que les notes et les images, dans l'apprentissage automatique d'IA générative. Cela est réalisé en incluant le drapeau « noai » dans la réponse HTML. Une prévention complète n'est toutefois pas possible, car il est au robot d'indexation de respecter cette demande."
|
||||||
options: "Options"
|
options: "Options"
|
||||||
specifyUser: "Spécifier l'utilisateur·rice"
|
specifyUser: "Spécifier l'utilisateur·rice"
|
||||||
openTagPageConfirm: "Ouvrir une page d'hashtags ?"
|
|
||||||
specifyHost: "Spécifier un serveur distant"
|
|
||||||
failedToPreviewUrl: "Aperçu d'URL échoué"
|
failedToPreviewUrl: "Aperçu d'URL échoué"
|
||||||
update: "Mettre à jour"
|
update: "Mettre à jour"
|
||||||
rolesThatCanBeUsedThisEmojiAsReaction: "Rôles qui peuvent utiliser cet émoji comme réaction"
|
rolesThatCanBeUsedThisEmojiAsReaction: "Rôles qui peuvent utiliser cet émoji comme réaction"
|
||||||
|
|
@ -1148,8 +1113,6 @@ createWithOptions: "Options"
|
||||||
createCount: "Quantité à créer"
|
createCount: "Quantité à créer"
|
||||||
inviteCodeCreated: "Code d'invitation créé"
|
inviteCodeCreated: "Code d'invitation créé"
|
||||||
inviteLimitExceeded: "Vous avez atteint la limite de codes d'invitation que vous pouvez générer."
|
inviteLimitExceeded: "Vous avez atteint la limite de codes d'invitation que vous pouvez générer."
|
||||||
createLimitRemaining: "Codes d'invitation pouvant être créés : {limit} restants"
|
|
||||||
inviteLimitResetCycle: "Vous pouvez créer jusqu'à {limit} codes d'invitation en {time}."
|
|
||||||
expirationDate: "Date d’expiration"
|
expirationDate: "Date d’expiration"
|
||||||
noExpirationDate: "Ne pas expirer"
|
noExpirationDate: "Ne pas expirer"
|
||||||
inviteCodeUsedAt: "Code d'invitation utilisé à"
|
inviteCodeUsedAt: "Code d'invitation utilisé à"
|
||||||
|
|
@ -1169,14 +1132,11 @@ forYou: "Pour vous"
|
||||||
currentAnnouncements: "Annonces actuelles"
|
currentAnnouncements: "Annonces actuelles"
|
||||||
pastAnnouncements: "Annonces passées"
|
pastAnnouncements: "Annonces passées"
|
||||||
youHaveUnreadAnnouncements: "Il y a des annonces non lues."
|
youHaveUnreadAnnouncements: "Il y a des annonces non lues."
|
||||||
useSecurityKey: "Suivez les instructions de votre navigateur ou de votre appareil pour utiliser une clé de sécurité ou une clé d'accès."
|
|
||||||
replies: "Réponses"
|
replies: "Réponses"
|
||||||
renotes: "Renotes"
|
renotes: "Renotes"
|
||||||
loadReplies: "Inclure les réponses"
|
loadReplies: "Inclure les réponses"
|
||||||
loadConversation: "Afficher la conversation"
|
loadConversation: "Afficher la conversation"
|
||||||
pinnedList: "Liste épinglée"
|
pinnedList: "Liste épinglée"
|
||||||
keepScreenOn: "Garder l'écran toujours allumé"
|
|
||||||
verifiedLink: "Votre propriété de ce lien a été vérifiée"
|
|
||||||
notifyNotes: "Notifier à propos des nouvelles notes"
|
notifyNotes: "Notifier à propos des nouvelles notes"
|
||||||
unnotifyNotes: "Ne pas notifier pour la publication des notes"
|
unnotifyNotes: "Ne pas notifier pour la publication des notes"
|
||||||
authentication: "Authentification"
|
authentication: "Authentification"
|
||||||
|
|
@ -1186,7 +1146,6 @@ showRenotes: "Afficher les renotes"
|
||||||
edited: "Modifié"
|
edited: "Modifié"
|
||||||
notificationRecieveConfig: "Paramètres des notifications"
|
notificationRecieveConfig: "Paramètres des notifications"
|
||||||
mutualFollow: "Abonnement mutuel"
|
mutualFollow: "Abonnement mutuel"
|
||||||
followingOrFollower: "Abonnement ou abonné"
|
|
||||||
fileAttachedOnly: "Avec fichiers joints seulement"
|
fileAttachedOnly: "Avec fichiers joints seulement"
|
||||||
showRepliesToOthersInTimeline: "Afficher les réponses aux autres dans le fil"
|
showRepliesToOthersInTimeline: "Afficher les réponses aux autres dans le fil"
|
||||||
hideRepliesToOthersInTimeline: "Masquer les réponses aux autres dans le fil"
|
hideRepliesToOthersInTimeline: "Masquer les réponses aux autres dans le fil"
|
||||||
|
|
@ -1217,7 +1176,9 @@ showAvatarDecorations: "Afficher les décorations d'avatar"
|
||||||
releaseToRefresh: "Relâcher pour rafraîchir"
|
releaseToRefresh: "Relâcher pour rafraîchir"
|
||||||
refreshing: "Rafraîchissement..."
|
refreshing: "Rafraîchissement..."
|
||||||
pullDownToRefresh: "Tirer vers le bas pour rafraîchir"
|
pullDownToRefresh: "Tirer vers le bas pour rafraîchir"
|
||||||
|
disableStreamingTimeline: "Désactiver les mises à jour en temps réel de la ligne du temps"
|
||||||
useGroupedNotifications: "Grouper les notifications"
|
useGroupedNotifications: "Grouper les notifications"
|
||||||
|
signupPendingError: "Un problème est survenu lors de la vérification de votre adresse e-mail. Le lien a peut-être expiré."
|
||||||
cwNotationRequired: "Si « Masquer le contenu » est activé, une description doit être fournie."
|
cwNotationRequired: "Si « Masquer le contenu » est activé, une description doit être fournie."
|
||||||
doReaction: "Réagir"
|
doReaction: "Réagir"
|
||||||
code: "Code"
|
code: "Code"
|
||||||
|
|
@ -1240,81 +1201,10 @@ ranking: "Classement"
|
||||||
lastNDays: "Derniers {n} jours"
|
lastNDays: "Derniers {n} jours"
|
||||||
backToTitle: "Retourner au titre"
|
backToTitle: "Retourner au titre"
|
||||||
hemisphere: "Votre région"
|
hemisphere: "Votre région"
|
||||||
withSensitive: "Afficher les notes contenant des fichiers joints sensibles"
|
|
||||||
userSaysSomethingSensitive: "Note de {name} contenant des fichiers joints sensibles"
|
|
||||||
enableHorizontalSwipe: "Glisser pour changer d'onglet"
|
enableHorizontalSwipe: "Glisser pour changer d'onglet"
|
||||||
loading: "Chargement en cours"
|
loading: "Chargement en cours"
|
||||||
surrender: "Annuler"
|
surrender: "Annuler"
|
||||||
gameRetry: "Réessayer"
|
gameRetry: "Réessayer"
|
||||||
notUsePleaseLeaveBlank: "Laisser vide si non utilisé"
|
|
||||||
useTotp: "Entrer un mot de passe à usage unique"
|
|
||||||
useBackupCode: "Utiliser le codes de secours"
|
|
||||||
launchApp: "Lancer l'app"
|
|
||||||
useNativeUIForVideoAudioPlayer: "Lire les vidéos et audios en utilisant l'UI du navigateur"
|
|
||||||
keepOriginalFilename: "Garder le nom original du fichier"
|
|
||||||
keepOriginalFilenameDescription: "Si vous désactivez ce paramètre, les noms de fichiers seront automatiquement remplacés par des noms aléatoires lorsque vous téléchargerez des fichiers."
|
|
||||||
noDescription: "Il n'y a pas de description"
|
|
||||||
alwaysConfirmFollow: "Confirmer lors d'un abonnement"
|
|
||||||
inquiry: "Contact"
|
|
||||||
tryAgain: "Veuillez réessayer plus tard"
|
|
||||||
confirmWhenRevealingSensitiveMedia: "Confirmer pour révéler du contenu sensible"
|
|
||||||
sensitiveMediaRevealConfirm: "Ceci pourrait être du contenu sensible. Voulez-vous l'afficher ?"
|
|
||||||
createdLists: "Listes créées"
|
|
||||||
createdAntennas: "Antennes créées"
|
|
||||||
fromX: "De {x}"
|
|
||||||
genEmbedCode: "Générer le code d'intégration"
|
|
||||||
noteOfThisUser: "Notes de cet·te utilisateur·rice"
|
|
||||||
clipNoteLimitExceeded: "Aucune note supplémentaire ne peut être ajoutée à ce clip."
|
|
||||||
performance: "Performance"
|
|
||||||
modified: "Modifié"
|
|
||||||
discard: "Annuler"
|
|
||||||
thereAreNChanges: "Il y a {n} modification(s)"
|
|
||||||
signinWithPasskey: "Se connecter avec une clé d'accès"
|
|
||||||
unknownWebAuthnKey: "Clé d'accès inconnue."
|
|
||||||
passkeyVerificationFailed: "La vérification de la clé d'accès a échoué."
|
|
||||||
passkeyVerificationSucceededButPasswordlessLoginDisabled: "La vérification de la clé d'accès a réussi, mais la connexion sans mot de passe est désactivée."
|
|
||||||
messageToFollower: "Message aux abonné·es"
|
|
||||||
target: "Destinataire"
|
|
||||||
prohibitedWordsForNameOfUser: "Mots interdits pour les noms d'utilisateur·rices"
|
|
||||||
lockdown: "Verrouiller"
|
|
||||||
pleaseSelectAccount: "Sélectionner un compte"
|
|
||||||
availableRoles: "Rôles disponibles"
|
|
||||||
postForm: "Formulaire de publication"
|
|
||||||
information: "Informations"
|
|
||||||
inMinutes: "min"
|
|
||||||
inDays: "j"
|
|
||||||
widgets: "Widgets"
|
|
||||||
presets: "Préréglage"
|
|
||||||
_imageEditing:
|
|
||||||
_vars:
|
|
||||||
filename: "Nom du fichier"
|
|
||||||
_imageFrameEditor:
|
|
||||||
header: "Entête"
|
|
||||||
font: "Police de caractères"
|
|
||||||
fontSerif: "Serif"
|
|
||||||
fontSansSerif: "Sans Serif"
|
|
||||||
_chat:
|
|
||||||
invitations: "Inviter"
|
|
||||||
noHistory: "Pas d'historique"
|
|
||||||
members: "Membres"
|
|
||||||
home: "Principal"
|
|
||||||
send: "Envoyer"
|
|
||||||
_abuseUserReport:
|
|
||||||
forward: "Transférer"
|
|
||||||
forwardDescription: "Transférer le signalement vers une instance distante en tant qu'anonyme."
|
|
||||||
resolve: "Résoudre"
|
|
||||||
accept: "Accepter"
|
|
||||||
reject: "Rejeter"
|
|
||||||
resolveTutorial: "Si le signalement est légitime dans son contenu, sélectionnez « Accepter » pour marquer le cas comme résolu par l'affirmative.\nSi le contenu du rapport n'est pas légitime, sélectionnez « Rejeter » pour marquer le cas comme résolu par la négative."
|
|
||||||
_delivery:
|
|
||||||
status: "Statut de la diffusion"
|
|
||||||
stop: "Suspendu·e"
|
|
||||||
resume: "Reprendre"
|
|
||||||
_type:
|
|
||||||
none: "Publié"
|
|
||||||
manuallySuspended: "Suspendre manuellement"
|
|
||||||
goneSuspended: "L'instance est suspendue en raison de la suppression de ce dernier"
|
|
||||||
autoSuspendedForNotResponding: "L'instance est suspendue car elle ne répond pas"
|
|
||||||
_bubbleGame:
|
_bubbleGame:
|
||||||
howToPlay: "Comment jouer"
|
howToPlay: "Comment jouer"
|
||||||
hold: "Réserver"
|
hold: "Réserver"
|
||||||
|
|
@ -1322,30 +1212,18 @@ _bubbleGame:
|
||||||
score: "Score"
|
score: "Score"
|
||||||
scoreYen: "Montant gagné"
|
scoreYen: "Montant gagné"
|
||||||
highScore: "Meilleur score"
|
highScore: "Meilleur score"
|
||||||
maxChain: "Nombre maximum de chaînes"
|
|
||||||
yen: "{yen} yens"
|
yen: "{yen} yens"
|
||||||
estimatedQty: "{qty} pièces"
|
|
||||||
scoreSweets: "{onigiriQtyWithUnit} Onigiri(s)"
|
|
||||||
_announcement:
|
_announcement:
|
||||||
forExistingUsers: "Pour les utilisateurs existants seulement"
|
forExistingUsers: "Pour les utilisateurs existants seulement"
|
||||||
needConfirmationToRead: "Exiger la confirmation de la lecture"
|
|
||||||
needConfirmationToReadDescription: "Si activé, afficher un dialogue de confirmation quand l'annonce est marquée comme lue. Aussi, elle sera exclue de « marquer tout comme lu » ."
|
|
||||||
end: "Archiver l'annonce"
|
|
||||||
tooManyActiveAnnouncementDescription: "Un grand nombre d'annonces actives peut baisser l'expérience utilisateur. Considérez d'archiver les annonces obsolètes."
|
|
||||||
readConfirmTitle: "Marquer comme lu ?"
|
readConfirmTitle: "Marquer comme lu ?"
|
||||||
readConfirmText: "Cela marquera le contenu de « {title} » comme lu."
|
|
||||||
shouldNotBeUsedToPresentPermanentInfo: "Puisque cela pourrait nuire considérablement à l'expérience utilisateur pour les nouveaux utilisateurs, il est recommandé d'utiliser les annonces pour afficher des informations temporaires plutôt que des informations persistantes."
|
shouldNotBeUsedToPresentPermanentInfo: "Puisque cela pourrait nuire considérablement à l'expérience utilisateur pour les nouveaux utilisateurs, il est recommandé d'utiliser les annonces pour afficher des informations temporaires plutôt que des informations persistantes."
|
||||||
dialogAnnouncementUxWarn: "Avoir deux ou plus annonces de style dialogue en même temps pourrait nuire considérablement à l'expérience utilisateur. Veuillez les utiliser avec caution."
|
dialogAnnouncementUxWarn: "Avoir deux ou plus annonces de style dialogue en même temps pourrait nuire considérablement à l'expérience utilisateur. Veuillez les utiliser avec caution."
|
||||||
silence: "Ne pas me notifier"
|
silence: "Ne pas me notifier"
|
||||||
silenceDescription: "Si activée, vous ne recevrez pas de notifications sur les annonces et n'aurez pas besoin de les marquer comme lues."
|
silenceDescription: "Si activée, vous ne recevrez pas de notifications sur les annonces et n'aurez pas besoin de les marquer comme lues."
|
||||||
_initialAccountSetting:
|
_initialAccountSetting:
|
||||||
accountCreated: "Votre compte a été créé avec succès !"
|
|
||||||
letsStartAccountSetup: "Procédons au réglage initial du compte."
|
|
||||||
letsFillYourProfile: "Commençons par configurer votre profil !"
|
|
||||||
profileSetting: "Paramètres du profil"
|
profileSetting: "Paramètres du profil"
|
||||||
privacySetting: "Paramètres de confidentialité"
|
privacySetting: "Paramètres de confidentialité"
|
||||||
initialAccountSettingCompleted: "Configuration du profil terminée avec succès !"
|
initialAccountSettingCompleted: "Configuration du profil terminée avec succès !"
|
||||||
haveFun: "Profitez de {name} !"
|
|
||||||
youCanContinueTutorial: "Vous pouvez procéder au tutoriel sur l'utilisation de {name}(Misskey) ou vous arrêter ici et commencer à l'utiliser immédiatement."
|
youCanContinueTutorial: "Vous pouvez procéder au tutoriel sur l'utilisation de {name}(Misskey) ou vous arrêter ici et commencer à l'utiliser immédiatement."
|
||||||
startTutorial: "Démarrer le tutoriel"
|
startTutorial: "Démarrer le tutoriel"
|
||||||
skipAreYouSure: "Désirez-vous ignorer la configuration du profil ?"
|
skipAreYouSure: "Désirez-vous ignorer la configuration du profil ?"
|
||||||
|
|
@ -1410,7 +1288,7 @@ _initialTutorial:
|
||||||
doItToContinue: "Marquez le fichier joint comme sensible pour procéder."
|
doItToContinue: "Marquez le fichier joint comme sensible pour procéder."
|
||||||
_done:
|
_done:
|
||||||
title: "Le tutoriel est terminé ! 🎉"
|
title: "Le tutoriel est terminé ! 🎉"
|
||||||
description: "Les fonctionnalités introduites ici ne sont que quelques-unes. Pour savoir plus sur l'utilisation de Misskey, veuillez consulter {link}."
|
description: "Les fonctionnalités introduites ici ne sont que quelques-unes. Pour savoir plus sur l'utilisation de Misskey, veuillez consulter {lien}."
|
||||||
_timelineDescription:
|
_timelineDescription:
|
||||||
home: "Sur le fil principal, vous pouvez voir les notes des utilisateurs auxquels vous êtes abonné·e."
|
home: "Sur le fil principal, vous pouvez voir les notes des utilisateurs auxquels vous êtes abonné·e."
|
||||||
local: "Sur le fil local, vous pouvez voir les notes de tous les utilisateurs sur cette instance."
|
local: "Sur le fil local, vous pouvez voir les notes de tous les utilisateurs sur cette instance."
|
||||||
|
|
@ -1439,60 +1317,18 @@ _achievements:
|
||||||
flavor: "Passez un bon moment avec Misskey !"
|
flavor: "Passez un bon moment avec Misskey !"
|
||||||
_notes10:
|
_notes10:
|
||||||
title: "Quelques notes"
|
title: "Quelques notes"
|
||||||
description: "Poster 10 notes"
|
|
||||||
_notes100:
|
_notes100:
|
||||||
title: "Beaucoup de notes"
|
title: "Beaucoup de notes"
|
||||||
description: "Poster 100 notes"
|
|
||||||
_notes500:
|
|
||||||
title: "Couvert de notes"
|
|
||||||
description: "Poster 500 notes"
|
|
||||||
_notes1000:
|
|
||||||
title: "Une montagne de notes"
|
|
||||||
description: "Poster 1000 notes"
|
|
||||||
_notes5000:
|
|
||||||
title: "Débordement de notes"
|
|
||||||
description: "Poster 5 000 notes"
|
|
||||||
_notes10000:
|
|
||||||
title: "Super note"
|
|
||||||
description: "Poster 10 000 notes"
|
|
||||||
_notes20000:
|
|
||||||
title: "Encore... plus... de... notes..."
|
|
||||||
description: "Poster 20 000 notes"
|
|
||||||
_notes30000:
|
|
||||||
title: "Notes notes notes !"
|
|
||||||
description: "Poster 30 000 notes"
|
|
||||||
_notes40000:
|
|
||||||
title: "Usine de notes"
|
|
||||||
description: "Poster 40 000 notes"
|
|
||||||
_notes50000:
|
|
||||||
title: "Planète des notes"
|
|
||||||
description: "Poster 50 000 notes"
|
|
||||||
_notes60000:
|
|
||||||
title: "Quasar de note"
|
|
||||||
description: "Poster 50 000 notes"
|
|
||||||
_notes70000:
|
|
||||||
title: "Trou noir de notes"
|
|
||||||
description: "Poster 70 000 notes"
|
|
||||||
_notes80000:
|
|
||||||
title: "Galaxie de notes"
|
|
||||||
description: "Poster 80 000 notes"
|
|
||||||
_notes90000:
|
|
||||||
title: "Univers de notes"
|
|
||||||
description: "Poster 90 000 notes"
|
|
||||||
_notes100000:
|
_notes100000:
|
||||||
title: "ALL YOUR NOTE ARE BELONG TO US"
|
title: "ALL YOUR NOTE ARE BELONG TO US"
|
||||||
description: "Poster 100 000 notes"
|
|
||||||
flavor: "Avez-vous tant de choses à dire ?"
|
|
||||||
_login3:
|
_login3:
|
||||||
title: "Débutant I"
|
title: "Débutant Ⅰ"
|
||||||
description: "Se connecter pour un total de 3 jours"
|
description: "Se connecter pour un total de 3 jours"
|
||||||
flavor: "Dès maintenant, appelez-moi Misskeynaute"
|
|
||||||
_login7:
|
_login7:
|
||||||
title: "Débutant II"
|
title: "Débutant Ⅱ"
|
||||||
description: "Se connecter pour un total de 7 jours"
|
description: "Se connecter pour un total de 7 jours"
|
||||||
flavor: "On s'habitue ?"
|
|
||||||
_login15:
|
_login15:
|
||||||
title: "Débutant III"
|
title: "Débutant Ⅲ"
|
||||||
description: "Se connecter pour un total de 15 jours"
|
description: "Se connecter pour un total de 15 jours"
|
||||||
_login30:
|
_login30:
|
||||||
title: "Misskeynaute I"
|
title: "Misskeynaute I"
|
||||||
|
|
@ -1516,7 +1352,6 @@ _achievements:
|
||||||
_login500:
|
_login500:
|
||||||
title: "Expert I"
|
title: "Expert I"
|
||||||
description: "Se connecter pour un total de 500 jours"
|
description: "Se connecter pour un total de 500 jours"
|
||||||
flavor: "Non, mes amis, j'aime les notes"
|
|
||||||
_login600:
|
_login600:
|
||||||
title: "Expert II"
|
title: "Expert II"
|
||||||
description: "Se connecter pour un total de 600 jours"
|
description: "Se connecter pour un total de 600 jours"
|
||||||
|
|
@ -1524,18 +1359,11 @@ _achievements:
|
||||||
title: "Expert III"
|
title: "Expert III"
|
||||||
description: "Se connecter pour un total de 700 jours"
|
description: "Se connecter pour un total de 700 jours"
|
||||||
_login800:
|
_login800:
|
||||||
title: "Maître des notes I"
|
|
||||||
description: "Se connecter pour un total de 800 jours"
|
description: "Se connecter pour un total de 800 jours"
|
||||||
_login900:
|
_login900:
|
||||||
title: "Maître des notes II"
|
|
||||||
description: "Se connecter pour un total de 900 jours"
|
description: "Se connecter pour un total de 900 jours"
|
||||||
_login1000:
|
_login1000:
|
||||||
title: "Maître des notes III"
|
|
||||||
description: "Se connecter pour un total de 1 000 jours"
|
|
||||||
flavor: "Merci d'utiliser Misskey !"
|
flavor: "Merci d'utiliser Misskey !"
|
||||||
_noteClipped1:
|
|
||||||
title: "Je... dois... clip..."
|
|
||||||
description: "Ajouter sa première note aux clips"
|
|
||||||
_profileFilled:
|
_profileFilled:
|
||||||
title: "Bien préparé"
|
title: "Bien préparé"
|
||||||
description: "Configuration de votre profil"
|
description: "Configuration de votre profil"
|
||||||
|
|
@ -1594,31 +1422,21 @@ _achievements:
|
||||||
_driveFolderCircularReference:
|
_driveFolderCircularReference:
|
||||||
title: "Référence circulaire"
|
title: "Référence circulaire"
|
||||||
_setNameToSyuilo:
|
_setNameToSyuilo:
|
||||||
title: "Complexe de dieu"
|
|
||||||
description: "Vous avez spécifié « syuilo » comme nom"
|
description: "Vous avez spécifié « syuilo » comme nom"
|
||||||
_passedSinceAccountCreated1:
|
_passedSinceAccountCreated1:
|
||||||
title: "Premier anniversaire"
|
title: "Premier anniversaire"
|
||||||
description: "Un an est passé depuis la création du compte"
|
|
||||||
_passedSinceAccountCreated2:
|
_passedSinceAccountCreated2:
|
||||||
title: "Second anniversaire"
|
title: "Second anniversaire"
|
||||||
description: "Deux ans sont passés depuis la création du compte"
|
|
||||||
_passedSinceAccountCreated3:
|
_passedSinceAccountCreated3:
|
||||||
title: "3ème anniversaire"
|
title: "3ème anniversaire"
|
||||||
description: "Trois ans sont passés depuis la création du compte"
|
|
||||||
_loggedInOnBirthday:
|
_loggedInOnBirthday:
|
||||||
title: "Joyeux Anniversaire !"
|
title: "Joyeux Anniversaire !"
|
||||||
description: "Vous vous êtes connecté à la date de votre anniversaire"
|
description: "Vous vous êtes connecté à la date de votre anniversaire"
|
||||||
_loggedInOnNewYearsDay:
|
_loggedInOnNewYearsDay:
|
||||||
title: "Bonne année !"
|
title: "Bonne année !"
|
||||||
description: "Vous vous êtes connecté le premier jour de l'année"
|
|
||||||
flavor: "Merci pour le soutient continue sur cette instance."
|
|
||||||
_cookieClicked:
|
_cookieClicked:
|
||||||
title: "Jeu de clic sur des cookies"
|
|
||||||
description: "Cliqué sur un cookie"
|
|
||||||
flavor: "Attendez une minute, vous êtes sur le mauvais site web ?"
|
flavor: "Attendez une minute, vous êtes sur le mauvais site web ?"
|
||||||
_brainDiver:
|
_brainDiver:
|
||||||
title: "Brain Diver"
|
|
||||||
description: "Poster le lien sur Brain Diver"
|
|
||||||
flavor: "Misskey-Misskey La-Tu-Ma"
|
flavor: "Misskey-Misskey La-Tu-Ma"
|
||||||
_smashTestNotificationButton:
|
_smashTestNotificationButton:
|
||||||
title: "Débordement de tests"
|
title: "Débordement de tests"
|
||||||
|
|
@ -1626,17 +1444,12 @@ _achievements:
|
||||||
_tutorialCompleted:
|
_tutorialCompleted:
|
||||||
title: "Diplôme de la course élémentaire de Misskey"
|
title: "Diplôme de la course élémentaire de Misskey"
|
||||||
description: "Terminer le tutoriel"
|
description: "Terminer le tutoriel"
|
||||||
_bubbleGameExplodingHead:
|
|
||||||
title: "🤯"
|
|
||||||
description: "Le plus gros objet du jeu de bulles"
|
|
||||||
_bubbleGameDoubleExplodingHead:
|
|
||||||
title: "Double🤯"
|
|
||||||
_role:
|
_role:
|
||||||
new: "Nouveau rôle"
|
new: "Nouveau rôle"
|
||||||
edit: "Modifier le rôle"
|
edit: "Modifier le rôle"
|
||||||
name: "Nom du rôle"
|
name: "Nom du rôle"
|
||||||
description: "Description du rôle"
|
description: "Description du rôle"
|
||||||
permission: "Autorisations du rôle"
|
permission: "Rôle et autorisations"
|
||||||
assignTarget: "Attribuer"
|
assignTarget: "Attribuer"
|
||||||
manual: "Manuel"
|
manual: "Manuel"
|
||||||
manualRoles: "Rôles manuels"
|
manualRoles: "Rôles manuels"
|
||||||
|
|
@ -1661,11 +1474,9 @@ _role:
|
||||||
canManageCustomEmojis: "Gestion des émojis personnalisés"
|
canManageCustomEmojis: "Gestion des émojis personnalisés"
|
||||||
canManageAvatarDecorations: "Gestion des décorations d'avatar"
|
canManageAvatarDecorations: "Gestion des décorations d'avatar"
|
||||||
driveCapacity: "Capacité de stockage du Disque"
|
driveCapacity: "Capacité de stockage du Disque"
|
||||||
antennaMax: "Nombre maximum d'antennes"
|
|
||||||
wordMuteMax: "Nombre maximal de caractères dans le filtre de mots"
|
wordMuteMax: "Nombre maximal de caractères dans le filtre de mots"
|
||||||
canUseTranslator: "Usage de la fonctionnalité de traduction"
|
canUseTranslator: "Usage de la fonctionnalité de traduction"
|
||||||
avatarDecorationLimit: "Nombre maximal de décorations d'avatar"
|
avatarDecorationLimit: "Nombre maximal de décorations d'avatar"
|
||||||
canImportAntennas: "Autoriser l'importation d'antennes"
|
|
||||||
_sensitiveMediaDetection:
|
_sensitiveMediaDetection:
|
||||||
description: "L'apprentissage automatique peut être utilisé pour détecter automatiquement les médias sensibles à modérer. La sollicitation des serveurs augmente légèrement."
|
description: "L'apprentissage automatique peut être utilisé pour détecter automatiquement les médias sensibles à modérer. La sollicitation des serveurs augmente légèrement."
|
||||||
sensitivity: "Sensibilité de la détection"
|
sensitivity: "Sensibilité de la détection"
|
||||||
|
|
@ -1834,6 +1645,7 @@ _theme:
|
||||||
header: "Entête"
|
header: "Entête"
|
||||||
navBg: "Fond de la barre latérale"
|
navBg: "Fond de la barre latérale"
|
||||||
navFg: "Texte de la barre latérale"
|
navFg: "Texte de la barre latérale"
|
||||||
|
navHoverFg: "Texte de la barre latérale (survolé)"
|
||||||
navActive: "Texte de la barre latérale (actif)"
|
navActive: "Texte de la barre latérale (actif)"
|
||||||
navIndicator: "Indicateur de barre latérale"
|
navIndicator: "Indicateur de barre latérale"
|
||||||
link: "Lien"
|
link: "Lien"
|
||||||
|
|
@ -1855,13 +1667,20 @@ _theme:
|
||||||
buttonBg: "Arrière-plan du bouton"
|
buttonBg: "Arrière-plan du bouton"
|
||||||
buttonHoverBg: "Arrière-plan du bouton (survolé)"
|
buttonHoverBg: "Arrière-plan du bouton (survolé)"
|
||||||
inputBorder: "Cadre de la zone de texte"
|
inputBorder: "Cadre de la zone de texte"
|
||||||
|
listItemHoverBg: "Arrière-plan d'item de liste (survolé)"
|
||||||
|
driveFolderBg: "Arrière-plan du dossier de disque"
|
||||||
|
wallpaperOverlay: "Superposition de fond d'écran"
|
||||||
badge: "Badge"
|
badge: "Badge"
|
||||||
messageBg: "Arrière plan de la discussion"
|
messageBg: "Arrière plan de la discussion"
|
||||||
|
accentDarken: "Plus sombre"
|
||||||
|
accentLighten: "Plus clair"
|
||||||
fgHighlighted: "Texte mis en évidence"
|
fgHighlighted: "Texte mis en évidence"
|
||||||
_sfx:
|
_sfx:
|
||||||
note: "Nouvelle note"
|
note: "Nouvelle note"
|
||||||
noteMy: "Ma note"
|
noteMy: "Ma note"
|
||||||
notification: "Notifications"
|
notification: "Notifications"
|
||||||
|
antenna: "Réception de l’antenne"
|
||||||
|
channel: "Notifications de canal"
|
||||||
reaction: "Lors de la sélection de la réaction"
|
reaction: "Lors de la sélection de la réaction"
|
||||||
_soundSettings:
|
_soundSettings:
|
||||||
driveFile: "Utiliser un effet sonore sur le Disque"
|
driveFile: "Utiliser un effet sonore sur le Disque"
|
||||||
|
|
@ -1943,30 +1762,6 @@ _permissions:
|
||||||
"write:gallery": "Éditer la galerie"
|
"write:gallery": "Éditer la galerie"
|
||||||
"read:gallery-likes": "Voir les mentions « J'aime » dans la galerie"
|
"read:gallery-likes": "Voir les mentions « J'aime » dans la galerie"
|
||||||
"write:gallery-likes": "Gérer les mentions « J'aime » dans la galerie"
|
"write:gallery-likes": "Gérer les mentions « J'aime » dans la galerie"
|
||||||
"read:flash": "Voir le Play"
|
|
||||||
"write:flash": "Modifier le Play"
|
|
||||||
"read:flash-likes": "Lire vos mentions j'aime des Play"
|
|
||||||
"write:flash-likes": "Modifier vos mentions j'aime des Play"
|
|
||||||
"read:admin:abuse-user-reports": "Voir les utilisateurs signalés"
|
|
||||||
"write:admin:delete-account": "Supprimer le compte d'utilisateur"
|
|
||||||
"write:admin:delete-all-files-of-a-user": "Supprimer tous les fichiers d'un utilisateur"
|
|
||||||
"read:admin:index-stats": "Voir les statistiques sur les index de base de données"
|
|
||||||
"read:admin:table-stats": "Voir les statistiques sur les index de base de données"
|
|
||||||
"read:admin:user-ips": "Voir l'adresse IP de l'utilisateur"
|
|
||||||
"read:admin:meta": "Voir les métadonnées de l'instance"
|
|
||||||
"write:admin:reset-password": "Réinitialiser le mot de passe de l'utilisateur"
|
|
||||||
"write:admin:resolve-abuse-user-report": "Résoudre le signalement d'un utilisateur"
|
|
||||||
"write:admin:send-email": "Envoyer un mail"
|
|
||||||
"read:admin:server-info": "Voir les informations de l'instance"
|
|
||||||
"read:admin:show-moderation-log": "Voir les logs de modération"
|
|
||||||
"read:admin:show-user": "Voir les informations privées de l'utilisateur"
|
|
||||||
"write:admin:suspend-user": "Suspendre l'utilisateur"
|
|
||||||
"write:admin:unset-user-avatar": "Retirer l'avatar de l'utilisateur"
|
|
||||||
"write:admin:unset-user-banner": "Retirer la bannière de l'utilisateur"
|
|
||||||
"write:admin:unsuspend-user": "Lever la suspension d'un utilisateur"
|
|
||||||
"write:admin:meta": "Gérer les métadonnées de l'instance"
|
|
||||||
"write:admin:roles": "Gérer les rôles"
|
|
||||||
"write:chat": "Gérer les discussions"
|
|
||||||
_auth:
|
_auth:
|
||||||
shareAccess: "Autoriser \"{name}\" à accéder à votre compte ?"
|
shareAccess: "Autoriser \"{name}\" à accéder à votre compte ?"
|
||||||
shareAccessAsk: "Voulez-vous vraiment autoriser cette application à accéder à votre compte?"
|
shareAccessAsk: "Voulez-vous vraiment autoriser cette application à accéder à votre compte?"
|
||||||
|
|
@ -2015,14 +1810,6 @@ _widgets:
|
||||||
_userList:
|
_userList:
|
||||||
chooseList: "Sélectionner une liste"
|
chooseList: "Sélectionner une liste"
|
||||||
birthdayFollowings: "Utilisateurs qui fêtent l'anniversaire aujourd'hui"
|
birthdayFollowings: "Utilisateurs qui fêtent l'anniversaire aujourd'hui"
|
||||||
_widgetOptions:
|
|
||||||
height: "Hauteur"
|
|
||||||
_button:
|
|
||||||
colored: "Coloré"
|
|
||||||
_clock:
|
|
||||||
size: "Taille"
|
|
||||||
_birthdayFollowings:
|
|
||||||
period: "Durée"
|
|
||||||
_cw:
|
_cw:
|
||||||
hide: "Masquer"
|
hide: "Masquer"
|
||||||
show: "Afficher le contenu"
|
show: "Afficher le contenu"
|
||||||
|
|
@ -2064,9 +1851,6 @@ _postForm:
|
||||||
replyPlaceholder: "Répondre à cette note ..."
|
replyPlaceholder: "Répondre à cette note ..."
|
||||||
quotePlaceholder: "Citez cette note ..."
|
quotePlaceholder: "Citez cette note ..."
|
||||||
channelPlaceholder: "Publier au canal…"
|
channelPlaceholder: "Publier au canal…"
|
||||||
_howToUse:
|
|
||||||
visibility_title: "Visibilité"
|
|
||||||
menu_title: "Menu"
|
|
||||||
_placeholders:
|
_placeholders:
|
||||||
a: "Quoi de neuf ?"
|
a: "Quoi de neuf ?"
|
||||||
b: "Il s'est passé quelque chose ?"
|
b: "Il s'est passé quelque chose ?"
|
||||||
|
|
@ -2129,16 +1913,7 @@ _timelines:
|
||||||
social: "Social"
|
social: "Social"
|
||||||
global: "Global"
|
global: "Global"
|
||||||
_play:
|
_play:
|
||||||
new: "Créer un Play"
|
|
||||||
edit: "Modifier un Play"
|
|
||||||
created: "Play créé"
|
|
||||||
updated: "Play édité"
|
|
||||||
deleted: "Play supprimé"
|
|
||||||
pageSetting: "Configuration du Play"
|
|
||||||
editThisPage: "Modifier ce Play"
|
|
||||||
viewSource: "Afficher la source"
|
viewSource: "Afficher la source"
|
||||||
my: "Mes Play"
|
|
||||||
liked: "Play aimés"
|
|
||||||
featured: "Populaire"
|
featured: "Populaire"
|
||||||
title: "Titre"
|
title: "Titre"
|
||||||
script: "Script"
|
script: "Script"
|
||||||
|
|
@ -2147,6 +1922,9 @@ _pages:
|
||||||
newPage: "Créer une page"
|
newPage: "Créer une page"
|
||||||
editPage: "Modifier une page"
|
editPage: "Modifier une page"
|
||||||
readPage: "Affichage de la source en cours"
|
readPage: "Affichage de la source en cours"
|
||||||
|
created: "La page a été créée !"
|
||||||
|
updated: "La page a été mise à jour !"
|
||||||
|
deleted: "La page a été supprimée"
|
||||||
pageSetting: "Paramètres de la Page"
|
pageSetting: "Paramètres de la Page"
|
||||||
nameAlreadyExists: "L'URL de page spécifiée existe déjà"
|
nameAlreadyExists: "L'URL de page spécifiée existe déjà"
|
||||||
invalidNameTitle: "L'URL de page spécifiée n’est pas valide"
|
invalidNameTitle: "L'URL de page spécifiée n’est pas valide"
|
||||||
|
|
@ -2206,16 +1984,13 @@ _notification:
|
||||||
unreadAntennaNote: "Antenne {name}"
|
unreadAntennaNote: "Antenne {name}"
|
||||||
roleAssigned: "Rôle attribué"
|
roleAssigned: "Rôle attribué"
|
||||||
emptyPushNotificationMessage: "Les notifications push ont été mises à jour"
|
emptyPushNotificationMessage: "Les notifications push ont été mises à jour"
|
||||||
achievementEarned: "Accomplissement déverrouillé"
|
achievementEarned: "Accomplissement"
|
||||||
testNotification: "Tester la notification"
|
testNotification: "Tester la notification"
|
||||||
reactedBySomeUsers: "{n} utilisateur·rice·s ont réagi"
|
reactedBySomeUsers: "{n} utilisateur·rice·s ont réagi"
|
||||||
likedBySomeUsers: "{n} utilisateurs ont aimé votre note"
|
|
||||||
renotedBySomeUsers: "{n} utilisateur·rice·s ont renoté"
|
renotedBySomeUsers: "{n} utilisateur·rice·s ont renoté"
|
||||||
followedBySomeUsers: "{n} utilisateur·rice·s se sont abonné·e·s à vous"
|
followedBySomeUsers: "{n} utilisateur·rice·s se sont abonné·e·s à vous"
|
||||||
login: "Quelqu'un s'est connecté"
|
|
||||||
_types:
|
_types:
|
||||||
all: "Toutes"
|
all: "Toutes"
|
||||||
note: "Nouvelles notes"
|
|
||||||
follow: "Nouvel·le abonné·e"
|
follow: "Nouvel·le abonné·e"
|
||||||
mention: "Mentions"
|
mention: "Mentions"
|
||||||
reply: "Réponses"
|
reply: "Réponses"
|
||||||
|
|
@ -2226,8 +2001,7 @@ _notification:
|
||||||
receiveFollowRequest: "Demande d'abonnement reçue"
|
receiveFollowRequest: "Demande d'abonnement reçue"
|
||||||
followRequestAccepted: "Demande d'abonnement acceptée"
|
followRequestAccepted: "Demande d'abonnement acceptée"
|
||||||
roleAssigned: "Rôle reçu"
|
roleAssigned: "Rôle reçu"
|
||||||
achievementEarned: "Déverrouillage d'accomplissement"
|
achievementEarned: "Accomplissement"
|
||||||
login: "Se connecter"
|
|
||||||
app: "Notifications provenant des apps"
|
app: "Notifications provenant des apps"
|
||||||
_actions:
|
_actions:
|
||||||
followBack: "Suivre"
|
followBack: "Suivre"
|
||||||
|
|
@ -2265,14 +2039,7 @@ _drivecleaner:
|
||||||
orderByCreatedAtAsc: "Date d'ajout ascendante"
|
orderByCreatedAtAsc: "Date d'ajout ascendante"
|
||||||
_webhookSettings:
|
_webhookSettings:
|
||||||
name: "Nom"
|
name: "Nom"
|
||||||
secret: "Secret"
|
|
||||||
trigger: "Activateur"
|
|
||||||
active: "Activé"
|
active: "Activé"
|
||||||
_abuseReport:
|
|
||||||
_notificationRecipient:
|
|
||||||
_recipientType:
|
|
||||||
mail: "E-mail "
|
|
||||||
keywords: "Mots clés "
|
|
||||||
_moderationLogTypes:
|
_moderationLogTypes:
|
||||||
createRole: "Rôle créé"
|
createRole: "Rôle créé"
|
||||||
deleteRole: "Rôle supprimé"
|
deleteRole: "Rôle supprimé"
|
||||||
|
|
@ -2309,7 +2076,6 @@ _moderationLogTypes:
|
||||||
deleteAvatarDecoration: "Décoration d'avatar supprimée"
|
deleteAvatarDecoration: "Décoration d'avatar supprimée"
|
||||||
unsetUserAvatar: "Supprimer l'avatar de l'utilisateur·rice"
|
unsetUserAvatar: "Supprimer l'avatar de l'utilisateur·rice"
|
||||||
unsetUserBanner: "Supprimer la bannière de l'utilisateur·rice"
|
unsetUserBanner: "Supprimer la bannière de l'utilisateur·rice"
|
||||||
deleteFlash: "Supprimer le Play"
|
|
||||||
_fileViewer:
|
_fileViewer:
|
||||||
title: "Détails du fichier"
|
title: "Détails du fichier"
|
||||||
type: "Type du fichier"
|
type: "Type du fichier"
|
||||||
|
|
@ -2323,8 +2089,10 @@ _externalResourceInstaller:
|
||||||
checkVendorBeforeInstall: "Veuillez confirmer que le distributeur est fiable avant l'installation."
|
checkVendorBeforeInstall: "Veuillez confirmer que le distributeur est fiable avant l'installation."
|
||||||
_plugin:
|
_plugin:
|
||||||
title: "Voulez-vous installer cette extension ?"
|
title: "Voulez-vous installer cette extension ?"
|
||||||
|
metaTitle: "Informations sur l'extension"
|
||||||
_theme:
|
_theme:
|
||||||
title: "Voulez-vous installer ce thème ?"
|
title: "Voulez-vous installer ce thème ?"
|
||||||
|
metaTitle: "Informations sur le thème"
|
||||||
_meta:
|
_meta:
|
||||||
base: "Palette de couleurs de base"
|
base: "Palette de couleurs de base"
|
||||||
_vendorInfo:
|
_vendorInfo:
|
||||||
|
|
@ -2364,53 +2132,12 @@ _dataSaver:
|
||||||
_avatar:
|
_avatar:
|
||||||
title: "Animation d'avatars"
|
title: "Animation d'avatars"
|
||||||
description: "Arrête l'animation d'avatars. Comme les images animées peuvent être plus volumineuses que les images normales, cela permet de réduire davantage le trafic de données."
|
description: "Arrête l'animation d'avatars. Comme les images animées peuvent être plus volumineuses que les images normales, cela permet de réduire davantage le trafic de données."
|
||||||
|
_urlPreview:
|
||||||
|
title: "Vignettes d'aperçu des URL"
|
||||||
|
description: "Les vignettes d'aperçu des URL ne seront plus chargées."
|
||||||
_code:
|
_code:
|
||||||
title: "Mise en évidence du code"
|
title: "Mise en évidence du code"
|
||||||
description: "Si la notation de mise en évidence du code est utilisée, par exemple dans la MFM, elle ne sera pas chargée tant qu'elle n'aura pas été tapée. La mise en évidence du code nécessite le chargement du fichier de définition de chaque langue à mettre en évidence, mais comme ces fichiers ne sont plus chargés automatiquement, on peut s'attendre à une réduction du trafic de données."
|
description: "Si la notation de mise en évidence du code est utilisée, par exemple dans la MFM, elle ne sera pas chargée tant qu'elle n'aura pas été tapée. La mise en évidence du code nécessite le chargement du fichier de définition de chaque langue à mettre en évidence, mais comme ces fichiers ne sont plus chargés automatiquement, on peut s'attendre à une réduction du trafic de données."
|
||||||
_reversi:
|
_reversi:
|
||||||
reversi: "Reversi"
|
|
||||||
blackIs: "{name} joue les noirs"
|
|
||||||
rules: "Règles"
|
|
||||||
waitingBoth: "Préparez-vous"
|
|
||||||
myTurn: "C’est votre tour"
|
|
||||||
turnOf: "C'est le tour de {name}"
|
|
||||||
pastTurnOf: "Tour de {name}"
|
|
||||||
surrender: "Se rendre"
|
|
||||||
surrendered: "Par abandon"
|
|
||||||
total: "Total"
|
total: "Total"
|
||||||
playing: "En cours"
|
|
||||||
lookingForPlayer: "Recherche d'adversaire"
|
|
||||||
_mediaControls:
|
|
||||||
playbackRate: "Vitesse de lecture"
|
|
||||||
_embedCodeGen:
|
|
||||||
title: "Personnaliser le code d'intégration"
|
|
||||||
generateCode: "Générer le code d'intégration"
|
|
||||||
_remoteLookupErrors:
|
|
||||||
_noSuchObject:
|
|
||||||
title: "Non trouvé"
|
|
||||||
_search:
|
|
||||||
searchScopeAll: "Tous"
|
|
||||||
searchScopeLocal: "Local"
|
|
||||||
searchScopeUser: "Spécifier l'utilisateur·rice"
|
|
||||||
_watermarkEditor:
|
|
||||||
driveFileTypeWarn: "Ce fichier n'est pas pris en charge"
|
|
||||||
opacity: "Transparence"
|
|
||||||
scale: "Taille"
|
|
||||||
text: "Texte"
|
|
||||||
position: "Position"
|
|
||||||
type: "Type"
|
|
||||||
image: "Images"
|
|
||||||
advanced: "Avancé"
|
|
||||||
angle: "Angle"
|
|
||||||
_imageEffector:
|
|
||||||
_fxProps:
|
|
||||||
angle: "Angle"
|
|
||||||
scale: "Taille"
|
|
||||||
size: "Taille"
|
|
||||||
offset: "Position"
|
|
||||||
color: "Couleur"
|
|
||||||
opacity: "Transparence"
|
|
||||||
lightness: "Clair"
|
|
||||||
_qr:
|
|
||||||
showTabTitle: "Affichage"
|
|
||||||
raw: "Texte"
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,230 @@
|
||||||
|
import * as fs from 'node:fs';
|
||||||
|
import { fileURLToPath } from 'node:url';
|
||||||
|
import { dirname } from 'node:path';
|
||||||
|
import * as yaml from 'js-yaml';
|
||||||
|
import ts from 'typescript';
|
||||||
|
|
||||||
|
const __filename = fileURLToPath(import.meta.url);
|
||||||
|
const __dirname = dirname(__filename);
|
||||||
|
const parameterRegExp = /\{(\w+)\}/g;
|
||||||
|
|
||||||
|
function createMemberType(item) {
|
||||||
|
if (typeof item !== 'string') {
|
||||||
|
return ts.factory.createTypeLiteralNode(createMembers(item));
|
||||||
|
}
|
||||||
|
const parameters = Array.from(
|
||||||
|
item.matchAll(parameterRegExp),
|
||||||
|
([, parameter]) => parameter,
|
||||||
|
);
|
||||||
|
return parameters.length
|
||||||
|
? ts.factory.createTypeReferenceNode(
|
||||||
|
ts.factory.createIdentifier('ParameterizedString'),
|
||||||
|
[
|
||||||
|
ts.factory.createUnionTypeNode(
|
||||||
|
parameters.map((parameter) =>
|
||||||
|
ts.factory.createStringLiteral(parameter),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
: ts.factory.createKeywordTypeNode(ts.SyntaxKind.StringKeyword);
|
||||||
|
}
|
||||||
|
|
||||||
|
function createMembers(record) {
|
||||||
|
return Object.entries(record).map(([k, v]) => {
|
||||||
|
const node = ts.factory.createPropertySignature(
|
||||||
|
undefined,
|
||||||
|
ts.factory.createStringLiteral(k),
|
||||||
|
undefined,
|
||||||
|
createMemberType(v),
|
||||||
|
);
|
||||||
|
if (typeof v === 'string') {
|
||||||
|
ts.addSyntheticLeadingComment(
|
||||||
|
node,
|
||||||
|
ts.SyntaxKind.MultiLineCommentTrivia,
|
||||||
|
`*
|
||||||
|
* ${v.replace(/\n/g, '\n * ')}
|
||||||
|
`,
|
||||||
|
true,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return node;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function generateDTS() {
|
||||||
|
const locale = yaml.load(fs.readFileSync(`${__dirname}/ja-JP.yml`, 'utf-8'));
|
||||||
|
const members = createMembers(locale);
|
||||||
|
const elements = [
|
||||||
|
ts.factory.createVariableStatement(
|
||||||
|
[ts.factory.createToken(ts.SyntaxKind.DeclareKeyword)],
|
||||||
|
ts.factory.createVariableDeclarationList(
|
||||||
|
[
|
||||||
|
ts.factory.createVariableDeclaration(
|
||||||
|
ts.factory.createIdentifier('kParameters'),
|
||||||
|
undefined,
|
||||||
|
ts.factory.createTypeOperatorNode(
|
||||||
|
ts.SyntaxKind.UniqueKeyword,
|
||||||
|
ts.factory.createKeywordTypeNode(ts.SyntaxKind.SymbolKeyword),
|
||||||
|
),
|
||||||
|
undefined,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
ts.NodeFlags.Const,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
ts.factory.createInterfaceDeclaration(
|
||||||
|
[ts.factory.createToken(ts.SyntaxKind.ExportKeyword)],
|
||||||
|
ts.factory.createIdentifier('ParameterizedString'),
|
||||||
|
[
|
||||||
|
ts.factory.createTypeParameterDeclaration(
|
||||||
|
undefined,
|
||||||
|
ts.factory.createIdentifier('T'),
|
||||||
|
ts.factory.createKeywordTypeNode(ts.SyntaxKind.StringKeyword),
|
||||||
|
ts.factory.createKeywordTypeNode(ts.SyntaxKind.StringKeyword),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
undefined,
|
||||||
|
[
|
||||||
|
ts.factory.createPropertySignature(
|
||||||
|
undefined,
|
||||||
|
ts.factory.createComputedPropertyName(
|
||||||
|
ts.factory.createIdentifier('kParameters'),
|
||||||
|
),
|
||||||
|
undefined,
|
||||||
|
ts.factory.createTypeReferenceNode(
|
||||||
|
ts.factory.createIdentifier('T'),
|
||||||
|
undefined,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
ts.factory.createInterfaceDeclaration(
|
||||||
|
[ts.factory.createToken(ts.SyntaxKind.ExportKeyword)],
|
||||||
|
ts.factory.createIdentifier('ILocale'),
|
||||||
|
undefined,
|
||||||
|
undefined,
|
||||||
|
[
|
||||||
|
ts.factory.createIndexSignature(
|
||||||
|
undefined,
|
||||||
|
[
|
||||||
|
ts.factory.createParameterDeclaration(
|
||||||
|
undefined,
|
||||||
|
undefined,
|
||||||
|
ts.factory.createIdentifier('_'),
|
||||||
|
undefined,
|
||||||
|
ts.factory.createKeywordTypeNode(ts.SyntaxKind.StringKeyword),
|
||||||
|
undefined,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
ts.factory.createUnionTypeNode([
|
||||||
|
ts.factory.createKeywordTypeNode(ts.SyntaxKind.StringKeyword),
|
||||||
|
ts.factory.createTypeReferenceNode(
|
||||||
|
ts.factory.createIdentifier('ParameterizedString'),
|
||||||
|
),
|
||||||
|
ts.factory.createTypeReferenceNode(
|
||||||
|
ts.factory.createIdentifier('ILocale'),
|
||||||
|
undefined,
|
||||||
|
),
|
||||||
|
]),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
ts.factory.createInterfaceDeclaration(
|
||||||
|
[ts.factory.createToken(ts.SyntaxKind.ExportKeyword)],
|
||||||
|
ts.factory.createIdentifier('Locale'),
|
||||||
|
undefined,
|
||||||
|
[
|
||||||
|
ts.factory.createHeritageClause(ts.SyntaxKind.ExtendsKeyword, [
|
||||||
|
ts.factory.createExpressionWithTypeArguments(
|
||||||
|
ts.factory.createIdentifier('ILocale'),
|
||||||
|
undefined,
|
||||||
|
),
|
||||||
|
]),
|
||||||
|
],
|
||||||
|
members,
|
||||||
|
),
|
||||||
|
ts.factory.createVariableStatement(
|
||||||
|
[ts.factory.createToken(ts.SyntaxKind.DeclareKeyword)],
|
||||||
|
ts.factory.createVariableDeclarationList(
|
||||||
|
[
|
||||||
|
ts.factory.createVariableDeclaration(
|
||||||
|
ts.factory.createIdentifier('locales'),
|
||||||
|
undefined,
|
||||||
|
ts.factory.createTypeLiteralNode([
|
||||||
|
ts.factory.createIndexSignature(
|
||||||
|
undefined,
|
||||||
|
[
|
||||||
|
ts.factory.createParameterDeclaration(
|
||||||
|
undefined,
|
||||||
|
undefined,
|
||||||
|
ts.factory.createIdentifier('lang'),
|
||||||
|
undefined,
|
||||||
|
ts.factory.createKeywordTypeNode(
|
||||||
|
ts.SyntaxKind.StringKeyword,
|
||||||
|
),
|
||||||
|
undefined,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
ts.factory.createTypeReferenceNode(
|
||||||
|
ts.factory.createIdentifier('Locale'),
|
||||||
|
undefined,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
]),
|
||||||
|
undefined,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
ts.NodeFlags.Const,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
ts.factory.createFunctionDeclaration(
|
||||||
|
[ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)],
|
||||||
|
undefined,
|
||||||
|
ts.factory.createIdentifier('build'),
|
||||||
|
undefined,
|
||||||
|
[],
|
||||||
|
ts.factory.createTypeReferenceNode(
|
||||||
|
ts.factory.createIdentifier('Locale'),
|
||||||
|
undefined,
|
||||||
|
),
|
||||||
|
undefined,
|
||||||
|
),
|
||||||
|
ts.factory.createExportDefault(ts.factory.createIdentifier('locales')),
|
||||||
|
];
|
||||||
|
ts.addSyntheticLeadingComment(
|
||||||
|
elements[0],
|
||||||
|
ts.SyntaxKind.MultiLineCommentTrivia,
|
||||||
|
' eslint-disable ',
|
||||||
|
true,
|
||||||
|
);
|
||||||
|
ts.addSyntheticLeadingComment(
|
||||||
|
elements[0],
|
||||||
|
ts.SyntaxKind.SingleLineCommentTrivia,
|
||||||
|
' This file is generated by locales/generateDTS.js',
|
||||||
|
true,
|
||||||
|
);
|
||||||
|
ts.addSyntheticLeadingComment(
|
||||||
|
elements[0],
|
||||||
|
ts.SyntaxKind.SingleLineCommentTrivia,
|
||||||
|
' Do not edit this file directly.',
|
||||||
|
true,
|
||||||
|
);
|
||||||
|
const printed = ts
|
||||||
|
.createPrinter({
|
||||||
|
newLine: ts.NewLineKind.LineFeed,
|
||||||
|
})
|
||||||
|
.printList(
|
||||||
|
ts.ListFormat.MultiLine,
|
||||||
|
ts.factory.createNodeArray(elements),
|
||||||
|
ts.createSourceFile(
|
||||||
|
'index.d.ts',
|
||||||
|
'',
|
||||||
|
ts.ScriptTarget.ESNext,
|
||||||
|
true,
|
||||||
|
ts.ScriptKind.TS,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
fs.writeFileSync(`${__dirname}/index.d.ts`, printed, 'utf-8');
|
||||||
|
}
|
||||||
|
|
@ -3,3 +3,4 @@ _lang_: "japanski"
|
||||||
ok: "OK"
|
ok: "OK"
|
||||||
gotIt: "Razumijem"
|
gotIt: "Razumijem"
|
||||||
cancel: "otkazati"
|
cancel: "otkazati"
|
||||||
|
|
||||||
|
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue