@tbsten/mir-core 0.0.2-alpha02 → 0.0.2-alpha04

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (120) hide show
  1. package/dist/__tests__/errors.test.d.ts +1 -0
  2. package/dist/__tests__/errors.test.js +51 -0
  3. package/dist/__tests__/errors.test.js.map +1 -0
  4. package/dist/__tests__/helpers/string-helpers.test.d.ts +1 -0
  5. package/dist/__tests__/helpers/string-helpers.test.js +61 -0
  6. package/dist/__tests__/helpers/string-helpers.test.js.map +1 -0
  7. package/dist/__tests__/hooks.test.d.ts +1 -0
  8. package/dist/__tests__/hooks.test.js +125 -0
  9. package/dist/__tests__/hooks.test.js.map +1 -0
  10. package/dist/__tests__/i18n.test.d.ts +1 -0
  11. package/dist/__tests__/i18n.test.js +51 -0
  12. package/dist/__tests__/i18n.test.js.map +1 -0
  13. package/dist/__tests__/remote-registry.test.d.ts +1 -0
  14. package/dist/__tests__/remote-registry.test.js +194 -0
  15. package/dist/__tests__/remote-registry.test.js.map +1 -0
  16. package/dist/__tests__/safe-yaml-parser.test.d.ts +1 -0
  17. package/dist/__tests__/safe-yaml-parser.test.js +159 -0
  18. package/dist/__tests__/safe-yaml-parser.test.js.map +1 -0
  19. package/dist/__tests__/snapshots/error-messages.snapshot.test.d.ts +1 -0
  20. package/dist/__tests__/snapshots/error-messages.snapshot.test.js +52 -0
  21. package/dist/__tests__/snapshots/error-messages.snapshot.test.js.map +1 -0
  22. package/dist/__tests__/snapshots/snippet-schema-output.snapshot.test.d.ts +1 -0
  23. package/dist/__tests__/snapshots/snippet-schema-output.snapshot.test.js +93 -0
  24. package/dist/__tests__/snapshots/snippet-schema-output.snapshot.test.js.map +1 -0
  25. package/dist/__tests__/snapshots/template-output.snapshot.test.d.ts +1 -0
  26. package/dist/__tests__/snapshots/template-output.snapshot.test.js +60 -0
  27. package/dist/__tests__/snapshots/template-output.snapshot.test.js.map +1 -0
  28. package/dist/__tests__/snippet-schema.test.d.ts +1 -0
  29. package/dist/__tests__/snippet-schema.test.js +137 -0
  30. package/dist/__tests__/snippet-schema.test.js.map +1 -0
  31. package/dist/__tests__/symlink-checker.test.d.ts +1 -0
  32. package/dist/__tests__/symlink-checker.test.js +81 -0
  33. package/dist/__tests__/symlink-checker.test.js.map +1 -0
  34. package/dist/__tests__/template-engine.test.d.ts +1 -0
  35. package/dist/__tests__/template-engine.test.js +175 -0
  36. package/dist/__tests__/template-engine.test.js.map +1 -0
  37. package/dist/__tests__/validate-name.test.d.ts +1 -0
  38. package/dist/__tests__/validate-name.test.js +49 -0
  39. package/dist/__tests__/validate-name.test.js.map +1 -0
  40. package/dist/errors.d.ts +31 -0
  41. package/dist/errors.js +68 -0
  42. package/dist/errors.js.map +1 -0
  43. package/dist/helpers/index.d.ts +5 -0
  44. package/dist/helpers/index.js +28 -0
  45. package/dist/helpers/index.js.map +1 -0
  46. package/dist/helpers/string-helpers.d.ts +15 -0
  47. package/dist/helpers/string-helpers.js +63 -0
  48. package/dist/helpers/string-helpers.js.map +1 -0
  49. package/dist/hooks.d.ts +9 -0
  50. package/dist/hooks.js +48 -0
  51. package/dist/hooks.js.map +1 -0
  52. package/dist/i18n/index.d.ts +6 -0
  53. package/dist/i18n/index.js +20 -0
  54. package/dist/i18n/index.js.map +1 -0
  55. package/dist/i18n/locales/en.d.ts +2 -0
  56. package/dist/i18n/locales/en.js +84 -0
  57. package/dist/i18n/locales/en.js.map +1 -0
  58. package/dist/i18n/locales/ja.d.ts +2 -0
  59. package/dist/i18n/locales/ja.js +84 -0
  60. package/dist/i18n/locales/ja.js.map +1 -0
  61. package/dist/i18n/types.d.ts +72 -0
  62. package/dist/i18n/types.js +2 -0
  63. package/dist/i18n/types.js.map +1 -0
  64. package/dist/index.d.ts +17 -0
  65. package/dist/index.js +23 -0
  66. package/dist/index.js.map +1 -0
  67. package/dist/lib/symlink-checker.d.ts +15 -0
  68. package/dist/lib/symlink-checker.js +54 -0
  69. package/dist/lib/symlink-checker.js.map +1 -0
  70. package/dist/registry.d.ts +8 -0
  71. package/dist/registry.js +86 -0
  72. package/dist/registry.js.map +1 -0
  73. package/dist/remote-registry.d.ts +51 -0
  74. package/dist/remote-registry.js +181 -0
  75. package/dist/remote-registry.js.map +1 -0
  76. package/dist/safe-yaml-parser.d.ts +26 -0
  77. package/{src/safe-yaml-parser.ts → dist/safe-yaml-parser.js} +28 -34
  78. package/dist/safe-yaml-parser.js.map +1 -0
  79. package/dist/snippet-schema.d.ts +38 -0
  80. package/dist/snippet-schema.js +63 -0
  81. package/dist/snippet-schema.js.map +1 -0
  82. package/dist/template-engine.d.ts +5 -0
  83. package/dist/template-engine.js +130 -0
  84. package/dist/template-engine.js.map +1 -0
  85. package/dist/validate-name.d.ts +1 -0
  86. package/dist/validate-name.js +9 -0
  87. package/dist/validate-name.js.map +1 -0
  88. package/package.json +6 -1
  89. package/src/__tests__/errors.test.ts +0 -71
  90. package/src/__tests__/helpers/string-helpers.test.ts +0 -100
  91. package/src/__tests__/hooks.test.ts +0 -145
  92. package/src/__tests__/i18n.test.ts +0 -60
  93. package/src/__tests__/remote-registry.test.ts +0 -265
  94. package/src/__tests__/safe-yaml-parser.test.ts +0 -187
  95. package/src/__tests__/snapshots/__snapshots__/error-messages.snapshot.test.ts.snap +0 -27
  96. package/src/__tests__/snapshots/__snapshots__/snippet-schema-output.snapshot.test.ts.snap +0 -78
  97. package/src/__tests__/snapshots/__snapshots__/template-output.snapshot.test.ts.snap +0 -45
  98. package/src/__tests__/snapshots/error-messages.snapshot.test.ts +0 -76
  99. package/src/__tests__/snapshots/snippet-schema-output.snapshot.test.ts +0 -98
  100. package/src/__tests__/snapshots/template-output.snapshot.test.ts +0 -73
  101. package/src/__tests__/snippet-schema.test.ts +0 -180
  102. package/src/__tests__/symlink-checker.test.ts +0 -95
  103. package/src/__tests__/template-engine.test.ts +0 -240
  104. package/src/__tests__/validate-name.test.ts +0 -61
  105. package/src/errors.ts +0 -82
  106. package/src/helpers/index.ts +0 -34
  107. package/src/helpers/string-helpers.ts +0 -76
  108. package/src/hooks.ts +0 -63
  109. package/src/i18n/index.ts +0 -32
  110. package/src/i18n/locales/en.ts +0 -96
  111. package/src/i18n/locales/ja.ts +0 -96
  112. package/src/i18n/types.ts +0 -96
  113. package/src/index.ts +0 -86
  114. package/src/lib/symlink-checker.ts +0 -62
  115. package/src/registry.ts +0 -120
  116. package/src/remote-registry.ts +0 -260
  117. package/src/snippet-schema.ts +0 -117
  118. package/src/template-engine.ts +0 -147
  119. package/src/validate-name.ts +0 -12
  120. package/tsconfig.json +0 -17
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,175 @@
1
+ /**
2
+ * mir-core: テンプレートエンジンの unit テスト
3
+ */
4
+ import { describe, it, expect, beforeEach, afterEach } from "vitest";
5
+ import fs from "node:fs";
6
+ import os from "node:os";
7
+ import path from "node:path";
8
+ import { expandTemplate, expandPath, extractVariables, extractVariablesFromDirectory, } from "../index.js";
9
+ // TODO: 現時点では理想の挙動をテストケースとして記述。後で有効化する。
10
+ describe("expandTemplate", () => {
11
+ it("変数を展開する", () => {
12
+ expect(expandTemplate("Hello, {{ name }}!", { name: "World" })).toBe("Hello, World!");
13
+ });
14
+ it("複数変数を展開する", () => {
15
+ const result = expandTemplate("{{ greeting }}, {{ name }}!", { greeting: "Hi", name: "User" });
16
+ expect(result).toBe("Hi, User!");
17
+ });
18
+ it("変数が未定義の場合は空文字に展開", () => {
19
+ expect(expandTemplate("Hello, {{ name }}!", {})).toBe("Hello, !");
20
+ });
21
+ it("変数を含まないテンプレートはそのまま返す", () => {
22
+ expect(expandTemplate("plain text", {})).toBe("plain text");
23
+ });
24
+ it("空テンプレートは空文字を返す", () => {
25
+ expect(expandTemplate("", {})).toBe("");
26
+ });
27
+ it("Handlebars の #if ブロックを展開する", () => {
28
+ const template = "{{#if enabled}}ON{{else}}OFF{{/if}}";
29
+ expect(expandTemplate(template, { enabled: true })).toBe("ON");
30
+ expect(expandTemplate(template, { enabled: false })).toBe("OFF");
31
+ });
32
+ it("noEscape モードで HTML タグがエスケープされない", () => {
33
+ expect(expandTemplate("{{ html }}", { html: "<div>test</div>" })).toBe("<div>test</div>");
34
+ });
35
+ });
36
+ describe("expandPath", () => {
37
+ it("パス内の変数を展開する", () => {
38
+ expect(expandPath("{{ name }}.ts", { name: "useAuth" })).toBe("useAuth.ts");
39
+ });
40
+ it("ネストしたパスの変数を展開する", () => {
41
+ const result = expandPath("{{ dir }}/{{ name }}.ts", {
42
+ dir: "hooks",
43
+ name: "useAuth",
44
+ });
45
+ expect(result).toMatch(/hooks[/\\]useAuth\.ts/);
46
+ });
47
+ it("パス区切りを正規化する", () => {
48
+ const result = expandPath("a//b/c", {});
49
+ expect(result).not.toContain("//");
50
+ });
51
+ });
52
+ describe("extractVariables", () => {
53
+ it("単一変数を抽出する", () => {
54
+ expect(extractVariables("{{ name }}")).toContain("name");
55
+ });
56
+ it("複数変数を抽出する", () => {
57
+ const vars = extractVariables("{{ name }} {{ description }}");
58
+ expect(vars).toContain("name");
59
+ expect(vars).toContain("description");
60
+ });
61
+ it("重複変数は1つにまとめる", () => {
62
+ const vars = extractVariables("{{ name }} {{ name }}");
63
+ expect(vars.filter((v) => v === "name")).toHaveLength(1);
64
+ });
65
+ it("変数がない場合は空配列", () => {
66
+ expect(extractVariables("no variables")).toEqual([]);
67
+ });
68
+ it("#if ブロック内の変数を抽出する", () => {
69
+ const vars = extractVariables("{{#if enabled}}{{ name }}{{/if}}");
70
+ expect(vars).toContain("enabled");
71
+ expect(vars).toContain("name");
72
+ });
73
+ });
74
+ describe("expandTemplate with helpers", () => {
75
+ it("lowercase ヘルパー", () => {
76
+ expect(expandTemplate("{{lowercase name}}", { name: "HELLO" })).toBe("hello");
77
+ });
78
+ it("uppercase ヘルパー", () => {
79
+ expect(expandTemplate("{{uppercase name}}", { name: "hello" })).toBe("HELLO");
80
+ });
81
+ it("replace ヘルパー", () => {
82
+ expect(expandTemplate('{{replace package "/" "."}}', { package: "com/example/app" })).toBe("com.example.app");
83
+ });
84
+ it("camelCase ヘルパー", () => {
85
+ expect(expandTemplate("{{camelCase name}}", { name: "my-component" })).toBe("myComponent");
86
+ });
87
+ it("pascalCase ヘルパー", () => {
88
+ expect(expandTemplate("{{pascalCase name}}", { name: "my-component" })).toBe("MyComponent");
89
+ });
90
+ it("snakeCase ヘルパー", () => {
91
+ expect(expandTemplate("{{snakeCase name}}", { name: "myComponent" })).toBe("my_component");
92
+ });
93
+ it("kebabCase ヘルパー", () => {
94
+ expect(expandTemplate("{{kebabCase name}}", { name: "MyComponent" })).toBe("my-component");
95
+ });
96
+ it("capitalize ヘルパー", () => {
97
+ expect(expandTemplate("{{capitalize name}}", { name: "hello" })).toBe("Hello");
98
+ });
99
+ it("uncapitalize ヘルパー", () => {
100
+ expect(expandTemplate("{{uncapitalize name}}", { name: "Hello" })).toBe("hello");
101
+ });
102
+ it("trim ヘルパー", () => {
103
+ expect(expandTemplate("{{trim name}}", { name: " hello " })).toBe("hello");
104
+ });
105
+ it("サブ式(ネスト): lowercase(replace(...))", () => {
106
+ expect(expandTemplate('{{lowercase (replace name "/" ".")}}', {
107
+ name: "COM/EXAMPLE/APP",
108
+ })).toBe("com.example.app");
109
+ });
110
+ it("サブ式(ネスト): pascalCase(replace(...))", () => {
111
+ expect(expandTemplate('{{pascalCase (replace pkg "/" "-")}}', {
112
+ pkg: "my/cool/component",
113
+ })).toBe("MyCoolComponent");
114
+ });
115
+ });
116
+ describe("extractVariables with helpers", () => {
117
+ it("ヘルパー名を変数に含めない", () => {
118
+ const vars = extractVariables("{{lowercase name}}");
119
+ expect(vars).toContain("name");
120
+ expect(vars).not.toContain("lowercase");
121
+ });
122
+ it("replace ヘルパーで変数のみ抽出", () => {
123
+ const vars = extractVariables('{{replace package "/" "."}}');
124
+ expect(vars).toContain("package");
125
+ expect(vars).not.toContain("replace");
126
+ });
127
+ it("サブ式でもヘルパー名を除外", () => {
128
+ const vars = extractVariables('{{lowercase (replace name "/" ".")}}');
129
+ expect(vars).toContain("name");
130
+ expect(vars).not.toContain("lowercase");
131
+ expect(vars).not.toContain("replace");
132
+ });
133
+ it("ヘルパーと通常変数が混在", () => {
134
+ const vars = extractVariables("{{name}} {{lowercase title}}");
135
+ expect(vars).toContain("name");
136
+ expect(vars).toContain("title");
137
+ expect(vars).not.toContain("lowercase");
138
+ });
139
+ it("組み込みヘルパー (if/each) も変数に含めない", () => {
140
+ const vars = extractVariables("{{#if enabled}}{{name}}{{/if}}");
141
+ expect(vars).toContain("enabled");
142
+ expect(vars).toContain("name");
143
+ expect(vars).not.toContain("if");
144
+ });
145
+ });
146
+ describe("extractVariablesFromDirectory", () => {
147
+ let tmpDir;
148
+ beforeEach(() => {
149
+ tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "mir-core-test-"));
150
+ });
151
+ afterEach(() => {
152
+ fs.rmSync(tmpDir, { recursive: true, force: true });
153
+ });
154
+ it("ファイル内容から変数を抽出する", () => {
155
+ fs.writeFileSync(path.join(tmpDir, "index.ts"), "export {{ name }}", "utf-8");
156
+ const vars = extractVariablesFromDirectory(tmpDir);
157
+ expect(vars).toContain("name");
158
+ });
159
+ it("ファイル名から変数を抽出する", () => {
160
+ fs.writeFileSync(path.join(tmpDir, "{{ name }}.ts"), "content", "utf-8");
161
+ const vars = extractVariablesFromDirectory(tmpDir);
162
+ expect(vars).toContain("name");
163
+ });
164
+ it("サブディレクトリ名から変数を抽出する", () => {
165
+ const subDir = path.join(tmpDir, "{{ module }}");
166
+ fs.mkdirSync(subDir, { recursive: true });
167
+ fs.writeFileSync(path.join(subDir, "index.ts"), "export {}", "utf-8");
168
+ const vars = extractVariablesFromDirectory(tmpDir);
169
+ expect(vars).toContain("module");
170
+ });
171
+ it("存在しないディレクトリは空配列", () => {
172
+ expect(extractVariablesFromDirectory("/nonexistent")).toEqual([]);
173
+ });
174
+ });
175
+ //# sourceMappingURL=template-engine.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"template-engine.test.js","sourceRoot":"","sources":["../../src/__tests__/template-engine.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,49 @@
1
+ /**
2
+ * mir-core: validateSnippetName の unit テスト
3
+ */
4
+ import { describe, it, expect } from "vitest";
5
+ import { validateSnippetName, ValidationError } from "../index.js";
6
+ // TODO: 現時点では理想の挙動をテストケースとして記述。後で有効化する。
7
+ describe("validateSnippetName", () => {
8
+ describe("正常系", () => {
9
+ it("英小文字のみ", () => {
10
+ expect(() => validateSnippetName("react")).not.toThrow();
11
+ });
12
+ it("英数字 + ハイフン", () => {
13
+ expect(() => validateSnippetName("react-hook")).not.toThrow();
14
+ });
15
+ it("数字始まり", () => {
16
+ expect(() => validateSnippetName("1component")).not.toThrow();
17
+ });
18
+ it("大文字含む", () => {
19
+ expect(() => validateSnippetName("MyComponent")).not.toThrow();
20
+ });
21
+ it("1文字", () => {
22
+ expect(() => validateSnippetName("a")).not.toThrow();
23
+ });
24
+ });
25
+ describe("異常系", () => {
26
+ it("空文字でエラー", () => {
27
+ expect(() => validateSnippetName("")).toThrow(ValidationError);
28
+ });
29
+ it("アンダースコアでエラー", () => {
30
+ expect(() => validateSnippetName("my_comp")).toThrow(ValidationError);
31
+ });
32
+ it("先頭ハイフンでエラー", () => {
33
+ expect(() => validateSnippetName("-invalid")).toThrow(ValidationError);
34
+ });
35
+ it("スペース含むとエラー", () => {
36
+ expect(() => validateSnippetName("my comp")).toThrow(ValidationError);
37
+ });
38
+ it("日本語でエラー", () => {
39
+ expect(() => validateSnippetName("テスト")).toThrow(ValidationError);
40
+ });
41
+ it("特殊文字でエラー", () => {
42
+ expect(() => validateSnippetName("react@hook")).toThrow(ValidationError);
43
+ });
44
+ it("ドット含むとエラー", () => {
45
+ expect(() => validateSnippetName("my.comp")).toThrow(ValidationError);
46
+ });
47
+ });
48
+ });
49
+ //# sourceMappingURL=validate-name.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate-name.test.js","sourceRoot":"","sources":["../../src/__tests__/validate-name.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,31 @@
1
+ export declare class MirError extends Error {
2
+ constructor(message: string);
3
+ }
4
+ export declare class ValidationError extends MirError {
5
+ constructor(message: string);
6
+ }
7
+ export declare class SnippetNotFoundError extends MirError {
8
+ readonly details: string;
9
+ constructor(name: string);
10
+ }
11
+ export declare class SnippetAlreadyExistsError extends MirError {
12
+ constructor(name: string);
13
+ }
14
+ export declare class RegistryNotFoundError extends MirError {
15
+ constructor(name: string);
16
+ }
17
+ export declare class RegistryRemoteError extends MirError {
18
+ constructor(name?: string);
19
+ }
20
+ export declare class PathTraversalError extends MirError {
21
+ constructor(filePath: string);
22
+ }
23
+ export declare class FileConflictError extends MirError {
24
+ constructor(filePath: string);
25
+ }
26
+ export declare class RemoteRegistryFetchError extends MirError {
27
+ constructor(url: string, status?: number);
28
+ }
29
+ export declare class InvalidManifestError extends MirError {
30
+ constructor(url: string);
31
+ }
package/dist/errors.js ADDED
@@ -0,0 +1,68 @@
1
+ import { t } from "./i18n/index.js";
2
+ export class MirError extends Error {
3
+ constructor(message) {
4
+ super(message);
5
+ this.name = "MirError";
6
+ }
7
+ }
8
+ export class ValidationError extends MirError {
9
+ constructor(message) {
10
+ super(message);
11
+ this.name = "ValidationError";
12
+ }
13
+ }
14
+ export class SnippetNotFoundError extends MirError {
15
+ details;
16
+ constructor(name) {
17
+ super(t("error.snippet-not-found", { name }));
18
+ this.name = "SnippetNotFoundError";
19
+ this.details = t("error.snippet-not-found-details");
20
+ }
21
+ }
22
+ export class SnippetAlreadyExistsError extends MirError {
23
+ constructor(name) {
24
+ super(t("error.snippet-already-exists", { name }));
25
+ this.name = "SnippetAlreadyExistsError";
26
+ }
27
+ }
28
+ export class RegistryNotFoundError extends MirError {
29
+ constructor(name) {
30
+ super(t("error.registry-not-found", { name }));
31
+ this.name = "RegistryNotFoundError";
32
+ }
33
+ }
34
+ export class RegistryRemoteError extends MirError {
35
+ constructor(name) {
36
+ super(name
37
+ ? t("error.registry-remote-named", { name })
38
+ : t("error.registry-remote"));
39
+ this.name = "RegistryRemoteError";
40
+ }
41
+ }
42
+ export class PathTraversalError extends MirError {
43
+ constructor(filePath) {
44
+ super(t("error.path-traversal", { path: filePath }));
45
+ this.name = "PathTraversalError";
46
+ }
47
+ }
48
+ export class FileConflictError extends MirError {
49
+ constructor(filePath) {
50
+ super(t("error.file-conflict", { path: filePath }));
51
+ this.name = "FileConflictError";
52
+ }
53
+ }
54
+ export class RemoteRegistryFetchError extends MirError {
55
+ constructor(url, status) {
56
+ super(status
57
+ ? t("error.remote-fetch-status", { url, status })
58
+ : t("error.remote-fetch", { url }));
59
+ this.name = "RemoteRegistryFetchError";
60
+ }
61
+ }
62
+ export class InvalidManifestError extends MirError {
63
+ constructor(url) {
64
+ super(t("error.invalid-manifest", { url }));
65
+ this.name = "InvalidManifestError";
66
+ }
67
+ }
68
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,iBAAiB,CAAC;AAEpC,MAAM,OAAO,QAAS,SAAQ,KAAK;IACjC,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,UAAU,CAAC;IACzB,CAAC;CACF;AAED,MAAM,OAAO,eAAgB,SAAQ,QAAQ;IAC3C,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,iBAAiB,CAAC;IAChC,CAAC;CACF;AAED,MAAM,OAAO,oBAAqB,SAAQ,QAAQ;IACvC,OAAO,CAAS;IAEzB,YAAY,IAAY;QACtB,KAAK,CAAC,CAAC,CAAC,yBAAyB,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;QAC9C,IAAI,CAAC,IAAI,GAAG,sBAAsB,CAAC;QACnC,IAAI,CAAC,OAAO,GAAG,CAAC,CAAC,iCAAiC,CAAC,CAAC;IACtD,CAAC;CACF;AAED,MAAM,OAAO,yBAA0B,SAAQ,QAAQ;IACrD,YAAY,IAAY;QACtB,KAAK,CAAC,CAAC,CAAC,8BAA8B,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;QACnD,IAAI,CAAC,IAAI,GAAG,2BAA2B,CAAC;IAC1C,CAAC;CACF;AAED,MAAM,OAAO,qBAAsB,SAAQ,QAAQ;IACjD,YAAY,IAAY;QACtB,KAAK,CAAC,CAAC,CAAC,0BAA0B,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;QAC/C,IAAI,CAAC,IAAI,GAAG,uBAAuB,CAAC;IACtC,CAAC;CACF;AAED,MAAM,OAAO,mBAAoB,SAAQ,QAAQ;IAC/C,YAAY,IAAa;QACvB,KAAK,CACH,IAAI;YACF,CAAC,CAAC,CAAC,CAAC,6BAA6B,EAAE,EAAE,IAAI,EAAE,CAAC;YAC5C,CAAC,CAAC,CAAC,CAAC,uBAAuB,CAAC,CAC/B,CAAC;QACF,IAAI,CAAC,IAAI,GAAG,qBAAqB,CAAC;IACpC,CAAC;CACF;AAED,MAAM,OAAO,kBAAmB,SAAQ,QAAQ;IAC9C,YAAY,QAAgB;QAC1B,KAAK,CAAC,CAAC,CAAC,sBAAsB,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC;QACrD,IAAI,CAAC,IAAI,GAAG,oBAAoB,CAAC;IACnC,CAAC;CACF;AAED,MAAM,OAAO,iBAAkB,SAAQ,QAAQ;IAC7C,YAAY,QAAgB;QAC1B,KAAK,CAAC,CAAC,CAAC,qBAAqB,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC;QACpD,IAAI,CAAC,IAAI,GAAG,mBAAmB,CAAC;IAClC,CAAC;CACF;AAED,MAAM,OAAO,wBAAyB,SAAQ,QAAQ;IACpD,YAAY,GAAW,EAAE,MAAe;QACtC,KAAK,CACH,MAAM;YACJ,CAAC,CAAC,CAAC,CAAC,2BAA2B,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC;YACjD,CAAC,CAAC,CAAC,CAAC,oBAAoB,EAAE,EAAE,GAAG,EAAE,CAAC,CACrC,CAAC;QACF,IAAI,CAAC,IAAI,GAAG,0BAA0B,CAAC;IACzC,CAAC;CACF;AAED,MAAM,OAAO,oBAAqB,SAAQ,QAAQ;IAChD,YAAY,GAAW;QACrB,KAAK,CAAC,CAAC,CAAC,wBAAwB,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC;QAC5C,IAAI,CAAC,IAAI,GAAG,sBAAsB,CAAC;IACrC,CAAC;CACF"}
@@ -0,0 +1,5 @@
1
+ import type Handlebars from "handlebars";
2
+ /** ヘルパー名一覧(extractVariables でフィルタ用) */
3
+ export declare const HELPER_NAMES: ReadonlySet<string>;
4
+ /** Handlebars インスタンスにヘルパーを一括登録 */
5
+ export declare function registerHelpers(hbs: typeof Handlebars): void;
@@ -0,0 +1,28 @@
1
+ import * as helpers from "./string-helpers.js";
2
+ /** ヘルパー名一覧(extractVariables でフィルタ用) */
3
+ export const HELPER_NAMES = new Set([
4
+ "lowercase",
5
+ "uppercase",
6
+ "capitalize",
7
+ "uncapitalize",
8
+ "replace",
9
+ "camelCase",
10
+ "pascalCase",
11
+ "snakeCase",
12
+ "kebabCase",
13
+ "trim",
14
+ ]);
15
+ /** Handlebars インスタンスにヘルパーを一括登録 */
16
+ export function registerHelpers(hbs) {
17
+ hbs.registerHelper("lowercase", (v) => helpers.lowercase(v));
18
+ hbs.registerHelper("uppercase", (v) => helpers.uppercase(v));
19
+ hbs.registerHelper("capitalize", (v) => helpers.capitalize(v));
20
+ hbs.registerHelper("uncapitalize", (v) => helpers.uncapitalize(v));
21
+ hbs.registerHelper("replace", (v, search, replacement) => helpers.replace(v, search, replacement));
22
+ hbs.registerHelper("camelCase", (v) => helpers.camelCase(v));
23
+ hbs.registerHelper("pascalCase", (v) => helpers.pascalCase(v));
24
+ hbs.registerHelper("snakeCase", (v) => helpers.snakeCase(v));
25
+ hbs.registerHelper("kebabCase", (v) => helpers.kebabCase(v));
26
+ hbs.registerHelper("trim", (v) => helpers.trim(v));
27
+ }
28
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/helpers/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,OAAO,MAAM,qBAAqB,CAAC;AAE/C,uCAAuC;AACvC,MAAM,CAAC,MAAM,YAAY,GAAwB,IAAI,GAAG,CAAC;IACvD,WAAW;IACX,WAAW;IACX,YAAY;IACZ,cAAc;IACd,SAAS;IACT,WAAW;IACX,YAAY;IACZ,WAAW;IACX,WAAW;IACX,MAAM;CACP,CAAC,CAAC;AAEH,kCAAkC;AAClC,MAAM,UAAU,eAAe,CAAC,GAAsB;IACpD,GAAG,CAAC,cAAc,CAAC,WAAW,EAAE,CAAC,CAAU,EAAE,EAAE,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;IACtE,GAAG,CAAC,cAAc,CAAC,WAAW,EAAE,CAAC,CAAU,EAAE,EAAE,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;IACtE,GAAG,CAAC,cAAc,CAAC,YAAY,EAAE,CAAC,CAAU,EAAE,EAAE,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;IACxE,GAAG,CAAC,cAAc,CAAC,cAAc,EAAE,CAAC,CAAU,EAAE,EAAE,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC;IAC5E,GAAG,CAAC,cAAc,CAChB,SAAS,EACT,CAAC,CAAU,EAAE,MAAe,EAAE,WAAoB,EAAE,EAAE,CACpD,OAAO,CAAC,OAAO,CAAC,CAAC,EAAE,MAAM,EAAE,WAAW,CAAC,CAC1C,CAAC;IACF,GAAG,CAAC,cAAc,CAAC,WAAW,EAAE,CAAC,CAAU,EAAE,EAAE,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;IACtE,GAAG,CAAC,cAAc,CAAC,YAAY,EAAE,CAAC,CAAU,EAAE,EAAE,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;IACxE,GAAG,CAAC,cAAc,CAAC,WAAW,EAAE,CAAC,CAAU,EAAE,EAAE,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;IACtE,GAAG,CAAC,cAAc,CAAC,WAAW,EAAE,CAAC,CAAU,EAAE,EAAE,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;IACtE,GAAG,CAAC,cAAc,CAAC,MAAM,EAAE,CAAC,CAAU,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;AAC9D,CAAC"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Handlebars カスタムヘルパー用の純粋関数群
3
+ * 外部ライブラリ不使用
4
+ */
5
+ export declare function lowercase(value: unknown): string;
6
+ export declare function uppercase(value: unknown): string;
7
+ export declare function capitalize(value: unknown): string;
8
+ export declare function uncapitalize(value: unknown): string;
9
+ /** リテラル文字列置換(replaceAll)。正規表現は受け付けない(ReDoS 防止) */
10
+ export declare function replace(value: unknown, search: unknown, replacement: unknown): string;
11
+ export declare function camelCase(value: unknown): string;
12
+ export declare function pascalCase(value: unknown): string;
13
+ export declare function snakeCase(value: unknown): string;
14
+ export declare function kebabCase(value: unknown): string;
15
+ export declare function trim(value: unknown): string;
@@ -0,0 +1,63 @@
1
+ /**
2
+ * Handlebars カスタムヘルパー用の純粋関数群
3
+ * 外部ライブラリ不使用
4
+ */
5
+ /** 単語分割: `-`, `_`, `.`, スペース, camelCase 境界で分割 */
6
+ function splitWords(value) {
7
+ return value
8
+ .replace(/([a-z0-9])([A-Z])/g, "$1\0$2")
9
+ .replace(/([A-Z]+)([A-Z][a-z])/g, "$1\0$2")
10
+ .split(/[-_.\s\0]+/)
11
+ .filter((w) => w.length > 0);
12
+ }
13
+ export function lowercase(value) {
14
+ return String(value).toLowerCase();
15
+ }
16
+ export function uppercase(value) {
17
+ return String(value).toUpperCase();
18
+ }
19
+ export function capitalize(value) {
20
+ const s = String(value);
21
+ if (s.length === 0)
22
+ return s;
23
+ return s[0].toUpperCase() + s.slice(1);
24
+ }
25
+ export function uncapitalize(value) {
26
+ const s = String(value);
27
+ if (s.length === 0)
28
+ return s;
29
+ return s[0].toLowerCase() + s.slice(1);
30
+ }
31
+ /** リテラル文字列置換(replaceAll)。正規表現は受け付けない(ReDoS 防止) */
32
+ export function replace(value, search, replacement) {
33
+ const s = String(value);
34
+ const searchStr = String(search);
35
+ const replaceStr = String(replacement);
36
+ if (searchStr === "")
37
+ return s;
38
+ return s.split(searchStr).join(replaceStr);
39
+ }
40
+ export function camelCase(value) {
41
+ const words = splitWords(String(value));
42
+ return words
43
+ .map((w, i) => i === 0 ? w.toLowerCase() : w[0].toUpperCase() + w.slice(1).toLowerCase())
44
+ .join("");
45
+ }
46
+ export function pascalCase(value) {
47
+ const words = splitWords(String(value));
48
+ return words.map((w) => w[0].toUpperCase() + w.slice(1).toLowerCase()).join("");
49
+ }
50
+ export function snakeCase(value) {
51
+ return splitWords(String(value))
52
+ .map((w) => w.toLowerCase())
53
+ .join("_");
54
+ }
55
+ export function kebabCase(value) {
56
+ return splitWords(String(value))
57
+ .map((w) => w.toLowerCase())
58
+ .join("-");
59
+ }
60
+ export function trim(value) {
61
+ return String(value).trim();
62
+ }
63
+ //# sourceMappingURL=string-helpers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"string-helpers.js","sourceRoot":"","sources":["../../src/helpers/string-helpers.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import { MirError } from "./errors.js";
2
+ import type { Action } from "./snippet-schema.js";
3
+ export declare class ExitHookError extends MirError {
4
+ constructor();
5
+ }
6
+ export interface HookExecutionOptions {
7
+ onEcho?: (message: string) => void;
8
+ }
9
+ export declare function executeHooks(actions: Action[], variables: Record<string, unknown>, options?: HookExecutionOptions): Record<string, unknown>;
package/dist/hooks.js ADDED
@@ -0,0 +1,48 @@
1
+ import { MirError } from "./errors.js";
2
+ import { expandTemplate } from "./template-engine.js";
3
+ import { t } from "./i18n/index.js";
4
+ export class ExitHookError extends MirError {
5
+ constructor() {
6
+ super(t("error.exit-hook"));
7
+ this.name = "ExitHookError";
8
+ }
9
+ }
10
+ export function executeHooks(actions, variables, options) {
11
+ const vars = { ...variables };
12
+ for (const action of actions) {
13
+ if (action.echo !== undefined) {
14
+ const message = expandTemplate(action.echo, vars);
15
+ options?.onEcho?.(message);
16
+ }
17
+ if (action.exit !== undefined) {
18
+ if (action.if !== undefined) {
19
+ const condition = expandTemplate(action.if, vars);
20
+ if (isTruthy(condition)) {
21
+ throw new ExitHookError();
22
+ }
23
+ }
24
+ else if (action.exit) {
25
+ throw new ExitHookError();
26
+ }
27
+ }
28
+ if (action.input !== undefined) {
29
+ for (const [, inputDef] of Object.entries(action.input)) {
30
+ const answerTo = inputDef["answer-to"];
31
+ if (!answerTo)
32
+ continue;
33
+ if (inputDef.schema?.default !== undefined) {
34
+ vars[answerTo] = inputDef.schema.default;
35
+ }
36
+ else {
37
+ throw new MirError(t("error.hook-input-required", { key: answerTo }));
38
+ }
39
+ }
40
+ }
41
+ }
42
+ return vars;
43
+ }
44
+ function isTruthy(value) {
45
+ const trimmed = value.trim();
46
+ return trimmed !== "" && trimmed !== "false" && trimmed !== "0";
47
+ }
48
+ //# sourceMappingURL=hooks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hooks.js","sourceRoot":"","sources":["../src/hooks.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACvC,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,CAAC,EAAE,MAAM,iBAAiB,CAAC;AAGpC,MAAM,OAAO,aAAc,SAAQ,QAAQ;IACzC;QACE,KAAK,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC;QAC5B,IAAI,CAAC,IAAI,GAAG,eAAe,CAAC;IAC9B,CAAC;CACF;AAMD,MAAM,UAAU,YAAY,CAC1B,OAAiB,EACjB,SAAkC,EAClC,OAA8B;IAE9B,MAAM,IAAI,GAAG,EAAE,GAAG,SAAS,EAAE,CAAC;IAE9B,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC7B,IAAI,MAAM,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;YAC9B,MAAM,OAAO,GAAG,cAAc,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;YAClD,OAAO,EAAE,MAAM,EAAE,CAAC,OAAO,CAAC,CAAC;QAC7B,CAAC;QAED,IAAI,MAAM,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;YAC9B,IAAI,MAAM,CAAC,EAAE,KAAK,SAAS,EAAE,CAAC;gBAC5B,MAAM,SAAS,GAAG,cAAc,CAAC,MAAM,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;gBAClD,IAAI,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;oBACxB,MAAM,IAAI,aAAa,EAAE,CAAC;gBAC5B,CAAC;YACH,CAAC;iBAAM,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC;gBACvB,MAAM,IAAI,aAAa,EAAE,CAAC;YAC5B,CAAC;QACH,CAAC;QAED,IAAI,MAAM,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;YAC/B,KAAK,MAAM,CAAC,EAAE,QAAQ,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;gBACxD,MAAM,QAAQ,GAAG,QAAQ,CAAC,WAAW,CAAC,CAAC;gBACvC,IAAI,CAAC,QAAQ;oBAAE,SAAS;gBAExB,IAAI,QAAQ,CAAC,MAAM,EAAE,OAAO,KAAK,SAAS,EAAE,CAAC;oBAC3C,IAAI,CAAC,QAAQ,CAAC,GAAG,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC;gBAC3C,CAAC;qBAAM,CAAC;oBACN,MAAM,IAAI,QAAQ,CAChB,CAAC,CAAC,2BAA2B,EAAE,EAAE,GAAG,EAAE,QAAQ,EAAE,CAAC,CAClD,CAAC;gBACJ,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,QAAQ,CAAC,KAAa;IAC7B,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;IAC7B,OAAO,OAAO,KAAK,EAAE,IAAI,OAAO,KAAK,OAAO,IAAI,OAAO,KAAK,GAAG,CAAC;AAClE,CAAC"}
@@ -0,0 +1,6 @@
1
+ import type { MessageKey, MessageCatalog } from "./types.js";
2
+ export type Locale = "ja" | "en";
3
+ export declare function setLocale(locale: Locale): void;
4
+ export declare function getLocale(): Locale;
5
+ export declare function t(key: MessageKey, params?: Record<string, string | number>): string;
6
+ export type { MessageKey, MessageCatalog };
@@ -0,0 +1,20 @@
1
+ import { ja } from "./locales/ja.js";
2
+ import { en } from "./locales/en.js";
3
+ const catalogs = { ja, en };
4
+ let currentLocale = "ja";
5
+ export function setLocale(locale) {
6
+ currentLocale = locale;
7
+ }
8
+ export function getLocale() {
9
+ return currentLocale;
10
+ }
11
+ export function t(key, params) {
12
+ let message = catalogs[currentLocale][key];
13
+ if (params) {
14
+ for (const [k, v] of Object.entries(params)) {
15
+ message = message.replaceAll(`{${k}}`, String(v));
16
+ }
17
+ }
18
+ return message;
19
+ }
20
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/i18n/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,EAAE,EAAE,MAAM,iBAAiB,CAAC;AACrC,OAAO,EAAE,EAAE,EAAE,MAAM,iBAAiB,CAAC;AAIrC,MAAM,QAAQ,GAAmC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC;AAE5D,IAAI,aAAa,GAAW,IAAI,CAAC;AAEjC,MAAM,UAAU,SAAS,CAAC,MAAc;IACtC,aAAa,GAAG,MAAM,CAAC;AACzB,CAAC;AAED,MAAM,UAAU,SAAS;IACvB,OAAO,aAAa,CAAC;AACvB,CAAC;AAED,MAAM,UAAU,CAAC,CACf,GAAe,EACf,MAAwC;IAExC,IAAI,OAAO,GAAG,QAAQ,CAAC,aAAa,CAAC,CAAC,GAAG,CAAC,CAAC;IAC3C,IAAI,MAAM,EAAE,CAAC;QACX,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;YAC5C,OAAO,GAAG,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;QACpD,CAAC;IACH,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC"}
@@ -0,0 +1,2 @@
1
+ import type { MessageCatalog } from "../types.js";
2
+ export declare const en: MessageCatalog;