@devbro/pashmak 0.1.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 +11 -0
- package/dist/DatabaseServiceProvider.d.ts +13 -0
- package/dist/DatabaseServiceProvider.js +55 -0
- package/dist/DatabaseServiceProvider.js.map +1 -0
- package/dist/app/console/DefaultCommand.d.ts +9 -0
- package/dist/app/console/DefaultCommand.js +35 -0
- package/dist/app/console/DefaultCommand.js.map +1 -0
- package/dist/app/console/KeyGenerateCommand.d.ts +13 -0
- package/dist/app/console/KeyGenerateCommand.js +79 -0
- package/dist/app/console/KeyGenerateCommand.js.map +1 -0
- package/dist/app/console/StartCommand.d.ts +11 -0
- package/dist/app/console/StartCommand.js +49 -0
- package/dist/app/console/StartCommand.js.map +1 -0
- package/dist/app/console/generate/GenerateControllerCommand.d.ts +9 -0
- package/dist/app/console/generate/GenerateControllerCommand.js +56 -0
- package/dist/app/console/generate/GenerateControllerCommand.js.map +1 -0
- package/dist/app/console/generate/controller.tpl +30 -0
- package/dist/app/console/generate/index.d.ts +2 -0
- package/dist/app/console/generate/index.js +2 -0
- package/dist/app/console/generate/index.js.map +1 -0
- package/dist/app/console/index.d.ts +9 -0
- package/dist/app/console/index.js +7 -0
- package/dist/app/console/index.js.map +1 -0
- package/dist/app/console/migrate/MakeMigrateCommand.d.ts +9 -0
- package/dist/app/console/migrate/MakeMigrateCommand.js +51 -0
- package/dist/app/console/migrate/MakeMigrateCommand.js.map +1 -0
- package/dist/app/console/migrate/MigrateCommand.d.ts +9 -0
- package/dist/app/console/migrate/MigrateCommand.js +93 -0
- package/dist/app/console/migrate/MigrateCommand.js.map +1 -0
- package/dist/app/console/migrate/MigrateRollbackCommand.d.ts +9 -0
- package/dist/app/console/migrate/MigrateRollbackCommand.js +57 -0
- package/dist/app/console/migrate/MigrateRollbackCommand.js.map +1 -0
- package/dist/app/console/migrate/index.d.ts +4 -0
- package/dist/app/console/migrate/index.js +4 -0
- package/dist/app/console/migrate/index.js.map +1 -0
- package/dist/app/console/migrate/make_migration.tpl +15 -0
- package/dist/app/console/project/CreateProjectCommand.d.ts +14 -0
- package/dist/app/console/project/CreateProjectCommand.js +106 -0
- package/dist/app/console/project/CreateProjectCommand.js.map +1 -0
- package/dist/app/console/project/base_project/README.md.tpl +1 -0
- package/dist/app/console/project/base_project/package.json.tpl +67 -0
- package/dist/app/console/project/base_project/src/app/console/YourFirstCommand.ts.tpl +23 -0
- package/dist/app/console/project/base_project/src/app/console/index.ts.tpl +1 -0
- package/dist/app/console/project/base_project/src/app/controllers/HelloController.ts.tpl +16 -0
- package/dist/app/console/project/base_project/src/app/models/README.md.tpl +1 -0
- package/dist/app/console/project/base_project/src/boot.ts.tpl +0 -0
- package/dist/app/console/project/base_project/src/config/databases.ts.tpl +8 -0
- package/dist/app/console/project/base_project/src/config/default.ts.tpl +41 -0
- package/dist/app/console/project/base_project/src/config/loggers.ts.tpl +11 -0
- package/dist/app/console/project/base_project/src/config/storages.ts.tpl +7 -0
- package/dist/app/console/project/base_project/src/config/test.ts.tpl +1 -0
- package/dist/app/console/project/base_project/src/database/migrations/2025_05_30_41329_create_sample.ts.tpl +13 -0
- package/dist/app/console/project/base_project/src/helpers.ts.tpl +28 -0
- package/dist/app/console/project/base_project/src/index.ts.tpl +12 -0
- package/dist/app/console/project/base_project/src/initialize.ts.tpl +7 -0
- package/dist/app/console/project/base_project/src/middlewares.ts.tpl +16 -0
- package/dist/app/console/project/base_project/src/routes.ts.tpl +18 -0
- package/dist/app/console/project/base_project/src/schedules.ts.tpl +22 -0
- package/dist/app/console/project/base_project/tests/basic_test.spec.ts.tpl +27 -0
- package/dist/app/console/project/base_project/tsconfig.json.tpl +23 -0
- package/dist/app/console/project/base_project/tsup.config.ts.tpl +25 -0
- package/dist/app/console/project/base_project/vitest.config.ts.tpl +17 -0
- package/dist/config.d.ts +7 -0
- package/dist/config.js +2 -0
- package/dist/config.js.map +1 -0
- package/dist/context.d.ts +1 -0
- package/dist/context.js +2 -0
- package/dist/context.js.map +1 -0
- package/dist/facades.d.ts +18 -0
- package/dist/facades.js +122 -0
- package/dist/facades.js.map +1 -0
- package/dist/helper.d.ts +1 -0
- package/dist/helper.js +2 -0
- package/dist/helper.js.map +1 -0
- package/dist/http.d.ts +1 -0
- package/dist/http.js +2 -0
- package/dist/http.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +40 -0
- package/dist/index.js.map +1 -0
- package/dist/logger.d.ts +1 -0
- package/dist/logger.js +2 -0
- package/dist/logger.js.map +1 -0
- package/dist/orm.d.ts +1 -0
- package/dist/orm.js +2 -0
- package/dist/orm.js.map +1 -0
- package/dist/pashmak_cli.d.ts +1 -0
- package/dist/pashmak_cli.js +9 -0
- package/dist/pashmak_cli.js.map +1 -0
- package/dist/router.d.ts +9 -0
- package/dist/router.js +37 -0
- package/dist/router.js.map +1 -0
- package/dist/sql.d.ts +1 -0
- package/dist/sql.js +2 -0
- package/dist/sql.js.map +1 -0
- package/package.json +134 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/app/console/migrate/MigrateCommand.ts"],"sourcesContent":["import { cli, db as database, logger } from \"../../../facades\";\nimport { Command, Option } from \"clipanion\";\nimport { Blueprint } from \"@devbro/neko-sql\";\nimport { context_provider } from \"@devbro/neko-context\";\nimport path from \"path\";\nimport fs from \"fs/promises\";\nimport { config } from \"@devbro/neko-config\";\nimport { Migration } from \"@devbro/neko-sql\";\n\nexport class MigrateCommand extends Command {\n static paths = [[`migrate`]];\n\n fresh = Option.Boolean(\"--fresh\", false);\n\n async execute() {\n await context_provider.run(async () => {\n // this.context.stdout.write(`Hello Migrate Command!\\n`);\n const db = database();\n const schema = db.getSchema();\n\n if (this.fresh) {\n logger().info(\"dropping all tables!!\");\n let retry = true;\n let retry_count = 0;\n while (retry && retry_count < 10) {\n retry = false;\n retry_count++;\n const tables = await schema.tables();\n for (const table of tables) {\n logger().info(`dropping table ${table.name}`);\n try {\n await schema.dropTable(table.name);\n } catch {\n logger().info(`failed to drop ${table.name}`);\n retry = true;\n }\n }\n }\n }\n\n //create migration table if not exists\n if (!(await schema.tableExists(\"migrations\"))) {\n await schema.createTable(\"migrations\", (blueprint: Blueprint) => {\n blueprint.id();\n blueprint.timestamps();\n blueprint.string(\"filename\");\n blueprint.integer(\"batch\");\n });\n }\n\n const migrationsDir = config.get(\"migration.path\");\n let files: string[] = [];\n\n const dirEntries = await fs.readdir(migrationsDir);\n files = dirEntries\n .filter((entry) => entry.endsWith(\".ts\") || entry.endsWith(\".js\"))\n .sort();\n let batch_number = await db.runQuery({\n sql: \"select max(batch) as next_batch from migrations\",\n bindings: [],\n });\n batch_number = batch_number[0].next_batch || 0;\n batch_number++;\n\n const migrations = await db.runQuery({\n sql: \"select * from migrations order by created_at ASC\",\n bindings: [],\n });\n\n const completed_migrations = migrations.map((r: any) => r.filename);\n const pending_migrations = files.filter(\n (file) => !completed_migrations.includes(file),\n );\n\n let migrated_count = 0;\n for (const class_to_migrate of pending_migrations) {\n logger().info(`migrating up ${class_to_migrate}`);\n const ClassToMigrate = (\n await import(path.join(migrationsDir, class_to_migrate))\n ).default;\n const c: Migration = new ClassToMigrate();\n await c.up(db.getSchema());\n await db.runQuery({\n sql: \"insert into migrations (filename, batch) values ($1,$2)\",\n bindings: [class_to_migrate, batch_number],\n });\n migrated_count++;\n }\n\n if (migrated_count === 0) {\n logger().warn(\"no migrations to run!\");\n return;\n }\n\n logger().info(`migrated ${migrated_count} migrations successfully!`);\n });\n }\n}\n\ncli().register(MigrateCommand);\n"],"mappings":";;AAAA,SAASA,KAAKC,MAAMC,UAAUC,cAAc;AAC5C,SAASC,SAASC,cAAc;AAEhC,SAASC,wBAAwB;AACjC,OAAOC,UAAU;AACjB,OAAOC,QAAQ;AACf,SAASC,cAAc;AAGhB,MAAMC,uBAAuBN,QAAAA;EATpC,OASoCA;;;EAClC,OAAOO,QAAQ;IAAC;MAAC;;;EAEjBC,QAAQP,OAAOQ,QAAQ,WAAW,KAAA;EAElC,MAAMC,UAAU;AACd,UAAMR,iBAAiBS,IAAI,YAAA;AAEzB,YAAMd,KAAKC,SAAAA;AACX,YAAMc,SAASf,GAAGgB,UAAS;AAE3B,UAAI,KAAKL,OAAO;AACdT,eAAAA,EAASe,KAAK,uBAAA;AACd,YAAIC,QAAQ;AACZ,YAAIC,cAAc;AAClB,eAAOD,SAASC,cAAc,IAAI;AAChCD,kBAAQ;AACRC;AACA,gBAAMC,SAAS,MAAML,OAAOK,OAAM;AAClC,qBAAWC,SAASD,QAAQ;AAC1BlB,mBAAAA,EAASe,KAAK,kBAAkBI,MAAMC,IAAI,EAAE;AAC5C,gBAAI;AACF,oBAAMP,OAAOQ,UAAUF,MAAMC,IAAI;YACnC,QAAQ;AACNpB,qBAAAA,EAASe,KAAK,kBAAkBI,MAAMC,IAAI,EAAE;AAC5CJ,sBAAQ;YACV;UACF;QACF;MACF;AAGA,UAAI,CAAE,MAAMH,OAAOS,YAAY,YAAA,GAAgB;AAC7C,cAAMT,OAAOU,YAAY,cAAc,CAACC,cAAAA;AACtCA,oBAAUC,GAAE;AACZD,oBAAUE,WAAU;AACpBF,oBAAUG,OAAO,UAAA;AACjBH,oBAAUI,QAAQ,OAAA;QACpB,CAAA;MACF;AAEA,YAAMC,gBAAgBvB,OAAOwB,IAAI,gBAAA;AACjC,UAAIC,QAAkB,CAAA;AAEtB,YAAMC,aAAa,MAAM3B,GAAG4B,QAAQJ,aAAAA;AACpCE,cAAQC,WACLE,OAAO,CAACC,UAAUA,MAAMC,SAAS,KAAA,KAAUD,MAAMC,SAAS,KAAA,CAAA,EAC1DC,KAAI;AACP,UAAIC,eAAe,MAAMxC,GAAGyC,SAAS;QACnCC,KAAK;QACLC,UAAU,CAAA;MACZ,CAAA;AACAH,qBAAeA,aAAa,CAAA,EAAGI,cAAc;AAC7CJ;AAEA,YAAMK,aAAa,MAAM7C,GAAGyC,SAAS;QACnCC,KAAK;QACLC,UAAU,CAAA;MACZ,CAAA;AAEA,YAAMG,uBAAuBD,WAAWE,IAAI,CAACC,MAAWA,EAAEC,QAAQ;AAClE,YAAMC,qBAAqBjB,MAAMG,OAC/B,CAACe,SAAS,CAACL,qBAAqBM,SAASD,IAAAA,CAAAA;AAG3C,UAAIE,iBAAiB;AACrB,iBAAWC,oBAAoBJ,oBAAoB;AACjDhD,eAAAA,EAASe,KAAK,gBAAgBqC,gBAAAA,EAAkB;AAChD,cAAMC,kBACJ,MAAM,OAAOjD,KAAKkD,KAAKzB,eAAeuB,gBAAAA,IACtCG;AACF,cAAMC,IAAe,IAAIH,eAAAA;AACzB,cAAMG,EAAEC,GAAG3D,GAAGgB,UAAS,CAAA;AACvB,cAAMhB,GAAGyC,SAAS;UAChBC,KAAK;UACLC,UAAU;YAACW;YAAkBd;;QAC/B,CAAA;AACAa;MACF;AAEA,UAAIA,mBAAmB,GAAG;AACxBnD,eAAAA,EAAS0D,KAAK,uBAAA;AACd;MACF;AAEA1D,aAAAA,EAASe,KAAK,YAAYoC,cAAAA,2BAAyC;IACrE,CAAA;EACF;AACF;AAEAtD,IAAAA,EAAM8D,SAASpD,cAAAA;","names":["cli","db","database","logger","Command","Option","context_provider","path","fs","config","MigrateCommand","paths","fresh","Boolean","execute","run","schema","getSchema","info","retry","retry_count","tables","table","name","dropTable","tableExists","createTable","blueprint","id","timestamps","string","integer","migrationsDir","get","files","dirEntries","readdir","filter","entry","endsWith","sort","batch_number","runQuery","sql","bindings","next_batch","migrations","completed_migrations","map","r","filename","pending_migrations","file","includes","migrated_count","class_to_migrate","ClassToMigrate","join","default","c","up","warn","register"]}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
3
|
+
import { cli, db as database } from "../../../facades";
|
|
4
|
+
import { Command, Option } from "clipanion";
|
|
5
|
+
import { context_provider } from "@devbro/neko-context";
|
|
6
|
+
import path from "path";
|
|
7
|
+
import fs from "fs/promises";
|
|
8
|
+
import { config } from "@devbro/neko-config";
|
|
9
|
+
import * as t from "typanion";
|
|
10
|
+
class MigrateRollbackCommand extends Command {
|
|
11
|
+
static {
|
|
12
|
+
__name(this, "MigrateRollbackCommand");
|
|
13
|
+
}
|
|
14
|
+
static paths = [
|
|
15
|
+
[
|
|
16
|
+
`migrate`,
|
|
17
|
+
"rollback"
|
|
18
|
+
]
|
|
19
|
+
];
|
|
20
|
+
steps = Option.String(`--steps`, {
|
|
21
|
+
description: `how many migrations to rollback`,
|
|
22
|
+
validator: t.isNumber()
|
|
23
|
+
});
|
|
24
|
+
async execute() {
|
|
25
|
+
await context_provider.run(async () => {
|
|
26
|
+
const db = database();
|
|
27
|
+
const schema = db.getSchema();
|
|
28
|
+
const migrationsDir = config.get("migration.path");
|
|
29
|
+
let files = [];
|
|
30
|
+
const dirEntries = await fs.readdir(migrationsDir);
|
|
31
|
+
files = dirEntries.filter((entry) => entry.endsWith(".ts")).sort();
|
|
32
|
+
const migrations = await db.runQuery({
|
|
33
|
+
sql: "select * from migrations order by created_at DESC",
|
|
34
|
+
bindings: []
|
|
35
|
+
});
|
|
36
|
+
const count = 0;
|
|
37
|
+
for (const migration of migrations) {
|
|
38
|
+
const class_to_migrate = migration.filename;
|
|
39
|
+
this.context.stdout.write(`rolling back ${class_to_migrate}`);
|
|
40
|
+
const ClassToMigrate = (await import(path.join(migrationsDir, class_to_migrate))).default;
|
|
41
|
+
const c = new ClassToMigrate();
|
|
42
|
+
await c.down(db.getSchema());
|
|
43
|
+
await db.runQuery({
|
|
44
|
+
sql: "delete from migrations where id = $1",
|
|
45
|
+
bindings: [
|
|
46
|
+
migration.id
|
|
47
|
+
]
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
cli().register(MigrateRollbackCommand);
|
|
54
|
+
export {
|
|
55
|
+
MigrateRollbackCommand
|
|
56
|
+
};
|
|
57
|
+
//# sourceMappingURL=MigrateRollbackCommand.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/app/console/migrate/MigrateRollbackCommand.ts"],"sourcesContent":["import { cli, db as database } from \"../../../facades\";\nimport { Command, Option } from \"clipanion\";\nimport { context_provider } from \"@devbro/neko-context\";\nimport path from \"path\";\nimport fs from \"fs/promises\";\nimport { config } from \"@devbro/neko-config\";\nimport { Migration } from \"@devbro/neko-sql\";\nimport * as t from \"typanion\";\n\nexport class MigrateRollbackCommand extends Command {\n static paths = [[`migrate`, \"rollback\"]];\n\n steps = Option.String(`--steps`, {\n description: `how many migrations to rollback`,\n validator: t.isNumber(),\n });\n\n async execute() {\n await context_provider.run(async () => {\n // this.context.stdout.write(`Hello Migrate Command!\\n`);\n const db = database();\n const schema = db.getSchema();\n\n const migrationsDir = config.get(\"migration.path\");\n let files: string[] = [];\n\n const dirEntries = await fs.readdir(migrationsDir);\n files = dirEntries.filter((entry) => entry.endsWith(\".ts\")).sort();\n\n const migrations = await db.runQuery({\n sql: \"select * from migrations order by created_at DESC\",\n bindings: [],\n });\n\n const count = 0;\n for (const migration of migrations) {\n const class_to_migrate = migration.filename;\n this.context.stdout.write(`rolling back ${class_to_migrate}`);\n\n const ClassToMigrate = (\n await import(path.join(migrationsDir, class_to_migrate))\n ).default;\n\n const c: Migration = new ClassToMigrate();\n await c.down(db.getSchema());\n await db.runQuery({\n sql: \"delete from migrations where id = $1\",\n bindings: [migration.id],\n });\n }\n });\n }\n}\n\ncli().register(MigrateRollbackCommand);\n"],"mappings":";;AAAA,SAASA,KAAKC,MAAMC,gBAAgB;AACpC,SAASC,SAASC,cAAc;AAChC,SAASC,wBAAwB;AACjC,OAAOC,UAAU;AACjB,OAAOC,QAAQ;AACf,SAASC,cAAc;AAEvB,YAAYC,OAAO;AAEZ,MAAMC,+BAA+BP,QAAAA;EAT5C,OAS4CA;;;EAC1C,OAAOQ,QAAQ;IAAC;MAAC;MAAW;;;EAE5BC,QAAQR,OAAOS,OAAO,WAAW;IAC/BC,aAAa;IACbC,WAAWN,EAAEO,SAAQ;EACvB,CAAA;EAEA,MAAMC,UAAU;AACd,UAAMZ,iBAAiBa,IAAI,YAAA;AAEzB,YAAMjB,KAAKC,SAAAA;AACX,YAAMiB,SAASlB,GAAGmB,UAAS;AAE3B,YAAMC,gBAAgBb,OAAOc,IAAI,gBAAA;AACjC,UAAIC,QAAkB,CAAA;AAEtB,YAAMC,aAAa,MAAMjB,GAAGkB,QAAQJ,aAAAA;AACpCE,cAAQC,WAAWE,OAAO,CAACC,UAAUA,MAAMC,SAAS,KAAA,CAAA,EAAQC,KAAI;AAEhE,YAAMC,aAAa,MAAM7B,GAAG8B,SAAS;QACnCC,KAAK;QACLC,UAAU,CAAA;MACZ,CAAA;AAEA,YAAMC,QAAQ;AACd,iBAAWC,aAAaL,YAAY;AAClC,cAAMM,mBAAmBD,UAAUE;AACnC,aAAKC,QAAQC,OAAOC,MAAM,gBAAgBJ,gBAAAA,EAAkB;AAE5D,cAAMK,kBACJ,MAAM,OAAOnC,KAAKoC,KAAKrB,eAAee,gBAAAA,IACtCO;AAEF,cAAMC,IAAe,IAAIH,eAAAA;AACzB,cAAMG,EAAEC,KAAK5C,GAAGmB,UAAS,CAAA;AACzB,cAAMnB,GAAG8B,SAAS;UAChBC,KAAK;UACLC,UAAU;YAACE,UAAUW;;QACvB,CAAA;MACF;IACF,CAAA;EACF;AACF;AAEA9C,IAAAA,EAAM+C,SAASrC,sBAAAA;","names":["cli","db","database","Command","Option","context_provider","path","fs","config","t","MigrateRollbackCommand","paths","steps","String","description","validator","isNumber","execute","run","schema","getSchema","migrationsDir","get","files","dirEntries","readdir","filter","entry","endsWith","sort","migrations","runQuery","sql","bindings","count","migration","class_to_migrate","filename","context","stdout","write","ClassToMigrate","join","default","c","down","id","register"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/app/console/migrate/index.ts"],"sourcesContent":["export * from \"./MigrateCommand\";\nexport * from \"./MakeMigrateCommand\";\nexport * from \"./MigrateRollbackCommand\";"],"mappings":"AAAA,cAAc;AACd,cAAc;AACd,cAAc;","names":[]}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Migration } from '@devbro/pashmak/sql';
|
|
2
|
+
import { Schema, Blueprint } from "@devbro/pashmak/sql";
|
|
3
|
+
|
|
4
|
+
export default class {{className}} extends Migration {
|
|
5
|
+
async up(schema: Schema) {
|
|
6
|
+
// await schema.createTable("{{className}}", (blueprint: Blueprint) => {
|
|
7
|
+
// blueprint.id();
|
|
8
|
+
// blueprint.timestamps();
|
|
9
|
+
// });
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
async down(schema: Schema) {
|
|
13
|
+
// await schema.dropTable("{{className}}");
|
|
14
|
+
}
|
|
15
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import * as clipanion from 'clipanion';
|
|
2
|
+
import { Command } from 'clipanion';
|
|
3
|
+
|
|
4
|
+
declare class CreateProjectCommand extends Command {
|
|
5
|
+
static paths: string[][];
|
|
6
|
+
static usage: clipanion.Usage;
|
|
7
|
+
projectPath: string;
|
|
8
|
+
git: boolean;
|
|
9
|
+
execute(): Promise<1 | undefined>;
|
|
10
|
+
processTplFolder(src: string, dest: string, data?: any): Promise<void>;
|
|
11
|
+
processTplFile(src: string, dest: string, data?: any): Promise<void>;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export { CreateProjectCommand };
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
3
|
+
import { cli } from "../../../facades";
|
|
4
|
+
import { Command, Option } from "clipanion";
|
|
5
|
+
import { Case } from "change-case-all";
|
|
6
|
+
import path from "path";
|
|
7
|
+
import * as fs from "fs/promises";
|
|
8
|
+
import { fileURLToPath } from "url";
|
|
9
|
+
import handlebars from "handlebars";
|
|
10
|
+
import { execSync } from "child_process";
|
|
11
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
12
|
+
class CreateProjectCommand extends Command {
|
|
13
|
+
static {
|
|
14
|
+
__name(this, "CreateProjectCommand");
|
|
15
|
+
}
|
|
16
|
+
static paths = [
|
|
17
|
+
[
|
|
18
|
+
`create`,
|
|
19
|
+
`project`
|
|
20
|
+
]
|
|
21
|
+
];
|
|
22
|
+
static usage = Command.Usage({
|
|
23
|
+
category: `Project`,
|
|
24
|
+
description: `Create a new project`,
|
|
25
|
+
details: `
|
|
26
|
+
This command creates a new project with the specified name at the given path.
|
|
27
|
+
If no path is provided, the project will be created in the current directory.
|
|
28
|
+
`,
|
|
29
|
+
examples: [
|
|
30
|
+
[
|
|
31
|
+
`Create a new project in the current directory`,
|
|
32
|
+
`create project my-project`
|
|
33
|
+
],
|
|
34
|
+
[
|
|
35
|
+
`Create a new project at a specific path`,
|
|
36
|
+
`create project my-project --path /path/to/projects`
|
|
37
|
+
]
|
|
38
|
+
]
|
|
39
|
+
});
|
|
40
|
+
projectPath = Option.String(`--path`, process.cwd(), {
|
|
41
|
+
description: `Path where the project should be created`
|
|
42
|
+
});
|
|
43
|
+
git = Option.Boolean(`--git`, false, {
|
|
44
|
+
description: `Initialize a git repository in the new project`
|
|
45
|
+
});
|
|
46
|
+
async execute() {
|
|
47
|
+
const projectPath = path.join(this.projectPath);
|
|
48
|
+
try {
|
|
49
|
+
await fs.access(projectPath);
|
|
50
|
+
console.error(`Error: Directory ${projectPath} already exists.`);
|
|
51
|
+
return 1;
|
|
52
|
+
} catch {
|
|
53
|
+
}
|
|
54
|
+
await fs.mkdir(projectPath, {
|
|
55
|
+
recursive: true
|
|
56
|
+
});
|
|
57
|
+
console.log(`Created project directory at: ${projectPath}`);
|
|
58
|
+
const baseProjectPath = path.join(__dirname, `./base_project`);
|
|
59
|
+
await this.processTplFolder(baseProjectPath, projectPath, {});
|
|
60
|
+
console.log(`Copied base project files to: ${projectPath}`);
|
|
61
|
+
const packageJsonPath = path.join(projectPath, `package.json`);
|
|
62
|
+
const packageJson = JSON.parse(await fs.readFile(packageJsonPath, `utf-8`));
|
|
63
|
+
packageJson.name = Case.snake(path.basename(projectPath));
|
|
64
|
+
await fs.writeFile(packageJsonPath, JSON.stringify(packageJson, null, 2));
|
|
65
|
+
console.log(`Updated package.json with project name: ${packageJson.name}`);
|
|
66
|
+
if (this.git) {
|
|
67
|
+
try {
|
|
68
|
+
execSync('git init; git add --all; git commit --allow-empty -m "chore: first commit for pashmak"', {
|
|
69
|
+
cwd: projectPath
|
|
70
|
+
});
|
|
71
|
+
} catch (error) {
|
|
72
|
+
console.error(`Failed to create project.`, error);
|
|
73
|
+
return 1;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
async processTplFolder(src, dest, data = {}) {
|
|
78
|
+
const files = await fs.readdir(src, {
|
|
79
|
+
withFileTypes: true
|
|
80
|
+
});
|
|
81
|
+
for (const file of files) {
|
|
82
|
+
const srcPath = path.join(src, file.name);
|
|
83
|
+
const destPath = file.isFile() && file.name.endsWith(".tpl") ? path.join(dest, file.name.substring(0, file.name.length - 4)) : path.join(dest, file.name);
|
|
84
|
+
if (file.isDirectory()) {
|
|
85
|
+
await fs.mkdir(destPath, {
|
|
86
|
+
recursive: true
|
|
87
|
+
});
|
|
88
|
+
await this.processTplFolder(srcPath, destPath, data);
|
|
89
|
+
} else if (file.name.endsWith(".tpl")) {
|
|
90
|
+
await this.processTplFile(srcPath, destPath, {});
|
|
91
|
+
} else {
|
|
92
|
+
throw new Error("unexpected non tpl file");
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
async processTplFile(src, dest, data = {}) {
|
|
97
|
+
const compiledTemplate = handlebars.compile((await fs.readFile(src)).toString());
|
|
98
|
+
const template = await compiledTemplate(data);
|
|
99
|
+
await fs.writeFile(dest, template);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
cli().register(CreateProjectCommand);
|
|
103
|
+
export {
|
|
104
|
+
CreateProjectCommand
|
|
105
|
+
};
|
|
106
|
+
//# sourceMappingURL=CreateProjectCommand.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/app/console/project/CreateProjectCommand.ts"],"sourcesContent":["import { cli } from \"../../../facades\";\nimport { Command, Option } from \"clipanion\";\nimport { Case } from \"change-case-all\";\nimport path from \"path\";\nimport * as fs from \"fs/promises\";\nimport { fileURLToPath } from \"url\";\nimport handlebars from \"handlebars\";\nimport { execSync } from \"child_process\";\nconst __dirname = path.dirname(fileURLToPath(import.meta.url));\n\nexport class CreateProjectCommand extends Command {\n static paths = [[`create`, `project`]];\n\n static usage = Command.Usage({\n category: `Project`,\n description: `Create a new project`,\n details: `\n This command creates a new project with the specified name at the given path.\n If no path is provided, the project will be created in the current directory.\n `,\n examples: [\n [\n `Create a new project in the current directory`,\n `create project my-project`,\n ],\n [\n `Create a new project at a specific path`,\n `create project my-project --path /path/to/projects`,\n ],\n ],\n });\n\n projectPath = Option.String(`--path`, process.cwd(), {\n description: `Path where the project should be created`,\n });\n\n git = Option.Boolean(`--git`, false, {\n description: `Initialize a git repository in the new project`,\n });\n\n async execute() {\n // Create the project directory path by joining the specified path and project name\n const projectPath = path.join(this.projectPath);\n // Check if directory already exists\n try {\n await fs.access(projectPath);\n console.error(`Error: Directory ${projectPath} already exists.`);\n return 1;\n } catch {\n // Directory doesn't exist, we can proceed\n }\n\n await fs.mkdir(projectPath, { recursive: true });\n console.log(`Created project directory at: ${projectPath}`);\n\n //copy content of ./base_project to the new project directory\n const baseProjectPath = path.join(__dirname, `./base_project`);\n\n await this.processTplFolder(baseProjectPath, projectPath, {});\n console.log(`Copied base project files to: ${projectPath}`);\n\n //modify package.json with foldername\n const packageJsonPath = path.join(projectPath, `package.json`);\n const packageJson = JSON.parse(await fs.readFile(packageJsonPath, `utf-8`));\n packageJson.name = Case.snake(path.basename(projectPath));\n await fs.writeFile(packageJsonPath, JSON.stringify(packageJson, null, 2));\n console.log(`Updated package.json with project name: ${packageJson.name}`);\n\n if (this.git) {\n try {\n execSync(\n 'git init; git add --all; git commit --allow-empty -m \"chore: first commit for pashmak\"',\n {\n cwd: projectPath,\n },\n );\n } catch (error) {\n console.error(`Failed to create project.`, error);\n return 1;\n }\n }\n }\n\n async processTplFolder(src: string, dest: string, data: any = {}) {\n const files = await fs.readdir(src, { withFileTypes: true });\n for (const file of files) {\n const srcPath = path.join(src, file.name);\n const destPath =\n file.isFile() && file.name.endsWith(\".tpl\")\n ? path.join(dest, file.name.substring(0, file.name.length - 4))\n : path.join(dest, file.name);\n\n if (file.isDirectory()) {\n await fs.mkdir(destPath, { recursive: true });\n await this.processTplFolder(srcPath, destPath, data);\n } else if (file.name.endsWith(\".tpl\")) {\n await this.processTplFile(srcPath, destPath, {});\n } else {\n throw new Error(\"unexpected non tpl file\");\n }\n }\n }\n\n async processTplFile(src: string, dest: string, data: any = {}) {\n const compiledTemplate = handlebars.compile(\n (await fs.readFile(src)).toString(),\n );\n const template = await compiledTemplate(data);\n await fs.writeFile(dest, template);\n }\n}\n\ncli().register(CreateProjectCommand);\n"],"mappings":"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","names":["cli","Command","Option","Case","path","fs","fileURLToPath","handlebars","execSync","__dirname","dirname","url","CreateProjectCommand","paths","usage","Usage","category","description","details","examples","projectPath","String","process","cwd","git","Boolean","execute","join","access","console","error","mkdir","recursive","log","baseProjectPath","processTplFolder","packageJsonPath","packageJson","JSON","parse","readFile","name","snake","basename","writeFile","stringify","src","dest","data","files","readdir","withFileTypes","file","srcPath","destPath","isFile","endsWith","substring","length","isDirectory","processTplFile","Error","compiledTemplate","compile","toString","template","register"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# Initial Pashmak Framework Project
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "test-app",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "testing application for the entire repo",
|
|
5
|
+
"main": "./dist/index.js",
|
|
6
|
+
"module": "./dist/index.mjs",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"type": "module",
|
|
9
|
+
"files": [
|
|
10
|
+
"dist"
|
|
11
|
+
],
|
|
12
|
+
"scripts": {
|
|
13
|
+
"build": "tsup",
|
|
14
|
+
"start": "tsx dist/index.js",
|
|
15
|
+
"test": "vitest run",
|
|
16
|
+
"test:watch": "vitest watch",
|
|
17
|
+
"test:coverage": "vitest run --coverage",
|
|
18
|
+
"format": "eslint . --fix --ext ts,tsx --report-unused-disable-directives --max-warnings 0 ",
|
|
19
|
+
"prepare": "husky",
|
|
20
|
+
"prettier": "prettier --write .",
|
|
21
|
+
"dev": "nodemon --watch src --ext ts,tsx,json --signal SIGTERM --exec \"clear && tsx -r tsconfig-paths/register src/index.ts start --all | npx pino-pretty\"",
|
|
22
|
+
"qdev": "tsx -r tsconfig-paths/register src/index.ts",
|
|
23
|
+
"clean": "rm -rf dist"
|
|
24
|
+
},
|
|
25
|
+
"author": "???",
|
|
26
|
+
"license": "MIT",
|
|
27
|
+
"devDependencies": {
|
|
28
|
+
"@swc/core": "^1.12.9",
|
|
29
|
+
"@types/config": "^3.3.5",
|
|
30
|
+
"@types/jsonwebtoken": "^9.0.9",
|
|
31
|
+
"@types/supertest": "^6.0.2",
|
|
32
|
+
"@types/yup": "^0.32.0",
|
|
33
|
+
"nodemon": "^3.1.10",
|
|
34
|
+
"supertest": "^6.3.3",
|
|
35
|
+
"tsx": "^4.20.3",
|
|
36
|
+
"typescript": "^5.8.3",
|
|
37
|
+
"vitest": "^3.2.4"
|
|
38
|
+
},
|
|
39
|
+
"dependencies": {
|
|
40
|
+
"@devbro/pashmak": "0.1.0",
|
|
41
|
+
"bcryptjs": "^3.0.2",
|
|
42
|
+
"clipanion": "^4.0.0-rc.4",
|
|
43
|
+
"dotenv": "^16.5.0",
|
|
44
|
+
"jsonwebtoken": "^9.0.2",
|
|
45
|
+
"tsconfig-paths": "^4.2.0",
|
|
46
|
+
"yup": "^1.6.1"
|
|
47
|
+
},
|
|
48
|
+
"directories": {
|
|
49
|
+
"doc": "docs",
|
|
50
|
+
"test": "tests"
|
|
51
|
+
},
|
|
52
|
+
"repository": {
|
|
53
|
+
"type": "git",
|
|
54
|
+
"url": "git+ssh://git@github.com/devbro1/pashmak.git"
|
|
55
|
+
},
|
|
56
|
+
"keywords": [
|
|
57
|
+
"pashmak"
|
|
58
|
+
],
|
|
59
|
+
"bugs": {
|
|
60
|
+
"url": "https://github.com/devbro1/pashmak/issues"
|
|
61
|
+
},
|
|
62
|
+
"homepage": "https://devbro1.github.io/pashmak/",
|
|
63
|
+
"tags": {
|
|
64
|
+
"needsCompile": true,
|
|
65
|
+
"canPublishToNpm": false
|
|
66
|
+
}
|
|
67
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { Command, Option } from "clipanion";
|
|
2
|
+
import { cli } from "@devbro/pashmak/facades";
|
|
3
|
+
|
|
4
|
+
export class YourFirstCommand extends Command {
|
|
5
|
+
static paths = [
|
|
6
|
+
[`hello`],
|
|
7
|
+
];
|
|
8
|
+
|
|
9
|
+
static usage = Command.Usage({
|
|
10
|
+
category: `Main`,
|
|
11
|
+
description: `First example command.`,
|
|
12
|
+
details: `
|
|
13
|
+
This command says hello to the world.
|
|
14
|
+
`,
|
|
15
|
+
examples: [],
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
async execute() {
|
|
19
|
+
console.log("Hello world!");
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
cli().register(YourFirstCommand);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./YourFirstCommand";
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import {
|
|
2
|
+
BaseController,
|
|
3
|
+
Controller,
|
|
4
|
+
Get,
|
|
5
|
+
} from "@devbro/pashmak/router";
|
|
6
|
+
|
|
7
|
+
@Controller("/api/v1/hello", { middlewares: [] })
|
|
8
|
+
export class HelloController extends BaseController {
|
|
9
|
+
@Get({ middlewares: [] })
|
|
10
|
+
async show() {
|
|
11
|
+
|
|
12
|
+
return {
|
|
13
|
+
message: "Hello world!",
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
all models associated in our db
|
|
File without changes
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import path from "path";
|
|
2
|
+
import os from "os";
|
|
3
|
+
import { getEnv } from "@devbro/pashmak/helper";
|
|
4
|
+
import { dirname } from "path";
|
|
5
|
+
import { fileURLToPath } from "url";
|
|
6
|
+
|
|
7
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
8
|
+
const __dirname = dirname(__filename);
|
|
9
|
+
|
|
10
|
+
export default {
|
|
11
|
+
databases: await import("./databases"),
|
|
12
|
+
storages: await import("./storages"),
|
|
13
|
+
port: getEnv("PORT", 3000),
|
|
14
|
+
file_upload_path: path.join(os.tmpdir(), ""),
|
|
15
|
+
migration: {
|
|
16
|
+
path: path.join(__dirname, "..", "database/migrations"),
|
|
17
|
+
},
|
|
18
|
+
loggers: await import("./loggers"),
|
|
19
|
+
jwt: {
|
|
20
|
+
options: {
|
|
21
|
+
algorithm: "RS256",
|
|
22
|
+
expiresIn: 8 * 3600,
|
|
23
|
+
},
|
|
24
|
+
refresh_options: {
|
|
25
|
+
algorithm: "RS256",
|
|
26
|
+
expiresIn: 3 * 24 * 3600,
|
|
27
|
+
},
|
|
28
|
+
secret:
|
|
29
|
+
"-----BEGIN PRIVATE KEY-----\n" +
|
|
30
|
+
process.env.jwt_secret_private +
|
|
31
|
+
"\n-----END PRIVATE KEY-----\n",
|
|
32
|
+
public:
|
|
33
|
+
"-----BEGIN PUBLIC KEY-----\n" +
|
|
34
|
+
process.env.jwt_secret_public +
|
|
35
|
+
"\n-----END PUBLIC KEY-----\n",
|
|
36
|
+
public_retired:
|
|
37
|
+
"-----BEGIN PUBLIC KEY-----\n" +
|
|
38
|
+
process.env.jwt_secret_public_retired +
|
|
39
|
+
"\n-----END PUBLIC KEY-----\n",
|
|
40
|
+
},
|
|
41
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { ctxSafe } from "@devbro/pashmak/context";
|
|
2
|
+
import { LogMessage } from "@devbro/pashmak/logger";
|
|
3
|
+
|
|
4
|
+
export default {
|
|
5
|
+
level: process.env.NODE_ENV === "test" ? "silent" : "info",
|
|
6
|
+
extrasFunction: (message: LogMessage) => {
|
|
7
|
+
let requestId = ctxSafe()?.get("requestId");
|
|
8
|
+
requestId && (message.requestId = requestId);
|
|
9
|
+
return message;
|
|
10
|
+
},
|
|
11
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export default {};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Blueprint } from "@devbro/pashmak/sql";
|
|
2
|
+
import { Migration } from "@devbro/pashmak/sql";
|
|
3
|
+
import { Schema } from "@devbro/pashmak/sql";
|
|
4
|
+
|
|
5
|
+
export default class CreateAnimals extends Migration {
|
|
6
|
+
async up(schema: Schema) {
|
|
7
|
+
// add to db schema
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
async down(schema: Schema) {
|
|
11
|
+
// remove from db schema
|
|
12
|
+
}
|
|
13
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { HttpBadRequestError } from "@devbro/pashmak/http";
|
|
2
|
+
import jwt from "jsonwebtoken";
|
|
3
|
+
import { config } from "@devbro/pashmak/config";
|
|
4
|
+
|
|
5
|
+
export function createJwtToken(data: any, token_params: jwt.SignOptions = {}) {
|
|
6
|
+
const secret = config.get("jwt.secret") as string;
|
|
7
|
+
const token_params2 = config.get("jwt.options") as jwt.SignOptions;
|
|
8
|
+
const token = jwt.sign(data, secret, { ...token_params2, ...token_params });
|
|
9
|
+
|
|
10
|
+
if (!token) {
|
|
11
|
+
throw new Error("Unable to sign token !!");
|
|
12
|
+
}
|
|
13
|
+
return token;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export async function decodeJwtToken(token: string) {
|
|
17
|
+
if (await jwt.verify(token, config.get("jwt.public"))) {
|
|
18
|
+
return await jwt.decode(token);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
if (await jwt.verify(token, config.get("jwt.public_retired"))) {
|
|
22
|
+
return await jwt.decode(token);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
throw new HttpBadRequestError(
|
|
26
|
+
"bad token. invalid, expired, or signed with wrong key.",
|
|
27
|
+
);
|
|
28
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import "./initialize";
|
|
2
|
+
import { logger, cli } from "@devbro/pashmak/facades";
|
|
3
|
+
|
|
4
|
+
logger().info("start of everything");
|
|
5
|
+
|
|
6
|
+
const [node, app, ...args] = process.argv;
|
|
7
|
+
cli()
|
|
8
|
+
.runExit(args)
|
|
9
|
+
.then(() => {})
|
|
10
|
+
.catch((err: any) => {
|
|
11
|
+
logger().error(err);
|
|
12
|
+
});
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { ctx } from "@devbro/pashmak/context";
|
|
2
|
+
import { Request, Response } from "@devbro/pashmak/router";
|
|
3
|
+
import { logger } from "@devbro/pashmak/facades";
|
|
4
|
+
|
|
5
|
+
export async function loggerMiddleware(
|
|
6
|
+
req: Request,
|
|
7
|
+
res: Response,
|
|
8
|
+
next: () => Promise<void>,
|
|
9
|
+
): Promise<void> {
|
|
10
|
+
logger().info({
|
|
11
|
+
msg: "available context",
|
|
12
|
+
keys: ctx().keys(),
|
|
13
|
+
route: req.url,
|
|
14
|
+
});
|
|
15
|
+
await next();
|
|
16
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { Request, Response } from "@devbro/pashmak/router";
|
|
2
|
+
import { router as routerFunc, db as dbf } from "@devbro/pashmak/facades";
|
|
3
|
+
import { sleep } from "@devbro/pashmak/helper";
|
|
4
|
+
import { HelloController } from "./app/controllers/HelloController";
|
|
5
|
+
import { loggerMiddleware } from "./middlewares";
|
|
6
|
+
|
|
7
|
+
const router = routerFunc();
|
|
8
|
+
|
|
9
|
+
router.addGlobalMiddleware(loggerMiddleware);
|
|
10
|
+
router.addRoute(
|
|
11
|
+
["GET", "HEAD"],
|
|
12
|
+
"/api/v1/meow",
|
|
13
|
+
async (req: any, res: any) => {
|
|
14
|
+
return { message: "meow meow!" };
|
|
15
|
+
},
|
|
16
|
+
).addMiddleware([]);
|
|
17
|
+
|
|
18
|
+
router.addController(HelloController);
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { scheduler } from "@devbro/pashmak/facades";
|
|
2
|
+
import { context_provider } from "@devbro/pashmak/context";
|
|
3
|
+
import { db } from "@devbro/pashmak/facades";
|
|
4
|
+
import { logger } from "@devbro/pashmak/facades";
|
|
5
|
+
|
|
6
|
+
scheduler().setContextWrapper(
|
|
7
|
+
(fn: () => Promise<void>): (() => Promise<void>) => {
|
|
8
|
+
return async (): Promise<void> => {
|
|
9
|
+
await context_provider.run(async (): Promise<void> => {
|
|
10
|
+
await fn();
|
|
11
|
+
});
|
|
12
|
+
};
|
|
13
|
+
},
|
|
14
|
+
);
|
|
15
|
+
|
|
16
|
+
scheduler()
|
|
17
|
+
.call(async () => {
|
|
18
|
+
logger().info("scheduled Hello meow World");
|
|
19
|
+
})
|
|
20
|
+
.setCronTime("* * * * *")
|
|
21
|
+
.setName("hello world cron job")
|
|
22
|
+
.setRunOnStart(true);
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import "@/initialize";
|
|
2
|
+
|
|
3
|
+
import { describe, expect, test } from "vitest";
|
|
4
|
+
import supertest from "supertest";
|
|
5
|
+
import { httpServer } from "@devbro/pashmak/facades";
|
|
6
|
+
|
|
7
|
+
describe("basic tests", () => {
|
|
8
|
+
test("funcational controller", async () => {
|
|
9
|
+
const server = httpServer();
|
|
10
|
+
|
|
11
|
+
const s = supertest(server.getHttpHanlder());
|
|
12
|
+
|
|
13
|
+
let r = await s.get("/api/v1/meow");
|
|
14
|
+
expect(r.status).toBe(200);
|
|
15
|
+
expect(r.text).toContain("meow meow!");
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
test("class controller", async () => {
|
|
19
|
+
const server = httpServer();
|
|
20
|
+
|
|
21
|
+
const s = supertest(server.getHttpHanlder());
|
|
22
|
+
|
|
23
|
+
let r = await s.get("/api/v1/hello");
|
|
24
|
+
expect(r.status).toBe(200);
|
|
25
|
+
expect(r.text).toContain("Hello world!");
|
|
26
|
+
});
|
|
27
|
+
});
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
/* Visit https://aka.ms/tsconfig to read more about this file */
|
|
4
|
+
"composite": false /* Enable constraints that allow a TypeScript project to be used with project references. */,
|
|
5
|
+
"target": "ESNext" /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */,
|
|
6
|
+
"experimentalDecorators": true /* Enable experimental support for legacy experimental decorators. */,
|
|
7
|
+
"emitDecoratorMetadata": true /* Emit design-type metadata for decorated declarations in source files. */,
|
|
8
|
+
"module": "esnext" /* Specify what module code is generated. */,
|
|
9
|
+
"rootDir": "./src" /* Specify the root folder within your source files. */,
|
|
10
|
+
"moduleResolution": "bundler" /* Specify how TypeScript looks up a file from a given module specifier. */,
|
|
11
|
+
"baseUrl": "./src" /* Specify the base directory to resolve non-relative module names. */,
|
|
12
|
+
"paths": {} /* Specify a set of entries that re-map imports to additional lookup locations. */,
|
|
13
|
+
"allowImportingTsExtensions": true /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */,
|
|
14
|
+
"allowJs": true /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */,
|
|
15
|
+
"emitDeclarationOnly": true /* Only output d.ts files and not JavaScript files. */,
|
|
16
|
+
"declaration": true,
|
|
17
|
+
"outDir": "./dist" /* Specify an output folder for all emitted files. */,
|
|
18
|
+
"esModuleInterop": true /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */,
|
|
19
|
+
"forceConsistentCasingInFileNames": true /* Ensure that casing is correct in imports. */,
|
|
20
|
+
"strict": true /* Enable all strict type-checking options. */,
|
|
21
|
+
"skipLibCheck": true /* Skip type checking all .d.ts files. */
|
|
22
|
+
}
|
|
23
|
+
}
|