@devbro/pashmak 0.1.9 → 0.1.11

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 (48) hide show
  1. package/dist/app/console/DefaultCommand.mjs +3 -1
  2. package/dist/app/console/DefaultCommand.mjs.map +1 -1
  3. package/dist/app/console/KeyGenerateCommand.mjs +19 -17
  4. package/dist/app/console/KeyGenerateCommand.mjs.map +1 -1
  5. package/dist/app/console/StartCommand.mjs +9 -13
  6. package/dist/app/console/StartCommand.mjs.map +1 -1
  7. package/dist/app/console/generate/GenerateControllerCommand.mjs +14 -17
  8. package/dist/app/console/generate/GenerateControllerCommand.mjs.map +1 -1
  9. package/dist/app/console/generate/index.mjs +1 -1
  10. package/dist/app/console/generate/index.mjs.map +1 -1
  11. package/dist/app/console/index.mjs +7 -7
  12. package/dist/app/console/index.mjs.map +1 -1
  13. package/dist/app/console/migrate/GenerateMigrateCommand.mjs +14 -17
  14. package/dist/app/console/migrate/GenerateMigrateCommand.mjs.map +1 -1
  15. package/dist/app/console/migrate/MigrateCommand.d.mts +1 -0
  16. package/dist/app/console/migrate/MigrateCommand.mjs +38 -26
  17. package/dist/app/console/migrate/MigrateCommand.mjs.map +1 -1
  18. package/dist/app/console/migrate/MigrateRollbackCommand.d.mts +1 -1
  19. package/dist/app/console/migrate/MigrateRollbackCommand.mjs +7 -15
  20. package/dist/app/console/migrate/MigrateRollbackCommand.mjs.map +1 -1
  21. package/dist/app/console/migrate/index.mjs +3 -3
  22. package/dist/app/console/migrate/index.mjs.map +1 -1
  23. package/dist/app/console/project/CreateProjectCommand.mjs +17 -23
  24. package/dist/app/console/project/CreateProjectCommand.mjs.map +1 -1
  25. package/dist/bin/app/console/DefaultCommand.cjs +99 -7
  26. package/dist/bin/app/console/KeyGenerateCommand.cjs +117 -25
  27. package/dist/bin/app/console/StartCommand.cjs +105 -19
  28. package/dist/bin/app/console/generate/GenerateControllerCommand.cjs +114 -27
  29. package/dist/bin/app/console/generate/index.cjs +114 -27
  30. package/dist/bin/app/console/index.cjs +241 -159
  31. package/dist/bin/app/console/migrate/GenerateMigrateCommand.cjs +113 -26
  32. package/dist/bin/app/console/migrate/MigrateCommand.cjs +136 -34
  33. package/dist/bin/app/console/migrate/MigrateRollbackCommand.cjs +105 -23
  34. package/dist/bin/app/console/migrate/index.cjs +164 -73
  35. package/dist/bin/app/console/project/CreateProjectCommand.cjs +21 -27
  36. package/dist/bin/bin/pashmak_cli.cjs +21 -27
  37. package/dist/bin/facades.cjs +94 -4
  38. package/dist/bin/index.cjs +257 -176
  39. package/dist/bin/middlewares.cjs +94 -4
  40. package/dist/bin/pashmak_cli.mjs +2 -2
  41. package/dist/bin/pashmak_cli.mjs.map +1 -1
  42. package/dist/bin/router.cjs +95 -5
  43. package/dist/index.d.mts +1 -0
  44. package/dist/index.mjs +2 -5
  45. package/dist/index.mjs.map +1 -1
  46. package/dist/router.mjs +1 -1
  47. package/dist/router.mjs.map +1 -1
  48. package/package.json +4 -3
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/app/console/migrate/MigrateRollbackCommand.ts"],"sourcesContent":["import { cli, db as database } from \"../../../facades.mjs\";\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"]}
1
+ {"version":3,"sources":["../../../../src/app/console/migrate/MigrateRollbackCommand.mts"],"sourcesContent":["import { cli, db as database, logger } from \"../../../facades.mjs\";\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`, \"1\", {\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 limit $1\",\n bindings: [this.steps],\n });\n\n for (const migration of migrations) {\n const class_to_migrate = migration.filename;\n logger().info(`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,SAAS,KAAK,MAAM,UAAU,cAAc;AAC5C,SAAS,SAAS,cAAc;AAChC,SAAS,wBAAwB;AACjC,OAAO,UAAU;AACjB,OAAO,QAAQ;AACf,SAAS,cAAc;AAEvB,YAAY,OAAO;AAEZ,MAAM,+BAA+B,QAAQ;AAAA,EATpD,OASoD;AAAA;AAAA;AAAA,EAClD,OAAO,QAAQ,CAAC,CAAC,WAAW,UAAU,CAAC;AAAA,EAEvC,QAAQ,OAAO,OAAO,WAAW,KAAK;AAAA,IACpC,aAAa;AAAA,IACb,WAAW,EAAE,SAAS;AAAA,EACxB,CAAC;AAAA,EAED,MAAM,UAAU;AACd,UAAM,iBAAiB,IAAI,YAAY;AAErC,YAAM,KAAK,SAAS;AACpB,YAAM,SAAS,GAAG,UAAU;AAE5B,YAAM,gBAAgB,OAAO,IAAI,gBAAgB;AACjD,UAAI,QAAkB,CAAC;AAEvB,YAAM,aAAa,MAAM,GAAG,QAAQ,aAAa;AACjD,cAAQ,WAAW,OAAO,CAAC,UAAU,MAAM,SAAS,KAAK,CAAC,EAAE,KAAK;AAEjE,YAAM,aAAa,MAAM,GAAG,SAAS;AAAA,QACnC,KAAK;AAAA,QACL,UAAU,CAAC,KAAK,KAAK;AAAA,MACvB,CAAC;AAED,iBAAW,aAAa,YAAY;AAClC,cAAM,mBAAmB,UAAU;AACnC,eAAO,EAAE,KAAK,gBAAgB,gBAAgB,EAAE;AAEhD,cAAM,kBACJ,MAAM,OAAO,KAAK,KAAK,eAAe,gBAAgB,IACtD;AAEF,cAAM,IAAe,IAAI,eAAe;AACxC,cAAM,EAAE,KAAK,GAAG,UAAU,CAAC;AAC3B,cAAM,GAAG,SAAS;AAAA,UAChB,KAAK;AAAA,UACL,UAAU,CAAC,UAAU,EAAE;AAAA,QACzB,CAAC;AAAA,MACH;AAAA,IACF,CAAC;AAAA,EACH;AACF;AAEA,IAAI,EAAE,SAAS,sBAAsB;","names":[]}
@@ -1,4 +1,4 @@
1
- export * from "./MigrateCommand";
2
- export * from "./GenerateMigrateCommand";
3
- export * from "./MigrateRollbackCommand";
1
+ export * from "./MigrateCommand.mjs";
2
+ export * from "./GenerateMigrateCommand.mjs";
3
+ export * from "./MigrateRollbackCommand.mjs";
4
4
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/app/console/migrate/index.ts"],"sourcesContent":["export * from \"./MigrateCommand\";\nexport * from \"./GenerateMigrateCommand\";\nexport * from \"./MigrateRollbackCommand\";\n"],"mappings":"AAAA,cAAc;AACd,cAAc;AACd,cAAc;","names":[]}
1
+ {"version":3,"sources":["../../../../src/app/console/migrate/index.mts"],"sourcesContent":["export * from \"./MigrateCommand.mjs\";\nexport * from \"./GenerateMigrateCommand.mjs\";\nexport * from \"./MigrateRollbackCommand.mjs\";\n"],"mappings":"AAAA,cAAc;AACd,cAAc;AACd,cAAc;","names":[]}
@@ -11,12 +11,7 @@ class CreateProjectCommand extends Command {
11
11
  static {
12
12
  __name(this, "CreateProjectCommand");
13
13
  }
14
- static paths = [
15
- [
16
- `create`,
17
- `project`
18
- ]
19
- ];
14
+ static paths = [[`create`, `project`]];
20
15
  static usage = Command.Usage({
21
16
  category: `Project`,
22
17
  description: `Create a new project`,
@@ -35,9 +30,7 @@ class CreateProjectCommand extends Command {
35
30
  ]
36
31
  ]
37
32
  });
