@navneet_25/tempjs 1.1.0 → 3.0.0
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.
- package/README.md +800 -35
- package/cli/brand-manager.js +277 -78
- package/cli/config.js +22 -1
- package/cli/copy.js +4 -18
- package/cli/db-setup.js +170 -49
- package/cli/doctor.js +393 -0
- package/cli/fetch-core-modules.js +130 -0
- package/cli/fetch.js +47 -29
- package/cli/file-tree.js +113 -0
- package/cli/fs-ignore.js +60 -0
- package/cli/index.js +274 -112
- package/cli/info.js +115 -0
- package/cli/init-options.js +209 -0
- package/cli/module-manager.js +168 -0
- package/cli/parse-args.js +177 -0
- package/cli/progress.js +33 -0
- package/cli/project-stamp.js +69 -0
- package/cli/prompt.js +19 -0
- package/cli/template-resolver.js +48 -0
- package/cli/theme-manager.js +28 -2
- package/cli/update.js +227 -0
- package/cli/version-manager.js +518 -0
- package/package.json +31 -4
- package/packages/core/modules/README.md +72 -0
- package/packages/core/modules/blog-compose/app/admin/components/blog-compose-form.ts +44 -0
- package/packages/core/modules/blog-compose/app/admin/hooks/useBlogPosts.ts +103 -0
- package/packages/core/modules/blog-compose/app/admin/panels/BlogComposePanel.tsx +388 -0
- package/packages/core/modules/blog-compose/app/api/blog-posts/[id]/route.ts +29 -0
- package/packages/core/modules/blog-compose/app/api/blog-posts/route.ts +21 -0
- package/packages/core/modules/blog-compose/app/blog/[slug]/page.tsx +79 -0
- package/packages/core/modules/blog-compose/app/blog/layout.tsx +22 -0
- package/packages/core/modules/blog-compose/app/blog/page.tsx +102 -0
- package/packages/core/modules/blog-compose/app/components/BlogSection.tsx +74 -0
- package/packages/core/modules/blog-compose/app/components/BlogShell.tsx +36 -0
- package/packages/core/modules/blog-compose/app/components/BlogSidebar.tsx +112 -0
- package/packages/core/modules/blog-compose/lib/blog/compose/annotate-text.tsx +103 -0
- package/packages/core/modules/blog-compose/lib/blog/compose/blocks/media-blocks.tsx +97 -0
- package/packages/core/modules/blog-compose/lib/blog/compose/blocks/text-blocks.tsx +115 -0
- package/packages/core/modules/blog-compose/lib/blog/compose/index.ts +21 -0
- package/packages/core/modules/blog-compose/lib/blog/compose/interpreter.tsx +55 -0
- package/packages/core/modules/blog-compose/lib/blog/compose/registry.ts +276 -0
- package/packages/core/modules/blog-compose/lib/blog/compose/types.ts +128 -0
- package/packages/core/modules/blog-compose/lib/blog/register-sitemap.ts +18 -0
- package/packages/core/modules/blog-compose/lib/controllers/BlogComposeController.ts +2 -0
- package/packages/core/modules/blog-compose/lib/features/blog-compose/blog-compose.controller.ts +78 -0
- package/packages/core/modules/blog-compose/lib/features/blog-compose/blog-compose.repository.ts +78 -0
- package/packages/core/modules/blog-compose/lib/features/blog-compose/blog-compose.service.ts +72 -0
- package/packages/core/modules/blog-compose/lib/features/blog-compose/blog-compose.types.ts +20 -0
- package/packages/core/modules/blog-compose/lib/features/blog-compose/index.ts +7 -0
- package/packages/core/modules/blog-compose/prisma/blog-compose.prisma +13 -0
- package/packages/core/modules/enquiry-modal/app/components/EnquiryModal.tsx +308 -0
- package/packages/core/modules/footer/app/components/Footer.tsx +127 -0
- package/packages/core/modules/gallery/app/admin/components/GalleryFormModal.tsx +132 -0
- package/packages/core/modules/gallery/app/admin/components/GalleryList.tsx +142 -0
- package/packages/core/modules/gallery/app/admin/hooks/useGallery.ts +72 -0
- package/packages/core/modules/gallery/app/api/gallery/[id]/route.ts +29 -0
- package/packages/core/modules/gallery/app/api/gallery/route.ts +22 -0
- package/packages/core/modules/gallery/app/components/GallerySection.tsx +92 -0
- package/packages/core/modules/gallery/app/gallery/layout.tsx +12 -0
- package/packages/core/modules/gallery/app/gallery/page.tsx +179 -0
- package/packages/core/modules/gallery/lib/controllers/GalleryController.ts +2 -0
- package/packages/core/modules/gallery/lib/features/gallery/gallery.controller.ts +78 -0
- package/packages/core/modules/gallery/lib/features/gallery/gallery.repository.ts +55 -0
- package/packages/core/modules/gallery/lib/features/gallery/gallery.service.ts +43 -0
- package/packages/core/modules/gallery/lib/features/gallery/gallery.types.ts +17 -0
- package/packages/core/modules/gallery/lib/features/gallery/index.ts +4 -0
- package/packages/core/modules/gallery/prisma/gallery.prisma +11 -0
- package/packages/core/modules/hero-simple/app/components/Hero.tsx +160 -0
- package/packages/core/modules/legal-pages/app/components/LegalDocumentPage.tsx +61 -0
- package/packages/core/modules/legal-pages/app/privacy-policy/page.tsx +19 -0
- package/packages/core/modules/legal-pages/app/terms-and-conditions/page.tsx +19 -0
- package/packages/core/modules/reviews/app/admin/components/ReviewFormModal.tsx +110 -0
- package/packages/core/modules/reviews/app/admin/components/ReviewsList.tsx +116 -0
- package/packages/core/modules/reviews/app/admin/hooks/useReviews.ts +70 -0
- package/packages/core/modules/reviews/app/api/reviews/[id]/route.ts +29 -0
- package/packages/core/modules/reviews/app/api/reviews/route.ts +17 -0
- package/packages/core/modules/reviews/app/components/ReviewsSection.tsx +100 -0
- package/packages/core/modules/reviews/lib/controllers/ReviewController.ts +2 -0
- package/packages/core/modules/reviews/lib/features/reviews/index.ts +3 -0
- package/packages/core/modules/reviews/lib/features/reviews/review.controller.ts +64 -0
- package/packages/core/modules/reviews/lib/features/reviews/review.repository.ts +50 -0
- package/packages/core/modules/reviews/lib/features/reviews/review.service.ts +38 -0
- package/packages/core/modules/reviews/prisma/reviews.prisma +9 -0
- package/packages/core/modules/seo/app/components/SiteJsonLd.tsx +16 -0
- package/packages/core/modules/seo/app/robots.ts +30 -0
- package/packages/core/modules/seo/app/sitemap.ts +9 -0
- package/packages/core/modules/seo/lib/seo/index.ts +5 -0
- package/packages/core/modules/seo/lib/seo/json-ld.ts +128 -0
- package/packages/core/modules/seo/lib/seo/metadata.ts +65 -0
- package/packages/core/modules/seo/lib/seo/sitemap.ts +82 -0
- package/packages/core/modules/seo/lib/seo/types.ts +30 -0
- package/packages/core/modules/seo/lib/seo/urls.ts +27 -0
- package/packages/core/modules/theme-modes/app/components/ThemeModeInit.tsx +24 -0
- package/packages/core/modules/theme-modes/app/components/ThemeModeToggle.tsx +58 -0
- package/packages/core/modules.json +140 -0
- package/packages/core/prisma/schema.prisma +33 -0
- package/scripts/module-installer-core.mjs +657 -0
- package/scripts/template-modules-admin.mjs +366 -0
- package/scripts/template-modules-home.mjs +120 -0
- package/templates.json +188 -3
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { removeDirectory } from "./copy.js";
|
|
2
|
+
import { fetchTemplateFromGitHub, loadLocalTemplate } from "./fetch.js";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* @typedef {{
|
|
6
|
+
* templateRoot: string,
|
|
7
|
+
* cleanupDir: string,
|
|
8
|
+
* stats: import('./fetch.js').FetchStats,
|
|
9
|
+
* release: () => void
|
|
10
|
+
* }} ResolvedTemplate
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Resolve template source from local package or remote GitHub tarball.
|
|
15
|
+
* @param {{
|
|
16
|
+
* repo: import('./config.js').RepositoryConfig,
|
|
17
|
+
* packageRoot: string,
|
|
18
|
+
* templateDirectory: string,
|
|
19
|
+
* useRemote: boolean
|
|
20
|
+
* }} options
|
|
21
|
+
* @returns {Promise<ResolvedTemplate>}
|
|
22
|
+
*/
|
|
23
|
+
export async function resolveTemplateSource(options) {
|
|
24
|
+
const { repo, packageRoot, templateDirectory, useRemote } = options;
|
|
25
|
+
|
|
26
|
+
let result = null;
|
|
27
|
+
|
|
28
|
+
if (!useRemote) {
|
|
29
|
+
result = await loadLocalTemplate(packageRoot, repo.templatesPath, templateDirectory);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
if (!result) {
|
|
33
|
+
result = await fetchTemplateFromGitHub(repo, templateDirectory);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const cleanupDir = result.cleanupDir;
|
|
37
|
+
|
|
38
|
+
return {
|
|
39
|
+
templateRoot: result.templateRoot,
|
|
40
|
+
cleanupDir,
|
|
41
|
+
stats: result.stats,
|
|
42
|
+
release: () => {
|
|
43
|
+
if (cleanupDir) {
|
|
44
|
+
removeDirectory(cleanupDir);
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
};
|
|
48
|
+
}
|
package/cli/theme-manager.js
CHANGED
|
@@ -152,6 +152,26 @@ export function getSavedConfig(targetDir) {
|
|
|
152
152
|
return {};
|
|
153
153
|
}
|
|
154
154
|
|
|
155
|
+
export function resolveThemeId(id) {
|
|
156
|
+
const theme = THEMES.find((t) => t.id === id);
|
|
157
|
+
if (!theme) {
|
|
158
|
+
throw new Error(
|
|
159
|
+
`Unknown theme: ${id}. Valid options: ${THEMES.map((t) => t.id).join(", ")}`
|
|
160
|
+
);
|
|
161
|
+
}
|
|
162
|
+
return theme.id;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
export function resolveFontId(id) {
|
|
166
|
+
const font = FONTS.find((f) => f.id === id);
|
|
167
|
+
if (!font) {
|
|
168
|
+
throw new Error(
|
|
169
|
+
`Unknown font: ${id}. Valid options: ${FONTS.map((f) => f.id).join(", ")}`
|
|
170
|
+
);
|
|
171
|
+
}
|
|
172
|
+
return font.id;
|
|
173
|
+
}
|
|
174
|
+
|
|
155
175
|
async function promptSelection(options, promptText, defaultValue) {
|
|
156
176
|
const rl = createInterface({ input, output });
|
|
157
177
|
try {
|
|
@@ -179,11 +199,17 @@ async function promptSelection(options, promptText, defaultValue) {
|
|
|
179
199
|
}
|
|
180
200
|
}
|
|
181
201
|
|
|
182
|
-
export async function promptTheme(currentThemeId = "theme1") {
|
|
202
|
+
export async function promptTheme(currentThemeId = "theme1", options = {}) {
|
|
203
|
+
if (options.yes || options.theme) {
|
|
204
|
+
return resolveThemeId(options.theme || currentThemeId || "theme1");
|
|
205
|
+
}
|
|
183
206
|
return promptSelection(THEMES, "Available Themes:", currentThemeId);
|
|
184
207
|
}
|
|
185
208
|
|
|
186
|
-
export async function promptFont(currentFontId = "default") {
|
|
209
|
+
export async function promptFont(currentFontId = "default", options = {}) {
|
|
210
|
+
if (options.yes || options.font) {
|
|
211
|
+
return resolveFontId(options.font || currentFontId || "default");
|
|
212
|
+
}
|
|
187
213
|
return promptSelection(FONTS, "Available Font combinations:", currentFontId);
|
|
188
214
|
}
|
|
189
215
|
|
package/cli/update.js
ADDED
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
import { cpSync, existsSync, mkdirSync } from "node:fs";
|
|
2
|
+
import { dirname, join } from "node:path";
|
|
3
|
+
import { loadManifest, resolveRepositoryConfig, getPackageRoot } from "./config.js";
|
|
4
|
+
import { isUpdateProtected, shouldSkipFileName } from "./fs-ignore.js";
|
|
5
|
+
import {
|
|
6
|
+
collectFileHashes,
|
|
7
|
+
diffTemplateTrees,
|
|
8
|
+
hashFileContents,
|
|
9
|
+
} from "./file-tree.js";
|
|
10
|
+
import { readProjectStamp, writeProjectStamp } from "./project-stamp.js";
|
|
11
|
+
import { confirmYesNo } from "./prompt.js";
|
|
12
|
+
import { resolveTemplateSource } from "./template-resolver.js";
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* @param {import('./file-tree.js').UpdateDiff} diff
|
|
16
|
+
* @param {{
|
|
17
|
+
* projectVersion: string,
|
|
18
|
+
* latestVersion: string,
|
|
19
|
+
* templateName: string
|
|
20
|
+
* }} meta
|
|
21
|
+
*/
|
|
22
|
+
export function printUpdateReport(diff, meta) {
|
|
23
|
+
console.log(`\nTemplate update report: ${meta.templateName}`);
|
|
24
|
+
console.log(` Project version: ${meta.projectVersion}`);
|
|
25
|
+
console.log(` Latest version: ${meta.latestVersion}`);
|
|
26
|
+
console.log("");
|
|
27
|
+
|
|
28
|
+
if (
|
|
29
|
+
diff.newFiles.length === 0 &&
|
|
30
|
+
diff.safeUpdates.length === 0 &&
|
|
31
|
+
diff.conflicts.length === 0 &&
|
|
32
|
+
diff.removedFromTemplate.length === 0
|
|
33
|
+
) {
|
|
34
|
+
console.log("Your project is up to date with the latest template.");
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
if (diff.newFiles.length > 0) {
|
|
39
|
+
console.log(`New files in template (${diff.newFiles.length}):`);
|
|
40
|
+
diff.newFiles.slice(0, 25).forEach((p) => console.log(` + ${p}`));
|
|
41
|
+
if (diff.newFiles.length > 25) {
|
|
42
|
+
console.log(` ... and ${diff.newFiles.length - 25} more`);
|
|
43
|
+
}
|
|
44
|
+
console.log("");
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
if (diff.safeUpdates.length > 0) {
|
|
48
|
+
console.log(`Safe updates (${diff.safeUpdates.length}) — template changed, you did not edit:`);
|
|
49
|
+
diff.safeUpdates.slice(0, 25).forEach((p) => console.log(` ~ ${p}`));
|
|
50
|
+
if (diff.safeUpdates.length > 25) {
|
|
51
|
+
console.log(` ... and ${diff.safeUpdates.length - 25} more`);
|
|
52
|
+
}
|
|
53
|
+
console.log("");
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
if (diff.conflicts.length > 0) {
|
|
57
|
+
console.log(`Conflicts (${diff.conflicts.length}) — you modified these files:`);
|
|
58
|
+
diff.conflicts.slice(0, 25).forEach((p) => console.log(` ! ${p}`));
|
|
59
|
+
if (diff.conflicts.length > 25) {
|
|
60
|
+
console.log(` ... and ${diff.conflicts.length - 25} more`);
|
|
61
|
+
}
|
|
62
|
+
console.log("");
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
if (meta.projectVersion !== meta.latestVersion) {
|
|
66
|
+
console.log(
|
|
67
|
+
`Version ${meta.projectVersion} → ${meta.latestVersion}: see CHANGELOG.md for release notes.`
|
|
68
|
+
);
|
|
69
|
+
console.log("");
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
if (diff.removedFromTemplate.length > 0) {
|
|
73
|
+
console.log(`Removed from template (${diff.removedFromTemplate.length}) — not deleted locally:`);
|
|
74
|
+
diff.removedFromTemplate.slice(0, 15).forEach((p) => console.log(` - ${p}`));
|
|
75
|
+
if (diff.removedFromTemplate.length > 15) {
|
|
76
|
+
console.log(` ... and ${diff.removedFromTemplate.length - 15} more`);
|
|
77
|
+
}
|
|
78
|
+
console.log("");
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
if (diff.upToDate.length > 0) {
|
|
82
|
+
console.log(`${diff.upToDate.length} file(s) already match the latest template.\n`);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* @param {string} sourcePath
|
|
88
|
+
* @param {string} targetPath
|
|
89
|
+
*/
|
|
90
|
+
export function copyTemplateFile(sourcePath, targetPath) {
|
|
91
|
+
mkdirSync(dirname(targetPath), { recursive: true });
|
|
92
|
+
cpSync(sourcePath, targetPath, { force: true });
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* @param {string} projectDir
|
|
97
|
+
* @param {import('./parse-args.js').CliFlags} flags
|
|
98
|
+
* @param {{ checkOnly: boolean }} mode
|
|
99
|
+
*/
|
|
100
|
+
export async function runUpdate(projectDir, flags, mode) {
|
|
101
|
+
const stamp = readProjectStamp(projectDir);
|
|
102
|
+
|
|
103
|
+
if (!stamp) {
|
|
104
|
+
console.error("No .tempjs.json found in this directory.");
|
|
105
|
+
console.error("Run `tempjs <template-id>` here first, or this project was not created with tempjs.");
|
|
106
|
+
process.exitCode = 1;
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
const manifest = loadManifest();
|
|
111
|
+
const entry = manifest.templates[stamp.template];
|
|
112
|
+
if (!entry) {
|
|
113
|
+
console.error(`Unknown template in .tempjs.json: ${stamp.template}`);
|
|
114
|
+
process.exitCode = 1;
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
const repo = resolveRepositoryConfig(manifest.repository);
|
|
119
|
+
const packageRoot = getPackageRoot();
|
|
120
|
+
const useRemote =
|
|
121
|
+
flags.remote ||
|
|
122
|
+
process.env.TEMPLATE_USE_REMOTE === "1" ||
|
|
123
|
+
process.env.TEMPLATE_USE_REMOTE === "true";
|
|
124
|
+
|
|
125
|
+
const latestVersion = entry.version ?? "0.0.0";
|
|
126
|
+
let resolved = null;
|
|
127
|
+
|
|
128
|
+
try {
|
|
129
|
+
resolved = await resolveTemplateSource({
|
|
130
|
+
repo,
|
|
131
|
+
packageRoot,
|
|
132
|
+
templateDirectory: entry.directory,
|
|
133
|
+
useRemote,
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
const latestHashes = collectFileHashes(resolved.templateRoot);
|
|
137
|
+
const baselineHashes = stamp.fileHashes ?? {};
|
|
138
|
+
const currentHashes = {};
|
|
139
|
+
|
|
140
|
+
for (const path of Object.keys(latestHashes)) {
|
|
141
|
+
const projectPath = join(projectDir, path);
|
|
142
|
+
if (existsSync(projectPath) && !shouldSkipFileName(path.split("/").pop() ?? "")) {
|
|
143
|
+
currentHashes[path] = hashFileContents(projectPath);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
const diff = diffTemplateTrees(baselineHashes, currentHashes, latestHashes);
|
|
148
|
+
|
|
149
|
+
printUpdateReport(diff, {
|
|
150
|
+
projectVersion: stamp.templateVersion,
|
|
151
|
+
latestVersion,
|
|
152
|
+
templateName: entry.name,
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
if (mode.checkOnly) {
|
|
156
|
+
if (stamp.templateVersion !== latestVersion) {
|
|
157
|
+
const changelogPath = join(projectDir, "CHANGELOG.md");
|
|
158
|
+
console.log("Run `tempjs update --merge` to apply non-conflicting template updates.");
|
|
159
|
+
if (existsSync(changelogPath)) {
|
|
160
|
+
console.log(`See CHANGELOG.md for what changed in v${latestVersion}.`);
|
|
161
|
+
} else {
|
|
162
|
+
console.log(
|
|
163
|
+
`After updating, read CHANGELOG.md in the template for v${latestVersion} changes.`
|
|
164
|
+
);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
const pathsToApply = [...diff.newFiles, ...diff.safeUpdates].filter(
|
|
171
|
+
(path) => !isUpdateProtected(path)
|
|
172
|
+
);
|
|
173
|
+
|
|
174
|
+
const skippedProtected = [...diff.newFiles, ...diff.safeUpdates].filter((path) =>
|
|
175
|
+
isUpdateProtected(path)
|
|
176
|
+
);
|
|
177
|
+
if (skippedProtected.length > 0) {
|
|
178
|
+
console.log(`Skipping ${skippedProtected.length} protected path(s) (brand, .env, etc.).`);
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
if (pathsToApply.length === 0) {
|
|
182
|
+
if (diff.conflicts.length > 0) {
|
|
183
|
+
console.log("\nNo safe updates to apply. Resolve conflicts manually.");
|
|
184
|
+
}
|
|
185
|
+
return;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
const confirmed = await confirmYesNo(
|
|
189
|
+
`\nApply ${pathsToApply.length} non-conflicting update(s)? [y/N] `,
|
|
190
|
+
flags.yes
|
|
191
|
+
);
|
|
192
|
+
|
|
193
|
+
if (!confirmed) {
|
|
194
|
+
console.log("Aborted.");
|
|
195
|
+
return;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
for (const relPath of pathsToApply) {
|
|
199
|
+
const from = join(resolved.templateRoot, relPath);
|
|
200
|
+
const to = join(projectDir, relPath);
|
|
201
|
+
copyTemplateFile(from, to);
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
await writeProjectStamp(projectDir, {
|
|
205
|
+
templateId: stamp.template,
|
|
206
|
+
templateVersion: latestVersion,
|
|
207
|
+
templateDirectory: entry.directory,
|
|
208
|
+
repository: `${repo.owner}/${repo.repo}`,
|
|
209
|
+
branch: repo.branch,
|
|
210
|
+
sourceDir: resolved.templateRoot,
|
|
211
|
+
isUpdate: true,
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
console.log(`\nApplied ${pathsToApply.length} update(s). Project stamped at template v${latestVersion}.`);
|
|
215
|
+
|
|
216
|
+
if (diff.conflicts.length > 0) {
|
|
217
|
+
console.log(`${diff.conflicts.length} conflict(s) still need manual review.`);
|
|
218
|
+
}
|
|
219
|
+
} catch (error) {
|
|
220
|
+
console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
|
|
221
|
+
process.exitCode = 1;
|
|
222
|
+
} finally {
|
|
223
|
+
if (resolved) {
|
|
224
|
+
resolved.release();
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
}
|