kroxt 1.2.2 → 1.3.1

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 (83) hide show
  1. package/README.md +116 -183
  2. package/dist/adapters/drizzle.d.ts +2 -1
  3. package/dist/adapters/drizzle.d.ts.map +1 -1
  4. package/dist/adapters/index.d.ts +9 -0
  5. package/dist/adapters/index.d.ts.map +1 -1
  6. package/dist/adapters/memory.d.ts.map +1 -1
  7. package/dist/adapters/mongoose.d.ts +7 -1
  8. package/dist/adapters/mongoose.d.ts.map +1 -1
  9. package/dist/adapters/prisma.d.ts +2 -1
  10. package/dist/adapters/prisma.d.ts.map +1 -1
  11. package/dist/{adapters → auth/adapters}/drizzle.cjs +33 -2
  12. package/dist/auth/adapters/drizzle.cjs.map +7 -0
  13. package/dist/auth/adapters/drizzle.js +58 -0
  14. package/dist/auth/adapters/drizzle.js.map +7 -0
  15. package/dist/{adapters → auth/adapters}/index.cjs.map +2 -2
  16. package/dist/{adapters → auth/adapters}/memory.cjs +28 -0
  17. package/dist/auth/adapters/memory.cjs.map +7 -0
  18. package/dist/auth/adapters/memory.js +59 -0
  19. package/dist/auth/adapters/memory.js.map +7 -0
  20. package/dist/auth/adapters/mongoose.cjs +99 -0
  21. package/dist/auth/adapters/mongoose.cjs.map +7 -0
  22. package/dist/auth/adapters/mongoose.js +74 -0
  23. package/dist/auth/adapters/mongoose.js.map +7 -0
  24. package/dist/{adapters → auth/adapters}/prisma.cjs +36 -2
  25. package/dist/auth/adapters/prisma.cjs.map +7 -0
  26. package/dist/auth/adapters/prisma.js +68 -0
  27. package/dist/auth/adapters/prisma.js.map +7 -0
  28. package/dist/{core → auth/core}/index.cjs +67 -2
  29. package/dist/auth/core/index.cjs.map +7 -0
  30. package/dist/auth/core/index.js +143 -0
  31. package/dist/auth/core/index.js.map +7 -0
  32. package/dist/{index.cjs → auth/index.cjs} +12 -4
  33. package/dist/{index.cjs.map → auth/index.cjs.map} +3 -3
  34. package/dist/{index.js → auth/index.js} +6 -1
  35. package/dist/{index.js.map → auth/index.js.map} +3 -3
  36. package/dist/{providers → auth/providers}/index.cjs.map +1 -1
  37. package/dist/{providers → auth/providers}/index.js.map +1 -1
  38. package/dist/{security → auth/security}/index.cjs +4 -1
  39. package/dist/{security → auth/security}/index.cjs.map +3 -3
  40. package/dist/{security → auth/security}/index.js +1 -0
  41. package/dist/{security → auth/security}/index.js.map +3 -3
  42. package/dist/auth/security/rate-limit.cjs +82 -0
  43. package/dist/auth/security/rate-limit.cjs.map +7 -0
  44. package/dist/auth/security/rate-limit.js +57 -0
  45. package/dist/auth/security/rate-limit.js.map +7 -0
  46. package/dist/cli/index.cjs +229 -0
  47. package/dist/cli/index.cjs.map +7 -0
  48. package/dist/cli/index.js +206 -0
  49. package/dist/cli/index.js.map +7 -0
  50. package/dist/cli/templates.cjs +202 -0
  51. package/dist/cli/templates.cjs.map +7 -0
  52. package/dist/cli/templates.js +165 -0
  53. package/dist/cli/templates.js.map +7 -0
  54. package/dist/core/index.d.ts +16 -1
  55. package/dist/core/index.d.ts.map +1 -1
  56. package/dist/index.d.ts +3 -1
  57. package/dist/index.d.ts.map +1 -1
  58. package/dist/security/index.d.ts +1 -0
  59. package/dist/security/index.d.ts.map +1 -1
  60. package/dist/security/rate-limit.d.ts +39 -0
  61. package/dist/security/rate-limit.d.ts.map +1 -0
  62. package/package.json +7 -1
  63. package/dist/adapters/drizzle.cjs.map +0 -7
  64. package/dist/adapters/drizzle.js +0 -27
  65. package/dist/adapters/drizzle.js.map +0 -7
  66. package/dist/adapters/memory.cjs.map +0 -7
  67. package/dist/adapters/memory.js +0 -31
  68. package/dist/adapters/memory.js.map +0 -7
  69. package/dist/adapters/mongoose.cjs +0 -55
  70. package/dist/adapters/mongoose.cjs.map +0 -7
  71. package/dist/adapters/mongoose.js +0 -31
  72. package/dist/adapters/mongoose.js.map +0 -7
  73. package/dist/adapters/prisma.cjs.map +0 -7
  74. package/dist/adapters/prisma.js +0 -34
  75. package/dist/adapters/prisma.js.map +0 -7
  76. package/dist/core/index.cjs.map +0 -7
  77. package/dist/core/index.js +0 -78
  78. package/dist/core/index.js.map +0 -7
  79. /package/dist/{adapters → auth/adapters}/index.cjs +0 -0
  80. /package/dist/{adapters → auth/adapters}/index.js +0 -0
  81. /package/dist/{adapters → auth/adapters}/index.js.map +0 -0
  82. /package/dist/{providers → auth/providers}/index.cjs +0 -0
  83. /package/dist/{providers → auth/providers}/index.js +0 -0