38
- projectPath = Option.String("--path", {
39
- required: true
40
- });
33
+ projectPath = Option.String("--path", { required: true });
41
34
  git = Option.Boolean(`--git`, false, {
42
35
  description: `Initialize a git repository in the new project`
43
36
  });
@@ -60,9 +53,7 @@ class CreateProjectCommand extends Command {
60
53
  return 1;
61
54
  } catch {
62
55
  }
63
- await fs.mkdir(projectPath, {
64
- recursive: true
65
- });
56
+ await fs.mkdir(projectPath, { recursive: true });
66
57
  console.log(`Created project directory at: ${projectPath}`);
67
58
  const dirname = typeof __dirname === "undefined" ? path.dirname(fileURLToPath(import.meta.url)) : __dirname;
68
59
  let basePath = path.join(dirname, `./base_project`);
@@ -80,9 +71,12 @@ class CreateProjectCommand extends Command {
80
71
  console.log(`Updated package.json with project name: ${packageJson.name}`);
81
72
  if (this.git) {
82
73
  try {
83
- execSync('git init; git add --all; git commit --allow-empty -m "chore: first commit for pashmak"', {
84
- cwd: projectPath
85
- });
74
+ execSync(
75
+ 'git init; git add --all; git commit --allow-empty -m "chore: first commit for pashmak"',
76
+ {
77
+ cwd: projectPath
78
+ }
79
+ );
86
80
  } catch (error) {
87
81
  console.error(`Failed to create project.`, error);
88
82
  return 1;
@@ -90,26 +84,26 @@ class CreateProjectCommand extends Command {
90
84
  }
91
85
  }
92
86
  async processTplFolder(src, dest, data = {}) {
93
- const files = await fs.readdir(src, {
94
- withFileTypes: true
95
- });
87
+ const files = await fs.readdir(src, { withFileTypes: true });
96
88
  for (const file of files) {
97
89
  const srcPath = path.join(src, file.name);
98
90
  const destPath = file.isFile() && file.name.endsWith(".tpl") ? path.join(dest, file.name.substring(0, file.name.length - 4)) : path.join(dest, file.name);
99
91
  if (file.isDirectory()) {
100
- await fs.mkdir(destPath, {
101
- recursive: true
102
- });
92
+ await fs.mkdir(destPath, { recursive: true });
103
93
  await this.processTplFolder(srcPath, destPath, data);
104
94
  } else if (file.name.endsWith(".tpl")) {
105
95
  await this.processTplFile(srcPath, destPath, {});
106
96
  } else {
107
- throw new Error("unexpected non tpl file: " + srcPath + " " + file.name);
97
+ throw new Error(
98
+ "unexpected non tpl file: " + srcPath + " " + file.name
99
+ );
108
100
  }
109
101
  }
110
102
  }
111
103
  async processTplFile(src, dest, data = {}) {
112
- const compiledTemplate = handlebars.compile((await fs.readFile(src)).toString());
104
+ const compiledTemplate = handlebars.compile(
105
+ (await fs.readFile(src)).toString()
106
+ );
113
107
  const template = await compiledTemplate(data);
114
108
  await fs.writeFile(dest, template);
115
109
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/app/console/project/CreateProjectCommand.ts"],"sourcesContent":["import { 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\";\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 specified directory`,\n `create project --path /path/to/my-project --git`,\n ],\n [\n `Create a new project at a specific path with git initialized`,\n `create project --path /path/to/my-project --git`,\n ],\n ],\n });\n\n projectPath = Option.String(\"--path\", { required: true });\n\n git = Option.Boolean(`--git`, false, {\n description: `Initialize a git repository in the new project`,\n });\n\n async folderExists(folderPath: string): Promise<boolean> {\n try {\n const stats = await fs.stat(folderPath);\n return stats.isDirectory();\n } catch (error: any) {\n if (error.code === \"ENOENT\") {\n return false; // Folder does not exist\n }\n throw error; // Other errors (e.g., permission issues)\n }\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 const dirname =\n typeof __dirname === \"undefined\"\n ? path.dirname(fileURLToPath(import.meta.url))\n : __dirname;\n\n let basePath = path.join(dirname, `./base_project`);\n if ((await this.folderExists(basePath)) === false) {\n // we are running a compiled code that was bundled and the code is running from ./dist/bin/ folder.\n basePath = path.join(dirname, `../app/console/project/base_project`);\n }\n\n console.log(`Using base project path: ${basePath}`);\n //copy content of ./base_project to the new project directory\n const baseProjectPath = basePath;\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(\n \"unexpected non tpl file: \" + srcPath + \" \" + file.name,\n );\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"],"mappings":"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","names":["Command","Option","Case","path","fs","fileURLToPath","handlebars","execSync","CreateProjectCommand","paths","usage","Usage","category","description","details","examples","projectPath","String","required","git","Boolean","folderExists","folderPath","stats","stat","isDirectory","error","code","execute","join","access","console","mkdir","recursive","log","dirname","__dirname","url","basePath","baseProjectPath","processTplFolder","packageJsonPath","packageJson","JSON","parse","readFile","name","snake","basename","writeFile","stringify","cwd","src","dest","data","files","readdir","withFileTypes","file","srcPath","destPath","isFile","endsWith","substring","length","processTplFile","Error","compiledTemplate","compile","toString","template"]}
1
+ {"version":3,"sources":["../../../../src/app/console/project/CreateProjectCommand.mts"],"sourcesContent":["import { 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\";\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 specified directory`,\n `create project --path /path/to/my-project --git`,\n ],\n [\n `Create a new project at a specific path with git initialized`,\n `create project --path /path/to/my-project --git`,\n ],\n ],\n });\n\n projectPath = Option.String(\"--path\", { required: true });\n\n git = Option.Boolean(`--git`, false, {\n description: `Initialize a git repository in the new project`,\n });\n\n async folderExists(folderPath: string): Promise<boolean> {\n try {\n const stats = await fs.stat(folderPath);\n return stats.isDirectory();\n } catch (error: any) {\n if (error.code === \"ENOENT\") {\n return false; // Folder does not exist\n }\n throw error; // Other errors (e.g., permission issues)\n }\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 const dirname =\n typeof __dirname === \"undefined\"\n ? path.dirname(fileURLToPath(import.meta.url))\n : __dirname;\n\n let basePath = path.join(dirname, `./base_project`);\n if ((await this.folderExists(basePath)) === false) {\n // we are running a compiled code that was bundled and the code is running from ./dist/bin/ folder.\n basePath = path.join(dirname, `../app/console/project/base_project`);\n }\n\n console.log(`Using base project path: ${basePath}`);\n //copy content of ./base_project to the new project directory\n const baseProjectPath = basePath;\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(\n \"unexpected non tpl file: \" + srcPath + \" \" + file.name,\n );\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"],"mappings":"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","names":[]}
@@ -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/app/console/DefaultCommand.ts
32
+ // src/app/console/DefaultCommand.mts
33
33
  var DefaultCommand_exports = {};
34
34
  __export(DefaultCommand_exports, {
35
35
  DefaultCommand: () => DefaultCommand
@@ -41,6 +41,9 @@ var import_clipanion2 = require("clipanion");
41
41
  var import_neko_context = require("@devbro/neko-context");
42
42
  var import_errors = require("@devbro/neko-http/errors");
43
43
 
44
+ // ../neko-router/dist/CompiledRoute.mjs
45
+ var import_stream = require("stream");
46
+
44
47
  // ../neko-router/dist/Middleware.mjs
45
48
  var Middleware = class {
46
49
  static {
@@ -118,6 +121,9 @@ var CompiledRoute = class {
118
121
  if (typeof value.toJson === "function") {
119
122
  return traverse(value.toJson());
120
123
  }
124
+ if (typeof value.toJSON === "function") {
125
+ return traverse(value.toJSON());
126
+ }
121
127
  if (Array.isArray(value)) {
122
128
  return value.map(traverse);
123
129
  }
@@ -142,7 +148,7 @@ var CompiledRoute = class {
142
148
  }
143
149
  return String(obj);
144
150
  }
145
- processResponseBody(res, controller_rc) {
151
+ async processResponseBody(res, controller_rc) {
146
152
  if (controller_rc && res.writableEnded) {
147
153
  throw new Error("cannot write to response, response has already ended");
148
154
  }
@@ -151,18 +157,36 @@ var CompiledRoute = class {
151
157
  }
152
158
  if (controller_rc) {
153
159
  const header_content_type = res.getHeader("Content-Type");
154
- if (!header_content_type && typeof controller_rc === "object") {
160
+ if (controller_rc instanceof import_stream.Stream || Buffer.isBuffer(controller_rc)) {
161
+ await this.writeAsync(res, controller_rc);
162
+ res.end();
163
+ } else if (!header_content_type && typeof controller_rc === "object") {
155
164
  res.setHeader("Content-Type", "application/json");
165
+ res.end(this.convertToString(controller_rc));
156
166
  } else if (!header_content_type) {
157
167
  res.setHeader("Content-Type", "text/plain");
168
+ res.end(this.convertToString(controller_rc));
169
+ } else {
170
+ res.end(this.convertToString(controller_rc));
158
171
  }
159
- res.end(this.convertToString(controller_rc));
160
172
  return;
161
173
  } else {
162
174
  res.statusCode = [200].includes(res.statusCode) ? 204 : res.statusCode;
163
175
  res.end();
164
176
  }
165
177
  }
178
+ async writeAsync(res, chunk) {
179
+ return new Promise((resolve, reject) => {
180
+ const ok = res.write(chunk, (err) => {
181
+ if (err) reject(err);
182
+ });
183
+ if (ok) {
184
+ resolve(0);
185
+ } else {
186
+ res.once("drain", resolve);
187
+ }
188
+ });
189
+ }
166
190
  async runMiddlewares(middlewares, req, res) {
167
191
  let index = 0;
168
192
  const me = this;
@@ -220,7 +244,7 @@ var Route = class {
220
244
  i = start;
221
245
  } else if (char === "*") {
222
246
  let start = i + 1;
223
- while (start < path2.length && /[a-zA-Z0-9_]/.test(path2[start])) {
247
+ while (start < path2.length && /[a-zA-Z0-9_\.]/.test(path2[start])) {
224
248
  start++;
225
249
  }
226
250
  tokens.push({ type: "WILDCARD", value: path2.slice(i + 1, start) });
@@ -290,6 +314,10 @@ var Route = class {
290
314
  params: r.groups || {}
291
315
  };
292
316
  }
317
+ prependMiddleware(middlewares) {
318
+ this.middlewares = [].concat(middlewares, this.middlewares);
319
+ return this;
320
+ }
293
321
  addMiddleware(middlewares) {
294
322
  this.middlewares = this.middlewares.concat(middlewares);
295
323
  return this;
@@ -304,6 +332,62 @@ var Route = class {
304
332
 
305
333
  // ../neko-router/dist/Router.mjs
306
334
  var import_path = __toESM(require("path"), 1);
335
+
336
+ // ../node_modules/url-join/lib/url-join.js
337
+ function normalize(strArray) {
338
+ var resultArray = [];
339
+ if (strArray.length === 0) {
340
+ return "";
341
+ }
342
+ if (typeof strArray[0] !== "string") {
343
+ throw new TypeError("Url must be a string. Received " + strArray[0]);
344
+ }
345
+ if (strArray[0].match(/^[^/:]+:\/*$/) && strArray.length > 1) {
346
+ var first = strArray.shift();
347
+ strArray[0] = first + strArray[0];
348
+ }
349
+ if (strArray[0].match(/^file:\/\/\//)) {
350
+ strArray[0] = strArray[0].replace(/^([^/:]+):\/*/, "$1:///");
351
+ } else {
352
+ strArray[0] = strArray[0].replace(/^([^/:]+):\/*/, "$1://");
353
+ }
354
+ for (var i = 0; i < strArray.length; i++) {
355
+ var component = strArray[i];
356
+ if (typeof component !== "string") {
357
+ throw new TypeError("Url must be a string. Received " + component);
358
+ }
359
+ if (component === "") {
360
+ continue;
361
+ }
362
+ if (i > 0) {
363
+ component = component.replace(/^[\/]+/, "");
364
+ }
365
+ if (i < strArray.length - 1) {
366
+ component = component.replace(/[\/]+$/, "");
367
+ } else {
368
+ component = component.replace(/[\/]+$/, "/");
369
+ }
370
+ resultArray.push(component);
371
+ }
372
+ var str = resultArray.join("/");
373
+ str = str.replace(/\/(\?|&|#[^!])/g, "$1");
374
+ var parts = str.split("?");
375
+ str = parts.shift() + (parts.length > 0 ? "?" : "") + parts.join("&");
376
+ return str;
377
+ }
378
+ __name(normalize, "normalize");
379
+ function urlJoin() {
380
+ var input;
381
+ if (typeof arguments[0] === "object") {
382
+ input = arguments[0];
383
+ } else {
384
+ input = [].slice.call(arguments);
385
+ }
386
+ return normalize(input);
387
+ }
388
+ __name(urlJoin, "urlJoin");
389
+
390
+ // ../neko-router/dist/Router.mjs
307
391
  var Router = class {
308
392
  static {
309
393
  __name(this, "Router");
@@ -328,6 +412,12 @@ var Router = class {
328
412
  }).addMiddleware([...controller.baseMiddlewares, ...route.middlewares]);
329
413
  }
330
414
  }
415
+ addRouter(path2, router2) {
416
+ for (const route of router2.routes) {
417
+ let path22 = urlJoin("/", path2, route.path);
418
+ this.addRoute(route.methods, path22, route.handler).addMiddleware(router2.getMiddlewares()).addMiddleware(route.getMiddlewares());
419
+ }
420
+ }
331
421
  addGlobalMiddleware(middlewares) {
332
422
  this.middlewares = this.middlewares.concat(middlewares);
333
423
  }
@@ -472,7 +562,7 @@ var mailer = (0, import_neko_helper.createSingleton)((label) => {
472
562
  return rc;
473
563
  });
474
564
 
475
- // src/app/console/DefaultCommand.ts
565
+ // src/app/console/DefaultCommand.mts
476
566
  var DefaultCommand = class extends import_clipanion2.Command {
477
567
  static {
478
568
  __name(this, "DefaultCommand");
@@ -490,7 +580,9 @@ var DefaultCommand = class extends import_clipanion2.Command {
490
580
  async execute() {
491
581
  const commandList = cli().registrations;
492
582
  const paths = [];
493
- commandList.forEach((index, val) => paths.push(index.builder.paths[0]?.join(" ") || ""));
583
+ commandList.forEach(
584
+ (index, val) => paths.push(index.builder.paths[0]?.join(" ") || "")
585
+ );
494
586
  console.log("Available commands:");
495
587
  for (const cmd of paths) {
496
588
  if (cmd) {
@@ -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/app/console/KeyGenerateCommand.ts
32
+ // src/app/console/KeyGenerateCommand.mts
33
33
  var KeyGenerateCommand_exports = {};
34
34
  __export(KeyGenerateCommand_exports, {
35
35
  KeyGenerateCommand: () => KeyGenerateCommand
@@ -37,13 +37,16 @@ __export(KeyGenerateCommand_exports, {
37
37
  module.exports = __toCommonJS(KeyGenerateCommand_exports);
38
38
  var import_clipanion2 = require("clipanion");
39
39
  var import_crypto = require("crypto");
40
- var import_promises = __toESM(require("fs/promises"));
41
- var import_path2 = __toESM(require("path"));
40
+ var import_promises = __toESM(require("fs/promises"), 1);
41
+ var import_path2 = __toESM(require("path"), 1);
42
42
 
43
43
  // src/router.mts
44
44
  var import_neko_context = require("@devbro/neko-context");
45
45
  var import_errors = require("@devbro/neko-http/errors");
46
46
 
47
+ // ../neko-router/dist/CompiledRoute.mjs
48
+ var import_stream = require("stream");
49
+
47
50
  // ../neko-router/dist/Middleware.mjs
48
51
  var Middleware = class {
49
52
  static {
@@ -121,6 +124,9 @@ var CompiledRoute = class {
121
124
  if (typeof value.toJson === "function") {
122
125
  return traverse(value.toJson());
123
126
  }
127
+ if (typeof value.toJSON === "function") {
128
+ return traverse(value.toJSON());
129
+ }
124
130
  if (Array.isArray(value)) {
125
131
  return value.map(traverse);
126
132
  }
@@ -145,7 +151,7 @@ var CompiledRoute = class {
145
151
  }
146
152
  return String(obj);
147
153
  }
148
- processResponseBody(res, controller_rc) {
154
+ async processResponseBody(res, controller_rc) {
149
155
  if (controller_rc && res.writableEnded) {
150
156
  throw new Error("cannot write to response, response has already ended");
151
157
  }
@@ -154,18 +160,36 @@ var CompiledRoute = class {
154
160
  }
155
161
  if (controller_rc) {
156
162
  const header_content_type = res.getHeader("Content-Type");
157
- if (!header_content_type && typeof controller_rc === "object") {
163
+ if (controller_rc instanceof import_stream.Stream || Buffer.isBuffer(controller_rc)) {
164
+ await this.writeAsync(res, controller_rc);
165
+ res.end();
166
+ } else if (!header_content_type && typeof controller_rc === "object") {
158
167
  res.setHeader("Content-Type", "application/json");
168
+ res.end(this.convertToString(controller_rc));
159
169
  } else if (!header_content_type) {
160
170
  res.setHeader("Content-Type", "text/plain");
171
+ res.end(this.convertToString(controller_rc));
172
+ } else {
173
+ res.end(this.convertToString(controller_rc));
161
174
  }
162
- res.end(this.convertToString(controller_rc));
163
175
  return;
164
176
  } else {
165
177
  res.statusCode = [200].includes(res.statusCode) ? 204 : res.statusCode;
166
178
  res.end();
167
179
  }
168
180
  }
181
+ async writeAsync(res, chunk) {
182
+ return new Promise((resolve, reject) => {
183
+ const ok = res.write(chunk, (err) => {
184
+ if (err) reject(err);
185
+ });
186
+ if (ok) {
187
+ resolve(0);
188
+ } else {
189
+ res.once("drain", resolve);
190
+ }
191
+ });
192
+ }
169
193
  async runMiddlewares(middlewares, req, res) {
170
194
  let index = 0;
171
195
  const me = this;
@@ -223,7 +247,7 @@ var Route = class {
223
247
  i = start;
224
248
  } else if (char === "*") {
225
249
  let start = i + 1;
226
- while (start < path3.length && /[a-zA-Z0-9_]/.test(path3[start])) {
250
+ while (start < path3.length && /[a-zA-Z0-9_\.]/.test(path3[start])) {
227
251
  start++;
228
252
  }
229
253
  tokens.push({ type: "WILDCARD", value: path3.slice(i + 1, start) });
@@ -293,6 +317,10 @@ var Route = class {
293
317
  params: r.groups || {}
294
318
  };
295
319
  }
320
+ prependMiddleware(middlewares) {
321
+ this.middlewares = [].concat(middlewares, this.middlewares);
322
+ return this;
323
+ }
296
324
  addMiddleware(middlewares) {
297
325
  this.middlewares = this.middlewares.concat(middlewares);
298
326
  return this;
@@ -307,6 +335,62 @@ var Route = class {
307
335
 
308
336
  // ../neko-router/dist/Router.mjs
309
337
  var import_path = __toESM(require("path"), 1);
338
+
339
+ // ../node_modules/url-join/lib/url-join.js
340
+ function normalize(strArray) {
341
+ var resultArray = [];
342
+ if (strArray.length === 0) {
343
+ return "";
344
+ }
345
+ if (typeof strArray[0] !== "string") {
346
+ throw new TypeError("Url must be a string. Received " + strArray[0]);
347
+ }
348
+ if (strArray[0].match(/^[^/:]+:\/*$/) && strArray.length > 1) {
349
+ var first = strArray.shift();
350
+ strArray[0] = first + strArray[0];
351
+ }
352
+ if (strArray[0].match(/^file:\/\/\//)) {
353
+ strArray[0] = strArray[0].replace(/^([^/:]+):\/*/, "$1:///");
354
+ } else {
355
+ strArray[0] = strArray[0].replace(/^([^/:]+):\/*/, "$1://");
356
+ }
357
+ for (var i = 0; i < strArray.length; i++) {
358
+ var component = strArray[i];
359
+ if (typeof component !== "string") {
360
+ throw new TypeError("Url must be a string. Received " + component);
361
+ }
362
+ if (component === "") {
363
+ continue;
364
+ }
365
+ if (i > 0) {
366
+ component = component.replace(/^[\/]+/, "");
367
+ }
368
+ if (i < strArray.length - 1) {
369
+ component = component.replace(/[\/]+$/, "");
370
+ } else {
371
+ component = component.replace(/[\/]+$/, "/");
372
+ }
373
+ resultArray.push(component);
374
+ }
375
+ var str = resultArray.join("/");
376
+ str = str.replace(/\/(\?|&|#[^!])/g, "$1");
377
+ var parts = str.split("?");
378
+ str = parts.shift() + (parts.length > 0 ? "?" : "") + parts.join("&");
379
+ return str;
380
+ }
381
+ __name(normalize, "normalize");
382
+ function urlJoin() {
383
+ var input;
384
+ if (typeof arguments[0] === "object") {
385
+ input = arguments[0];
386
+ } else {
387
+ input = [].slice.call(arguments);
388
+ }
389
+ return normalize(input);
390
+ }
391
+ __name(urlJoin, "urlJoin");
392
+
393
+ // ../neko-router/dist/Router.mjs
310
394
  var Router = class {
311
395
  static {
312
396
  __name(this, "Router");
@@ -331,6 +415,12 @@ var Router = class {
331
415
  }).addMiddleware([...controller.baseMiddlewares, ...route.middlewares]);
332
416
  }
333
417
  }
418
+ addRouter(path22, router2) {
419
+ for (const route of router2.routes) {
420
+ let path222 = urlJoin("/", path22, route.path);
421
+ this.addRoute(route.methods, path222, route.handler).addMiddleware(router2.getMiddlewares()).addMiddleware(route.getMiddlewares());
422
+ }
423
+ }
334
424
  addGlobalMiddleware(middlewares) {
335
425
  this.middlewares = this.middlewares.concat(middlewares);
336
426
  }
@@ -475,17 +565,12 @@ var mailer = (0, import_neko_helper.createSingleton)((label) => {
475
565
  return rc;
476
566
  });
477
567
 
478
- // src/app/console/KeyGenerateCommand.ts
568
+ // src/app/console/KeyGenerateCommand.mts
479
569
  var KeyGenerateCommand = class extends import_clipanion2.Command {
480
570
  static {
481
571
  __name(this, "KeyGenerateCommand");
482
572
  }
483
- static paths = [
484
- [
485
- `generate`,
486
- "key"
487
- ]
488
- ];
573
+ static paths = [[`generate`, "key"]];
489
574
  static usage = import_clipanion2.Command.Usage({
490
575
  category: `Main`,
491
576
  description: `generate keys`,
@@ -494,14 +579,8 @@ var KeyGenerateCommand = class extends import_clipanion2.Command {
494
579
  Use --rotate flag to preserve old public key.
495
580
  `,
496
581
  examples: [
497
- [
498
- `Generate new keys`,
499
- `generate key`
500
- ],
501
- [
502
- `Rotate existing keys`,
503
- `generate key --rotate`
504
- ]
582
+ [`Generate new keys`, `generate key`],
583
+ [`Rotate existing keys`, `generate key --rotate`]
505
584
  ]
506
585
  });
507
586
  rotate = import_clipanion2.Option.Boolean(`--rotate`, false, {
@@ -511,6 +590,7 @@ var KeyGenerateCommand = class extends import_clipanion2.Command {
511
590
  logger().info("generating keys for jwt token and adding to .env file");
512
591
  const { publicKey, privateKey } = (0, import_crypto.generateKeyPairSync)("rsa", {
513
592
  modulusLength: 2048,
593
+ // 2048-bit key is standard for RS256
514
594
  publicKeyEncoding: {
515
595
  type: "spki",
516
596
  format: "pem"
@@ -526,10 +606,22 @@ var KeyGenerateCommand = class extends import_clipanion2.Command {
526
606
  } catch {
527
607
  }
528
608
  let old_public_key = envfile.match(/^jwt_secret_public=(.*)/m);
529
- envfile = this.addEnvParam(envfile, "jwt_secret_public", this.stripPemHeaders(publicKey));
530
- envfile = this.addEnvParam(envfile, "jwt_secret_private", this.stripPemHeaders(privateKey));
609
+ envfile = this.addEnvParam(
610
+ envfile,
611
+ "jwt_secret_public",
612
+ this.stripPemHeaders(publicKey)
613
+ );
614
+ envfile = this.addEnvParam(
615
+ envfile,
616
+ "jwt_secret_private",
617
+ this.stripPemHeaders(privateKey)
618
+ );
531
619
  if (this.rotate && old_public_key && old_public_key[1]) {
532
- envfile = this.addEnvParam(envfile, "jwt_secret_public_retired", old_public_key[1]);
620
+ envfile = this.addEnvParam(
621
+ envfile,
622
+ "jwt_secret_public_retired",
623
+ old_public_key[1]
624
+ );
533
625
  }
534
626
  await import_promises.default.writeFile(import_path2.default.join(process.cwd(), ".env"), envfile, "utf-8");
535
627
  }