This commit is contained in:
Pongstr
2023-02-01 11:40:12 +02:00
parent 4f91aeb80b
commit faf629cca5
31 changed files with 7996 additions and 19711 deletions
+17
View File
@@ -0,0 +1,17 @@
{
"root": true,
"parser": "@typescript-eslint/parser",
"plugins": ["@typescript-eslint"],
"extends": [
"eslint:recommended",
"plugin:@typescript-eslint/eslint-recommended",
"plugin:@typescript-eslint/recommended"
],
"ignorePatterns": ["./**/*.js", "./webpack/*.config.js", "./e2e/*.ts"],
"rules": {
"no-throw-literal": "error",
"no-unused-expressions": "error",
"curly": "error",
"class-methods-use-this": "warn"
}
}
+1
View File
@@ -0,0 +1 @@
auto-install-peers = true
+4 -7
View File
@@ -1,8 +1,5 @@
{
// See http://go.microsoft.com/fwlink/?LinkId=827846
// for the documentation about the extensions.json format
"recommendations": [
"ms-vscode.vscode-typescript-tslint-plugin",
"eliostruyf.vscode-typescript-exportallmodules"
]
}
// See http://go.microsoft.com/fwlink/?LinkId=827846
// for the documentation about the extensions.json format
"recommendations": ["eliostruyf.vscode-typescript-exportallmodules"]
}
+20 -28
View File
@@ -3,32 +3,24 @@
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
{
"version": "0.2.0",
"configurations": [
{
"name": "Launch Extension",
"type": "extensionHost",
"request": "launch",
"runtimeExecutable": "${execPath}",
"args": [
"--extensionDevelopmentPath=${workspaceFolder}"
],
"outFiles": [
"${workspaceFolder}/dist/**/*.js"
],
"preLaunchTask": "npm: build:ext"
},
{
"name": "Attach Extension",
"type": "extensionHost",
"request": "launch",
"runtimeExecutable": "${execPath}",
"args": [
"--extensionDevelopmentPath=${workspaceFolder}"
],
"outFiles": [
"${workspaceFolder}/dist/**/*.js"
]
}
]
"version": "0.2.0",
"configurations": [
{
"name": "Launch Extension",
"type": "extensionHost",
"request": "launch",
"runtimeExecutable": "${execPath}",
"args": ["--extensionDevelopmentPath=${workspaceFolder}"],
"outFiles": ["${workspaceFolder}/dist/**/*.js"],
"preLaunchTask": "pnpm: build:ext"
},
{
"name": "Attach Extension",
"type": "extensionHost",
"request": "launch",
"runtimeExecutable": "${execPath}",
"args": ["--extensionDevelopmentPath=${workspaceFolder}"],
"outFiles": ["${workspaceFolder}/dist/**/*.js"]
}
]
}
+13 -13
View File
@@ -1,7 +1,7 @@
{
"Recoil Atom": {
"prefix": "sq-atom",
"body": [
"Recoil Atom": {
"prefix": "sq-atom",
"body": [
"import { atom } from 'recoil';",
"",
"export const ${1:CollectionId}Atom = atom({",
@@ -12,9 +12,9 @@
"description": "Creates a new atom",
"scope": "typescript"
},
"Recoil Selector (sync)": {
"prefix": "sq-selector-sync",
"body": [
"Recoil Selector (sync)": {
"prefix": "sq-selector-sync",
"body": [
"import { selector } from 'recoil';",
"",
"export const ${1:CollectionData}Selector = selector({",
@@ -27,9 +27,9 @@
"description": "Creates a new synchronous selector",
"scope": "typescript"
},
"Recoil Selector (async)": {
"prefix": "sq-selector-async",
"body": [
"Recoil Selector (async)": {
"prefix": "sq-selector-async",
"body": [
"import { selector } from 'recoil';",
"",
"export const ${1:CollectionData}Selector = selector({",
@@ -42,9 +42,9 @@
"description": "Creates a new asynchronous selector",
"scope": "typescript"
},
"Recoil selectorFamily": {
"prefix": "sq-selector-fam",
"body": [
"Recoil selectorFamily": {
"prefix": "sq-selector-fam",
"body": [
"import { selectorFamily } from 'recoil';",
"",
"export const ${1:CollectionData}Selector = selectorFamily({",
@@ -63,4 +63,4 @@
"description": "Include the translations",
"scope": "typescriptreact"
}
}
}
+48 -48
View File
@@ -1,52 +1,52 @@
// Place your settings in this file to overwrite default and user settings.
{
"files.exclude": {
"out": false // set this to true to hide the "out" folder with the compiled JS files
"files.exclude": {
"out": false // set this to true to hide the "out" folder with the compiled JS files
},
"search.exclude": {
"out": true // set this to false to include "out" folder in search results
},
// Turn off tsc task auto detection since we have the necessary tasks as npm scripts
"typescript.tsc.autoDetect": "off",
"eliostruyf.writingstyleguide.terms.isDisabled": true,
"eliostruyf.writingstyleguide.biasFree.isDisabled": true,
"squarl.groups": [
{
"id": "dashboard",
"name": "Dashboard"
},
"search.exclude": {
"out": true // set this to false to include "out" folder in search results
{
"id": "panel",
"name": "Panel"
}
],
"squarl.bookmarks": [
{
"name": "App.tsx",
"path": "src/dashboardWebView/components/App.tsx",
"description": "Start of dashboard",
"type": "file",
"groupId": "dashboard"
},
// Turn off tsc task auto detection since we have the necessary tasks as npm scripts
"typescript.tsc.autoDetect": "off",
"eliostruyf.writingstyleguide.terms.isDisabled": true,
"eliostruyf.writingstyleguide.biasFree.isDisabled": true,
"squarl.groups": [
{
"id": "dashboard",
"name": "Dashboard"
},
{
"id": "panel",
"name": "Panel"
}
],
"squarl.bookmarks": [
{
"name": "App.tsx",
"path": "src/dashboardWebView/components/App.tsx",
"description": "Start of dashboard",
"type": "file",
"groupId": "dashboard"
},
{
"name": "ViewPanel.tsx",
"path": "src/panelWebView/ViewPanel.tsx",
"description": "Start of panel",
"type": "file",
"groupId": "panel"
},
{
"name": "styles.css",
"path": "src/panelWebView/styles.css",
"description": "Panel styles",
"type": "file",
"groupId": "panel"
},
{
"name": "settings.ts",
"path": "src/constants/settings.ts",
"description": "Settings names",
"type": "file"
}
],
}
{
"name": "ViewPanel.tsx",
"path": "src/panelWebView/ViewPanel.tsx",
"description": "Start of panel",
"type": "file",
"groupId": "panel"
},
{
"name": "styles.css",
"path": "src/panelWebView/styles.css",
"description": "Panel styles",
"type": "file",
"groupId": "panel"
},
{
"name": "settings.ts",
"path": "src/constants/settings.ts",
"description": "Settings names",
"type": "file"
}
]
}
+24 -24
View File
@@ -1,28 +1,28 @@
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
{
"version": "2.0.0",
"tasks": [
{
"type": "npm",
"script": "watch",
"problemMatcher": "$tsc-watch",
"isBackground": true,
"presentation": {
"reveal": "never"
},
"group": {
"kind": "build",
"isDefault": true
}
},
{
"type": "npm",
"script": "build:ext",
"group": {
"kind": "build",
"isDefault": true
}
}
]
"version": "2.0.0",
"tasks": [
{
"type": "npm",
"script": "watch",
"problemMatcher": "$tsc-watch",
"isBackground": true,
"presentation": {
"reveal": "never"
},
"group": {
"kind": "build",
"isDefault": true
}
},
{
"type": "npm",
"script": "build:ext",
"group": {
"kind": "build",
"isDefault": true
}
}
]
}
+1 -2
View File
@@ -5,7 +5,6 @@ src/**
.gitignore
vsc-extension-quickstart.md
**/tsconfig.json
**/tslint.json
**/*.map
**/*.ts
webpack.config.js
@@ -28,4 +27,4 @@ frontmatter.json
webpack
README.beta.md
e2e
storage
storage
+2 -2
View File
@@ -15,7 +15,7 @@ async function main(): Promise<void> {
const exTester = new ExTester(storageFolder, ReleaseQuality.Stable, extFolder);
await exTester.downloadCode(version);
await exTester.installVsix();
await exTester.installVsix({ useYarn: false });
// await exTester.installFromMarketplace("eliostruyf.vscode-front-matter");
await exTester.downloadChromeDriver(version);
// await exTester.setupRequirements({vscodeVersion: version});
@@ -30,4 +30,4 @@ async function main(): Promise<void> {
}
}
main();
main();
-19403
View File
File diff suppressed because it is too large Load Diff
+22 -9
View File
@@ -208,7 +208,10 @@
"description": "Defines a custom preview path for the folder."
},
"filePrefix": {
"type": [ "null", "string" ],
"type": [
"null",
"string"
],
"description": "Defines a prefix for the file name."
},
"contentTypes": {
@@ -462,7 +465,10 @@
"scope": "Custom scripts"
},
"frontMatter.dashboard.content.pagination": {
"type": ["boolean", "number"],
"type": [
"boolean",
"number"
],
"default": true,
"markdownDescription": "Specify if you want to enable/disable pagination for your content. You can define your page number up to 52. Default items per page is `16`. Disabling the pagination can be done by setting it to `false`. [Check in the docs](https://frontmatter.codes/docs/settings#frontmatter.dashboard.content.pagination)",
"scope": "Dashboard"
@@ -2132,7 +2138,8 @@
"clean": "rimraf dist",
"start:site": "cd ./docs && npm run dev",
"clean:test": "rm ./e2e/sample/frontmatter.json || exit 0 && rm -rf ./e2e/sample/.frontmatter || exit 0",
"test": "tsc -p tsconfig.e2e.json && npm run clean:test && node ./e2e/out/runTests.js"
"test": "tsc -p tsconfig.e2e.json && npm run clean:test && node ./e2e/out/runTests.js",
"lint": "eslint --max-warnings=0 ./src/{commands,components}"
},
"devDependencies": {
"@actions/core": "^1.8.2",
@@ -2153,6 +2160,7 @@
"@types/lodash.omit": "^4.5.6",
"@types/lodash.uniqby": "4.7.6",
"@types/lodash.xor": "^4.5.6",
"@types/mdast": "^3.0.10",
"@types/mime-types": "^2.1.1",
"@types/mocha": "^5.2.7",
"@types/mustache": "^4.1.2",
@@ -2162,17 +2170,20 @@
"@types/react-datepicker": "^4.1.7",
"@types/react-dom": "17.0.0",
"@types/vscode": "^1.63.0",
"@typescript-eslint/eslint-plugin": "^5.50.0",
"@typescript-eslint/parser": "^5.50.0",
"@vscode/codicons": "0.0.20",
"@vscode/extension-telemetry": "^0.4.7",
"@vscode/webview-ui-toolkit": "^0.9.1",
"@webpack-cli/serve": "^1.6.0",
"ajv": "^8.8.2",
"array-move": "^4.0.0",
"autoprefixer": "^10.3.2",
"autoprefixer": "10.3.3",
"chai": "^4.3.6",
"css-loader": "5.2.7",
"date-fns": "2.23.0",
"downshift": "6.0.6",
"eslint": "^8.33.0",
"fuse.js": "6.5.3",
"glob": "7.1.6",
"gray-matter": "4.0.3",
@@ -2180,6 +2191,7 @@
"html-webpack-plugin": "4.5.0",
"image-size": "^1.0.0",
"invariant": "^2.2.4",
"js-yaml": "^4.1.0",
"jsonc-parser": "^3.2.0",
"lodash-es": "^4.17.21",
"lodash.omit": "^4.5.0",
@@ -2189,6 +2201,7 @@
"mime-types": "^2.1.35",
"mocha": "^10.0.0",
"mustache": "^4.2.0",
"node-fetch": "^2.6.9",
"node-json-db": "^1.3.0",
"npm-run-all": "^4.1.5",
"path-browserify": "^1.0.1",
@@ -2199,6 +2212,7 @@
"react-datepicker": "4.2.1",
"react-dom": "17.0.1",
"react-dropzone": "^11.3.4",
"react-popper": "^2.3.0",
"react-quill": "^2.0.0-beta.4",
"react-router-dom": "^6.3.0",
"react-sortable-hoc": "^2.0.0",
@@ -2211,14 +2225,13 @@
"tailwindcss": "^2.2.7",
"tailwindcss-nested-groups": "^1.2.4",
"ts-loader": "8.0.3",
"tslint": "6.1.3",
"typescript": "^4.5.4",
"typescript": "4.5.5",
"uniforms": "^3.7.0",
"uniforms-antd": "^3.7.0",
"uniforms-bridge-json-schema": "^3.7.0",
"uniforms-unstyled": "^3.7.0",
"url-join-ts": "^1.0.5",
"vscode-extension-tester": "^4.2.5",
"vscode-extension-tester": "4.2.5",
"wc-react": "github:estruyf/wc-react",
"webpack": "^5.65.0",
"webpack-bundle-analyzer": "^4.5.0",
@@ -2227,7 +2240,7 @@
"yaml": "^1.10.2",
"yawn-yaml": "^1.5.0"
},
"dependencies": {
"node-fetch": "^2.6.7"
"vsce": {
"dependencies": false
}
}
+7668
View File
File diff suppressed because it is too large Load Diff
+18 -18
View File
@@ -1,7 +1,7 @@
import { Folders } from './Folders';
import { DEFAULT_CONTENT_TYPE } from './../constants/ContentType';
import { isValidFile } from './../helpers/isValidFile';
import { SETTING_AUTO_UPDATE_DATE, SETTING_MODIFIED_FIELD, SETTING_SLUG_UPDATE_FILE_NAME, SETTING_TEMPLATES_PREFIX, CONFIG_KEY, SETTING_DATE_FORMAT, SETTING_SLUG_PREFIX, SETTING_SLUG_SUFFIX, SETTING_CONTENT_PLACEHOLDERS, TelemetryEvent } from './../constants';
import { SETTING_AUTO_UPDATE_DATE, SETTING_SLUG_UPDATE_FILE_NAME, SETTING_TEMPLATES_PREFIX, CONFIG_KEY, SETTING_DATE_FORMAT, SETTING_SLUG_PREFIX, SETTING_SLUG_SUFFIX, SETTING_CONTENT_PLACEHOLDERS, TelemetryEvent } from './../constants';
import * as vscode from 'vscode';
import { CustomPlaceholder, Field, TaxonomyType } from "../models";
import { format } from "date-fns";
@@ -95,7 +95,7 @@ export class Article {
return;
}
article = this.updateDate(article, true);
article = this.updateDate(article);
try {
ArticleHelper.update(editor, article);
@@ -106,10 +106,10 @@ export class Article {
/**
* Update the date in the front matter
* @param article
* @param article
*/
public static updateDate(article: ParsedFrontMatter, forceCreate: boolean = false) {
article.data = ArticleHelper.updateDates(article.data);
public static updateDate(article: ParsedFrontMatter) {
article.data = ArticleHelper.updateDates(article.data);
return article;
}
@@ -163,7 +163,7 @@ export class Article {
try {
cloneArticle.data[dateField] = Article.formatDate(new Date());
return cloneArticle;
} catch (e: any) {
} catch (e: unknown) {
Notifications.error(`Something failed while parsing the date format. Check your "${CONFIG_KEY}${SETTING_DATE_FORMAT}" setting.`);
}
}
@@ -196,7 +196,7 @@ export class Article {
*/
public static async updateSlug() {
Telemetry.send(TelemetryEvent.generateSlug);
const updateFileName = Settings.get(SETTING_SLUG_UPDATE_FILE_NAME) as string;
let filePrefix = Settings.get<string>(SETTING_TEMPLATES_PREFIX);
const editor = vscode.window.activeTextEditor;
@@ -220,13 +220,13 @@ export class Article {
const titleField = "title";
const articleTitle: string = article.data[titleField];
const slugInfo = Article.generateSlug(articleTitle);
if (slugInfo && slugInfo.slug && slugInfo.slugWithPrefixAndSuffix) {
article.data["slug"] = slugInfo.slugWithPrefixAndSuffix;
if (contentType) {
// Update the fields containing the slug placeholder
let fieldsToUpdate: Field[] = contentType.fields.filter(f => f.default === "{{slug}}");
const fieldsToUpdate: Field[] = contentType.fields.filter(f => f.default === "{{slug}}");
for (const field of fieldsToUpdate) {
article.data[field.name] = slugInfo.slug;
}
@@ -253,7 +253,7 @@ export class Article {
if (editor) {
const ext = extname(editor.document.fileName);
const fileName = basename(editor.document.fileName);
let slugName = slugInfo.slug.startsWith("/") ? slugInfo.slug.substring(1) : slugInfo.slug;
slugName = slugName.endsWith("/") ? slugName.substring(0, slugName.length - 1) : slugName;
@@ -270,8 +270,8 @@ export class Article {
await vscode.workspace.fs.rename(editor.document.uri, vscode.Uri.file(newPath), {
overwrite: false
});
} catch (e: any) {
Notifications.error(`Failed to rename file: ${e?.message || e}`);
} catch (e: unknown) {
Notifications.error(`Failed to rename file: ${(e as Error).message || e}`);
}
}
}
@@ -361,7 +361,7 @@ export class Article {
* Insert an image from the media dashboard into the article
*/
public static async insertMedia() {
let editor = vscode.window.activeTextEditor;
const editor = vscode.window.activeTextEditor;
if (!editor) {
return;
}
@@ -391,7 +391,7 @@ export class Article {
* Insert a snippet into the article
*/
public static async insertSnippet() {
let editor = vscode.window.activeTextEditor;
const editor = vscode.window.activeTextEditor;
if (!editor) {
return;
}
@@ -415,10 +415,10 @@ export class Article {
/**
* Update the article date and return it
* @param article
* @param dateFormat
* @param field
* @param forceCreate
* @param article
* @param dateFormat
* @param field
* @param forceCreate
*/
private static articleDate(article: ParsedFrontMatter, field: string, forceCreate: boolean) {
if (typeof article.data[field] !== "undefined" || forceCreate) {
+11 -11
View File
@@ -14,7 +14,7 @@ import { GitListener, ModeListener } from '../listeners/general';
export class Dashboard {
private static webview: WebviewPanel | null = null;
private static _viewData: DashboardData | undefined;
private static isDisposed: boolean = true;
private static isDisposed = true;
public static get viewData(): DashboardData | undefined {
return Dashboard._viewData;
@@ -35,7 +35,7 @@ export class Dashboard {
*/
public static async open(data?: DashboardData) {
MediaLibrary.getInstance();
Dashboard._viewData = data;
if (Dashboard.isOpen) {
@@ -57,7 +57,7 @@ export class Dashboard {
/**
* Reveal the dashboard if it is open
*/
public static reveal(hasData: boolean = false) {
public static reveal(hasData = false) {
if (Dashboard.webview) {
Dashboard.webview.reveal();
@@ -85,7 +85,7 @@ export class Dashboard {
public static resetViewData() {
Dashboard._viewData = undefined;
}
/**
* Create the dashboard webview
*/
@@ -136,7 +136,7 @@ export class Dashboard {
Dashboard.webview.webview.onDidReceiveMessage(async (msg) => {
Logger.info(`Receiving message from webview: ${msg.command}`);
DashboardListener.process(msg);
ExtensionListener.process(msg);
MediaListener.process(msg);
@@ -162,9 +162,9 @@ export class Dashboard {
/**
* Post data to the dashboard
* @param msg
* @param msg
*/
public static postWebviewMessage(msg: { command: DashboardCommand, data?: any }) {
public static postWebviewMessage(msg: { command: DashboardCommand, data?: unknown }) {
if (Dashboard.isDisposed) {
return;
}
@@ -173,10 +173,10 @@ export class Dashboard {
Dashboard.webview?.webview.postMessage(msg);
}
}
/**
* Retrieve the webview HTML contents
* @param webView
* @param webView
*/
private static getWebviewContent(webView: Webview, extensionPath: Uri): string {
const dashboardFile = "dashboardWebView.js";
@@ -188,7 +188,7 @@ export class Dashboard {
if (isProd) {
scriptUri = webView.asWebviewUri(Uri.joinPath(extensionPath, 'dist', dashboardFile)).toString();
} else {
scriptUri = `http://${localServerUrl}/${dashboardFile}`;
scriptUri = `http://${localServerUrl}/${dashboardFile}`;
}
const nonce = WebviewHelper.getNonce();
@@ -226,4 +226,4 @@ export class Dashboard {
</html>
`;
}
}
}
+48 -48
View File
@@ -26,11 +26,11 @@ export class Folders {
/**
* Add a media folder
* @returns
* @returns
*/
public static async addMediaFolder(data?: {selectedFolder?: string}) {
let wsFolder = Folders.getWorkspaceFolder();
let staticFolder = Folders.getStaticFolderRelativePath();
const wsFolder = Folders.getWorkspaceFolder();
const staticFolder = Folders.getStaticFolderRelativePath();
let startPath = "";
@@ -48,7 +48,7 @@ export class Folders {
startPath = startPath.replace(STATIC_FOLDER_PLACEHOLDER.hexo.placeholder, STATIC_FOLDER_PLACEHOLDER.hexo.postsFolder);
}
const folderName = await window.showInputBox({
const folderName = await window.showInputBox({
title: `Add media folder`,
prompt: `Which name would you like to give to your folder (use "/" to create multi-level folders)?`,
value: startPath,
@@ -60,7 +60,7 @@ export class Folders {
Notifications.warning(`No folder name was specified.`);
return;
}
await Folders.createFolder(join(parseWinPath(wsFolder?.fsPath || ""), folderName));
}
@@ -79,7 +79,7 @@ export class Folders {
/**
* Create content in a registered folder
* @returns
* @returns
*/
public static async create() {
const selectedFolder = await Questions.SelectContentFolder();
@@ -99,7 +99,7 @@ export class Folders {
/**
* Register the new folder path
* @param folderInfo
* @param folderInfo
*/
public static async register(folderInfo: { title: string, path: Uri } | Uri) {
let folderName = folderInfo instanceof Uri ? undefined : folderInfo.title;
@@ -119,7 +119,7 @@ export class Folders {
if (!folderName) {
folderName = await window.showInputBox({
title: `Register folder`,
title: `Register folder`,
prompt: `Which name would you like to specify for this folder?`,
placeHolder: `Folder name`,
value: basename(folder.fsPath),
@@ -137,7 +137,7 @@ export class Folders {
Notifications.info(`Folder registered`);
Telemetry.send(TelemetryEvent.registerFolder);
Telemetry.send(TelemetryEvent.registerFolder);
SettingsListener.getSettings(true);
}
@@ -145,7 +145,7 @@ export class Folders {
/**
* Unregister a folder path
* @param folder
* @param folder
*/
public static async unregister(folder: Uri) {
if (folder && folder.path) {
@@ -153,13 +153,13 @@ export class Folders {
folders = folders.filter(f => f.path !== folder.fsPath);
await Folders.update(folders);
Telemetry.send(TelemetryEvent.unregisterFolder);
Telemetry.send(TelemetryEvent.unregisterFolder);
}
}
/**
* Get the static folder its relative path
* @returns
* @returns
*/
public static getStaticFolderRelativePath(): string | undefined {
let staticFolder = Settings.get<string>(SETTING_CONTENT_STATIC_FOLDER);
@@ -178,8 +178,8 @@ export class Folders {
/**
* Retrieve the folder path
* @param folder
* @returns
* @param folder
* @returns
*/
public static getFolderPath(folder: Uri) {
let folderPath = "";
@@ -197,12 +197,12 @@ export class Folders {
*/
public static getWorkspaceFolder(): Uri | undefined {
const folders = workspace.workspaceFolders;
if (folders && folders.length === 1) {
return folders[0].uri;
} else if (folders && folders.length > 1) {
let projectFolder = undefined;
let projectFolder = undefined;
for (const folder of folders) {
if (!projectFolder && existsSync(join(folder.uri.fsPath, Settings.globalFile))) {
projectFolder = folder.uri;
@@ -223,7 +223,7 @@ export class Folders {
return projectFolder;
}
return undefined;
}
@@ -247,24 +247,24 @@ export class Folders {
const wsFolder = parseWinPath(Folders.getWorkspaceFolder()?.fsPath || "");
if (folders && folders.length > 0) {
let folderInfo: FolderInfo[] = [];
const folderInfo: FolderInfo[] = [];
for (const folder of folders) {
try {
let projectStart = parseWinPath(folder.path).replace(wsFolder, "");
if (projectStart) {
projectStart = projectStart.replace(/\\/g, '/');
projectStart = projectStart.startsWith('/') ? projectStart.substring(1) : projectStart;
let files: Uri[] = [];
for (const fileType of (supportedFiles || DEFAULT_FILE_TYPES)) {
const filePath = join(projectStart, folder.excludeSubdir ? '/' : '**', `*${fileType.startsWith('.') ? '' : '.'}${fileType}`);
const foundFiles = await workspace.findFiles(filePath, '**/node_modules/**');
files = [...files, ...foundFiles];
}
if (files) {
let fileStats: FileInfo[] = [];
@@ -272,7 +272,7 @@ export class Folders {
try {
const fileName = basename(file.fsPath);
const folderName = dirname(file.fsPath).split(sep).pop();
const stats = await workspace.fs.stat(file);
fileStats.push({
@@ -287,7 +287,7 @@ export class Folders {
}
fileStats = fileStats.sort((a, b) => b.mtime - a.mtime);
if (limit) {
fileStats = fileStats.slice(0, limit);
}
@@ -312,7 +312,7 @@ export class Folders {
/**
* Get the folder settings
* @returns
* @returns
*/
public static get(): ContentFolder[] {
const wsFolder = Folders.getWorkspaceFolder();
@@ -323,11 +323,11 @@ export class Folders {
folder.title = basename(folder.path);
}
let folderPath = Folders.absWsFolder(folder, wsFolder);
const folderPath = Folders.absWsFolder(folder, wsFolder);
if (!existsSync(folderPath)) {
Notifications.errorShowOnce(`Folder "${folder.title} (${folder.path})" does not exist. Please remove it from the settings.`, "Remove folder").then(answer => {
if (answer === "Remove folder") {
let folders = Folders.get();
const folders = Folders.get();
Folders.update(folders.filter(f => f.path !== folder.path));
}
});
@@ -339,20 +339,20 @@ export class Folders {
path: folderPath
}
})
return contentFolders.filter(folder => folder !== null) as ContentFolder[];
}
/**
* Update the folder settings
* @param folders
* @param folders
*/
public static async update(folders: ContentFolder[]) {
const wsFolder = Folders.getWorkspaceFolder();
let folderDetails = folders.map(folder => ({
const folderDetails = folders.map(folder => ({
...folder,
path: Folders.relWsFolder(folder, wsFolder)
path: Folders.relWsFolder(folder, wsFolder)
}));
await Settings.update(SETTING_CONTENT_PAGE_FOLDERS, folderDetails, true);
@@ -363,8 +363,8 @@ export class Folders {
/**
* Retrieve the absolute file path
* @param filePath
* @returns
* @param filePath
* @returns
*/
public static getAbsFilePath(filePath: string): string {
const wsFolder = Folders.getWorkspaceFolder();
@@ -376,9 +376,9 @@ export class Folders {
/**
* Generate the absolute URL for the workspace
* @param folder
* @param wsFolder
* @returns
* @param folder
* @param wsFolder
* @returns
*/
private static absWsFolder(folder: ContentFolder, wsFolder?: Uri) {
const isWindows = process.platform === 'win32';
@@ -389,9 +389,9 @@ export class Folders {
/**
* Generate relative folder path
* @param folder
* @param wsFolder
* @returns
* @param folder
* @param wsFolder
* @returns
*/
public static relWsFolder(folder: ContentFolder, wsFolder?: Uri) {
const isWindows = process.platform === 'win32';
@@ -417,7 +417,7 @@ export class Folders {
Logger.error(`Something went wrong while searching for folders with pattern "${pattern}": ${(e as Error).message}`);
}
}
// Filter out the workspace folder
if (wsFolder) {
folders = folders.filter(folder => folder !== wsFolder.fsPath);
@@ -429,8 +429,8 @@ export class Folders {
/**
* Returns the file prefix for the given folder path
* @param folderPath
* @returns
* @param folderPath
* @returns
*/
public static getFilePrefixByFolderPath(folderPath: string) {
const folders = Folders.get();
@@ -446,8 +446,8 @@ export class Folders {
/**
* Returns the file prefix for the given file path
* @param filePath
* @returns
* @param filePath
* @returns
*/
public static getFilePrefixBeFilePath(filePath: string) {
const folders = Folders.get();
@@ -474,8 +474,8 @@ export class Folders {
/**
* Retrieve all content folders
* @param pattern
* @returns
* @param pattern
* @returns
*/
private static findFolders(pattern: string): Promise<string[]> {
return new Promise(resolve => {
+8 -7
View File
@@ -16,7 +16,7 @@ export class Project {
title:
slug:
description:
author:
author:
date: 2019-08-22T15:20:28.000Z
lastmod: 2019-08-22T15:20:28.000Z
draft: true
@@ -44,7 +44,7 @@ categories: []
} else {
Notifications.info("Project initialized successfully.");
}
Telemetry.send(TelemetryEvent.initialization);
// Check if you can find the framework
@@ -56,7 +56,8 @@ categories: []
}
SettingsListener.getSettings(true);
} catch (err: any) {
} catch (error: unknown) {
const err = (error as Error)
Logger.error(`Project::init: ${err?.message || err}`);
Notifications.error(`Sorry, something went wrong - ${err?.message || err}`);
}
@@ -64,8 +65,8 @@ categories: []
/**
* Creates the templates folder + sample if needed
* @param sampleTemplate
* @returns
* @param sampleTemplate
* @returns
*/
public static async createSampleTemplate(sampleTemplate?: boolean) {
const fileType = Settings.get<string>(SETTING_CONTENT_DEFAULT_FILETYPE);
@@ -76,7 +77,7 @@ categories: []
if (!folder || !templatePath) {
return;
}
const article = Uri.file(join(templatePath.fsPath, `article.${fileType}`));
if (!(await existsAsync(templatePath.fsPath))) {
@@ -103,4 +104,4 @@ categories: []
const templatePath = Uri.file(join(wsFolder.fsPath, folder));
return templatePath;
}
}
}
+1 -1
View File
@@ -163,7 +163,7 @@ export class Settings {
}
const type = taxType === "Tag" ? TaxonomyType.Tag : TaxonomyType.Category;
let options = SettingsHelper.getTaxonomy(type);
const options = SettingsHelper.getTaxonomy(type);
if (!options || options.length === 0) {
Notifications.info(`No ${type === TaxonomyType.Tag ? "tags" : "categories"} configured.`);
+21 -21
View File
@@ -10,12 +10,12 @@ import { commands } from 'vscode';
import { Field } from '../models';
export class StatusListener {
/**
* Update the text of the status bar
*
* @param frontMatterSB
* @param collection
*
* @param frontMatterSB
* @param collection
*/
public static async verify(frontMatterSB: vscode.StatusBarItem, collection: vscode.DiagnosticCollection) {
const draftMsg = "in draft";
@@ -25,8 +25,8 @@ export class StatusListener {
if (!draft || draft.type !== "boolean") {
frontMatterSB.hide();
}
let editor = vscode.window.activeTextEditor;
const editor = vscode.window.activeTextEditor;
if (editor && ArticleHelper.isSupportedFile()) {
try {
commands.executeCommand('setContext', CONTEXT.isValidFile, true);
@@ -52,11 +52,11 @@ export class StatusListener {
const titleLength = Settings.get(SETTING_SEO_TITLE_LENGTH) as number || -1;
const descLength = Settings.get(SETTING_SEO_DESCRIPTION_LENGTH) as number || -1;
const fieldName = Settings.get(SETTING_SEO_DESCRIPTION_FIELD) as string || DefaultFields.Description;
if (article.data.title && titleLength > -1) {
SeoHelper.checkLength(editor, collection, article, "title", titleLength);
}
if (article.data[fieldName] && descLength > -1) {
SeoHelper.checkLength(editor, collection, article, fieldName, descLength);
}
@@ -64,10 +64,10 @@ export class StatusListener {
// Check the required fields
StatusListener.verifyRequiredFields(editor, article, collection);
}
const panel = ExplorerView.getInstance();
if (panel && panel.visible) {
DataListener.pushMetadata(article!.data);
DataListener.pushMetadata(article?.data);
}
return;
@@ -88,8 +88,8 @@ export class StatusListener {
/**
* Verify the required fields
* @param article
* @param collection
* @param article
* @param collection
*/
private static verifyRequiredFields(editor: vscode.TextEditor, article: ParsedFrontMatter, collection: vscode.DiagnosticCollection) {
// Check for missing fields
@@ -110,13 +110,13 @@ export class StatusListener {
for (const field of fields) {
const totalSpaces = level * (typeof editorSpaces === "string" ? parseInt(editorSpaces) : editorSpaces || 2);
const crntIdx = StatusListener.findFieldLine(text, txtIdx, totalSpaces, field);
const crntIdx = StatusListener.findFieldLine(text, txtIdx, totalSpaces, field);
if (crntIdx && crntIdx > txtIdx) {
txtIdx = crntIdx;
fieldName = field.name;
}
++level;
}
@@ -137,7 +137,7 @@ export class StatusListener {
requiredDiagnostics.push(diagnostic);
}
}
if (collection.has(editor.document.uri)) {
const otherDiag = collection.get(editor.document.uri) || [];
collection.set(editor.document.uri, [...otherDiag, ...requiredDiagnostics]);
@@ -153,11 +153,11 @@ export class StatusListener {
/**
* Find the line of the field
* @param text
* @param startIdx
* @param totalSpaces
* @param field
* @returns
* @param text
* @param startIdx
* @param totalSpaces
* @param field
* @returns
*/
private static findFieldLine(text: string, startIdx: number, totalSpaces: number, field: Field): number | undefined {
const crntIdx = text.indexOf(field.name, startIdx === -1 ? 0 : startIdx);
@@ -179,4 +179,4 @@ export class StatusListener {
return;
}
}
}
+2 -2
View File
@@ -57,7 +57,7 @@ export class Template {
await Project.init(false);
const templatePath = Project.templatePath();
if (templatePath) {
let fileContents = ArticleHelper.stringifyFrontMatter(keepContents === "no" ? "" : clonedArticle.content, clonedArticle.data);
const fileContents = ArticleHelper.stringifyFrontMatter(keepContents === "no" ? "" : clonedArticle.content, clonedArticle.data);
const templateFile = path.join(templatePath.fsPath, `${titleValue}.${fileType}`);
await writeFileAsync(templateFile, fileContents, { encoding: "utf-8" });
@@ -127,7 +127,7 @@ export class Template {
}
const fileExtension = extname(template.fsPath).replace(".", "");
let newFilePath: string | undefined = await ArticleHelper.createContent(contentType, folderPath, titleValue, fileExtension);
const newFilePath: string | undefined = await ArticleHelper.createContent(contentType, folderPath, titleValue, fileExtension);
if (!newFilePath) {
return;
}
+26 -26
View File
@@ -20,10 +20,10 @@ export class Wysiwyg {
/**
* Registers the markup commands for the WYSIWYG controls
* @param subscriptions
* @returns
* @param subscriptions
* @returns
*/
public static async registerCommands(subscriptions: any) {
public static async registerCommands(subscriptions: unknown[]) {
const wysiwygEnabled = Settings.get(SETTING_CONTENT_WYSIWYG);
@@ -63,8 +63,8 @@ export class Wysiwyg {
]
const option = await window.showQuickPick([ ...qpItems ], {
title: "WYSIWYG Options",
placeHolder: "Which type of markup would you like to insert?",
title: "WYSIWYG Options",
placeHolder: "Which type of markup would you like to insert?",
canPickMany: false,
ignoreFocusOut: true
});
@@ -91,8 +91,8 @@ export class Wysiwyg {
/**
* Add the markup to the content
* @param type
* @returns
* @param type
* @returns
*/
private static async addMarkup(type: MarkupType) {
const editor = window.activeTextEditor;
@@ -118,13 +118,13 @@ export class Wysiwyg {
// Replace the selection and surround with the markup
const selectionText = editor.document.getText(selection);
const txt = await this.insertText(markers, type, selectionText);
editor.edit(builder => {
builder.replace(selection, txt);
});
} else {
const txt = await this.insertText(markers, type);
// Insert the markers where cursor is located.
const markerLength = this.isMarkupWrapping(type) ? txt.length + 1 : markers.length;
let newPosition = crntSelection.with(crntSelection.line, crntSelection.character + markerLength);
@@ -150,8 +150,8 @@ export class Wysiwyg {
const linkText = hasTextSelection ? editor.document.getText(selection) : "";
const link = await window.showInputBox({
title: "WYSIWYG Hyperlink",
placeHolder: "Enter the URL",
title: "WYSIWYG Hyperlink",
placeHolder: "Enter the URL",
prompt: "Enter the URL",
value: linkText,
ignoreFocusOut: true
@@ -188,12 +188,12 @@ export class Wysiwyg {
/**
* Check if the text will be wrapped
* @param type
* @returns
* @param type
* @returns
*/
private static isMarkupWrapping(type: MarkupType) {
private static isMarkupWrapping(type: MarkupType) {
return (
type === MarkupType.blockquote ||
type === MarkupType.blockquote ||
type === MarkupType.heading ||
type === MarkupType.unorderedList ||
type === MarkupType.orderedList ||
@@ -210,15 +210,15 @@ export class Wysiwyg {
if (this.isMarkupWrapping(type)) {
if (type === MarkupType.heading) {
const headingLvl = await window.showQuickPick([
"Heading 1",
"Heading 2",
"Heading 3",
"Heading 4",
"Heading 5",
"Heading 1",
"Heading 2",
"Heading 3",
"Heading 4",
"Heading 5",
"Heading 6"
], {
title: "Heading Level",
canPickMany: false,
canPickMany: false,
placeHolder: "Which heading level do you want to insert?",
ignoreFocusOut: true
});
@@ -247,8 +247,8 @@ export class Wysiwyg {
/**
* Check if linebreak needs to be added
* @param type
* @returns
* @param type
* @returns
*/
private static lineBreak(type: MarkupType) {
if (type === MarkupType.codeblock) {
@@ -259,8 +259,8 @@ export class Wysiwyg {
/**
* Retrieve the type of markers
* @param type
* @returns
* @param type
* @returns
*/
private static getMarkers(type: MarkupType) {
switch(type) {
@@ -288,4 +288,4 @@ export class Wysiwyg {
return;
}
}
}
}
@@ -1,6 +1,5 @@
import * as invariant from 'invariant';
import { createAutoField } from 'uniforms';
import { PreviewImageField } from '../../panelWebView/components/Fields/PreviewImageField';
export { AutoFieldProps } from 'uniforms';
import BoolField from './BoolField';
@@ -2,8 +2,9 @@ import { AutoForm } from 'uniforms';
import ValidatedQuickForm from './ValidatedQuickForm';
function Auto(parent: any) {
class _ extends AutoForm.Auto(parent) {
function Auto(parent: unknown) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
class _ extends AutoForm.Auto(parent as any) {
static Auto = Auto;
}
@@ -1,5 +1,6 @@
import { BaseForm } from 'uniforms';
// eslint-disable-next-line @typescript-eslint/no-explicit-any
function Unstyled(parent: any) {
class _ extends parent {
static Unstyled = Unstyled;
@@ -4,7 +4,7 @@ import { Override, connectField, filterDOMProps } from 'uniforms';
export type ErrorFieldProps = Override<
Omit<HTMLProps<HTMLDivElement>, 'onChange'>,
{ error?: any; errorMessage?: string }
{ error?: unknown; errorMessage?: string }
>;
function Error({ children, error, errorMessage, ...props }: ErrorFieldProps) {
@@ -2,18 +2,20 @@ import * as React from 'react';
import { HTMLProps, Ref, useEffect } from 'react';
import { Override, filterDOMProps, useField } from 'uniforms';
type ValueType = string | number | readonly string[] | undefined
export type HiddenFieldProps = Override<
HTMLProps<HTMLInputElement>,
{
inputRef?: Ref<HTMLInputElement>;
name: string;
noDOM?: boolean;
value?: any;
value?: ValueType;
}
>;
export default function HiddenField({ value, ...rawProps }: HiddenFieldProps) {
const props = useField(rawProps.name, rawProps, { initialValue: false })[0];
const defaultValue = props.value as ValueType ?? ''
useEffect(() => {
if (value !== undefined && value !== props.value) {
@@ -28,7 +30,7 @@ export default function HiddenField({ value, ...rawProps }: HiddenFieldProps) {
readOnly={props.readOnly}
ref={props.inputRef}
type="hidden"
value={value ?? props.value ?? ''}
value={value ?? defaultValue}
{...filterDOMProps(props)}
/>
);
@@ -9,8 +9,11 @@ import {
} from 'uniforms';
import './ListAddField.css';
type ParentFieldType = { initialCount?: number; maxCount?: number }
type ValueType = string | readonly string[] | undefined
export type ListAddFieldProps = HTMLFieldProps<
unknown,
ValueType,
HTMLSpanElement,
{ initialCount?: number }
>;
@@ -25,13 +28,14 @@ function ListAdd({
}: ListAddFieldProps) {
const nameParts = joinName(null, name);
const parentName = joinName(nameParts.slice(0, -1));
const parent = useField<
{ initialCount?: number; maxCount?: number },
unknown[]
>(parentName, { initialCount }, { absoluteName: true })[0];
const parent = {
maxCount: 0,
value: [] as ValueType[],
...useField<ParentFieldType, ValueType[]>(parentName, { initialCount }, { absoluteName: true })[0]
};
const limitNotReached =
!disabled && !(parent.maxCount! <= parent.value!.length);
!disabled && !(parent.maxCount <= parent.value.length);
function onAction(event: React.KeyboardEvent | React.MouseEvent) {
if (
@@ -39,13 +43,14 @@ function ListAdd({
!readOnly &&
(!('key' in event) || event.key === 'Enter')
) {
parent.onChange(parent.value!.concat([Object.assign({}, value)]));
parent.onChange(parent.value.concat([value]));
}
}
return (
<span
className='autoform__list_add_field'
// eslint-disable-next-line @typescript-eslint/no-explicit-any
{...filterDOMProps(props as any)}
onClick={onAction}
onKeyDown={onAction}
@@ -15,14 +15,18 @@ function ListDel({ disabled, name, readOnly, ...props }: ListDelFieldProps) {
const nameParts = joinName(null, name);
const nameIndex = +nameParts[nameParts.length - 1];
const parentName = joinName(nameParts.slice(0, -1));
const parent = useField<{ minCount?: number }, unknown[]>(
parentName,
{},
{ absoluteName: true },
)[0];
const parent = {
minCount: 0,
value: [],
...useField<{ minCount?: number }, unknown[]>(
parentName,
{},
{ absoluteName: true },
)[0]
};
const limitNotReached =
!disabled && !(parent.minCount! >= parent.value!.length);
!disabled && !(parent.minCount >= parent.value.length);
function onAction(
event:
@@ -34,7 +38,7 @@ function ListDel({ disabled, name, readOnly, ...props }: ListDelFieldProps) {
!readOnly &&
(!('key' in event) || event.key === 'Enter')
) {
const value = parent.value!.slice();
const value = parent.value.slice();
value.splice(nameIndex, 1);
parent.onChange(value);
}
@@ -53,7 +57,7 @@ function ListDel({ disabled, name, readOnly, ...props }: ListDelFieldProps) {
<TrashIcon />
</span>
);
}
@@ -1,3 +1,4 @@
/* eslint-disable class-methods-use-this */
import { QuickForm } from 'uniforms';
import AutoField from './AutoField';
@@ -5,6 +6,7 @@ import BaseForm from './BaseForm';
import ErrorsField from './ErrorsField';
import SubmitField from './SubmitField';
// eslint-disable-next-line @typescript-eslint/no-explicit-any
function Quick(parent: any) {
class _ extends QuickForm.Quick(parent) {
static Quick = Quick;
@@ -24,7 +24,7 @@ export type SelectFieldProps = HTMLFieldProps<
>;
function Select({
allowedValues,
allowedValues = [],
checkboxes,
disabled,
fieldType,
@@ -38,20 +38,20 @@ function Select({
required,
disableItem,
transform,
value,
value = [],
...props
}: SelectFieldProps) {
const multiple = fieldType === Array;
return (
<div className='autoform__select_field' {...filterDOMProps(props)}>
<LabelField label={label} id={id} required={required} />
{checkboxes ? (
allowedValues!.map(item => (
allowedValues.map(item => (
<div key={item}>
<input
checked={
fieldType === Array ? value!.includes(item) : value === item
fieldType === Array ? value.includes(item) : value === item
}
disabled={disableItem?.(item) ?? disabled}
id={`${id}-${escape(item)}`}
@@ -2,6 +2,7 @@ import { ValidatedForm } from 'uniforms';
import BaseForm from './BaseForm';
// eslint-disable-next-line @typescript-eslint/no-explicit-any
function Validated(parent: any) {
class _ extends ValidatedForm.Validated(parent) {
static Validated = Validated;
-15
View File
@@ -1,15 +0,0 @@
{
"rules": {
"no-string-throw": true,
"no-unused-expression": true,
"no-duplicate-variable": true,
"curly": true,
"class-name": true,
"semicolon": [
true,
"always"
],
"triple-equals": true
},
"defaultSeverity": "warning"
}