@@ -0,0 +1,229 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ var __create = Object.create;
4
+ var __defProp = Object.defineProperty;
5
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
+ var __getOwnPropNames = Object.getOwnPropertyNames;
7
+ var __getProtoOf = Object.getPrototypeOf;
8
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
9
+ var __copyProps = (to, from, except, desc) => {
10
+ if (from && typeof from === "object" || typeof from === "function") {
11
+ for (let key of __getOwnPropNames(from))
12
+ if (!__hasOwnProp.call(to, key) && key !== except)
13
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
14
+ }
15
+ return to;
16
+ };
17
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
18
+ // If the importer is in node compatibility mode or this is not an ESM
19
+ // file that has been converted to a CommonJS file using a Babel-
20
+ // compatible transform (i.e. "__esModule" has not been set), then set
21
+ // "default" to the CommonJS "module.exports" for node compatibility.
22
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
23
+ mod
24
+ ));
25
+ var import_commander = require("commander");
26
+ var import_enquirer = __toESM(require("enquirer"), 1);
27
+ var import_chalk = __toESM(require("chalk"), 1);
28
+ var import_fs = __toESM(require("fs"), 1);
29
+ var import_path = __toESM(require("path"), 1);
30
+ var import_crypto = __toESM(require("crypto"), 1);
31
+ var import_child_process = require("child_process");
32
+ var import_templates = require("./templates.js");
33
+ const program = new import_commander.Command();
34
+ const enquirer = new import_enquirer.default();
35
+ program.name("kroxt").description("Kroxt CLI for bootstrapping auth engines").version("1.0.0");
36
+ program.command("init").description("Initialize Kroxt in your project").option("-y, --yes", "Skip prompts and use defaults").action(async (options) => {
37
+ console.log(import_chalk.default.bold.white("\n\u2B22 KROXT AUTH INITIALIZER\n"));
38
+ try {
39
+ let response = {
40
+ adapter: "memory",
41
+ generateEnv: true,
42
+ useRateLimit: true,
43
+ useIPBlocking: true,
44
+ useStrictRevocation: true,
45
+ usePepper: true,
46
+ createModel: true,
47
+ targetDir: ""
48
+ };
49
+ const projectContext = getProjectContext();
50
+ const defaultDir = projectContext.isExpress ? projectContext.hasSrc ? "src/config" : "config" : projectContext.hasSrc ? "src/lib/kroxt" : "lib/kroxt";
51
+ if (!options.yes) {
52
+ response = await enquirer.prompt([
53
+ {
54
+ type: "select",
55
+ name: "adapter",
56
+ message: "Choose your database adapter:",
57
+ choices: [
58
+ { name: "memory", message: "In-Memory (Testing)" },
59
+ { name: "mongoose", message: "Mongoose (MongoDB)" },
60
+ { name: "prisma", message: "Prisma (PostgreSQL/MySQL)" },
61
+ { name: "drizzle", message: "Drizzle (SQLite/PostgreSQL)" },
62
+ { name: "none", message: "None (Manual Setup)" }
63
+ ]
64
+ },
65
+ {
66
+ type: "input",
67
+ name: "targetDir",
68
+ message: "Where should I put the Kroxt files?",
69
+ initial: defaultDir
70
+ },
71
+ {
72
+ type: "confirm",
73
+ name: "useRateLimit",
74
+ message: "Enable rate limiting defensive layer?",
75
+ initial: true
76
+ },
77
+ {
78
+ type: "confirm",
79
+ name: "useIPBlocking",
80
+ message: "Enable automatic IP blocking?",
81
+ initial: true
82
+ },
83
+ {
84
+ type: "confirm",
85
+ name: "useStrictRevocation",
86
+ message: "Enforce strict session revocation?",
87
+ initial: true
88
+ },
89
+ {
90
+ type: "confirm",
91
+ name: "usePepper",
92
+ message: "Use server-side password peppering?",
93
+ initial: true
94
+ },
95
+ {
96
+ type: "confirm",
97
+ name: "createModel",
98
+ message: "Create a boilerplate User model for you?",
99
+ initial: true
100
+ },
101
+ {
102
+ type: "confirm",
103
+ name: "generateEnv",
104
+ message: "Generate secure secrets in .env?",
105
+ initial: true
106
+ }
107
+ ]);
108
+ } else {
109
+ console.log(import_chalk.default.gray("Using default settings (--yes)..."));
110
+ response = {
111
+ ...response,
112
+ useRateLimit: true,
113
+ useIPBlocking: true,
114
+ useStrictRevocation: true,
115
+ usePepper: true,
116
+ createModel: true,
117
+ targetDir: defaultDir
118
+ };
119
+ }
120
+ const secret = import_crypto.default.randomBytes(32).toString("hex");
121
+ const authContent = (0, import_templates.authTemplate)(response.adapter, secret, response);
122
+ const authPath = import_path.default.join(process.cwd(), response.targetDir, "auth.ts");
123
+ const dirPath = import_path.default.dirname(authPath);
124
+ if (!import_fs.default.existsSync(dirPath)) {
125
+ import_fs.default.mkdirSync(dirPath, { recursive: true });
126
+ }
127
+ import_fs.default.writeFileSync(authPath, authContent);
128
+ console.log(import_chalk.default.green(`
129
+ \u2714 Created: ${import_chalk.default.white(import_path.default.relative(process.cwd(), authPath))}`));
130
+ const tsConfigPath = import_path.default.join(process.cwd(), "tsconfig.json");
131
+ if (!import_fs.default.existsSync(tsConfigPath)) {
132
+ import_fs.default.writeFileSync(tsConfigPath, import_templates.tsConfigTemplate);
133
+ console.log(import_chalk.default.green(`\u2714 Created: ${import_chalk.default.white("tsconfig.json")}`));
134
+ }
135
+ if (response.createModel && response.adapter !== "memory" && response.adapter !== "none") {
136
+ let modelPath = "";
137
+ switch (response.adapter) {
138
+ case "mongoose":
139
+ modelPath = import_path.default.join(process.cwd(), response.targetDir, "user.model.ts");
140
+ break;
141
+ case "drizzle":
142
+ modelPath = import_path.default.join(process.cwd(), response.targetDir, "schema.ts");
143
+ break;
144
+ case "prisma":
145
+ modelPath = import_path.default.join(process.cwd(), response.targetDir, "user.prisma");
146
+ break;
147
+ }
148
+ if (modelPath) {
149
+ const modelDirPath = import_path.default.dirname(modelPath);
150
+ if (!import_fs.default.existsSync(modelDirPath)) {
151
+ import_fs.default.mkdirSync(modelDirPath, { recursive: true });
152
+ }
153
+ const { userModelTemplate } = await import("./templates.js");
154
+ import_fs.default.writeFileSync(modelPath, userModelTemplate(response.adapter));
155
+ console.log(import_chalk.default.green(`\u2714 Created: ${import_chalk.default.white(import_path.default.relative(process.cwd(), modelPath))}`));
156
+ }
157
+ }
158
+ if (response.generateEnv) {
159
+ const envPath = import_path.default.join(process.cwd(), ".env");
160
+ const envContent = (0, import_templates.envTemplate)(secret, response.usePepper);
161
+ if (import_fs.default.existsSync(envPath)) {
162
+ import_fs.default.appendFileSync(envPath, envContent);
163
+ console.log(import_chalk.default.green(`\u2714 Updated: ${import_chalk.default.white(".env")} (Appended JWT_SECRET)`));
164
+ } else {
165
+ import_fs.default.writeFileSync(envPath, envContent);
166
+ console.log(import_chalk.default.green(`\u2714 Created: ${import_chalk.default.white(".env")}`));
167
+ }
168
+ }
169
+ console.log(import_chalk.default.bold.white("\nKroxt is ready. Happy coding! \u{1F680}\n"));
170
+ await checkAndInstallDeps(response.adapter, !!options.yes);
171
+ } catch (err) {
172
+ console.error(import_chalk.default.red("\n\u2716 Initialization cancelled."));
173
+ process.exit(1);
174
+ }
175
+ });
176
+ async function checkAndInstallDeps(adapter, skipPrompts = false) {
177
+ const pkgPath = import_path.default.join(process.cwd(), "package.json");
178
+ if (!import_fs.default.existsSync(pkgPath)) return;
179
+ const pkg = JSON.parse(import_fs.default.readFileSync(pkgPath, "utf8"));
180
+ const deps = { ...pkg.dependencies, ...pkg.devDependencies };
181
+ const required = {
182
+ memory: ["kroxt", "dotenv"],
183
+ mongoose: ["kroxt", "mongoose", "dotenv"],
184
+ prisma: ["kroxt", "@prisma/client", "dotenv"],
185
+ drizzle: ["kroxt", "drizzle-orm", "dotenv"],
186
+ none: ["kroxt"]
187
+ };
188
+ const packages = required[adapter] || [];
189
+ const missing = packages.filter((dep) => !deps[dep]);
190
+ if (missing.length > 0) {
191
+ let confirm = true;
192
+ if (!skipPrompts) {
193
+ const enquirer2 = new import_enquirer.default();
194
+ const result = await enquirer2.prompt({
195
+ type: "confirm",
196
+ name: "confirm",
197
+ message: `Required dependencies are missing: ${import_chalk.default.cyan(missing.join(", "))}. Install them now?`,
198
+ initial: true
199
+ });
200
+ confirm = result.confirm;
201
+ }
202
+ if (confirm) {
203
+ console.log(import_chalk.default.gray(`
204
+ Installing ${missing.join(", ")}...`));
205
+ return new Promise((resolve) => {
206
+ const child = (0, import_child_process.spawn)("npm", ["install", ...missing], {
207
+ stdio: "inherit",
208
+ shell: true
209
+ });
210
+ child.on("close", resolve);
211
+ });
212
+ }
213
+ }
214
+ }
215
+ function getProjectContext() {
216
+ const hasSrc = import_fs.default.existsSync(import_path.default.join(process.cwd(), "src"));
217
+ const pkgPath = import_path.default.join(process.cwd(), "package.json");
218
+ let isExpress = false;
219
+ let isNext = false;
220
+ if (import_fs.default.existsSync(pkgPath)) {
221
+ const pkg = JSON.parse(import_fs.default.readFileSync(pkgPath, "utf8"));
222
+ const deps = { ...pkg.dependencies, ...pkg.devDependencies };
223
+ isExpress = !!(deps.express || deps.fastify);
224
+ isNext = !!deps.next;
225
+ }
226
+ return { hasSrc, isExpress, isNext };
227
+ }
228
+ program.parse(process.argv);
229
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/cli/index.ts"],
4
+ "sourcesContent": ["#!/usr/bin/env node\nimport { Command } from 'commander';\nimport Enquirer from 'enquirer';\nimport chalk from 'chalk';\nimport fs from 'fs';\nimport path from 'path';\nimport crypto from 'crypto';\nimport { spawn } from 'child_process';\nimport { authTemplate, envTemplate, tsConfigTemplate } from './templates.js';\n\nconst program = new Command();\nconst enquirer = new Enquirer();\n\nprogram\n .name('kroxt')\n .description('Kroxt CLI for bootstrapping auth engines')\n .version('1.0.0');\n\nprogram\n .command('init')\n .description('Initialize Kroxt in your project')\n .option('-y, --yes', 'Skip prompts and use defaults')\n .action(async (options) => {\n console.log(chalk.bold.white('\\n\u2B22 KROXT AUTH INITIALIZER\\n'));\n\n try {\n let response = {\n adapter: 'memory',\n generateEnv: true,\n useRateLimit: true,\n useIPBlocking: true,\n useStrictRevocation: true,\n usePepper: true,\n createModel: true,\n targetDir: ''\n };\n\n const projectContext = getProjectContext();\n const defaultDir = projectContext.isExpress ? (projectContext.hasSrc ? 'src/config' : 'config') : (projectContext.hasSrc ? 'src/lib/kroxt' : 'lib/kroxt');\n\n if (!options.yes) {\n response = await enquirer.prompt([\n {\n type: 'select',\n name: 'adapter',\n message: 'Choose your database adapter:',\n choices: [\n { name: 'memory', message: 'In-Memory (Testing)' },\n { name: 'mongoose', message: 'Mongoose (MongoDB)' },\n { name: 'prisma', message: 'Prisma (PostgreSQL/MySQL)' },\n { name: 'drizzle', message: 'Drizzle (SQLite/PostgreSQL)' },\n { name: 'none', message: 'None (Manual Setup)' }\n ]\n },\n {\n type: 'input',\n name: 'targetDir',\n message: 'Where should I put the Kroxt files?',\n initial: defaultDir\n },\n {\n type: 'confirm',\n name: 'useRateLimit',\n message: 'Enable rate limiting defensive layer?',\n initial: true\n },\n {\n type: 'confirm',\n name: 'useIPBlocking',\n message: 'Enable automatic IP blocking?',\n initial: true\n },\n {\n type: 'confirm',\n name: 'useStrictRevocation',\n message: 'Enforce strict session revocation?',\n initial: true\n },\n {\n type: 'confirm',\n name: 'usePepper',\n message: 'Use server-side password peppering?',\n initial: true\n },\n {\n type: 'confirm',\n name: 'createModel',\n message: 'Create a boilerplate User model for you?',\n initial: true\n },\n {\n type: 'confirm',\n name: 'generateEnv',\n message: 'Generate secure secrets in .env?',\n initial: true\n }\n ]) as any;\n } else {\n console.log(chalk.gray('Using default settings (--yes)...'));\n response = {\n ...response,\n useRateLimit: true,\n useIPBlocking: true,\n useStrictRevocation: true,\n usePepper: true,\n createModel: true,\n targetDir: defaultDir\n } as any;\n }\n\n const secret = crypto.randomBytes(32).toString('hex');\n const authContent = authTemplate(response.adapter, secret, response);\n\n // Write auth.ts\n const authPath = path.join(process.cwd(), response.targetDir, 'auth.ts');\n const dirPath = path.dirname(authPath);\n\n if (!fs.existsSync(dirPath)) {\n fs.mkdirSync(dirPath, { recursive: true });\n }\n\n fs.writeFileSync(authPath, authContent);\n console.log(chalk.green(`\\n\u2714 Created: ${chalk.white(path.relative(process.cwd(), authPath))}`));\n\n // Write tsconfig.json if not present\n const tsConfigPath = path.join(process.cwd(), 'tsconfig.json');\n if (!fs.existsSync(tsConfigPath)) {\n fs.writeFileSync(tsConfigPath, tsConfigTemplate);\n console.log(chalk.green(`\u2714 Created: ${chalk.white('tsconfig.json')}`));\n }\n\n // Write User Model if requested\n if (response.createModel && response.adapter !== 'memory' && response.adapter !== 'none') {\n let modelPath = '';\n switch (response.adapter) {\n case 'mongoose':\n modelPath = path.join(process.cwd(), response.targetDir, 'user.model.ts');\n break;\n case 'drizzle':\n modelPath = path.join(process.cwd(), response.targetDir, 'schema.ts');\n break;\n case 'prisma':\n modelPath = path.join(process.cwd(), response.targetDir, 'user.prisma');\n break;\n }\n\n if (modelPath) {\n const modelDirPath = path.dirname(modelPath);\n if (!fs.existsSync(modelDirPath)) {\n fs.mkdirSync(modelDirPath, { recursive: true });\n }\n \n const { userModelTemplate } = await import('./templates.js');\n fs.writeFileSync(modelPath, userModelTemplate(response.adapter));\n console.log(chalk.green(`\u2714 Created: ${chalk.white(path.relative(process.cwd(), modelPath))}`));\n }\n }\n\n // Write .env\n if (response.generateEnv) {\n const envPath = path.join(process.cwd(), '.env');\n const envContent = envTemplate(secret, response.usePepper);\n \n if (fs.existsSync(envPath)) {\n fs.appendFileSync(envPath, envContent);\n console.log(chalk.green(`\u2714 Updated: ${chalk.white('.env')} (Appended JWT_SECRET)`));\n } else {\n fs.writeFileSync(envPath, envContent);\n console.log(chalk.green(`\u2714 Created: ${chalk.white('.env')}`));\n }\n }\n\n console.log(chalk.bold.white('\\nKroxt is ready. Happy coding! \uD83D\uDE80\\n'));\n\n // --- DEPENDENCY AUTO-INSTALLATION ---\n await checkAndInstallDeps(response.adapter, !!options.yes);\n\n } catch (err) {\n console.error(chalk.red('\\n\u2716 Initialization cancelled.'));\n process.exit(1);\n }\n });\n\nasync function checkAndInstallDeps(adapter: string, skipPrompts: boolean = false) {\n const pkgPath = path.join(process.cwd(), 'package.json');\n if (!fs.existsSync(pkgPath)) return;\n\n const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8'));\n const deps = { ...pkg.dependencies, ...pkg.devDependencies };\n\n const required: Record<string, string[]> = {\n memory: ['kroxt', 'dotenv'],\n mongoose: ['kroxt', 'mongoose', 'dotenv'],\n prisma: ['kroxt', '@prisma/client', 'dotenv'],\n drizzle: ['kroxt', 'drizzle-orm', 'dotenv'],\n none: ['kroxt']\n };\n\n const packages = required[adapter] || [];\n const missing = packages.filter(dep => !deps[dep]);\n\n if (missing.length > 0) {\n let confirm = true;\n\n if (!skipPrompts) {\n const enquirer = new Enquirer();\n const result = await enquirer.prompt({\n type: 'confirm',\n name: 'confirm',\n message: `Required dependencies are missing: ${chalk.cyan(missing.join(', '))}. Install them now?`,\n initial: true\n }) as any;\n confirm = result.confirm;\n }\n\n if (confirm) {\n console.log(chalk.gray(`\\nInstalling ${missing.join(', ')}...`));\n return new Promise((resolve) => {\n const child = spawn('npm', ['install', ...missing], { \n stdio: 'inherit',\n shell: true \n });\n child.on('close', resolve);\n });\n }\n }\n}\n\nfunction getProjectContext() {\n const hasSrc = fs.existsSync(path.join(process.cwd(), 'src'));\n const pkgPath = path.join(process.cwd(), 'package.json');\n let isExpress = false;\n let isNext = false;\n\n if (fs.existsSync(pkgPath)) {\n const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8'));\n const deps = { ...pkg.dependencies, ...pkg.devDependencies };\n isExpress = !!(deps.express || deps.fastify);\n isNext = !!deps.next;\n }\n\n return { hasSrc, isExpress, isNext };\n}\n\nprogram.parse(process.argv);\n"],
5
+ "mappings": "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",
6
+ "names": ["Enquirer", "chalk", "crypto", "path", "fs", "enquirer"]
7
+ }
@@ -0,0 +1,206 @@
1
+ #!/usr/bin/env node
2
+ import { Command } from "commander";
3
+ import Enquirer from "enquirer";
4
+ import chalk from "chalk";
5
+ import fs from "fs";
6
+ import path from "path";
7
+ import crypto from "crypto";
8
+ import { spawn } from "child_process";
9
+ import { authTemplate, envTemplate, tsConfigTemplate } from "./templates.js";
10
+ const program = new Command();
11
+ const enquirer = new Enquirer();
12
+ program.name("kroxt").description("Kroxt CLI for bootstrapping auth engines").version("1.0.0");
13
+ program.command("init").description("Initialize Kroxt in your project").option("-y, --yes", "Skip prompts and use defaults").action(async (options) => {
14
+ console.log(chalk.bold.white("\n\u2B22 KROXT AUTH INITIALIZER\n"));
15
+ try {
16
+ let response = {
17
+ adapter: "memory",
18
+ generateEnv: true,
19
+ useRateLimit: true,
20
+ useIPBlocking: true,
21
+ useStrictRevocation: true,
22
+ usePepper: true,
23
+ createModel: true,
24
+ targetDir: ""
25
+ };
26
+ const projectContext = getProjectContext();
27
+ const defaultDir = projectContext.isExpress ? projectContext.hasSrc ? "src/config" : "config" : projectContext.hasSrc ? "src/lib/kroxt" : "lib/kroxt";
28
+ if (!options.yes) {
29
+ response = await enquirer.prompt([
30
+ {
31
+ type: "select",
32
+ name: "adapter",
33
+ message: "Choose your database adapter:",
34
+ choices: [
35
+ { name: "memory", message: "In-Memory (Testing)" },
36
+ { name: "mongoose", message: "Mongoose (MongoDB)" },
37
+ { name: "prisma", message: "Prisma (PostgreSQL/MySQL)" },
38
+ { name: "drizzle", message: "Drizzle (SQLite/PostgreSQL)" },
39
+ { name: "none", message: "None (Manual Setup)" }
40
+ ]
41
+ },
42
+ {
43
+ type: "input",
44
+ name: "targetDir",
45
+ message: "Where should I put the Kroxt files?",
46
+ initial: defaultDir
47
+ },
48
+ {
49
+ type: "confirm",
50
+ name: "useRateLimit",
51
+ message: "Enable rate limiting defensive layer?",
52
+ initial: true
53
+ },
54
+ {
55
+ type: "confirm",
56
+ name: "useIPBlocking",
57
+ message: "Enable automatic IP blocking?",
58
+ initial: true
59
+ },
60
+ {
61
+ type: "confirm",
62
+ name: "useStrictRevocation",
63
+ message: "Enforce strict session revocation?",
64
+ initial: true
65
+ },
66
+ {
67
+ type: "confirm",
68
+ name: "usePepper",
69
+ message: "Use server-side password peppering?",
70
+ initial: true
71
+ },
72
+ {
73
+ type: "confirm",
74
+ name: "createModel",
75
+ message: "Create a boilerplate User model for you?",
76
+ initial: true
77
+ },
78
+ {
79
+ type: "confirm",
80
+ name: "generateEnv",
81
+ message: "Generate secure secrets in .env?",
82
+ initial: true
83
+ }
84
+ ]);
85
+ } else {
86
+ console.log(chalk.gray("Using default settings (--yes)..."));
87
+ response = {
88
+ ...response,
89
+ useRateLimit: true,
90
+ useIPBlocking: true,
91
+ useStrictRevocation: true,
92
+ usePepper: true,
93
+ createModel: true,
94
+ targetDir: defaultDir
95
+ };
96
+ }
97
+ const secret = crypto.randomBytes(32).toString("hex");
98
+ const authContent = authTemplate(response.adapter, secret, response);
99
+ const authPath = path.join(process.cwd(), response.targetDir, "auth.ts");
100
+ const dirPath = path.dirname(authPath);
101
+ if (!fs.existsSync(dirPath)) {
102
+ fs.mkdirSync(dirPath, { recursive: true });
103
+ }
104
+ fs.writeFileSync(authPath, authContent);
105
+ console.log(chalk.green(`
106
+ \u2714 Created: ${chalk.white(path.relative(process.cwd(), authPath))}`));
107
+ const tsConfigPath = path.join(process.cwd(), "tsconfig.json");
108
+ if (!fs.existsSync(tsConfigPath)) {
109
+ fs.writeFileSync(tsConfigPath, tsConfigTemplate);
110
+ console.log(chalk.green(`\u2714 Created: ${chalk.white("tsconfig.json")}`));
111
+ }
112
+ if (response.createModel && response.adapter !== "memory" && response.adapter !== "none") {
113
+ let modelPath = "";
114
+ switch (response.adapter) {
115
+ case "mongoose":
116
+ modelPath = path.join(process.cwd(), response.targetDir, "user.model.ts");
117
+ break;
118
+ case "drizzle":
119
+ modelPath = path.join(process.cwd(), response.targetDir, "schema.ts");
120
+ break;
121
+ case "prisma":
122
+ modelPath = path.join(process.cwd(), response.targetDir, "user.prisma");
123
+ break;
124
+ }
125
+ if (modelPath) {
126
+ const modelDirPath = path.dirname(modelPath);
127
+ if (!fs.existsSync(modelDirPath)) {
128
+ fs.mkdirSync(modelDirPath, { recursive: true });
129
+ }
130
+ const { userModelTemplate } = await import("./templates.js");
131
+ fs.writeFileSync(modelPath, userModelTemplate(response.adapter));
132
+ console.log(chalk.green(`\u2714 Created: ${chalk.white(path.relative(process.cwd(), modelPath))}`));
133
+ }
134
+ }
135
+ if (response.generateEnv) {
136
+ const envPath = path.join(process.cwd(), ".env");
137
+ const envContent = envTemplate(secret, response.usePepper);
138
+ if (fs.existsSync(envPath)) {
139
+ fs.appendFileSync(envPath, envContent);
140
+ console.log(chalk.green(`\u2714 Updated: ${chalk.white(".env")} (Appended JWT_SECRET)`));
141
+ } else {
142
+ fs.writeFileSync(envPath, envContent);
143
+ console.log(chalk.green(`\u2714 Created: ${chalk.white(".env")}`));
144
+ }
145
+ }
146
+ console.log(chalk.bold.white("\nKroxt is ready. Happy coding! \u{1F680}\n"));
147
+ await checkAndInstallDeps(response.adapter, !!options.yes);
148
+ } catch (err) {
149
+ console.error(chalk.red("\n\u2716 Initialization cancelled."));
150
+ process.exit(1);
151
+ }
152
+ });
153
+ async function checkAndInstallDeps(adapter, skipPrompts = false) {
154
+ const pkgPath = path.join(process.cwd(), "package.json");
155
+ if (!fs.existsSync(pkgPath)) return;
156
+ const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf8"));
157
+ const deps = { ...pkg.dependencies, ...pkg.devDependencies };
158
+ const required = {
159
+ memory: ["kroxt", "dotenv"],
160
+ mongoose: ["kroxt", "mongoose", "dotenv"],
161
+ prisma: ["kroxt", "@prisma/client", "dotenv"],
162
+ drizzle: ["kroxt", "drizzle-orm", "dotenv"],
163
+ none: ["kroxt"]
164
+ };
165
+ const packages = required[adapter] || [];
166
+ const missing = packages.filter((dep) => !deps[dep]);
167
+ if (missing.length > 0) {
168
+ let confirm = true;
169
+ if (!skipPrompts) {
170
+ const enquirer2 = new Enquirer();
171
+ const result = await enquirer2.prompt({
172
+ type: "confirm",
173
+ name: "confirm",
174
+ message: `Required dependencies are missing: ${chalk.cyan(missing.join(", "))}. Install them now?`,
175
+ initial: true
176
+ });
177
+ confirm = result.confirm;
178
+ }
179
+ if (confirm) {
180
+ console.log(chalk.gray(`
181
+ Installing ${missing.join(", ")}...`));
182
+ return new Promise((resolve) => {
183
+ const child = spawn("npm", ["install", ...missing], {
184
+ stdio: "inherit",
185
+ shell: true
186
+ });
187
+ child.on("close", resolve);
188
+ });
189
+ }
190
+ }
191
+ }
192
+ function getProjectContext() {
193
+ const hasSrc = fs.existsSync(path.join(process.cwd(), "src"));
194
+ const pkgPath = path.join(process.cwd(), "package.json");
195
+ let isExpress = false;
196
+ let isNext = false;
197
+ if (fs.existsSync(pkgPath)) {
198
+ const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf8"));
199
+ const deps = { ...pkg.dependencies, ...pkg.devDependencies };
200
+ isExpress = !!(deps.express || deps.fastify);
201
+ isNext = !!deps.next;
202
+ }
203
+ return { hasSrc, isExpress, isNext };
204
+ }
205
+ program.parse(process.argv);
206
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/cli/index.ts"],
4
+ "sourcesContent": ["#!/usr/bin/env node\nimport { Command } from 'commander';\nimport Enquirer from 'enquirer';\nimport chalk from 'chalk';\nimport fs from 'fs';\nimport path from 'path';\nimport crypto from 'crypto';\nimport { spawn } from 'child_process';\nimport { authTemplate, envTemplate, tsConfigTemplate } from './templates.js';\n\nconst program = new Command();\nconst enquirer = new Enquirer();\n\nprogram\n .name('kroxt')\n .description('Kroxt CLI for bootstrapping auth engines')\n .version('1.0.0');\n\nprogram\n .command('init')\n .description('Initialize Kroxt in your project')\n .option('-y, --yes', 'Skip prompts and use defaults')\n .action(async (options) => {\n console.log(chalk.bold.white('\\n\u2B22 KROXT AUTH INITIALIZER\\n'));\n\n try {\n let response = {\n adapter: 'memory',\n generateEnv: true,\n useRateLimit: true,\n useIPBlocking: true,\n useStrictRevocation: true,\n usePepper: true,\n createModel: true,\n targetDir: ''\n };\n\n const projectContext = getProjectContext();\n const defaultDir = projectContext.isExpress ? (projectContext.hasSrc ? 'src/config' : 'config') : (projectContext.hasSrc ? 'src/lib/kroxt' : 'lib/kroxt');\n\n if (!options.yes) {\n response = await enquirer.prompt([\n {\n type: 'select',\n name: 'adapter',\n message: 'Choose your database adapter:',\n choices: [\n { name: 'memory', message: 'In-Memory (Testing)' },\n { name: 'mongoose', message: 'Mongoose (MongoDB)' },\n { name: 'prisma', message: 'Prisma (PostgreSQL/MySQL)' },\n { name: 'drizzle', message: 'Drizzle (SQLite/PostgreSQL)' },\n { name: 'none', message: 'None (Manual Setup)' }\n ]\n },\n {\n type: 'input',\n name: 'targetDir',\n message: 'Where should I put the Kroxt files?',\n initial: defaultDir\n },\n {\n type: 'confirm',\n name: 'useRateLimit',\n message: 'Enable rate limiting defensive layer?',\n initial: true\n },\n {\n type: 'confirm',\n name: 'useIPBlocking',\n message: 'Enable automatic IP blocking?',\n initial: true\n },\n {\n type: 'confirm',\n name: 'useStrictRevocation',\n message: 'Enforce strict session revocation?',\n initial: true\n },\n {\n type: 'confirm',\n name: 'usePepper',\n message: 'Use server-side password peppering?',\n initial: true\n },\n {\n type: 'confirm',\n name: 'createModel',\n message: 'Create a boilerplate User model for you?',\n initial: true\n },\n {\n type: 'confirm',\n name: 'generateEnv',\n message: 'Generate secure secrets in .env?',\n initial: true\n }\n ]) as any;\n } else {\n console.log(chalk.gray('Using default settings (--yes)...'));\n response = {\n ...response,\n useRateLimit: true,\n useIPBlocking: true,\n useStrictRevocation: true,\n usePepper: true,\n createModel: true,\n targetDir: defaultDir\n } as any;\n }\n\n const secret = crypto.randomBytes(32).toString('hex');\n const authContent = authTemplate(response.adapter, secret, response);\n\n // Write auth.ts\n const authPath = path.join(process.cwd(), response.targetDir, 'auth.ts');\n const dirPath = path.dirname(authPath);\n\n if (!fs.existsSync(dirPath)) {\n fs.mkdirSync(dirPath, { recursive: true });\n }\n\n fs.writeFileSync(authPath, authContent);\n console.log(chalk.green(`\\n\u2714 Created: ${chalk.white(path.relative(process.cwd(), authPath))}`));\n\n // Write tsconfig.json if not present\n const tsConfigPath = path.join(process.cwd(), 'tsconfig.json');\n if (!fs.existsSync(tsConfigPath)) {\n fs.writeFileSync(tsConfigPath, tsConfigTemplate);\n console.log(chalk.green(`\u2714 Created: ${chalk.white('tsconfig.json')}`));\n }\n\n // Write User Model if requested\n if (response.createModel && response.adapter !== 'memory' && response.adapter !== 'none') {\n let modelPath = '';\n switch (response.adapter) {\n case 'mongoose':\n modelPath = path.join(process.cwd(), response.targetDir, 'user.model.ts');\n break;\n case 'drizzle':\n modelPath = path.join(process.cwd(), response.targetDir, 'schema.ts');\n break;\n case 'prisma':\n modelPath = path.join(process.cwd(), response.targetDir, 'user.prisma');\n break;\n }\n\n if (modelPath) {\n const modelDirPath = path.dirname(modelPath);\n if (!fs.existsSync(modelDirPath)) {\n fs.mkdirSync(modelDirPath, { recursive: true });\n }\n \n const { userModelTemplate } = await import('./templates.js');\n fs.writeFileSync(modelPath, userModelTemplate(response.adapter));\n console.log(chalk.green(`\u2714 Created: ${chalk.white(path.relative(process.cwd(), modelPath))}`));\n }\n }\n\n // Write .env\n if (response.generateEnv) {\n const envPath = path.join(process.cwd(), '.env');\n const envContent = envTemplate(secret, response.usePepper);\n \n if (fs.existsSync(envPath)) {\n fs.appendFileSync(envPath, envContent);\n console.log(chalk.green(`\u2714 Updated: ${chalk.white('.env')} (Appended JWT_SECRET)`));\n } else {\n fs.writeFileSync(envPath, envContent);\n console.log(chalk.green(`\u2714 Created: ${chalk.white('.env')}`));\n }\n }\n\n console.log(chalk.bold.white('\\nKroxt is ready. Happy coding! \uD83D\uDE80\\n'));\n\n // --- DEPENDENCY AUTO-INSTALLATION ---\n await checkAndInstallDeps(response.adapter, !!options.yes);\n\n } catch (err) {\n console.error(chalk.red('\\n\u2716 Initialization cancelled.'));\n process.exit(1);\n }\n });\n\nasync function checkAndInstallDeps(adapter: string, skipPrompts: boolean = false) {\n const pkgPath = path.join(process.cwd(), 'package.json');\n if (!fs.existsSync(pkgPath)) return;\n\n const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8'));\n const deps = { ...pkg.dependencies, ...pkg.devDependencies };\n\n const required: Record<string, string[]> = {\n memory: ['kroxt', 'dotenv'],\n mongoose: ['kroxt', 'mongoose', 'dotenv'],\n prisma: ['kroxt', '@prisma/client', 'dotenv'],\n drizzle: ['kroxt', 'drizzle-orm', 'dotenv'],\n none: ['kroxt']\n };\n\n const packages = required[adapter] || [];\n const missing = packages.filter(dep => !deps[dep]);\n\n if (missing.length > 0) {\n let confirm = true;\n\n if (!skipPrompts) {\n const enquirer = new Enquirer();\n const result = await enquirer.prompt({\n type: 'confirm',\n name: 'confirm',\n message: `Required dependencies are missing: ${chalk.cyan(missing.join(', '))}. Install them now?`,\n initial: true\n }) as any;\n confirm = result.confirm;\n }\n\n if (confirm) {\n console.log(chalk.gray(`\\nInstalling ${missing.join(', ')}...`));\n return new Promise((resolve) => {\n const child = spawn('npm', ['install', ...missing], { \n stdio: 'inherit',\n shell: true \n });\n child.on('close', resolve);\n });\n }\n }\n}\n\nfunction getProjectContext() {\n const hasSrc = fs.existsSync(path.join(process.cwd(), 'src'));\n const pkgPath = path.join(process.cwd(), 'package.json');\n let isExpress = false;\n let isNext = false;\n\n if (fs.existsSync(pkgPath)) {\n const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8'));\n const deps = { ...pkg.dependencies, ...pkg.devDependencies };\n isExpress = !!(deps.express || deps.fastify);\n isNext = !!deps.next;\n }\n\n return { hasSrc, isExpress, isNext };\n}\n\nprogram.parse(process.argv);\n"],
5
+ "mappings": "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",
6
+ "names": ["enquirer"]
7
+ }