@devbro/pashmak 0.1.10 → 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.
- package/dist/app/console/migrate/MigrateCommand.d.mts +1 -0
- package/dist/app/console/migrate/MigrateCommand.mjs +33 -16
- package/dist/app/console/migrate/MigrateCommand.mjs.map +1 -1
- package/dist/app/console/migrate/MigrateRollbackCommand.d.mts +1 -1
- package/dist/app/console/migrate/MigrateRollbackCommand.mjs +5 -6
- package/dist/app/console/migrate/MigrateRollbackCommand.mjs.map +1 -1
- package/dist/bin/app/console/DefaultCommand.cjs +94 -4
- package/dist/bin/app/console/KeyGenerateCommand.cjs +94 -4
- package/dist/bin/app/console/StartCommand.cjs +94 -4
- package/dist/bin/app/console/generate/GenerateControllerCommand.cjs +94 -4
- package/dist/bin/app/console/generate/index.cjs +94 -4
- package/dist/bin/app/console/index.cjs +131 -25
- package/dist/bin/app/console/migrate/GenerateMigrateCommand.cjs +94 -4
- package/dist/bin/app/console/migrate/MigrateCommand.cjs +127 -20
- package/dist/bin/app/console/migrate/MigrateRollbackCommand.cjs +98 -9
- package/dist/bin/app/console/migrate/index.cjs +131 -25
- package/dist/bin/facades.cjs +94 -4
- package/dist/bin/index.cjs +134 -26
- package/dist/bin/middlewares.cjs +94 -4
- package/dist/bin/router.cjs +95 -5
- package/dist/router.mjs +1 -1
- package/dist/router.mjs.map +1 -1
- package/package.json +4 -3
|
@@ -11,29 +11,46 @@ class MigrateCommand extends Command {
|
|
|
11
11
|
__name(this, "MigrateCommand");
|
|
12
12
|
}
|
|
13
13
|
static paths = [[`migrate`]];
|
|
14
|
-
fresh = Option.Boolean(
|
|
14
|
+
fresh = Option.Boolean(`--fresh`, false, {
|
|
15
|
+
description: `whether to delete and recreate database`
|
|
16
|
+
});
|
|
17
|
+
refresh = Option.Boolean(`--refresh`, false, {
|
|
18
|
+
description: `whether to drop all tables before running migrations by using rollback function`
|
|
19
|
+
});
|
|
15
20
|
async execute() {
|
|
16
21
|
await context_provider.run(async () => {
|
|
17
22
|
const db = database();
|
|
18
23
|
const schema = db.getSchema();
|
|
19
24
|
if (this.fresh) {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
25
|
+
throw new Error("not implemented");
|
|
26
|
+
}
|
|
27
|
+
if (this.refresh) {
|
|
28
|
+
logger().info("reverting all migrations!!");
|
|
29
|
+
const existing_migrations = await db.runQuery({
|
|
30
|
+
sql: "select * from migrations order by created_at DESC",
|
|
31
|
+
bindings: []
|
|
32
|
+
});
|
|
33
|
+
const migrationsDir2 = config.get("migration.path");
|
|
34
|
+
for (const migration_record of existing_migrations) {
|
|
35
|
+
logger().info(`rolling back ${migration_record.filename}`);
|
|
36
|
+
try {
|
|
37
|
+
const MigrationClass = (await import(path.join(migrationsDir2, migration_record.filename))).default;
|
|
38
|
+
const migrationInstance = new MigrationClass();
|
|
39
|
+
await migrationInstance.down(db.getSchema());
|
|
40
|
+
await db.runQuery({
|
|
41
|
+
sql: "delete from migrations where filename = $1",
|
|
42
|
+
bindings: [migration_record.filename]
|
|
43
|
+
});
|
|
44
|
+
} catch (error) {
|
|
45
|
+
logger().error(
|
|
46
|
+
`Failed to rollback migration ${migration_record.filename}: ${error}`
|
|
47
|
+
);
|
|
48
|
+
throw error;
|
|
35
49
|
}
|
|
36
50
|
}
|
|
51
|
+
logger().info(
|
|
52
|
+
`rolled back ${existing_migrations.length} migrations successfully!`
|
|
53
|
+
);
|
|
37
54
|
}
|
|
38
55
|
if (!await schema.tableExists("migrations")) {
|
|
39
56
|
await schema.createTable("migrations", (blueprint) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/app/console/migrate/MigrateCommand.mts"],"sourcesContent":["import { cli, db as database, logger } from \"../../../facades.mjs\";\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(
|
|
1
|
+
{"version":3,"sources":["../../../../src/app/console/migrate/MigrateCommand.mts"],"sourcesContent":["import { cli, db as database, logger } from \"../../../facades.mjs\";\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 description: `whether to delete and recreate database`,\n });\n\n refresh = Option.Boolean(`--refresh`, false, {\n description: `whether to drop all tables before running migrations by using rollback function`,\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 if (this.fresh) {\n throw new Error(\"not implemented\");\n }\n\n if (this.refresh) {\n logger().info(\"reverting all migrations!!\");\n // read all migrations and undo them all\n const existing_migrations = await db.runQuery({\n sql: \"select * from migrations order by created_at DESC\",\n bindings: [],\n });\n\n const migrationsDir = config.get(\"migration.path\");\n\n for (const migration_record of existing_migrations) {\n logger().info(`rolling back ${migration_record.filename}`);\n try {\n const MigrationClass = (\n await import(path.join(migrationsDir, migration_record.filename))\n ).default;\n const migrationInstance: Migration = new MigrationClass();\n\n // Call the down method to rollback the migration\n await migrationInstance.down(db.getSchema());\n\n // Remove the migration record from the migrations table\n await db.runQuery({\n sql: \"delete from migrations where filename = $1\",\n bindings: [migration_record.filename],\n });\n } catch (error) {\n logger().error(\n `Failed to rollback migration ${migration_record.filename}: ${error}`,\n );\n throw error;\n }\n }\n\n logger().info(\n `rolled back ${existing_migrations.length} migrations successfully!`,\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":"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","names":["migrationsDir"]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
var __defProp = Object.defineProperty;
|
|
2
2
|
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
3
|
-
import { cli, db as database } from "../../../facades.mjs";
|
|
3
|
+
import { cli, db as database, logger } from "../../../facades.mjs";
|
|
4
4
|
import { Command, Option } from "clipanion";
|
|
5
5
|
import { context_provider } from "@devbro/neko-context";
|
|
6
6
|
import path from "path";
|
|
@@ -12,7 +12,7 @@ class MigrateRollbackCommand extends Command {
|
|
|
12
12
|
__name(this, "MigrateRollbackCommand");
|
|
13
13
|
}
|
|
14
14
|
static paths = [[`migrate`, "rollback"]];
|
|
15
|
-
steps = Option.String(`--steps`, {
|
|
15
|
+
steps = Option.String(`--steps`, "1", {
|
|
16
16
|
description: `how many migrations to rollback`,
|
|
17
17
|
validator: t.isNumber()
|
|
18
18
|
});
|
|
@@ -25,13 +25,12 @@ class MigrateRollbackCommand extends Command {
|
|
|
25
25
|
const dirEntries = await fs.readdir(migrationsDir);
|
|
26
26
|
files = dirEntries.filter((entry) => entry.endsWith(".ts")).sort();
|
|
27
27
|
const migrations = await db.runQuery({
|
|
28
|
-
sql: "select * from migrations order by created_at DESC",
|
|
29
|
-
bindings: []
|
|
28
|
+
sql: "select * from migrations order by created_at DESC limit $1",
|
|
29
|
+
bindings: [this.steps]
|
|
30
30
|
});
|
|
31
|
-
const count = 0;
|
|
32
31
|
for (const migration of migrations) {
|
|
33
32
|
const class_to_migrate = migration.filename;
|
|
34
|
-
|
|
33
|
+
logger().info(`rolling back ${class_to_migrate}`);
|
|
35
34
|
const ClassToMigrate = (await import(path.join(migrationsDir, class_to_migrate))).default;
|
|
36
35
|
const c = new ClassToMigrate();
|
|
37
36
|
await c.down(db.getSchema());
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/app/console/migrate/MigrateRollbackCommand.mts"],"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
|
|
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":[]}
|
|
@@ -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 (
|
|
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
|
}
|
|
@@ -44,6 +44,9 @@ var import_path2 = __toESM(require("path"), 1);
|
|
|
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 (
|
|
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
|
}
|
|
@@ -42,6 +42,9 @@ var import_neko_config2 = require("@devbro/neko-config");
|
|
|
42
42
|
var import_neko_context = require("@devbro/neko-context");
|
|
43
43
|
var import_errors = require("@devbro/neko-http/errors");
|
|
44
44
|
|
|
45
|
+
// ../neko-router/dist/CompiledRoute.mjs
|
|
46
|
+
var import_stream = require("stream");
|
|
47
|
+
|
|
45
48
|
// ../neko-router/dist/Middleware.mjs
|
|
46
49
|
var Middleware = class {
|
|
47
50
|
static {
|
|
@@ -119,6 +122,9 @@ var CompiledRoute = class {
|
|
|
119
122
|
if (typeof value.toJson === "function") {
|
|
120
123
|
return traverse(value.toJson());
|
|
121
124
|
}
|
|
125
|
+
if (typeof value.toJSON === "function") {
|
|
126
|
+
return traverse(value.toJSON());
|
|
127
|
+
}
|
|
122
128
|
if (Array.isArray(value)) {
|
|
123
129
|
return value.map(traverse);
|
|
124
130
|
}
|
|
@@ -143,7 +149,7 @@ var CompiledRoute = class {
|
|
|
143
149
|
}
|
|
144
150
|
return String(obj);
|
|
145
151
|
}
|
|
146
|
-
processResponseBody(res, controller_rc) {
|
|
152
|
+
async processResponseBody(res, controller_rc) {
|
|
147
153
|
if (controller_rc && res.writableEnded) {
|
|
148
154
|
throw new Error("cannot write to response, response has already ended");
|
|
149
155
|
}
|
|
@@ -152,18 +158,36 @@ var CompiledRoute = class {
|
|
|
152
158
|
}
|
|
153
159
|
if (controller_rc) {
|
|
154
160
|
const header_content_type = res.getHeader("Content-Type");
|
|
155
|
-
if (
|
|
161
|
+
if (controller_rc instanceof import_stream.Stream || Buffer.isBuffer(controller_rc)) {
|
|
162
|
+
await this.writeAsync(res, controller_rc);
|
|
163
|
+
res.end();
|
|
164
|
+
} else if (!header_content_type && typeof controller_rc === "object") {
|
|
156
165
|
res.setHeader("Content-Type", "application/json");
|
|
166
|
+
res.end(this.convertToString(controller_rc));
|
|
157
167
|
} else if (!header_content_type) {
|
|
158
168
|
res.setHeader("Content-Type", "text/plain");
|
|
169
|
+
res.end(this.convertToString(controller_rc));
|
|
170
|
+
} else {
|
|
171
|
+
res.end(this.convertToString(controller_rc));
|
|
159
172
|
}
|
|
160
|
-
res.end(this.convertToString(controller_rc));
|
|
161
173
|
return;
|
|
162
174
|
} else {
|
|
163
175
|
res.statusCode = [200].includes(res.statusCode) ? 204 : res.statusCode;
|
|
164
176
|
res.end();
|
|
165
177
|
}
|
|
166
178
|
}
|
|
179
|
+
async writeAsync(res, chunk) {
|
|
180
|
+
return new Promise((resolve, reject) => {
|
|
181
|
+
const ok = res.write(chunk, (err) => {
|
|
182
|
+
if (err) reject(err);
|
|
183
|
+
});
|
|
184
|
+
if (ok) {
|
|
185
|
+
resolve(0);
|
|
186
|
+
} else {
|
|
187
|
+
res.once("drain", resolve);
|
|
188
|
+
}
|
|
189
|
+
});
|
|
190
|
+
}
|
|
167
191
|
async runMiddlewares(middlewares, req, res) {
|
|
168
192
|
let index = 0;
|
|
169
193
|
const me = this;
|
|
@@ -221,7 +245,7 @@ var Route = class {
|
|
|
221
245
|
i = start;
|
|
222
246
|
} else if (char === "*") {
|
|
223
247
|
let start = i + 1;
|
|
224
|
-
while (start < path2.length && /[a-zA-Z0-9_]/.test(path2[start])) {
|
|
248
|
+
while (start < path2.length && /[a-zA-Z0-9_\.]/.test(path2[start])) {
|
|
225
249
|
start++;
|
|
226
250
|
}
|
|
227
251
|
tokens.push({ type: "WILDCARD", value: path2.slice(i + 1, start) });
|
|
@@ -291,6 +315,10 @@ var Route = class {
|
|
|
291
315
|
params: r.groups || {}
|
|
292
316
|
};
|
|
293
317
|
}
|
|
318
|
+
prependMiddleware(middlewares) {
|
|
319
|
+
this.middlewares = [].concat(middlewares, this.middlewares);
|
|
320
|
+
return this;
|
|
321
|
+
}
|
|
294
322
|
addMiddleware(middlewares) {
|
|
295
323
|
this.middlewares = this.middlewares.concat(middlewares);
|
|
296
324
|
return this;
|
|
@@ -305,6 +333,62 @@ var Route = class {
|
|
|
305
333
|
|
|
306
334
|
// ../neko-router/dist/Router.mjs
|
|
307
335
|
var import_path = __toESM(require("path"), 1);
|
|
336
|
+
|
|
337
|
+
// ../node_modules/url-join/lib/url-join.js
|
|
338
|
+
function normalize(strArray) {
|
|
339
|
+
var resultArray = [];
|
|
340
|
+
if (strArray.length === 0) {
|
|
341
|
+
return "";
|
|
342
|
+
}
|
|
343
|
+
if (typeof strArray[0] !== "string") {
|
|
344
|
+
throw new TypeError("Url must be a string. Received " + strArray[0]);
|
|
345
|
+
}
|
|
346
|
+
if (strArray[0].match(/^[^/:]+:\/*$/) && strArray.length > 1) {
|
|
347
|
+
var first = strArray.shift();
|
|
348
|
+
strArray[0] = first + strArray[0];
|
|
349
|
+
}
|
|
350
|
+
if (strArray[0].match(/^file:\/\/\//)) {
|
|
351
|
+
strArray[0] = strArray[0].replace(/^([^/:]+):\/*/, "$1:///");
|
|
352
|
+
} else {
|
|
353
|
+
strArray[0] = strArray[0].replace(/^([^/:]+):\/*/, "$1://");
|
|
354
|
+
}
|
|
355
|
+
for (var i = 0; i < strArray.length; i++) {
|
|
356
|
+
var component = strArray[i];
|
|
357
|
+
if (typeof component !== "string") {
|
|
358
|
+
throw new TypeError("Url must be a string. Received " + component);
|
|
359
|
+
}
|
|
360
|
+
if (component === "") {
|
|
361
|
+
continue;
|
|
362
|
+
}
|
|
363
|
+
if (i > 0) {
|
|
364
|
+
component = component.replace(/^[\/]+/, "");
|
|
365
|
+
}
|
|
366
|
+
if (i < strArray.length - 1) {
|
|
367
|
+
component = component.replace(/[\/]+$/, "");
|
|
368
|
+
} else {
|
|
369
|
+
component = component.replace(/[\/]+$/, "/");
|
|
370
|
+
}
|
|
371
|
+
resultArray.push(component);
|
|
372
|
+
}
|
|
373
|
+
var str = resultArray.join("/");
|
|
374
|
+
str = str.replace(/\/(\?|&|#[^!])/g, "$1");
|
|
375
|
+
var parts = str.split("?");
|
|
376
|
+
str = parts.shift() + (parts.length > 0 ? "?" : "") + parts.join("&");
|
|
377
|
+
return str;
|
|
378
|
+
}
|
|
379
|
+
__name(normalize, "normalize");
|
|
380
|
+
function urlJoin() {
|
|
381
|
+
var input;
|
|
382
|
+
if (typeof arguments[0] === "object") {
|
|
383
|
+
input = arguments[0];
|
|
384
|
+
} else {
|
|
385
|
+
input = [].slice.call(arguments);
|
|
386
|
+
}
|
|
387
|
+
return normalize(input);
|
|
388
|
+
}
|
|
389
|
+
__name(urlJoin, "urlJoin");
|
|
390
|
+
|
|
391
|
+
// ../neko-router/dist/Router.mjs
|
|
308
392
|
var Router = class {
|
|
309
393
|
static {
|
|
310
394
|
__name(this, "Router");
|
|
@@ -329,6 +413,12 @@ var Router = class {
|
|
|
329
413
|
}).addMiddleware([...controller.baseMiddlewares, ...route.middlewares]);
|
|
330
414
|
}
|
|
331
415
|
}
|
|
416
|
+
addRouter(path2, router2) {
|
|
417
|
+
for (const route of router2.routes) {
|
|
418
|
+
let path22 = urlJoin("/", path2, route.path);
|
|
419
|
+
this.addRoute(route.methods, path22, route.handler).addMiddleware(router2.getMiddlewares()).addMiddleware(route.getMiddlewares());
|
|
420
|
+
}
|
|
421
|
+
}
|
|
332
422
|
addGlobalMiddleware(middlewares) {
|
|
333
423
|
this.middlewares = this.middlewares.concat(middlewares);
|
|
334
424
|
}
|