From e8d39ab2f7988e7dac52b61e62830fd1832baf54 Mon Sep 17 00:00:00 2001 From: Ana Gelez Date: Tue, 23 Jun 2026 23:42:49 +0200 Subject: [PATCH 1/6] =?UTF-8?q?Passage=20=C3=A0=20Typescript=206?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package-lock.json | 8 ++++---- package.json | 2 +- tsconfig.json | 1 - 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/package-lock.json b/package-lock.json index 4ac6ad8e..8b52bf5c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -52,7 +52,7 @@ "sinon-chai": "^3.7.0", "svelte": "^5.0.0", "svelte-check": "^4.0.0", - "typescript": "^5.5.0" + "typescript": "^6.0.3" } }, "node_modules/@babel/runtime": { @@ -7411,9 +7411,9 @@ } }, "node_modules/typescript": { - "version": "5.9.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", - "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-6.0.3.tgz", + "integrity": "sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==", "dev": true, "license": "Apache-2.0", "bin": { diff --git a/package.json b/package.json index e6fd0a65..013e03b4 100644 --- a/package.json +++ b/package.json @@ -58,7 +58,7 @@ "sinon-chai": "^3.7.0", "svelte": "^5.0.0", "svelte-check": "^4.0.0", - "typescript": "^5.5.0" + "typescript": "^6.0.3" }, "dependencies": { "@isomorphic-git/lightning-fs": "^4.6.0", diff --git a/tsconfig.json b/tsconfig.json index 1f6e3a8e..b48af06f 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -11,7 +11,6 @@ "moduleResolution": "bundler", "target": "esnext", "lib": ["ES2022", "dom", "dom.iterable"], - "downlevelIteration": true, "types": ["node", "mocha"], "noUnusedLocals": true, "noUnusedParameters": true From 86173f5c6d45e4b4b94b1b7444466663eea29305 Mon Sep 17 00:00:00 2001 From: Ana Gelez Date: Wed, 24 Jun 2026 10:19:18 +0200 Subject: [PATCH 2/6] =?UTF-8?q?Passage=20=C3=A0=20la=20syntaxe=20TypeScrip?= =?UTF-8?q?t?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- assets/scripts/{GitAgent.js => GitAgent.ts} | 173 ++++-------- .../actions/{article.js => article.ts} | 61 ++-- ...nt-repository.js => current-repository.ts} | 53 ++-- .../{current-user.js => current-user.ts} | 47 ++-- assets/scripts/actions/{file.js => file.ts} | 58 +--- assets/scripts/actions/{page.js => page.ts} | 69 ++--- assets/scripts/actions/{setup.js => setup.ts} | 52 ++-- .../{buildStatus.js => buildStatus.ts} | 43 +-- assets/scripts/components/Header.svelte | 70 ++--- assets/scripts/components/Skeleton.svelte | 24 +- .../scripts/components/screens/Account.svelte | 12 +- .../components/screens/AfterOauthLogin.svelte | 13 +- .../components/screens/ArticleContenu.svelte | 27 +- .../components/screens/AtelierArticles.svelte | 24 +- .../components/screens/AtelierPages.svelte | 24 +- .../components/screens/ChooseAccount.svelte | 2 +- .../components/screens/CreateAccount.svelte | 12 +- .../components/screens/CreateNewSite.svelte | 10 +- .../scripts/components/screens/Login.svelte | 14 +- .../components/screens/PageContenu.svelte | 29 +- .../ResolutionDesynchronisation.svelte | 26 +- .../screens/SelectCurrentSite.svelte | 21 +- .../screens/SelectOrCreateSite.svelte | 2 +- .../components/screens/Settings.svelte | 32 +-- .../scripts/components/screens/Welcome.svelte | 17 +- .../components/screens/intern/Editeur.svelte | 43 ++- .../screens/intern/ListContenu.svelte | 42 ++- assets/scripts/{config.js => config.ts} | 11 +- .../{github.js => github.ts} | 130 ++++----- assets/scripts/oauth-services-api/gitlab.js | 264 ------------------ assets/scripts/oauth-services-api/gitlab.ts | 239 ++++++++++++++++ .../oauth-services-api/{index.js => index.ts} | 38 +-- .../scripts/routeComponentLifeCycle.svelte.js | 62 ---- .../scripts/routeComponentLifeCycle.svelte.ts | 52 ++++ .../scripts/routes/{account.js => account.ts} | 12 +- ...er-oauth-login.js => after-oauth-login.ts} | 7 +- assets/scripts/routes/atelier-articles.js | 143 ---------- assets/scripts/routes/atelier-articles.ts | 142 ++++++++++ ...t-articles.js => atelier-list-articles.ts} | 27 +- ...er-list-pages.js => atelier-list-pages.ts} | 16 +- assets/scripts/routes/atelier-pages.js | 150 ---------- assets/scripts/routes/atelier-pages.ts | 150 ++++++++++ .../{choose-account.js => choose-account.ts} | 4 +- .../{create-account.js => create-account.ts} | 12 +- ...{create-new-site.js => create-new-site.ts} | 2 +- assets/scripts/routes/{login.js => login.ts} | 28 +- assets/scripts/routes/{main.js => main.ts} | 9 +- ...ion.js => resolution-desynchronisation.ts} | 16 +- ...reate-site.js => select-or-create-site.ts} | 2 +- .../routes/{settings.js => settings.ts} | 29 +- ...ng-site.js => start-from-existing-site.ts} | 10 +- assets/scripts/routes/urls.js | 7 - assets/scripts/routes/urls.ts | 8 + .../scripts/routes/{welcome.js => welcome.ts} | 6 +- assets/scripts/scribouilliGitRepo.js | 66 ----- assets/scripts/scribouilliGitRepo.ts | 63 +++++ assets/scripts/{scripts.js => scripts.ts} | 2 - assets/scripts/{store.js => store.ts} | 166 +++++------ assets/scripts/types/atelier.js | 37 --- assets/scripts/types/atelier.ts | 33 +++ assets/scripts/types/git.js | 88 ------ assets/scripts/types/git.ts | 95 +++++++ assets/scripts/{utils.js => utils.ts} | 80 ++---- docs/conseils.md | 30 ++ package-lock.json | 69 +++++ package.json | 3 + rollup.config.js | 52 ---- rollup.config.ts | 54 ++++ tsconfig.json | 5 +- 69 files changed, 1529 insertions(+), 1890 deletions(-) rename assets/scripts/{GitAgent.js => GitAgent.ts} (76%) rename assets/scripts/actions/{article.js => article.ts} (77%) rename assets/scripts/actions/{current-repository.js => current-repository.ts} (86%) rename assets/scripts/actions/{current-user.js => current-user.ts} (74%) rename assets/scripts/actions/{file.js => file.ts} (64%) rename assets/scripts/actions/{page.js => page.ts} (74%) rename assets/scripts/actions/{setup.js => setup.ts} (80%) rename assets/scripts/{buildStatus.js => buildStatus.ts} (84%) rename assets/scripts/{config.js => config.ts} (80%) rename assets/scripts/oauth-services-api/{github.js => github.ts} (56%) delete mode 100644 assets/scripts/oauth-services-api/gitlab.js create mode 100644 assets/scripts/oauth-services-api/gitlab.ts rename assets/scripts/oauth-services-api/{index.js => index.ts} (59%) delete mode 100644 assets/scripts/routeComponentLifeCycle.svelte.js create mode 100644 assets/scripts/routeComponentLifeCycle.svelte.ts rename assets/scripts/routes/{account.js => account.ts} (75%) rename assets/scripts/routes/{after-oauth-login.js => after-oauth-login.ts} (94%) delete mode 100644 assets/scripts/routes/atelier-articles.js create mode 100644 assets/scripts/routes/atelier-articles.ts rename assets/scripts/routes/{atelier-list-articles.js => atelier-list-articles.ts} (69%) rename assets/scripts/routes/{atelier-list-pages.js => atelier-list-pages.ts} (75%) delete mode 100644 assets/scripts/routes/atelier-pages.js create mode 100644 assets/scripts/routes/atelier-pages.ts rename assets/scripts/routes/{choose-account.js => choose-account.ts} (74%) rename assets/scripts/routes/{create-account.js => create-account.ts} (66%) rename assets/scripts/routes/{create-new-site.js => create-new-site.ts} (85%) rename assets/scripts/routes/{login.js => login.ts} (83%) rename assets/scripts/routes/{main.js => main.ts} (94%) rename assets/scripts/routes/{resolution-desynchronisation.js => resolution-desynchronisation.ts} (73%) rename assets/scripts/routes/{select-or-create-site.js => select-or-create-site.ts} (77%) rename assets/scripts/routes/{settings.js => settings.ts} (83%) rename assets/scripts/routes/{start-from-existing-site.js => start-from-existing-site.ts} (81%) delete mode 100644 assets/scripts/routes/urls.js create mode 100644 assets/scripts/routes/urls.ts rename assets/scripts/routes/{welcome.js => welcome.ts} (93%) delete mode 100644 assets/scripts/scribouilliGitRepo.js create mode 100644 assets/scripts/scribouilliGitRepo.ts rename assets/scripts/{scripts.js => scripts.ts} (96%) rename assets/scripts/{store.js => store.ts} (51%) delete mode 100644 assets/scripts/types/atelier.js create mode 100644 assets/scripts/types/atelier.ts delete mode 100644 assets/scripts/types/git.js create mode 100644 assets/scripts/types/git.ts rename assets/scripts/{utils.js => utils.ts} (61%) create mode 100644 docs/conseils.md delete mode 100644 rollup.config.js create mode 100644 rollup.config.ts diff --git a/assets/scripts/GitAgent.js b/assets/scripts/GitAgent.ts similarity index 76% rename from assets/scripts/GitAgent.js rename to assets/scripts/GitAgent.ts index 51328d4e..8fd96037 100644 --- a/assets/scripts/GitAgent.js +++ b/assets/scripts/GitAgent.ts @@ -1,5 +1,3 @@ -//@ts-check - /** * Ce fichier gère les interactions avec git (contenu, commits, branches, remotes, pull/pull, etc.) * et aussi le contenu sous-jacent et le filesystem @@ -17,8 +15,8 @@ import http from 'isomorphic-git/http/web' const DEFAULT_CORS_PROXY_URL = 'https://cors.isomorphic-git.org' -/** @typedef {import('isomorphic-git')} isomorphicGit */ -/** @typedef {import('isomorphic-git').GitAuth} GitAuth */ +import type { CommitObject, GitAuth } from 'isomorphic-git' +import { ResolutionOption } from './store' export default class GitAgent { #fs @@ -33,20 +31,20 @@ export default class GitAgent { #hostname #repoDirectory - /** - * @param { object } _ - * @param { string } _.repoId - * @param { string } _.remoteURL - * @param { string } [_.corsProxyURL] - * @param { GitAuth } _.auth - * @param {((resolutionOptions: import('./store.js').ResolutionOption[]) => void) | undefined } [_.onMergeConflict] - */ constructor({ repoId, remoteURL, corsProxyURL = DEFAULT_CORS_PROXY_URL, auth, onMergeConflict, + }: { + repoId: string + remoteURL: string + corsProxyURL?: string + auth: GitAuth + onMergeConflict?: + | ((resolutionOptions: ResolutionOption[]) => void) + | undefined }) { this.#fs = new FS('scribouilli') @@ -63,31 +61,18 @@ export default class GitAgent { this.#repoDirectory = `/${this.#hostname}/${this.#repoId}` } - /** - * - * @param {string} filename - * @returns {string} - */ - #path(filename) { + #path(filename: string): string { return `${this.#repoDirectory}/${filename}` } /** * @summary helper to create ref strings for remotes - * - * @param {string} remote - * @param {string} ref - * @returns {string} */ - #createRemoteRef(remote, ref) { + #createRemoteRef(remote: string, ref: string): string { return `remotes/${remote}/${ref}` } - /** - * - * @returns {ReturnType} - */ - clone() { + clone(): ReturnType { console.info('clone', this.#remoteURL) return git.clone({ fs: this.#fs, @@ -101,25 +86,18 @@ export default class GitAgent { }) } - /** - * - * @returns {ReturnType} - */ - currentBranch() { + currentBranch(): ReturnType { return git.currentBranch({ fs: this.#fs, dir: this.#repoDirectory, }) } - /** - * - * @param {string} branch - * @param {boolean} [force] - * @param {boolean} [checkout] - * @returns {ReturnType} - */ - branch(branch, force = false, checkout = true) { + branch( + branch: string, + force: boolean = false, + checkout: boolean = true, + ): ReturnType { return git.branch({ fs: this.#fs, dir: this.#repoDirectory, @@ -129,23 +107,14 @@ export default class GitAgent { }) } - /** - * - * @returns {ReturnType} - */ - listRemotes() { + listRemotes(): ReturnType { return git.listRemotes({ fs: this.#fs, dir: this.#repoDirectory, }) } - /** - * - * @param {string} [remote] - * @returns {ReturnType} - */ - listBranches(remote) { + listBranches(remote: string): ReturnType { return git.listBranches({ fs: this.#fs, dir: this.#repoDirectory, @@ -156,10 +125,8 @@ export default class GitAgent { /** * @summary This version of git push may fail if the remote repo * has unmerged changes - * - * @returns {ReturnType} */ - falliblePush() { + falliblePush(): ReturnType { console.info('falliblePush') return git.push({ fs: this.#fs, @@ -176,10 +143,8 @@ export default class GitAgent { * @summary This version of git push tries to push * then tries to pull if the push fails * and tries again to push if the pull succeeded - * - * @returns {Promise} */ - safePush() { + safePush(): Promise { console.info('safePush') return this.falliblePush() .catch(err => { @@ -203,10 +168,8 @@ export default class GitAgent { /** * @summary like git push --force - * - * @returns {ReturnType} */ - forcePush() { + forcePush(): ReturnType { console.info('forcePush') return git.push({ fs: this.#fs, @@ -220,11 +183,7 @@ export default class GitAgent { }) } - /** - * - * @returns {ReturnType} - */ - async fetch() { + async fetch(): ReturnType { return git.fetch({ fs: this.#fs, http, @@ -235,12 +194,9 @@ export default class GitAgent { }) } - /** - * - * @param {string} [ref] - * @returns {Promise} - */ - currentCommit(ref = undefined) { + currentCommit( + ref: string | undefined = undefined, + ): Promise { return git .log({ fs: this.#fs, @@ -251,12 +207,9 @@ export default class GitAgent { .then(commits => ({ oid: commits[0].oid, ...commits[0].commit })) } - /** - * - * @param {string} [ref] - * @returns {ReturnType} - */ - checkout(ref = undefined) { + checkout( + ref: string | undefined = undefined, + ): ReturnType { return git.checkout({ fs: this.#fs, dir: this.#repoDirectory, @@ -265,13 +218,10 @@ export default class GitAgent { } /** - * * @summary This function tries to merge * If it fails, it forwards the conflict to this.onMergeConflict with resolution propositions - * - * @returns {Promise} */ - async tryMerging() { + async tryMerging(): Promise { console.info('tryMerging') const [currentBranch, remotes] = await Promise.all([ this.currentBranch(), @@ -338,12 +288,8 @@ export default class GitAgent { /** * @summary Create a commit with the given message. - * - * @param {string} message - * - * @returns {ReturnType} sha of the commit */ - commit(message) { + commit(message: string): ReturnType { return git.commit({ fs: this.#fs, dir: this.#repoDirectory, @@ -353,11 +299,8 @@ export default class GitAgent { /** * @summary Remove file from git tree and from the file system - * - * @param {string} fileName - * @returns {ReturnType} */ - async removeFile(fileName) { + async removeFile(fileName: string): ReturnType { const path = this.#path(fileName) await this.#fs.promises.unlink(path) return await git.remove({ @@ -369,19 +312,13 @@ export default class GitAgent { /** * @summary like a git pull but the merge is better customized - * - * @returns {Promise} */ - async fetchAndTryMerging() { + async fetchAndTryMerging(): Promise { await this.fetch() await this.tryMerging() } - /** - * - * @return {Promise} - */ - async pullOrCloneRepo() { + async pullOrCloneRepo(): Promise { let dirExists = true try { const stat = await this.#fs.promises.stat(this.#repoDirectory) @@ -408,12 +345,11 @@ export default class GitAgent { * https://isomorphic-git.org/docs/en/setConfig * * Alors, on doit passer le repoName - * - * @param {string} login - * @param {string} email - * @returns {Promise>} */ - async setAuthor(login, email) { + async setAuthor( + login: string, + email: string, + ): Promise> { if (!login || !email) { return } @@ -434,11 +370,8 @@ export default class GitAgent { /** * @summary Get file informations - * - * @param {string} fileName - * @returns {Promise} */ - async getFile(fileName) { + async getFile(fileName: string): Promise { const content = await this.#fs.promises.readFile(this.#path(fileName), { encoding: 'utf8', }) @@ -450,13 +383,11 @@ export default class GitAgent { /** * @summary Create or update a file and add it to the git staging area - * - * @param {string | Uint8Array} content - * @param {string} fileName - * - * @returns {Promise} */ - async writeFile(fileName, content) { + async writeFile( + fileName: string, + content: string | Uint8Array, + ): Promise { // This condition is here just in case, but it should not happen in practice // Having an empty file name will not lead immediately to a crash but will result in // some bugs later, see https://github.com/Scribouilli/scribouilli/issues/49#issuecomment-1648226372 @@ -472,21 +403,11 @@ export default class GitAgent { }) } - /** - * - * @param {string} dir - * @returns - */ - listFiles(dir) { + listFiles(dir: string) { return this.#fs.promises.readdir(this.#path(dir)) } - /** - * - * @param {string} filename - * @returns - */ - async checkFileExistence(filename) { + async checkFileExistence(filename: string) { const stat = await this.#fs.promises.stat(this.#path(filename)) return stat.isFile() } diff --git a/assets/scripts/actions/article.js b/assets/scripts/actions/article.ts similarity index 77% rename from assets/scripts/actions/article.js rename to assets/scripts/actions/article.ts index e5192029..5727bb78 100644 --- a/assets/scripts/actions/article.js +++ b/assets/scripts/actions/article.ts @@ -1,18 +1,15 @@ -//@ts-check - import lireFrontMatter from 'front-matter' -import store from './../store.js' +import store, { type ScribouilliState } from './../store.js' import { deleteFileAndPushChanges, writeFileAndPushChanges } from './file.js' import { keepMarkdownAndHTMLFiles } from './page.js' import { makeArticleFileName, makeArticleFrontMatter } from './../utils.js' +import { Article } from '../types/atelier.js' /** Return whether the blog is enabled or not and whether the "Articles" section * should be available. - * - * @param {import("../store.js").ScribouilliState} state */ -export function showArticles(state) { +export function showArticles(state: ScribouilliState) { const index = blogIndex(state) return index !== undefined } @@ -22,11 +19,8 @@ export function showArticles(state) { * * It is true iff there is a file in the root of the project that has `blogIndex: true` * in its front-matter. - * - * @param {import("../store.js").ScribouilliState} state - * @returns {string | undefined} */ -export function blogIndex(state) { +export function blogIndex(state: ScribouilliState): string | undefined { const pages = state.pages ?? [] const index = pages.find(p => p.blogIndex ?? false)?.path // In previous versions we assumed that the blog index was always @@ -34,11 +28,7 @@ export function blogIndex(state) { return index ?? pages.find(p => p.path === 'blog.md')?.path } -/** - * - * @returns {Promise} - */ -export async function getArticlesList() { +export async function getArticlesList(): Promise { const { gitAgent } = store.state if (!gitAgent) { @@ -57,7 +47,13 @@ export async function getArticlesList() { content.toString(), ) return { - title: data?.title, + title: + typeof data === 'object' && + data !== null && + 'title' in data && + typeof data.title === 'string' + ? data.title + : '', path: fullName, content: markdownContent, } @@ -65,12 +61,9 @@ export async function getArticlesList() { ) } -/** - * @param {string} fileName - * - * @returns {ReturnType} - */ -export const deleteArticle = fileName => { +export const deleteArticle = ( + fileName: string, +): ReturnType => { const { state } = store store.mutations.setArticles( @@ -85,13 +78,10 @@ export const deleteArticle = fileName => { ) } -/** - * @param {string} title - * @param {string} content - * - * @returns {ReturnType} - */ -export const createArticle = (title, content) => { +export const createArticle = ( + title: string, + content: string, +): ReturnType => { const { state } = store const date = new Date() @@ -116,14 +106,11 @@ export const createArticle = (title, content) => { ) } -/** - * @param {string} fileName - * @param {string} content - * @param {string} title - * - * @returns {ReturnType} - */ -export const updateArticle = async (fileName, title, content) => { +export const updateArticle = async ( + fileName: string, + title: string, + content: string, +): ReturnType => { const { gitAgent } = store.state if (!gitAgent) { diff --git a/assets/scripts/actions/current-repository.js b/assets/scripts/actions/current-repository.ts similarity index 86% rename from assets/scripts/actions/current-repository.js rename to assets/scripts/actions/current-repository.ts index a0decf5f..f9ce8dfb 100644 --- a/assets/scripts/actions/current-repository.js +++ b/assets/scripts/actions/current-repository.ts @@ -1,5 +1,3 @@ -//@ts-check - import page from 'page' import yaml from 'js-yaml' @@ -34,11 +32,10 @@ export const getCurrentRepoArticles = () => { * repository to be functionnal. It sets the current repository in the store, * but also the build status and the site repo config. If the user is not * logged in, it redirects to the authentication page. - * - * @param {string} querystring - * @returns {Promise} */ -export const setCurrentRepositoryFromQuerystring = async querystring => { +export const setCurrentRepositoryFromQuerystring = async ( + querystring: string, +): Promise => { const params = new URLSearchParams(querystring) const repoName = params.get('repoName') const owner = params.get('account') @@ -101,11 +98,10 @@ export const setCurrentRepositoryFromQuerystring = async querystring => { setBuildStatus(scribouilliGitRepo, gitAgent) } -/** - * @param {ScribouilliGitRepo} scribouilliGitRepo - * @param {GitAgent} gitAgent - */ -export const setBuildStatus = (scribouilliGitRepo, gitAgent) => { +export const setBuildStatus = ( + scribouilliGitRepo: ScribouilliGitRepo, + gitAgent: GitAgent, +) => { store.mutations.setBuildStatus(makeBuildStatus(scribouilliGitRepo, gitAgent)) /* Appel sans vérification, @@ -119,11 +115,10 @@ export const setBuildStatus = (scribouilliGitRepo, gitAgent) => { * @description if baseurl param is set, always update the config with it * otherwise, wait for currentRepository.publishedWebsiteURL and * compute the new config.baseurl from it - * - * @param {string} [baseUrl] - * @returns {Promise} */ -export const setBaseUrlInConfigIfNecessary = async baseUrl => { +export const setBaseUrlInConfigIfNecessary = async ( + baseUrl?: string, +): Promise => { const currentRepository = store.state.currentRepository if (!currentRepository) { @@ -147,7 +142,6 @@ export const setBaseUrlInConfigIfNecessary = async baseUrl => { } const config = await getCurrentRepoConfig() - /** @type {string} */ const currentBaseURL = config.baseurl || '' if (currentBaseURL === newBaseUrl) { @@ -172,15 +166,14 @@ export const setBaseUrlInConfigIfNecessary = async baseUrl => { ) } } - /** - * @param {string} plugin - * @param {string} version - * @returns {Promise} true if the plugin was installed, false if it was already here. + * @returns true if the plugin was installed, false if it was already here. */ -export async function installPluginIfNecessary(plugin, version) { - /** @type {{ plugins: string[] }} */ - const config = await getCurrentRepoConfig() +export async function installPluginIfNecessary( + plugin: string, + version: string, +): Promise { + const config: { plugins: string[] } = await getCurrentRepoConfig() if (config.plugins.includes(plugin)) { return false } @@ -226,10 +219,7 @@ export async function installPluginIfNecessary(plugin, version) { return true } -/** - * @returns {Promise} - */ -const getCurrentRepoConfig = () => { +const getCurrentRepoConfig = (): Promise => { const { currentRepository, gitAgent } = store.state if (!currentRepository) { @@ -245,11 +235,10 @@ const getCurrentRepoConfig = () => { .catch(handleErrors) } -/** - * @param {string} css - * @returns {ReturnType} - */ -export function saveCustomCSS(css, localStore = store) { +export function saveCustomCSS( + css: string, + localStore = store, +): ReturnType { localStore.mutations.setTheme(css) localStore.state.buildStatus.setBuildingAndCheckStatusLater(10000) return file.writeFileAndPushChanges( diff --git a/assets/scripts/actions/current-user.js b/assets/scripts/actions/current-user.ts similarity index 74% rename from assets/scripts/actions/current-user.js rename to assets/scripts/actions/current-user.ts index 5d7be9a5..35167882 100644 --- a/assets/scripts/actions/current-user.js +++ b/assets/scripts/actions/current-user.ts @@ -1,15 +1,11 @@ -//@ts-check - import page from 'page' import { forget } from 'remember' import { getOAuthServiceAPI } from '../oauth-services-api/index.js' -import store from '../store.js' +import store, { ResolutionOption } from '../store.js' import { logMessage } from '../utils.js' import { OAUTH_PROVIDER_STORAGE_KEY } from '../config.js' - - const logout = () => { forget(OAUTH_PROVIDER_STORAGE_KEY) store.mutations.logout() @@ -24,11 +20,14 @@ const logout = () => { * It returns the login of the user or the organization. If the user is not * logged in, it redirects to the authentication page. * - * @returns {Promise<{login: string, email: string}>} A promise that resolves to the login of the - * authenticated user or organization. + * @returns A promise that resolves to the login of the authenticated user or + * organization. * */ -export const fetchAuthenticatedUserLogin = () => { +export const fetchAuthenticatedUserLogin = (): Promise<{ + login: string + email: string +}> => { const loginP = getOAuthServiceAPI() .getAuthenticatedUser() .then(({ login = '' }) => { @@ -45,8 +44,8 @@ export const fetchAuthenticatedUserLogin = () => { switch (errorMessage) { case 'INVALIDATE_TOKEN': case 'NO_LOGIN': { - logout(); - break; + logout() + break } default: @@ -83,19 +82,17 @@ export const fetchAuthenticatedUserLogin = () => { } /** - * @summary Fetch the list of repositories for the current user - * and set it in the store. + * @summary Fetch the list of repositories for the current user and set it in + * the store. * * @description This function is called on every page that needs the list of * repositories for the current user. It returns a promise that resolves to the * list of repositories. If the user is not logged in, it redirects to the * authentication page. * - * @returns A promise that resolves to the list of - * repositories for the current user. - * + * @returns A promise that resolves to the list of repositories for the current + * user. */ - export const fetchCurrentUserRepositories = async () => { const { login } = await fetchAuthenticatedUserLogin() const currentUserRepositoriesP = getOAuthServiceAPI() @@ -110,16 +107,12 @@ export const fetchCurrentUserRepositories = async () => { return currentUserRepositoriesP } -/** - * - * @param {import('./../store.js').ResolutionOption['resolution']} resolution - * @returns {import('./../store.js').ResolutionOption['resolution']} - */ -export function addConflictRemovalAndRedirectToResolution(resolution) { - return function (/** @type {any} */ ...args) { - return resolution(...args).then(() => { - store.mutations.setConflict(undefined) - history.back() - }) +export function addConflictRemovalAndRedirectToResolution( + resolution: ResolutionOption['resolution'], +): ResolutionOption['resolution'] { + return async function (...args: any) { + await resolution(...args) + store.mutations.setConflict(undefined) + history.back() } } diff --git a/assets/scripts/actions/file.js b/assets/scripts/actions/file.ts similarity index 64% rename from assets/scripts/actions/file.js rename to assets/scripts/actions/file.ts index 3ee49ec7..2c348348 100644 --- a/assets/scripts/actions/file.js +++ b/assets/scripts/actions/file.ts @@ -1,21 +1,12 @@ -//@ts-check - import GitAgent from '../GitAgent.js' -import store from './../store.js' +import store from '../store.js' -/** - * @param {string} fileName - * @param {string|Uint8Array} content - * @param {string} [commitMessage] - * - * @returns {Promise} - */ export const writeFileAndCommit = async ( - fileName, - content, - commitMessage, + fileName: string, + content: string | Uint8Array, + commitMessage: string, localStore = store, -) => { +): Promise => { if (typeof commitMessage !== 'string' || commitMessage === '') { commitMessage = `Modification du fichier ${fileName}` } @@ -29,19 +20,12 @@ export const writeFileAndCommit = async ( return gitAgent.commit(commitMessage) } -/** - * @param {string} fileName - * @param {string|Uint8Array} content - * @param {string} [commitMessage] - * - * @returns {ReturnType} - */ export const writeFileAndPushChanges = async ( - fileName, - content, - commitMessage = '', + fileName: string, + content: string | Uint8Array, + commitMessage: string = '', localStore = store, -) => { +): ReturnType => { const { gitAgent } = localStore.state if (!gitAgent) { @@ -52,17 +36,11 @@ export const writeFileAndPushChanges = async ( return gitAgent.safePush() } -/** - * @param {string} fileName - * @param {string} [commitMessage] - * - * @returns {ReturnType} - */ export const deleteFileAndCommit = async ( - fileName, - commitMessage = '', + fileName: string, + commitMessage: string = '', localStore = store, -) => { +): ReturnType => { const { gitAgent } = localStore.state if (!gitAgent) { @@ -77,17 +55,11 @@ export const deleteFileAndCommit = async ( return gitAgent.commit(commitMessage) } -/** - * @param {string} fileName - * @param {string} [commitMessage] - * - * @returns {ReturnType} - */ export const deleteFileAndPushChanges = ( - fileName, - commitMessage, + fileName: string, + commitMessage: string, localStore = store, -) => { +): ReturnType => { const { gitAgent } = localStore.state if (!gitAgent) { diff --git a/assets/scripts/actions/page.js b/assets/scripts/actions/page.ts similarity index 74% rename from assets/scripts/actions/page.js rename to assets/scripts/actions/page.ts index f0bcce55..69f5b38b 100644 --- a/assets/scripts/actions/page.js +++ b/assets/scripts/actions/page.ts @@ -1,25 +1,15 @@ -//@ts-check - import lireFrontMatter from 'front-matter' import store from './../store.js' import { makeFileNameFromTitle, makePageFrontMatter } from './../utils.js' import { deleteFileAndPushChanges, writeFileAndPushChanges } from './file.js' +import { Page } from '../types/atelier.js' -/** - * - * @param {string} filename - * @returns {boolean} - */ -export function keepMarkdownAndHTMLFiles(filename) { +export function keepMarkdownAndHTMLFiles(filename: string): boolean { return filename.endsWith('.md') || filename.endsWith('.html') } -/** - * - * @returns {Promise} - */ -export async function getPagesList() { +export async function getPagesList(): Promise { const { gitAgent } = store.state if (!gitAgent) { @@ -31,9 +21,13 @@ export async function getPagesList() { return Promise.all( allFiles.filter(keepMarkdownAndHTMLFiles).map(async filename => { const content = await gitAgent.getFile(filename) - const { attributes: data, body: markdownContent } = lireFrontMatter( - content.toString(), - ) + // TODO: validate data with zod or equivalent + const { attributes: data, body: markdownContent } = lireFrontMatter<{ + title: string + order: number + in_menu: boolean | undefined + blog_index: boolean | undefined + }>(content.toString()) return { title: data?.title, @@ -48,12 +42,9 @@ export async function getPagesList() { ) } -/** - * @param {string} fileName - * - * @returns {ReturnType} - */ -export const deletePage = fileName => { +export const deletePage = ( + fileName: string, +): ReturnType => { const { state } = store store.mutations.setPages( @@ -69,14 +60,11 @@ export const deletePage = fileName => { ) } -/** - * @param {string} content - * @param {string} title - * @param {number} index - * - * @returns {ReturnType} - */ -export const createPage = (content, title, index) => { +export const createPage = ( + content: string, + title: string, + index: number, +): ReturnType => { const { state } = store const fileName = makeFileNameFromTitle(title) @@ -99,22 +87,13 @@ export const createPage = (content, title, index) => { ) } -/** - * @param {string} fileName - * @param {string} content - * @param {string} title - * @param {number} index - * @param {boolean} blogIndex - * - * @returns {ReturnType} - */ export const updatePage = async ( - fileName, - title, - content, - index, - blogIndex, -) => { + fileName: string, + title: string, + content: string, + index: number, + blogIndex: boolean, +): ReturnType => { const { gitAgent } = store.state if (!gitAgent) { diff --git a/assets/scripts/actions/setup.js b/assets/scripts/actions/setup.ts similarity index 80% rename from assets/scripts/actions/setup.js rename to assets/scripts/actions/setup.ts index 87d8d06e..52681b29 100644 --- a/assets/scripts/actions/setup.js +++ b/assets/scripts/actions/setup.ts @@ -1,8 +1,6 @@ -//@ts-check - import page from 'page' -import store from './../store.js' +import store, { ResolutionOption } from './../store.js' import ScribouilliGitRepo, { makePublicRepositoryURL, makeRepoId, @@ -12,14 +10,12 @@ import { makeAtelierListPageURL } from './../routes/urls.js' import { logMessage } from './../utils.js' import { setBaseUrlInConfigIfNecessary } from './current-repository.js' import GitAgent from '../GitAgent.js' +import git from 'isomorphic-git' +import type { GitSiteTemplate } from '../types/git.js' -/** @typedef {import('isomorphic-git')} isomorphicGit */ - -/** - * @param {ScribouilliGitRepo} scribouilliGitRepo - * @returns {Promise} - */ -const waitRepoReady = scribouilliGitRepo => { +const waitRepoReady = ( + scribouilliGitRepo: ScribouilliGitRepo, +): Promise => { return new Promise(resolve => { const timer = setInterval(() => { getOAuthServiceAPI() @@ -35,10 +31,7 @@ const waitRepoReady = scribouilliGitRepo => { }) } -/** - * @returns {Promise} - */ -export const waitOauthProvider = () => { +export const waitOauthProvider = (): Promise => { return new Promise(resolve => { if (store.state.oAuthProvider) resolve() else { @@ -52,10 +45,9 @@ export const waitOauthProvider = () => { }) } -/** - * @returns {Promise>} - */ -export const setupLocalRepository = async () => { +export const setupLocalRepository = async (): Promise< + ReturnType +> => { const login = await store.state.login const { gitAgent, email } = store.state @@ -76,11 +68,12 @@ export const setupLocalRepository = async () => { /** * @summary guess the published URL until a call to OAuthServiceAPI.getPublishedWebsiteURL is made - * - * @param {ScribouilliGitRepo} _ - * @returns {string} */ -export function guessBaseURL({ owner, repoName, origin }) { +export function guessBaseURL({ + owner, + repoName, + origin, +}: ScribouilliGitRepo): string { if (origin === 'https://github.com') { const publishedHostname = `${owner.toLowerCase()}.github.io` repoName = repoName.toLowerCase() @@ -104,16 +97,19 @@ export function guessBaseURL({ owner, repoName, origin }) { * and set a GitHub Pages branch. It redirects to the * list of pages for the atelier. * - * @param {string} repoName - The name of the repository to create - * @param {GitSiteTemplate} template - The git site template to use + * @param repoName The name of the repository to create + * @param template The git site template to use * - * @returns {Promise} A promise that resolves when the repository + * @returns A promise that resolves when the repository * is created. * - * @throws {string} An error message if the repository cannot be created. + * @throws An error message if the repository cannot be created. * */ -export const createRepositoryForCurrentAccount = async (repoName, template) => { +export const createRepositoryForCurrentAccount = async ( + repoName: string, + template: GitSiteTemplate, +): Promise => { const owner = await store.state.login if (!owner) { @@ -157,7 +153,7 @@ export const createRepositoryForCurrentAccount = async (repoName, template) => { repoId: makeRepoId(owner, escapedRepoName), remoteURL: remoteURL, onMergeConflict: ( - /** @type {import("./../store.js").ResolutionOption[] | undefined} */ resolutionOptions, + resolutionOptions: ResolutionOption[] | undefined, ) => { store.mutations.setConflict(resolutionOptions) }, diff --git a/assets/scripts/buildStatus.js b/assets/scripts/buildStatus.ts similarity index 84% rename from assets/scripts/buildStatus.js rename to assets/scripts/buildStatus.ts index 0f02a5e2..5bb1a987 100644 --- a/assets/scripts/buildStatus.js +++ b/assets/scripts/buildStatus.ts @@ -1,21 +1,16 @@ -//@ts-check - import GitAgent from './GitAgent.js' import { getOAuthServiceAPI } from './oauth-services-api/index.js' +import ScribouilliGitRepo from './scribouilliGitRepo.js' +import { BuildStatus } from './types/git.js' import { isItStillCompiling } from './utils.js' -/** - * - * @param {ScribouilliGitRepo} scribouilliGitRepo - * @param {GitAgent} gitAgent - */ -export default function (scribouilliGitRepo, gitAgent) { - /** @type {BuildStatus} */ - let repoStatus = 'in_progress' - /** @type {(status: BuildStatus) => any} */ - let reaction - /** @type {ReturnType | undefined} */ - let timeout +export default function ( + scribouilliGitRepo: ScribouilliGitRepo, + gitAgent: GitAgent, +) { + let repoStatus: BuildStatus = 'in_progress' + let reaction: (status: BuildStatus) => any + let timeout: ReturnType | undefined function scheduleCheck(delay = 5000) { if (!timeout) { @@ -30,11 +25,7 @@ export default function (scribouilliGitRepo, gitAgent) { get status() { return repoStatus }, - /** - * - * @param {(status: BuildStatus) => any} callback - */ - subscribe(callback) { + subscribe(callback: (status: BuildStatus) => any) { reaction = callback }, checkStatus() { @@ -76,12 +67,11 @@ export default function (scribouilliGitRepo, gitAgent) { * mimoza includes the hash of the latest built commit in a comment in the HTML * of each page. We use that to know which version is currently online, and * whether the last build succeeded or not. - * - * @param {ScribouilliGitRepo} currentRepository - * @param {GitAgent} gitAgent - * @returns {Promise} */ -async function getBuildStatus(currentRepository, gitAgent) { +async function getBuildStatus( + currentRepository: ScribouilliGitRepo, + gitAgent: GitAgent, +): Promise { const publishedWebsiteURL = await currentRepository.publishedWebsiteURL const lastCommit = await gitAgent.currentCommit() @@ -161,10 +151,7 @@ async function getBuildStatus(currentRepository, gitAgent) { return 'success' } -/** - * @param {ScribouilliGitRepo} scribouilliGitRepo - */ -function getViaApi(scribouilliGitRepo) { +function getViaApi(scribouilliGitRepo: ScribouilliGitRepo) { return getOAuthServiceAPI().getPagesWebsiteDeploymentStatus( scribouilliGitRepo, ) diff --git a/assets/scripts/components/Header.svelte b/assets/scripts/components/Header.svelte index bc207178..371604ab 100644 --- a/assets/scripts/components/Header.svelte +++ b/assets/scripts/components/Header.svelte @@ -1,26 +1,23 @@ -
diff --git a/assets/scripts/components/Skeleton.svelte b/assets/scripts/components/Skeleton.svelte index 260f7f31..16f915ce 100644 --- a/assets/scripts/components/Skeleton.svelte +++ b/assets/scripts/components/Skeleton.svelte @@ -1,26 +1,24 @@ -
diff --git a/assets/scripts/components/screens/Account.svelte b/assets/scripts/components/screens/Account.svelte index f3562b63..01277ddd 100644 --- a/assets/scripts/components/screens/Account.svelte +++ b/assets/scripts/components/screens/Account.svelte @@ -1,13 +1,11 @@ - diff --git a/assets/scripts/components/screens/AfterOauthLogin.svelte b/assets/scripts/components/screens/AfterOauthLogin.svelte index 76dcfc59..facb75da 100644 --- a/assets/scripts/components/screens/AfterOauthLogin.svelte +++ b/assets/scripts/components/screens/AfterOauthLogin.svelte @@ -1,14 +1,13 @@ - diff --git a/assets/scripts/components/screens/ArticleContenu.svelte b/assets/scripts/components/screens/ArticleContenu.svelte index 38e10c79..117ef033 100644 --- a/assets/scripts/components/screens/ArticleContenu.svelte +++ b/assets/scripts/components/screens/ArticleContenu.svelte @@ -1,19 +1,20 @@ - + + + diff --git a/assets/scripts/components/screens/CreateAccount.svelte b/assets/scripts/components/screens/CreateAccount.svelte index bd33d55d..219e6c66 100644 --- a/assets/scripts/components/screens/CreateAccount.svelte +++ b/assets/scripts/components/screens/CreateAccount.svelte @@ -1,13 +1,11 @@ - diff --git a/assets/scripts/components/screens/CreateNewSite.svelte b/assets/scripts/components/screens/CreateNewSite.svelte index 4e40f22d..ca36a553 100644 --- a/assets/scripts/components/screens/CreateNewSite.svelte +++ b/assets/scripts/components/screens/CreateNewSite.svelte @@ -1,15 +1,15 @@ - diff --git a/assets/scripts/components/screens/PageContenu.svelte b/assets/scripts/components/screens/PageContenu.svelte index a7e6bc80..35b29366 100644 --- a/assets/scripts/components/screens/PageContenu.svelte +++ b/assets/scripts/components/screens/PageContenu.svelte @@ -1,18 +1,19 @@ - + diff --git a/assets/scripts/components/screens/SelectCurrentSite.svelte b/assets/scripts/components/screens/SelectCurrentSite.svelte index 6b68e670..b6c89bc6 100644 --- a/assets/scripts/components/screens/SelectCurrentSite.svelte +++ b/assets/scripts/components/screens/SelectCurrentSite.svelte @@ -1,21 +1,18 @@ - diff --git a/assets/scripts/components/screens/Settings.svelte b/assets/scripts/components/screens/Settings.svelte index 96f45d23..880a935a 100644 --- a/assets/scripts/components/screens/Settings.svelte +++ b/assets/scripts/components/screens/Settings.svelte @@ -1,24 +1,18 @@ - diff --git a/assets/scripts/components/screens/intern/Editeur.svelte b/assets/scripts/components/screens/intern/Editeur.svelte index d29c0013..a6e2d14d 100644 --- a/assets/scripts/components/screens/intern/Editeur.svelte +++ b/assets/scripts/components/screens/intern/Editeur.svelte @@ -1,5 +1,4 @@ -