@devbro/pashmak 0.1.55 → 0.1.57
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/dist/cjs/app/console/DefaultCommand.js +52 -0
- package/dist/cjs/app/console/KeyGenerateCommand.js +52 -0
- package/dist/cjs/app/console/StartCommand.js +52 -0
- package/dist/cjs/app/console/generate/GenerateApiDocsCommand.js +52 -0
- package/dist/cjs/app/console/generate/GenerateControllerCommand.js +52 -0
- package/dist/cjs/app/console/generate/index.js +52 -0
- package/dist/cjs/app/console/index.js +320 -70
- package/dist/cjs/app/console/migrate/GenerateMigrateCommand.js +52 -0
- package/dist/cjs/app/console/migrate/MigrateCommand.js +52 -0
- package/dist/cjs/app/console/migrate/MigrateRollbackCommand.js +52 -0
- package/dist/cjs/app/console/migrate/index.js +52 -0
- package/dist/cjs/app/console/project/CreateProjectCommand.js +263 -65
- package/dist/cjs/app/console/project/base_project/src/config/caches.ts.tpl +11 -1
- package/dist/cjs/app/console/project/base_project/src/config/databases.ts.tpl +8 -6
- package/dist/cjs/app/console/project/base_project/src/config/default.mts.tpl +13 -20
- package/dist/cjs/app/console/project/base_project/src/config/loggers.ts.tpl +13 -3
- package/dist/cjs/app/console/project/base_project/src/config/storages.ts.tpl +1 -2
- package/dist/cjs/app/console/project/base_project/src/initialize.ts.tpl +48 -16
- package/dist/cjs/app/console/project/base_project/src/routes.ts.tpl +2 -2
- package/dist/cjs/app/console/queue/GenerateQueueMigrateCommand.js +52 -0
- package/dist/cjs/bin/pashmak_cli.js +265 -66
- package/dist/cjs/cache/MultiCache.js +71 -0
- package/dist/cjs/{cache.js → cache/cache.js} +54 -2
- package/dist/cjs/facades.js +52 -0
- package/dist/cjs/factories.js +52 -0
- package/dist/cjs/http.js +52 -0
- package/dist/cjs/index.js +1900 -2056
- package/dist/cjs/middlewares.js +112 -2
- package/dist/cjs/queue.js +52 -0
- package/dist/esm/app/console/project/CreateProjectCommand.d.mts +15 -2
- package/dist/esm/app/console/project/CreateProjectCommand.mjs +265 -67
- package/dist/esm/app/console/project/CreateProjectCommand.mjs.map +1 -1
- package/dist/esm/app/console/project/base_project/src/config/caches.ts.tpl +11 -1
- package/dist/esm/app/console/project/base_project/src/config/databases.ts.tpl +8 -6
- package/dist/esm/app/console/project/base_project/src/config/default.mts.tpl +13 -20
- package/dist/esm/app/console/project/base_project/src/config/loggers.ts.tpl +13 -3
- package/dist/esm/app/console/project/base_project/src/config/storages.ts.tpl +1 -2
- package/dist/esm/app/console/project/base_project/src/initialize.ts.tpl +48 -16
- package/dist/esm/app/console/project/base_project/src/routes.ts.tpl +2 -2
- package/dist/esm/bin/pashmak_cli.mjs +2 -1
- package/dist/esm/bin/pashmak_cli.mjs.map +1 -1
- package/dist/esm/cache/MultiCache.d.mts +14 -0
- package/dist/esm/cache/MultiCache.mjs +47 -0
- package/dist/esm/cache/MultiCache.mjs.map +1 -0
- package/dist/esm/{cache.mjs → cache/cache.mjs} +1 -1
- package/dist/esm/cache/cache.mjs.map +1 -0
- package/dist/esm/config.mjs.map +1 -1
- package/dist/esm/factories.mjs +9 -0
- package/dist/esm/factories.mjs.map +1 -1
- package/dist/esm/index.d.mts +1 -7
- package/dist/esm/index.mjs +1 -32
- package/dist/esm/index.mjs.map +1 -1
- package/dist/esm/middlewares.d.mts +12 -1
- package/dist/esm/middlewares.mjs +52 -0
- package/dist/esm/middlewares.mjs.map +1 -1
- package/package.json +4 -2
- package/dist/cjs/app/console/project/base_project/package.json.tpl +0 -74
- package/dist/cjs/app/console/project/base_project/src/config/test.ts.tpl +0 -1
- package/dist/esm/app/console/project/base_project/package.json.tpl +0 -74
- package/dist/esm/app/console/project/base_project/src/config/test.ts.tpl +0 -1
- package/dist/esm/cache.mjs.map +0 -1
- /package/dist/cjs/app/console/project/base_project/src/config/{mailer.ts.tpl → mailers.ts.tpl} +0 -0
- /package/dist/esm/app/console/project/base_project/src/config/{mailer.ts.tpl → mailers.ts.tpl} +0 -0
- /package/dist/esm/{cache.d.mts → cache/cache.d.mts} +0 -0
|
@@ -592,6 +592,51 @@ var DatabaseTransport = class {
|
|
|
592
592
|
// src/factories.mts
|
|
593
593
|
var import_neko_cache = require("@devbro/neko-cache");
|
|
594
594
|
var import_neko_storage = require("@devbro/neko-storage");
|
|
595
|
+
|
|
596
|
+
// src/cache/MultiCache.mts
|
|
597
|
+
var MultiCache = class {
|
|
598
|
+
constructor(caches) {
|
|
599
|
+
this.caches = caches;
|
|
600
|
+
}
|
|
601
|
+
static {
|
|
602
|
+
__name(this, "MultiCache");
|
|
603
|
+
}
|
|
604
|
+
async get(key) {
|
|
605
|
+
for (const cache2 of this.caches) {
|
|
606
|
+
const value = await cache2.get(key);
|
|
607
|
+
if (value !== void 0) {
|
|
608
|
+
return value;
|
|
609
|
+
}
|
|
610
|
+
}
|
|
611
|
+
return void 0;
|
|
612
|
+
}
|
|
613
|
+
async put(key, value, ttl) {
|
|
614
|
+
await Promise.all(this.caches.map((cache2) => cache2.put(key, value, ttl)));
|
|
615
|
+
}
|
|
616
|
+
async delete(key) {
|
|
617
|
+
await Promise.all(this.caches.map((cache2) => cache2.delete(key)));
|
|
618
|
+
}
|
|
619
|
+
async has(key) {
|
|
620
|
+
for (const cache2 of this.caches) {
|
|
621
|
+
if (await cache2.has(key)) {
|
|
622
|
+
return true;
|
|
623
|
+
}
|
|
624
|
+
}
|
|
625
|
+
return false;
|
|
626
|
+
}
|
|
627
|
+
async increment(key, amount) {
|
|
628
|
+
let rc = void 0;
|
|
629
|
+
for (const cache2 of this.caches) {
|
|
630
|
+
let rc2 = await cache2.increment(key, amount);
|
|
631
|
+
if (rc === void 0) {
|
|
632
|
+
rc = rc2;
|
|
633
|
+
}
|
|
634
|
+
}
|
|
635
|
+
return rc;
|
|
636
|
+
}
|
|
637
|
+
};
|
|
638
|
+
|
|
639
|
+
// src/factories.mts
|
|
595
640
|
var FlexibleFactory = class {
|
|
596
641
|
static {
|
|
597
642
|
__name(this, "FlexibleFactory");
|
|
@@ -662,6 +707,13 @@ CacheProviderFactory.register("redis", (opt) => {
|
|
|
662
707
|
CacheProviderFactory.register("file", (opt) => {
|
|
663
708
|
return new import_neko_cache.FileCacheProvider(opt);
|
|
664
709
|
});
|
|
710
|
+
CacheProviderFactory.register("multi", (opt) => {
|
|
711
|
+
const caches = [];
|
|
712
|
+
for (const c of opt.caches) {
|
|
713
|
+
caches.push(cache(c));
|
|
714
|
+
}
|
|
715
|
+
return new MultiCache(caches);
|
|
716
|
+
});
|
|
665
717
|
CacheProviderFactory.register("disabled", (opt) => {
|
|
666
718
|
return new import_neko_cache.DisabledCacheProvider();
|
|
667
719
|
});
|
|
@@ -46,24 +46,17 @@ var CreateProjectCommand = class extends import_clipanion.Command {
|
|
|
46
46
|
category: `Project`,
|
|
47
47
|
description: `Create a new project`,
|
|
48
48
|
details: `
|
|
49
|
-
This command creates a new project
|
|
50
|
-
|
|
49
|
+
This command creates a new project interactively.
|
|
50
|
+
You will be prompted for the project path and other configuration options.
|
|
51
51
|
`,
|
|
52
|
-
examples: [
|
|
53
|
-
[
|
|
54
|
-
`Create a new project in specified directory`,
|
|
55
|
-
`create project --path /path/to/my-project --git`
|
|
56
|
-
],
|
|
57
|
-
[
|
|
58
|
-
`Create a new project at a specific path with git initialized`,
|
|
59
|
-
`create project --path /path/to/my-project --git`
|
|
60
|
-
]
|
|
61
|
-
]
|
|
62
|
-
});
|
|
63
|
-
projectPath = import_clipanion.Option.String("--path", { required: true });
|
|
64
|
-
git = import_clipanion.Option.Boolean(`--git`, false, {
|
|
65
|
-
description: `Initialize a git repository in the new project`
|
|
52
|
+
examples: [[`Create a new project`, `create project`]]
|
|
66
53
|
});
|
|
54
|
+
projectPath = "";
|
|
55
|
+
executor = "";
|
|
56
|
+
packageManager = "";
|
|
57
|
+
linter = "";
|
|
58
|
+
validation_library = "";
|
|
59
|
+
database_type = "";
|
|
67
60
|
async folderExists(folderPath) {
|
|
68
61
|
try {
|
|
69
62
|
const stats = await fs.stat(folderPath);
|
|
@@ -76,14 +69,148 @@ var CreateProjectCommand = class extends import_clipanion.Command {
|
|
|
76
69
|
}
|
|
77
70
|
}
|
|
78
71
|
async execute() {
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
72
|
+
await this.setupProjectPath();
|
|
73
|
+
await this.setupGit();
|
|
74
|
+
await this.setupExecutorAndPackageManager();
|
|
75
|
+
await this.setupLinter();
|
|
76
|
+
await this.setupGeneralPackages();
|
|
77
|
+
await this.setupBaseProject();
|
|
78
|
+
await this.installPackages();
|
|
79
|
+
}
|
|
80
|
+
async processTplFolder(src, dest, data = {}) {
|
|
81
|
+
const files = await fs.readdir(src, { withFileTypes: true });
|
|
82
|
+
for (const file of files) {
|
|
83
|
+
const srcPath = import_path.default.join(src, file.name);
|
|
84
|
+
const destPath = file.isFile() && file.name.endsWith(".tpl") ? import_path.default.join(dest, file.name.substring(0, file.name.length - 4)) : import_path.default.join(dest, file.name);
|
|
85
|
+
if (file.isDirectory()) {
|
|
86
|
+
await fs.mkdir(destPath, { recursive: true });
|
|
87
|
+
await this.processTplFolder(srcPath, destPath, data);
|
|
88
|
+
} else if (file.name.endsWith(".tpl")) {
|
|
89
|
+
await this.processTplFile(srcPath, destPath, data);
|
|
90
|
+
} else {
|
|
91
|
+
throw new Error(
|
|
92
|
+
"unexpected non tpl file: " + srcPath + " " + file.name
|
|
93
|
+
);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
async processTplFile(src, dest, data = {}) {
|
|
98
|
+
import_handlebars.default.registerHelper("eq", (a, b) => a === b);
|
|
99
|
+
const compiledTemplate = import_handlebars.default.compile(
|
|
100
|
+
(await fs.readFile(src)).toString()
|
|
101
|
+
);
|
|
102
|
+
const template = await compiledTemplate(data);
|
|
103
|
+
await fs.writeFile(dest, template);
|
|
104
|
+
}
|
|
105
|
+
async setupProjectPath() {
|
|
106
|
+
const pathInput = await (0, import_prompts.input)({
|
|
107
|
+
message: "Enter project path (leave empty to use current directory):",
|
|
108
|
+
default: ""
|
|
109
|
+
});
|
|
110
|
+
this.projectPath = pathInput.trim() ? import_path.default.resolve(pathInput.trim()) : process.cwd();
|
|
111
|
+
await fs.mkdir(this.projectPath, { recursive: true });
|
|
112
|
+
const files = await fs.readdir(this.projectPath);
|
|
113
|
+
if (files.length > 0) {
|
|
114
|
+
throw new Error(
|
|
115
|
+
`Directory ${this.projectPath} is not empty. Please use an empty directory.`
|
|
116
|
+
);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
async setupExecutorAndPackageManager() {
|
|
120
|
+
this.executor = await (0, import_prompts.select)({
|
|
121
|
+
message: "Select a TypeScript executor",
|
|
122
|
+
choices: [
|
|
123
|
+
{
|
|
124
|
+
name: "Bun",
|
|
125
|
+
value: "bun",
|
|
126
|
+
description: "Fast all-in-one JavaScript runtime"
|
|
127
|
+
},
|
|
128
|
+
{
|
|
129
|
+
name: "TSX",
|
|
130
|
+
value: "tsx",
|
|
131
|
+
description: "TypeScript execute (tsx) - Node.js enhanced with esbuild"
|
|
132
|
+
}
|
|
133
|
+
]
|
|
134
|
+
});
|
|
135
|
+
this.packageManager = this.executor === "bun" ? "bun" : await (0, import_prompts.select)({
|
|
136
|
+
message: "Select a package manager",
|
|
137
|
+
choices: [
|
|
138
|
+
{
|
|
139
|
+
name: "Yarn",
|
|
140
|
+
value: "yarn",
|
|
141
|
+
description: "Fast, reliable, and secure dependency management"
|
|
142
|
+
},
|
|
143
|
+
{
|
|
144
|
+
name: "npm",
|
|
145
|
+
value: "npm",
|
|
146
|
+
description: "Node package manager (default)"
|
|
147
|
+
},
|
|
148
|
+
{
|
|
149
|
+
name: "Bun",
|
|
150
|
+
value: "bun",
|
|
151
|
+
description: "Ultra-fast package manager built into Bun"
|
|
152
|
+
}
|
|
153
|
+
],
|
|
154
|
+
default: "yarn"
|
|
155
|
+
});
|
|
156
|
+
(0, import_child_process.execSync)(`${this.packageManager} init -y`, {
|
|
157
|
+
stdio: "inherit",
|
|
158
|
+
cwd: this.projectPath
|
|
159
|
+
});
|
|
160
|
+
const packageJsonPath = import_path.default.join(this.projectPath, `package.json`);
|
|
161
|
+
let packageJson = JSON.parse(await fs.readFile(packageJsonPath, `utf-8`));
|
|
162
|
+
packageJson.type = "module";
|
|
163
|
+
packageJson.scripts = packageJson.scripts || {};
|
|
164
|
+
packageJson.scripts.prepare = "husky init";
|
|
165
|
+
packageJson.scripts.clean = "rm -rf dist";
|
|
166
|
+
if (this.executor === "bun") {
|
|
167
|
+
packageJson.scripts.dev = "bun run dev";
|
|
168
|
+
packageJson.scripts.start = "bun run pdev";
|
|
169
|
+
packageJson.scripts.build = "bun run build";
|
|
170
|
+
packageJson.scripts.test = "vitest";
|
|
171
|
+
packageJson.scripts["test:watch"] = "vitest --watch";
|
|
172
|
+
packageJson.scripts["test:coverage"] = "vitest run --coverage";
|
|
173
|
+
} else if (this.executor === "tsx") {
|
|
174
|
+
packageJson.scripts.dev = "tsx --watch -r tsconfig-paths/register src/index.ts start --all | npx pino-pretty";
|
|
175
|
+
packageJson.scripts.start = "tsx dist/index.js";
|
|
176
|
+
packageJson.scripts.build = "tsc";
|
|
177
|
+
packageJson.scripts.test = "vitest";
|
|
178
|
+
packageJson.scripts["test:watch"] = "vitest --watch";
|
|
179
|
+
packageJson.scripts["test:coverage"] = "vitest run --coverage";
|
|
180
|
+
}
|
|
181
|
+
await fs.writeFile(packageJsonPath, JSON.stringify(packageJson, null, 2));
|
|
182
|
+
}
|
|
183
|
+
async setupLinter() {
|
|
184
|
+
this.linter = await (0, import_prompts.select)({
|
|
185
|
+
message: "Select a linter",
|
|
186
|
+
choices: [
|
|
187
|
+
{
|
|
188
|
+
name: "Biome",
|
|
189
|
+
value: "biome",
|
|
190
|
+
description: "Fast formatter and linter for JavaScript, TypeScript, and more"
|
|
191
|
+
},
|
|
192
|
+
{
|
|
193
|
+
name: "ESLint",
|
|
194
|
+
value: "eslint",
|
|
195
|
+
description: "Find and fix problems in your JavaScript code"
|
|
196
|
+
}
|
|
197
|
+
]
|
|
198
|
+
});
|
|
199
|
+
const packageJsonPath = import_path.default.join(this.projectPath, `package.json`);
|
|
200
|
+
let packageJson = JSON.parse(await fs.readFile(packageJsonPath, `utf-8`));
|
|
201
|
+
if (this.linter === "biome") {
|
|
202
|
+
packageJson.scripts.lint = "biome check . --ext .ts,.tsx";
|
|
203
|
+
packageJson.scripts.format = "biome format . --ext .ts,.tsx --write";
|
|
204
|
+
this.addPackage("@biomejs/biome", true);
|
|
205
|
+
} else if (this.linter === "eslint") {
|
|
206
|
+
packageJson.scripts.lint = "eslint . --ext .ts,.tsx";
|
|
207
|
+
packageJson.scripts.format = "eslint . --ext .ts,.tsx --fix";
|
|
208
|
+
this.addPackage("eslint", true);
|
|
85
209
|
}
|
|
86
|
-
|
|
210
|
+
await fs.writeFile(packageJsonPath, JSON.stringify(packageJson, null, 2));
|
|
211
|
+
}
|
|
212
|
+
async setupGeneralPackages() {
|
|
213
|
+
this.validation_library = await (0, import_prompts.select)({
|
|
87
214
|
message: "Select a package you want for validation",
|
|
88
215
|
choices: [
|
|
89
216
|
{
|
|
@@ -104,8 +231,42 @@ var CreateProjectCommand = class extends import_clipanion.Command {
|
|
|
104
231
|
}
|
|
105
232
|
]
|
|
106
233
|
});
|
|
107
|
-
|
|
108
|
-
|
|
234
|
+
this.validation_library === "none" || await this.addPackage(this.validation_library);
|
|
235
|
+
this.database_type = await (0, import_prompts.select)({
|
|
236
|
+
message: "Select a database type (you can add more databases later)",
|
|
237
|
+
choices: [
|
|
238
|
+
{
|
|
239
|
+
name: "PostgreSQL",
|
|
240
|
+
value: "postgresql",
|
|
241
|
+
description: "A powerful, open source object-relational database system"
|
|
242
|
+
},
|
|
243
|
+
{
|
|
244
|
+
name: "MySQL",
|
|
245
|
+
value: "mysql",
|
|
246
|
+
description: "The world's most popular open source database"
|
|
247
|
+
},
|
|
248
|
+
{
|
|
249
|
+
name: "SQLite",
|
|
250
|
+
value: "sqlite",
|
|
251
|
+
description: "A C library that provides a lightweight disk-based database"
|
|
252
|
+
}
|
|
253
|
+
]
|
|
254
|
+
});
|
|
255
|
+
if (this.database_type === "postgresql") {
|
|
256
|
+
await this.addPackage("pg pg-cursor");
|
|
257
|
+
} else if (this.database_type === "mysql") {
|
|
258
|
+
await this.addPackage("mysql2");
|
|
259
|
+
} else if (this.database_type === "sqlite") {
|
|
260
|
+
await this.addPackage("sqlite3");
|
|
261
|
+
}
|
|
262
|
+
await this.addPackage("@devbro/pashmak tsconfig-paths dotenv ");
|
|
263
|
+
await this.addPackage(
|
|
264
|
+
"husky vitest supertest @types/supertest pino-pretty typescript tsx",
|
|
265
|
+
true
|
|
266
|
+
);
|
|
267
|
+
}
|
|
268
|
+
async setupBaseProject() {
|
|
269
|
+
console.log(`Using project directory: ${this.projectPath}`);
|
|
109
270
|
const dirname = typeof __dirname === "undefined" ? import_path.default.dirname((0, import_url.fileURLToPath)(import_meta.url)) : __dirname;
|
|
110
271
|
let basePath = import_path.default.join(dirname, `./base_project`);
|
|
111
272
|
if (await this.folderExists(basePath) === false) {
|
|
@@ -113,53 +274,90 @@ var CreateProjectCommand = class extends import_clipanion.Command {
|
|
|
113
274
|
}
|
|
114
275
|
console.log(`Using base project path: ${basePath}`);
|
|
115
276
|
const baseProjectPath = basePath;
|
|
116
|
-
await this.processTplFolder(baseProjectPath, projectPath, {
|
|
117
|
-
validation_library
|
|
277
|
+
await this.processTplFolder(baseProjectPath, this.projectPath, {
|
|
278
|
+
validation_library: this.validation_library,
|
|
279
|
+
executor: this.executor,
|
|
280
|
+
package_manager: this.packageManager,
|
|
281
|
+
linter: this.linter,
|
|
282
|
+
database_type: this.database_type
|
|
118
283
|
});
|
|
119
|
-
console.log(`Copied base project files to: ${projectPath}`);
|
|
120
|
-
const packageJsonPath = import_path.default.join(projectPath,
|
|
121
|
-
|
|
122
|
-
packageJson.name = import_change_case_all.Case.snake(import_path.default.basename(projectPath));
|
|
284
|
+
console.log(`Copied base project files to: ${this.projectPath}`);
|
|
285
|
+
const packageJsonPath = import_path.default.join(this.projectPath, "package.json");
|
|
286
|
+
let packageJson = JSON.parse(await fs.readFile(packageJsonPath, `utf-8`));
|
|
287
|
+
packageJson.name = import_change_case_all.Case.snake(import_path.default.basename(this.projectPath));
|
|
123
288
|
await fs.writeFile(packageJsonPath, JSON.stringify(packageJson, null, 2));
|
|
124
289
|
console.log(`Updated package.json with project name: ${packageJson.name}`);
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
290
|
+
}
|
|
291
|
+
async addPackage(packageName, dev = false) {
|
|
292
|
+
let install_command = "";
|
|
293
|
+
switch (this.packageManager) {
|
|
294
|
+
case "bun":
|
|
295
|
+
install_command = `bun add ${packageName}${dev ? " -d" : ""}`;
|
|
296
|
+
break;
|
|
297
|
+
case "yarn":
|
|
298
|
+
install_command = `yarn add ${packageName}${dev ? " -D" : ""} --no-install`;
|
|
299
|
+
break;
|
|
300
|
+
case "npm":
|
|
301
|
+
install_command = `npm install ${packageName}${dev ? " --save-dev" : ""} --package-lock-only`;
|
|
302
|
+
break;
|
|
137
303
|
}
|
|
304
|
+
(0, import_child_process.execSync)(install_command, {
|
|
305
|
+
stdio: "inherit",
|
|
306
|
+
cwd: this.projectPath
|
|
307
|
+
});
|
|
138
308
|
}
|
|
139
|
-
async
|
|
140
|
-
const
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
309
|
+
async installPackages() {
|
|
310
|
+
const install_command = this.packageManager === "bun" ? `bun install` : this.packageManager === "yarn" ? `yarn` : `npm install`;
|
|
311
|
+
(0, import_child_process.execSync)(install_command, {
|
|
312
|
+
stdio: "inherit",
|
|
313
|
+
cwd: this.projectPath
|
|
314
|
+
});
|
|
315
|
+
}
|
|
316
|
+
async setupGit() {
|
|
317
|
+
const initGit = await (0, import_prompts.select)({
|
|
318
|
+
message: "Initialize a git repository?",
|
|
319
|
+
choices: [
|
|
320
|
+
{
|
|
321
|
+
name: "Yes",
|
|
322
|
+
value: true,
|
|
323
|
+
description: "Initialize git and create first commit"
|
|
324
|
+
},
|
|
325
|
+
{
|
|
326
|
+
name: "No",
|
|
327
|
+
value: false,
|
|
328
|
+
description: "Skip git initialization"
|
|
329
|
+
}
|
|
330
|
+
]
|
|
331
|
+
});
|
|
332
|
+
if (initGit) {
|
|
333
|
+
const gitignoreContent = [
|
|
334
|
+
"node_modules/",
|
|
335
|
+
"dist/",
|
|
336
|
+
".env",
|
|
337
|
+
".env.*",
|
|
338
|
+
"!.env.example",
|
|
339
|
+
"*.log",
|
|
340
|
+
"coverage/",
|
|
341
|
+
".DS_Store"
|
|
342
|
+
].join("\n") + "\n";
|
|
343
|
+
await fs.writeFile(
|
|
344
|
+
import_path.default.join(this.projectPath, ".gitignore"),
|
|
345
|
+
gitignoreContent
|
|
346
|
+
);
|
|
347
|
+
(0, import_child_process.execSync)(
|
|
348
|
+
`git init; git add --all; git commit --allow-empty -m "chore: first commit"`,
|
|
349
|
+
{
|
|
350
|
+
cwd: this.projectPath
|
|
351
|
+
}
|
|
352
|
+
);
|
|
154
353
|
}
|
|
155
354
|
}
|
|
156
|
-
async
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
await fs.writeFile(dest, template);
|
|
355
|
+
async catch(error) {
|
|
356
|
+
if (Error.isError(error)) {
|
|
357
|
+
console.error(error.message);
|
|
358
|
+
} else {
|
|
359
|
+
console.error(error);
|
|
360
|
+
}
|
|
163
361
|
}
|
|
164
362
|
};
|
|
165
363
|
|
|
@@ -173,5 +371,6 @@ var cli = new import_clipanion2.Cli({
|
|
|
173
371
|
cli.register(CreateProjectCommand);
|
|
174
372
|
cli.runExit(args).then(() => {
|
|
175
373
|
}).catch((err) => {
|
|
176
|
-
console.error(err);
|
|
374
|
+
console.error("Fatal error:", err.message);
|
|
375
|
+
process.exit(1);
|
|
177
376
|
});
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
7
|
+
var __export = (target, all) => {
|
|
8
|
+
for (var name in all)
|
|
9
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
10
|
+
};
|
|
11
|
+
var __copyProps = (to, from, except, desc) => {
|
|
12
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
13
|
+
for (let key of __getOwnPropNames(from))
|
|
14
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
15
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
16
|
+
}
|
|
17
|
+
return to;
|
|
18
|
+
};
|
|
19
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
20
|
+
|
|
21
|
+
// src/cache/MultiCache.mts
|
|
22
|
+
var MultiCache_exports = {};
|
|
23
|
+
__export(MultiCache_exports, {
|
|
24
|
+
MultiCache: () => MultiCache
|
|
25
|
+
});
|
|
26
|
+
module.exports = __toCommonJS(MultiCache_exports);
|
|
27
|
+
var MultiCache = class {
|
|
28
|
+
constructor(caches) {
|
|
29
|
+
this.caches = caches;
|
|
30
|
+
}
|
|
31
|
+
static {
|
|
32
|
+
__name(this, "MultiCache");
|
|
33
|
+
}
|
|
34
|
+
async get(key) {
|
|
35
|
+
for (const cache of this.caches) {
|
|
36
|
+
const value = await cache.get(key);
|
|
37
|
+
if (value !== void 0) {
|
|
38
|
+
return value;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
return void 0;
|
|
42
|
+
}
|
|
43
|
+
async put(key, value, ttl) {
|
|
44
|
+
await Promise.all(this.caches.map((cache) => cache.put(key, value, ttl)));
|
|
45
|
+
}
|
|
46
|
+
async delete(key) {
|
|
47
|
+
await Promise.all(this.caches.map((cache) => cache.delete(key)));
|
|
48
|
+
}
|
|
49
|
+
async has(key) {
|
|
50
|
+
for (const cache of this.caches) {
|
|
51
|
+
if (await cache.has(key)) {
|
|
52
|
+
return true;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return false;
|
|
56
|
+
}
|
|
57
|
+
async increment(key, amount) {
|
|
58
|
+
let rc = void 0;
|
|
59
|
+
for (const cache of this.caches) {
|
|
60
|
+
let rc2 = await cache.increment(key, amount);
|
|
61
|
+
if (rc === void 0) {
|
|
62
|
+
rc = rc2;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
return rc;
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
69
|
+
0 && (module.exports = {
|
|
70
|
+
MultiCache
|
|
71
|
+
});
|
|
@@ -29,7 +29,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
29
29
|
));
|
|
30
30
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
31
31
|
|
|
32
|
-
// src/cache.mts
|
|
32
|
+
// src/cache/cache.mts
|
|
33
33
|
var cache_exports = {};
|
|
34
34
|
__export(cache_exports, {
|
|
35
35
|
cacheQuery: () => cacheQuery
|
|
@@ -593,6 +593,51 @@ var DatabaseTransport = class {
|
|
|
593
593
|
// src/factories.mts
|
|
594
594
|
var import_neko_cache = require("@devbro/neko-cache");
|
|
595
595
|
var import_neko_storage = require("@devbro/neko-storage");
|
|
596
|
+
|
|
597
|
+
// src/cache/MultiCache.mts
|
|
598
|
+
var MultiCache = class {
|
|
599
|
+
constructor(caches) {
|
|
600
|
+
this.caches = caches;
|
|
601
|
+
}
|
|
602
|
+
static {
|
|
603
|
+
__name(this, "MultiCache");
|
|
604
|
+
}
|
|
605
|
+
async get(key) {
|
|
606
|
+
for (const cache2 of this.caches) {
|
|
607
|
+
const value = await cache2.get(key);
|
|
608
|
+
if (value !== void 0) {
|
|
609
|
+
return value;
|
|
610
|
+
}
|
|
611
|
+
}
|
|
612
|
+
return void 0;
|
|
613
|
+
}
|
|
614
|
+
async put(key, value, ttl) {
|
|
615
|
+
await Promise.all(this.caches.map((cache2) => cache2.put(key, value, ttl)));
|
|
616
|
+
}
|
|
617
|
+
async delete(key) {
|
|
618
|
+
await Promise.all(this.caches.map((cache2) => cache2.delete(key)));
|
|
619
|
+
}
|
|
620
|
+
async has(key) {
|
|
621
|
+
for (const cache2 of this.caches) {
|
|
622
|
+
if (await cache2.has(key)) {
|
|
623
|
+
return true;
|
|
624
|
+
}
|
|
625
|
+
}
|
|
626
|
+
return false;
|
|
627
|
+
}
|
|
628
|
+
async increment(key, amount) {
|
|
629
|
+
let rc = void 0;
|
|
630
|
+
for (const cache2 of this.caches) {
|
|
631
|
+
let rc2 = await cache2.increment(key, amount);
|
|
632
|
+
if (rc === void 0) {
|
|
633
|
+
rc = rc2;
|
|
634
|
+
}
|
|
635
|
+
}
|
|
636
|
+
return rc;
|
|
637
|
+
}
|
|
638
|
+
};
|
|
639
|
+
|
|
640
|
+
// src/factories.mts
|
|
596
641
|
var FlexibleFactory = class {
|
|
597
642
|
static {
|
|
598
643
|
__name(this, "FlexibleFactory");
|
|
@@ -663,6 +708,13 @@ CacheProviderFactory.register("redis", (opt) => {
|
|
|
663
708
|
CacheProviderFactory.register("file", (opt) => {
|
|
664
709
|
return new import_neko_cache.FileCacheProvider(opt);
|
|
665
710
|
});
|
|
711
|
+
CacheProviderFactory.register("multi", (opt) => {
|
|
712
|
+
const caches = [];
|
|
713
|
+
for (const c of opt.caches) {
|
|
714
|
+
caches.push(cache(c));
|
|
715
|
+
}
|
|
716
|
+
return new MultiCache(caches);
|
|
717
|
+
});
|
|
666
718
|
CacheProviderFactory.register("disabled", (opt) => {
|
|
667
719
|
return new import_neko_cache.DisabledCacheProvider();
|
|
668
720
|
});
|
|
@@ -803,7 +855,7 @@ var cache = wrapSingletonWithAccessors(
|
|
|
803
855
|
})
|
|
804
856
|
);
|
|
805
857
|
|
|
806
|
-
// src/cache.mts
|
|
858
|
+
// src/cache/cache.mts
|
|
807
859
|
async function cacheQuery(q, options = {}) {
|
|
808
860
|
options.ttl = options.ttl ?? 3600;
|
|
809
861
|
options.cache_label = options.cache_label ?? "default";
|
package/dist/cjs/facades.js
CHANGED
|
@@ -601,6 +601,51 @@ var DatabaseTransport = class {
|
|
|
601
601
|
// src/factories.mts
|
|
602
602
|
var import_neko_cache = require("@devbro/neko-cache");
|
|
603
603
|
var import_neko_storage = require("@devbro/neko-storage");
|
|
604
|
+
|
|
605
|
+
// src/cache/MultiCache.mts
|
|
606
|
+
var MultiCache = class {
|
|
607
|
+
constructor(caches) {
|
|
608
|
+
this.caches = caches;
|
|
609
|
+
}
|
|
610
|
+
static {
|
|
611
|
+
__name(this, "MultiCache");
|
|
612
|
+
}
|
|
613
|
+
async get(key) {
|
|
614
|
+
for (const cache2 of this.caches) {
|
|
615
|
+
const value = await cache2.get(key);
|
|
616
|
+
if (value !== void 0) {
|
|
617
|
+
return value;
|
|
618
|
+
}
|
|
619
|
+
}
|
|
620
|
+
return void 0;
|
|
621
|
+
}
|
|
622
|
+
async put(key, value, ttl) {
|
|
623
|
+
await Promise.all(this.caches.map((cache2) => cache2.put(key, value, ttl)));
|
|
624
|
+
}
|
|
625
|
+
async delete(key) {
|
|
626
|
+
await Promise.all(this.caches.map((cache2) => cache2.delete(key)));
|
|
627
|
+
}
|
|
628
|
+
async has(key) {
|
|
629
|
+
for (const cache2 of this.caches) {
|
|
630
|
+
if (await cache2.has(key)) {
|
|
631
|
+
return true;
|
|
632
|
+
}
|
|
633
|
+
}
|
|
634
|
+
return false;
|
|
635
|
+
}
|
|
636
|
+
async increment(key, amount) {
|
|
637
|
+
let rc = void 0;
|
|
638
|
+
for (const cache2 of this.caches) {
|
|
639
|
+
let rc2 = await cache2.increment(key, amount);
|
|
640
|
+
if (rc === void 0) {
|
|
641
|
+
rc = rc2;
|
|
642
|
+
}
|
|
643
|
+
}
|
|
644
|
+
return rc;
|
|
645
|
+
}
|
|
646
|
+
};
|
|
647
|
+
|
|
648
|
+
// src/factories.mts
|
|
604
649
|
var FlexibleFactory = class {
|
|
605
650
|
static {
|
|
606
651
|
__name(this, "FlexibleFactory");
|
|
@@ -671,6 +716,13 @@ CacheProviderFactory.register("redis", (opt) => {
|
|
|
671
716
|
CacheProviderFactory.register("file", (opt) => {
|
|
672
717
|
return new import_neko_cache.FileCacheProvider(opt);
|
|
673
718
|
});
|
|
719
|
+
CacheProviderFactory.register("multi", (opt) => {
|
|
720
|
+
const caches = [];
|
|
721
|
+
for (const c of opt.caches) {
|
|
722
|
+
caches.push(cache(c));
|
|
723
|
+
}
|
|
724
|
+
return new MultiCache(caches);
|
|
725
|
+
});
|
|
674
726
|
CacheProviderFactory.register("disabled", (opt) => {
|
|
675
727
|
return new import_neko_cache.DisabledCacheProvider();
|
|
676
728
|
});
|