Skip to content

Commit c827f84

Browse files
committed
feat: add handlebar helper.
1 parent 6f79ea9 commit c827f84

File tree

10 files changed

+96
-41
lines changed

10 files changed

+96
-41
lines changed

src/commands.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ export default class Commands{
1515
public static map(): Map<string,any>{
1616
let map:Map<string,any> = new Map<string,any>();
1717
for(const value of this.list()){
18-
map.set("extension.add"+ Formatting.toUpperCase(value) ,
18+
map.set("extension.add"+ Formatting.toPascalCase(value) ,
1919
{
2020
filename: value.toLocaleLowerCase(),
2121
resource: value

src/file-contents.ts

Lines changed: 18 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,12 @@
11
import * as fs from 'fs-extra';
22
import * as path from 'path';
3-
import Formatting from './formatting';
3+
import StringFormatting from './formatting';
44
import { HandleBarsHelper } from './handlebars-helper';
55
import * as vscode from 'vscode';
66
import { FileNameUtils } from './file-name.utils';
77
import { Menu } from './enums/menu';
8-
import { Validator } from './validator';
98
import { FileConfig } from './models/file-config';
109
import { TemplateConfig } from "./models/template-config";
11-
import Commands from './commands';
1210
export class FileContents {
1311
private readonly TEMPLATES_FOLDER = 'templates';
1412
private readonly NEW_CONFIG_NAME = 'vue-typescript-files';
@@ -18,11 +16,7 @@ export class FileContents {
1816
this.config = vscode.workspace.getConfiguration(this.NEW_CONFIG_NAME);
1917
}
2018

21-
private getTemplate(uri: vscode.Uri , templateName: string): string {
22-
23-
const workspaceFolder = vscode.workspace.getWorkspaceFolder(uri);
24-
const workspacePath = workspaceFolder?.uri.fsPath || '';
25-
19+
private getTemplate(workspacePath: string , templateName: string): string {
2620
const workspaceConfigDir = workspacePath + '/.' + this.NEW_CONFIG_NAME;
2721
// 获取当前工作区下是否有自定义模版
2822
const hasworkspaceConfigDir = fs.existsSync(workspaceConfigDir);
@@ -39,21 +33,28 @@ export class FileContents {
3933

4034
const customPath = templateConfig.path;
4135

42-
if ( customPath && fs.existsSync(path.join(customPath, templateName)) ) {
36+
if (customPath && fs.existsSync(path.join(customPath, templateName)) ) {
4337
return fs.readFileSync(path.join(customPath, templateName), 'utf8');
4438
}
4539

4640
return fs.readFileSync(path.join(__dirname, this.TEMPLATES_FOLDER, templateName), 'utf8');
4741

4842
}
4943

44+
private getWorkspacePath(uri: vscode.Uri): string {
45+
const workspaceFolder = vscode.workspace.getWorkspaceFolder(uri);
46+
const workspacePath = workspaceFolder?.uri.fsPath || '';
47+
return workspacePath;
48+
}
49+
5050
// 获得修改后的模板内容
5151
public getTemplateContent(uri: vscode.Uri, templateName: Menu, inputName: string, args: string[]) {
5252
let result = '';
53-
const template = this.getTemplate(uri,templateName);
53+
const workspacePath = this.getWorkspacePath(uri);
54+
const template = this.getTemplate(workspacePath,templateName);
5455
if (template && template != '') {
5556
const text = this.textCase(templateName, inputName, args);
56-
const intance = HandleBarsHelper.getInstance();
57+
const intance = HandleBarsHelper.getInstance(workspacePath);
5758
const templateDelegate = intance.compile(template, { noEscape: true});
5859
result = templateDelegate(text);
5960
}
@@ -68,27 +69,22 @@ export class FileContents {
6869
var inputArgs: string[] = [];
6970

7071
if(this.parseConfig("file")?.spotStyleName){
71-
className = Formatting.toCamelCaseWithSpot(className);
72+
className = StringFormatting.replaceDotWithHyphen(className);
7273
}
7374
// 获取配置信息
7475
className = fileConfig.prefix + (fileConfig.prefix ? "-" : "") + className + (fileConfig.suffix ? "-" : "") + fileConfig.suffix;
7576

7677
const result = {
77-
resourcesName: resourcesName,
78-
upperName: Formatting.toUpperCase(className),
79-
hyphensName: Formatting.toHyphensCase(className),
80-
dynamicName: Formatting.toUpperCase(className),
8178
inputName: inputName,
8279
args: inputArgs,
83-
fileName: Formatting.toUpperCase(inputName),
84-
template: fileConfig.templates,
85-
templateLang: fileConfig.templateLang,
86-
styleLang: fileConfig.styleLang,
87-
styleScope: fileConfig.styleScope,
88-
exportModule: fileConfig.exportModule
80+
resourcesName: resourcesName,
81+
hyphensName: StringFormatting.toHyphenCase(className),
82+
dynamicName: StringFormatting.toPascalCase(className),
83+
fileName: StringFormatting.toPascalCase(inputName),
8984
}
9085
return result;
9186
}
87+
9288
// * 解析配置文件
9389
private parseConfig(configName: string, switchExtend?: any) {
9490

src/formatting.ts

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,39 @@
1-
export default class Formatting {
1+
export default class Formatter {
22
private constructor() { }
33

4+
// Converts a hyphen-separated string to camel case.
5+
// Demo: "hello-world" => "helloWorld"
46
public static toCamelCase(input: string) {
57
return input.replace(/-([a-z])/ig, (all, letter) => letter.toUpperCase());
68
}
79

8-
public static toTileCase(input: string) {
10+
// Converts a string to title case, capitalizing the first letter of each word.
11+
// Demo: "hello world" => "Hello World"
12+
public static toTitleCase(input: string) {
913
return input.replace(/\w\S*/g, txt => txt.charAt(0).toUpperCase() + txt.substring(1).toLowerCase());
1014
}
1115

12-
public static toUpperCase(input: string) {
16+
// Converts a string to Pascal case, which is similar to Camel Case but the first letter is capitalized.
17+
// Demo: "hello world" => "HelloWorld"
18+
public static toPascalCase(input: string) {
1319
return this.toCamelCase(input.charAt(0).toUpperCase() + input.slice(1));
1420
}
1521

16-
public static toHyphensCase(input: string) {
22+
// Converts a camel cased string to a hyphen-separated string.
23+
// Demo: "helloWorld" => "hello-world"
24+
public static toHyphenCase(input: string) {
1725
return input.charAt(0).toLowerCase() + input.substring(1).replace(/[A-Z]+/g, txt => "-" + txt).toLowerCase();
1826
}
1927

20-
public static toCamelCaseWithSpot(input:string){
21-
return input.replace(".","-");
28+
// Replaces a dot with a hyphen in a string.
29+
// Demo: "user.name" => "user-name"
30+
public static replaceDotWithHyphen(input: string) {
31+
return input.replace(".", "-");
2232
}
23-
}
33+
34+
// Converts the first character of a string to lower case, keeping the rest of the string unchanged.
35+
// Demo: "HelloWorld" => "helloWorld"
36+
public static toLocaleLowerCaseFirst(input: string) {
37+
return input.substring(0, 1).toLocaleLowerCase() + input.substring(1);
38+
}
39+
}

src/handlebars-helper.ts

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,15 @@
11
import * as HandleBars from "handlebars";
2+
import StringFormatter from "./formatting";
3+
import IOUtil from "./ioutil";
4+
25
export class HandleBarsHelper {
36

47
private static instance: typeof HandleBars = HandleBars.create();
8+
private static workspacePath: string;
59

6-
public static getInstance(): typeof HandleBars {
10+
public static getInstance(workspacePath: string): typeof HandleBars {
711
this.handlebarHelper(this.instance);
12+
this.workspacePath = workspacePath;
813
return this.instance;
914
}
1015

@@ -44,6 +49,26 @@ export class HandleBarsHelper {
4449
}
4550
}
4651
return false;
52+
},
53+
to_camel_case: function (v1) {
54+
return StringFormatter.toCamelCase(v1);
55+
},
56+
to_title_case: function(v1) {
57+
return StringFormatter.toTitleCase(v1);
58+
},
59+
to_pascal_case: function(v1) {
60+
return StringFormatter.toPascalCase(v1);
61+
},
62+
to_hyphen_case: function(v1) {
63+
return StringFormatter.toHyphenCase(v1);
64+
},
65+
to_locale_lower_case_first: function(v1) {
66+
return StringFormatter.toLocaleLowerCaseFirst(v1);
67+
},
68+
case_from_json: function(v1, filename) {
69+
const text = IOUtil.readText(HandleBarsHelper.workspacePath,filename);
70+
const json = JSON.parse(text);
71+
return json[v1] ?? json['default'];
4772
}
4873
});
4974
}

src/ioutil.ts

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { Menu } from './enums/menu';
44
import { FileNameUtils } from './file-name.utils';
55
import { IFiles } from './models/file';
66
import { IPath } from './models/path';
7-
7+
import { isAbsolute, join } from 'path';
88
export default class IOUtil {
99
private constructor() { }
1010
public static async createFiles(loc: IPath, files: IFiles[]): Promise<string> {
@@ -37,4 +37,22 @@ export default class IOUtil {
3737
});
3838
return flag;
3939
}
40+
41+
42+
public static readText(rootPath: string, url: string): string {
43+
44+
let filePath: string;
45+
if (isAbsolute(url)) {
46+
filePath = url;
47+
} else {
48+
filePath = join(rootPath, url);
49+
}
50+
const hasFile = fs.existsSync(filePath);
51+
if (hasFile) {
52+
const data = fs.readFileSync(filePath, "utf8");
53+
return data;
54+
}
55+
return "";
56+
}
57+
4058
}

templates/class.tmpl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
export class {{upperName}} {
2-
1+
export class {{dynamicName}} {
2+
{{#if le 1 0}} hello {{/if}}
33
}
4-
export default new {{upperName}}();
4+
export default new {{dynamicName}}();

templates/declare.tmpl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
declare module '{{hyphensName}}' {
22
import { PluginFunction } from 'vue';
33
export const install: PluginFunction<{}>;
4-
interface {{upperName}}{}
5-
export const {{upperName}}: {{upperName}};
4+
interface {{dynamicName}}{}
5+
export const {{dynamicName}}: {{dynamicName}};
66
}

templates/directive.tmpl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { DirectiveOptions, VNode } from 'vue';
22
import { DirectiveBinding } from 'vue/types/options';
3-
export class {{upperName}} implements DirectiveOptions {
3+
export class {{dynamicName}} implements DirectiveOptions {
44
bind(el: HTMLElement, binding: DirectiveBinding, vnode: VNode, oldVnode: VNode) {
55

66
}
@@ -18,4 +18,4 @@ export class {{upperName}} implements DirectiveOptions {
1818
}
1919

2020
}
21-
export default new {{upperName}}();
21+
export default new {{dynamicName}}();

templates/enum.tmpl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
export enum {{upperName}} {
1+
export enum {{dynamicName}} {
22

33
}

templates/interface.tmpl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
export interface {{upperName}} {
1+
export interface {{dynamicName}} {
22

33
}

0 commit comments

Comments
 (0)