@devbro/pashmak 0.1.52 → 0.1.54
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +31 -5
- package/dist/{bin/DatabaseServiceProvider.cjs → cjs/DatabaseServiceProvider.js} +2 -2
- package/dist/{bin/app/console/DefaultCommand.cjs → cjs/app/console/DefaultCommand.js} +8 -8
- package/dist/{bin/app/console/KeyGenerateCommand.cjs → cjs/app/console/KeyGenerateCommand.js} +8 -8
- package/dist/{bin/app/console/StartCommand.cjs → cjs/app/console/StartCommand.js} +8 -8
- package/dist/{bin/app/console/generate/GenerateApiDocsCommand.cjs → cjs/app/console/generate/GenerateApiDocsCommand.js} +8 -8
- package/dist/{bin/app/console/generate/GenerateControllerCommand.cjs → cjs/app/console/generate/GenerateControllerCommand.js} +8 -8
- package/dist/{bin/app/console/generate/index.cjs → cjs/app/console/generate/index.js} +8 -8
- package/dist/{bin/app/console/index.cjs → cjs/app/console/index.js} +8 -8
- package/dist/{bin/app/console/migrate/GenerateMigrateCommand.cjs → cjs/app/console/migrate/GenerateMigrateCommand.js} +8 -8
- package/dist/{bin/app/console/migrate/MigrateCommand.cjs → cjs/app/console/migrate/MigrateCommand.js} +8 -8
- package/dist/{bin/app/console/migrate/MigrateRollbackCommand.cjs → cjs/app/console/migrate/MigrateRollbackCommand.js} +8 -8
- package/dist/{bin/app/console/migrate/index.cjs → cjs/app/console/migrate/index.js} +8 -8
- package/dist/{bin/app/console/queue/GenerateQueueMigrateCommand.cjs → cjs/app/console/queue/GenerateQueueMigrateCommand.js} +8 -8
- package/dist/{bin/cache.cjs → cjs/cache.js} +8 -8
- package/dist/{bin/facades.cjs → cjs/facades.js} +8 -8
- package/dist/{bin/factories.cjs → cjs/factories.js} +8 -8
- package/dist/{bin/http.cjs → cjs/http.js} +8 -8
- package/dist/{bin/index.cjs → cjs/index.js} +24 -24
- package/dist/{bin/middlewares.cjs → cjs/middlewares.js} +8 -8
- package/dist/{bin/queue.cjs → cjs/queue.js} +8 -8
- package/dist/{bin/router.cjs → cjs/router.js} +10 -10
- package/dist/esm/DatabaseServiceProvider.mjs.map +1 -0
- package/dist/esm/app/console/DefaultCommand.mjs.map +1 -0
- package/dist/esm/app/console/KeyGenerateCommand.mjs.map +1 -0
- package/dist/esm/app/console/StartCommand.mjs.map +1 -0
- package/dist/esm/app/console/generate/GenerateApiDocsCommand.mjs.map +1 -0
- package/dist/esm/app/console/generate/GenerateControllerCommand.mjs.map +1 -0
- package/dist/esm/app/console/generate/controller.tpl +41 -0
- package/dist/esm/app/console/generate/index.mjs.map +1 -0
- package/dist/esm/app/console/index.mjs.map +1 -0
- package/dist/esm/app/console/migrate/GenerateMigrateCommand.mjs.map +1 -0
- package/dist/esm/app/console/migrate/MigrateCommand.mjs.map +1 -0
- package/dist/esm/app/console/migrate/MigrateRollbackCommand.mjs.map +1 -0
- package/dist/esm/app/console/migrate/index.mjs.map +1 -0
- package/dist/esm/app/console/migrate/make_migration.tpl +15 -0
- package/dist/esm/app/console/project/CreateProjectCommand.mjs.map +1 -0
- package/dist/esm/app/console/project/base_project/README.md.tpl +1 -0
- package/dist/esm/app/console/project/base_project/package.json.tpl +74 -0
- package/dist/esm/app/console/project/base_project/src/app/console/YourFirstCommand.ts.tpl +23 -0
- package/dist/esm/app/console/project/base_project/src/app/console/index.ts.tpl +1 -0
- package/dist/esm/app/console/project/base_project/src/app/controllers/HelloController.ts.tpl +16 -0
- package/dist/esm/app/console/project/base_project/src/app/models/index.ts.tpl +1 -0
- package/dist/esm/app/console/project/base_project/src/app/queues/index.ts.tpl +9 -0
- package/dist/esm/app/console/project/base_project/src/boot.ts.tpl +0 -0
- package/dist/esm/app/console/project/base_project/src/config/caches.ts.tpl +5 -0
- package/dist/esm/app/console/project/base_project/src/config/databases.ts.tpl +10 -0
- package/dist/esm/app/console/project/base_project/src/config/default.mts.tpl +64 -0
- package/dist/esm/app/console/project/base_project/src/config/loggers.ts.tpl +13 -0
- package/dist/esm/app/console/project/base_project/src/config/mailer.ts.tpl +22 -0
- package/dist/esm/app/console/project/base_project/src/config/queues.ts.tpl +5 -0
- package/dist/esm/app/console/project/base_project/src/config/storages.ts.tpl +12 -0
- package/dist/esm/app/console/project/base_project/src/config/test.ts.tpl +1 -0
- package/dist/esm/app/console/project/base_project/src/database/migrations/2025_05_30_41329_create_sample.ts.tpl +13 -0
- package/dist/esm/app/console/project/base_project/src/helpers/QueryKit.ts.tpl +175 -0
- package/dist/esm/app/console/project/base_project/src/helpers/index.ts.tpl +96 -0
- package/dist/esm/app/console/project/base_project/src/helpers/validation.ts.tpl +26 -0
- package/dist/esm/app/console/project/base_project/src/index.ts.tpl +12 -0
- package/dist/esm/app/console/project/base_project/src/initialize.ts.tpl +69 -0
- package/dist/esm/app/console/project/base_project/src/middlewares.ts.tpl +16 -0
- package/dist/esm/app/console/project/base_project/src/routes.ts.tpl +18 -0
- package/dist/esm/app/console/project/base_project/src/schedules.ts.tpl +22 -0
- package/dist/esm/app/console/project/base_project/tests/basic_test.spec.ts.tpl +27 -0
- package/dist/esm/app/console/project/base_project/tsconfig.json.tpl +26 -0
- package/dist/esm/app/console/project/base_project/tsup.config.ts.tpl +25 -0
- package/dist/esm/app/console/project/base_project/vitest.config.ts.tpl +17 -0
- package/dist/esm/app/console/queue/GenerateQueueMigrateCommand.mjs.map +1 -0
- package/dist/esm/app/console/queue/queue_migration.tpl +21 -0
- package/dist/esm/bin/pashmak_cli.mjs.map +1 -0
- package/dist/esm/cache.mjs.map +1 -0
- package/dist/esm/config.mjs.map +1 -0
- package/dist/esm/context.mjs.map +1 -0
- package/dist/esm/facades.mjs.map +1 -0
- package/dist/esm/factories.mjs.map +1 -0
- package/dist/esm/global.mjs.map +1 -0
- package/dist/esm/helper.mjs.map +1 -0
- package/dist/esm/http.mjs.map +1 -0
- package/dist/esm/index.mjs.map +1 -0
- package/dist/esm/logger.mjs.map +1 -0
- package/dist/esm/mailer.mjs.map +1 -0
- package/dist/esm/middlewares.mjs.map +1 -0
- package/dist/esm/orm.mjs.map +1 -0
- package/dist/esm/queue.mjs.map +1 -0
- package/dist/esm/router.mjs.map +1 -0
- package/dist/esm/sql.mjs.map +1 -0
- package/dist/esm/storage.mjs.map +1 -0
- package/package.json +58 -58
- package/dist/DatabaseServiceProvider.mjs.map +0 -1
- package/dist/app/console/DefaultCommand.mjs.map +0 -1
- package/dist/app/console/KeyGenerateCommand.mjs.map +0 -1
- package/dist/app/console/StartCommand.mjs.map +0 -1
- package/dist/app/console/generate/GenerateApiDocsCommand.mjs.map +0 -1
- package/dist/app/console/generate/GenerateControllerCommand.mjs.map +0 -1
- package/dist/app/console/generate/index.mjs.map +0 -1
- package/dist/app/console/index.mjs.map +0 -1
- package/dist/app/console/migrate/GenerateMigrateCommand.mjs.map +0 -1
- package/dist/app/console/migrate/MigrateCommand.mjs.map +0 -1
- package/dist/app/console/migrate/MigrateRollbackCommand.mjs.map +0 -1
- package/dist/app/console/migrate/index.mjs.map +0 -1
- package/dist/app/console/project/CreateProjectCommand.mjs.map +0 -1
- package/dist/app/console/queue/GenerateQueueMigrateCommand.mjs.map +0 -1
- package/dist/bin/pashmak_cli.mjs.map +0 -1
- package/dist/cache.mjs.map +0 -1
- package/dist/config.mjs.map +0 -1
- package/dist/context.mjs.map +0 -1
- package/dist/facades.mjs.map +0 -1
- package/dist/factories.mjs.map +0 -1
- package/dist/global.mjs.map +0 -1
- package/dist/helper.mjs.map +0 -1
- package/dist/http.mjs.map +0 -1
- package/dist/index.mjs.map +0 -1
- package/dist/logger.mjs.map +0 -1
- package/dist/mailer.mjs.map +0 -1
- package/dist/middlewares.mjs.map +0 -1
- package/dist/orm.mjs.map +0 -1
- package/dist/queue.mjs.map +0 -1
- package/dist/router.mjs.map +0 -1
- package/dist/sql.mjs.map +0 -1
- package/dist/storage.mjs.map +0 -1
- /package/dist/{app → cjs/app}/console/generate/controller.tpl +0 -0
- /package/dist/{app → cjs/app}/console/migrate/make_migration.tpl +0 -0
- /package/dist/{bin/app/console/project/CreateProjectCommand.cjs → cjs/app/console/project/CreateProjectCommand.js} +0 -0
- /package/dist/{app → cjs/app}/console/project/base_project/README.md.tpl +0 -0
- /package/dist/{app → cjs/app}/console/project/base_project/package.json.tpl +0 -0
- /package/dist/{app → cjs/app}/console/project/base_project/src/app/console/YourFirstCommand.ts.tpl +0 -0
- /package/dist/{app → cjs/app}/console/project/base_project/src/app/console/index.ts.tpl +0 -0
- /package/dist/{app → cjs/app}/console/project/base_project/src/app/controllers/HelloController.ts.tpl +0 -0
- /package/dist/{app → cjs/app}/console/project/base_project/src/app/models/index.ts.tpl +0 -0
- /package/dist/{app → cjs/app}/console/project/base_project/src/app/queues/index.ts.tpl +0 -0
- /package/dist/{app → cjs/app}/console/project/base_project/src/boot.ts.tpl +0 -0
- /package/dist/{app → cjs/app}/console/project/base_project/src/config/caches.ts.tpl +0 -0
- /package/dist/{app → cjs/app}/console/project/base_project/src/config/databases.ts.tpl +0 -0
- /package/dist/{app → cjs/app}/console/project/base_project/src/config/default.mts.tpl +0 -0
- /package/dist/{app → cjs/app}/console/project/base_project/src/config/loggers.ts.tpl +0 -0
- /package/dist/{app → cjs/app}/console/project/base_project/src/config/mailer.ts.tpl +0 -0
- /package/dist/{app → cjs/app}/console/project/base_project/src/config/queues.ts.tpl +0 -0
- /package/dist/{app → cjs/app}/console/project/base_project/src/config/storages.ts.tpl +0 -0
- /package/dist/{app → cjs/app}/console/project/base_project/src/config/test.ts.tpl +0 -0
- /package/dist/{app → cjs/app}/console/project/base_project/src/database/migrations/2025_05_30_41329_create_sample.ts.tpl +0 -0
- /package/dist/{app → cjs/app}/console/project/base_project/src/helpers/QueryKit.ts.tpl +0 -0
- /package/dist/{app → cjs/app}/console/project/base_project/src/helpers/index.ts.tpl +0 -0
- /package/dist/{app → cjs/app}/console/project/base_project/src/helpers/validation.ts.tpl +0 -0
- /package/dist/{app → cjs/app}/console/project/base_project/src/index.ts.tpl +0 -0
- /package/dist/{app → cjs/app}/console/project/base_project/src/initialize.ts.tpl +0 -0
- /package/dist/{app → cjs/app}/console/project/base_project/src/middlewares.ts.tpl +0 -0
- /package/dist/{app → cjs/app}/console/project/base_project/src/routes.ts.tpl +0 -0
- /package/dist/{app → cjs/app}/console/project/base_project/src/schedules.ts.tpl +0 -0
- /package/dist/{app → cjs/app}/console/project/base_project/tests/basic_test.spec.ts.tpl +0 -0
- /package/dist/{app → cjs/app}/console/project/base_project/tsconfig.json.tpl +0 -0
- /package/dist/{app → cjs/app}/console/project/base_project/tsup.config.ts.tpl +0 -0
- /package/dist/{app → cjs/app}/console/project/base_project/vitest.config.ts.tpl +0 -0
- /package/dist/{app → cjs/app}/console/queue/queue_migration.tpl +0 -0
- /package/dist/{bin/bin/pashmak_cli.cjs → cjs/bin/pashmak_cli.js} +0 -0
- /package/dist/{bin/config.cjs → cjs/config.js} +0 -0
- /package/dist/{bin/context.cjs → cjs/context.js} +0 -0
- /package/dist/{bin/global.cjs → cjs/global.js} +0 -0
- /package/dist/{bin/helper.cjs → cjs/helper.js} +0 -0
- /package/dist/{bin/logger.cjs → cjs/logger.js} +0 -0
- /package/dist/{bin/mailer.cjs → cjs/mailer.js} +0 -0
- /package/dist/{bin/orm.cjs → cjs/orm.js} +0 -0
- /package/dist/{bin/sql.cjs → cjs/sql.js} +0 -0
- /package/dist/{bin/storage.cjs → cjs/storage.js} +0 -0
- /package/dist/{DatabaseServiceProvider.d.mts → esm/DatabaseServiceProvider.d.mts} +0 -0
- /package/dist/{DatabaseServiceProvider.mjs → esm/DatabaseServiceProvider.mjs} +0 -0
- /package/dist/{app → esm/app}/console/DefaultCommand.d.mts +0 -0
- /package/dist/{app → esm/app}/console/DefaultCommand.mjs +0 -0
- /package/dist/{app → esm/app}/console/KeyGenerateCommand.d.mts +0 -0
- /package/dist/{app → esm/app}/console/KeyGenerateCommand.mjs +0 -0
- /package/dist/{app → esm/app}/console/StartCommand.d.mts +0 -0
- /package/dist/{app → esm/app}/console/StartCommand.mjs +0 -0
- /package/dist/{app → esm/app}/console/generate/GenerateApiDocsCommand.d.mts +0 -0
- /package/dist/{app → esm/app}/console/generate/GenerateApiDocsCommand.mjs +0 -0
- /package/dist/{app → esm/app}/console/generate/GenerateControllerCommand.d.mts +0 -0
- /package/dist/{app → esm/app}/console/generate/GenerateControllerCommand.mjs +0 -0
- /package/dist/{app → esm/app}/console/generate/index.d.mts +0 -0
- /package/dist/{app → esm/app}/console/generate/index.mjs +0 -0
- /package/dist/{app → esm/app}/console/index.d.mts +0 -0
- /package/dist/{app → esm/app}/console/index.mjs +0 -0
- /package/dist/{app → esm/app}/console/migrate/GenerateMigrateCommand.d.mts +0 -0
- /package/dist/{app → esm/app}/console/migrate/GenerateMigrateCommand.mjs +0 -0
- /package/dist/{app → esm/app}/console/migrate/MigrateCommand.d.mts +0 -0
- /package/dist/{app → esm/app}/console/migrate/MigrateCommand.mjs +0 -0
- /package/dist/{app → esm/app}/console/migrate/MigrateRollbackCommand.d.mts +0 -0
- /package/dist/{app → esm/app}/console/migrate/MigrateRollbackCommand.mjs +0 -0
- /package/dist/{app → esm/app}/console/migrate/index.d.mts +0 -0
- /package/dist/{app → esm/app}/console/migrate/index.mjs +0 -0
- /package/dist/{app → esm/app}/console/project/CreateProjectCommand.d.mts +0 -0
- /package/dist/{app → esm/app}/console/project/CreateProjectCommand.mjs +0 -0
- /package/dist/{app → esm/app}/console/queue/GenerateQueueMigrateCommand.d.mts +0 -0
- /package/dist/{app → esm/app}/console/queue/GenerateQueueMigrateCommand.mjs +0 -0
- /package/dist/{bin → esm/bin}/pashmak_cli.d.mts +0 -0
- /package/dist/{bin → esm/bin}/pashmak_cli.mjs +0 -0
- /package/dist/{cache.d.mts → esm/cache.d.mts} +0 -0
- /package/dist/{cache.mjs → esm/cache.mjs} +0 -0
- /package/dist/{config.d.mts → esm/config.d.mts} +0 -0
- /package/dist/{config.mjs → esm/config.mjs} +0 -0
- /package/dist/{context.d.mts → esm/context.d.mts} +0 -0
- /package/dist/{context.mjs → esm/context.mjs} +0 -0
- /package/dist/{facades.d.mts → esm/facades.d.mts} +0 -0
- /package/dist/{facades.mjs → esm/facades.mjs} +0 -0
- /package/dist/{factories.d.mts → esm/factories.d.mts} +0 -0
- /package/dist/{factories.mjs → esm/factories.mjs} +0 -0
- /package/dist/{global.d.mts → esm/global.d.mts} +0 -0
- /package/dist/{global.mjs → esm/global.mjs} +0 -0
- /package/dist/{helper.d.mts → esm/helper.d.mts} +0 -0
- /package/dist/{helper.mjs → esm/helper.mjs} +0 -0
- /package/dist/{http.d.mts → esm/http.d.mts} +0 -0
- /package/dist/{http.mjs → esm/http.mjs} +0 -0
- /package/dist/{index.d.mts → esm/index.d.mts} +0 -0
- /package/dist/{index.mjs → esm/index.mjs} +0 -0
- /package/dist/{logger.d.mts → esm/logger.d.mts} +0 -0
- /package/dist/{logger.mjs → esm/logger.mjs} +0 -0
- /package/dist/{mailer.d.mts → esm/mailer.d.mts} +0 -0
- /package/dist/{mailer.mjs → esm/mailer.mjs} +0 -0
- /package/dist/{middlewares.d.mts → esm/middlewares.d.mts} +0 -0
- /package/dist/{middlewares.mjs → esm/middlewares.mjs} +0 -0
- /package/dist/{orm.d.mts → esm/orm.d.mts} +0 -0
- /package/dist/{orm.mjs → esm/orm.mjs} +0 -0
- /package/dist/{queue.d.mts → esm/queue.d.mts} +0 -0
- /package/dist/{queue.mjs → esm/queue.mjs} +0 -0
- /package/dist/{router.d.mts → esm/router.d.mts} +0 -0
- /package/dist/{router.mjs → esm/router.mjs} +0 -0
- /package/dist/{sql.d.mts → esm/sql.d.mts} +0 -0
- /package/dist/{sql.mjs → esm/sql.mjs} +0 -0
- /package/dist/{storage.d.mts → esm/storage.d.mts} +0 -0
- /package/dist/{storage.mjs → esm/storage.mjs} +0 -0
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { LocalStorageProviderConfig } from '@devbro/pashmak/storage';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import os from 'os';
|
|
4
|
+
|
|
5
|
+
export default {
|
|
6
|
+
default: {
|
|
7
|
+
provider: 'local',
|
|
8
|
+
config: {
|
|
9
|
+
basePath: path.join(os.tmpdir(), '/app-storage/'),
|
|
10
|
+
} as LocalStorageProviderConfig,
|
|
11
|
+
},
|
|
12
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export default {};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Blueprint } from "@devbro/pashmak/sql";
|
|
2
|
+
import { Migration } from "@devbro/pashmak/sql";
|
|
3
|
+
import { Schema } from "@devbro/pashmak/sql";
|
|
4
|
+
|
|
5
|
+
export default class CreateAnimals extends Migration {
|
|
6
|
+
async up(schema: Schema) {
|
|
7
|
+
// add to db schema
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
async down(schema: Schema) {
|
|
11
|
+
// remove from db schema
|
|
12
|
+
}
|
|
13
|
+
}
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
import { logger } from '@devbro/pashmak/facades';
|
|
2
|
+
import { JSONValue, Num } from '@devbro/pashmak/helper';
|
|
3
|
+
import { Query } from '@devbro/pashmak/sql';
|
|
4
|
+
import { cacheQuery } from '@devbro/pashmak/cache';
|
|
5
|
+
|
|
6
|
+
type orderByDirection = 'asc' | 'desc';
|
|
7
|
+
export class QueryKit {
|
|
8
|
+
private query: Query;
|
|
9
|
+
private pagination: { min: number; max: number; sort: '' } = { min: 10, max: 1000, sort: '' };
|
|
10
|
+
private parameters: Record<string, any> = {};
|
|
11
|
+
private sorts: Record<string, CustomSort> = {};
|
|
12
|
+
private filters: Record<string, QueryFilter> = {};
|
|
13
|
+
private defaultSortKey: string = '';
|
|
14
|
+
private _cache_results: boolean = false;
|
|
15
|
+
|
|
16
|
+
get cacheResults(): boolean {
|
|
17
|
+
return this._cache_results;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
set cacheResults(value: boolean) {
|
|
21
|
+
this._cache_results = value;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
constructor(query: Query) {
|
|
25
|
+
this.query = query;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
setParameters(parameters: Record<string, any>) {
|
|
29
|
+
this.parameters = parameters;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
addSort(fields: (string | { key: string; field: string })[]) {
|
|
33
|
+
for (const field of fields) {
|
|
34
|
+
if (typeof field === 'string') {
|
|
35
|
+
this.sorts[field] = {
|
|
36
|
+
apply: (query: Query, sort_key: string, direction: orderByDirection) => {
|
|
37
|
+
query.orderBy(sort_key, direction);
|
|
38
|
+
},
|
|
39
|
+
};
|
|
40
|
+
continue;
|
|
41
|
+
}
|
|
42
|
+
if (typeof field === 'object' && field.key && field.field) {
|
|
43
|
+
this.sorts[field.key] = {
|
|
44
|
+
apply: (query: Query, sort_key: string, direction: orderByDirection) => {
|
|
45
|
+
query.orderBy(field.field, direction);
|
|
46
|
+
},
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
addCustomSort(
|
|
53
|
+
sort_key: string,
|
|
54
|
+
callback: (query: Query, sort_key: string, direction: orderByDirection) => undefined
|
|
55
|
+
) {
|
|
56
|
+
this.sorts[sort_key] = {
|
|
57
|
+
apply: callback,
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
setDefaultSort(sort_key: string) {
|
|
62
|
+
this.defaultSortKey = sort_key;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
addFilter(filter: QueryFilter) {
|
|
66
|
+
this.filters[filter.getKey()] = filter;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
setPagination(min_pagination: number, max_pagination: number) {
|
|
70
|
+
this.pagination.min = min_pagination;
|
|
71
|
+
this.pagination.max = max_pagination;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
async get() {
|
|
75
|
+
// Apply filters
|
|
76
|
+
for (const key in this.parameters.filter) {
|
|
77
|
+
if (this.filters[key] && this.parameters.filter[key]) {
|
|
78
|
+
this.filters[key].apply(this.query, key, this.parameters.filter[key]);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
let total_rows = await this.query.count();
|
|
83
|
+
|
|
84
|
+
// apply sorting
|
|
85
|
+
let sort_key = this.parameters.sort || this.defaultSortKey;
|
|
86
|
+
let sort_direction: orderByDirection = 'asc';
|
|
87
|
+
if (sort_key && sort_key.charAt(0) === '-') {
|
|
88
|
+
sort_key = sort_key.substring(1);
|
|
89
|
+
sort_direction = 'desc';
|
|
90
|
+
}
|
|
91
|
+
if (this.sorts[sort_key]) {
|
|
92
|
+
this.sorts[sort_key].apply(this.query, sort_key, sort_direction);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// Apply pagination
|
|
96
|
+
let per_page = this?.parameters?.page?.per_page || this.pagination.max;
|
|
97
|
+
per_page = Num.clamp(per_page, this.pagination.min, this.pagination.max);
|
|
98
|
+
|
|
99
|
+
this.query.limit(per_page);
|
|
100
|
+
|
|
101
|
+
// Apply offset if page is provided
|
|
102
|
+
const page_number: number = this?.parameters?.page?.number || 1;
|
|
103
|
+
const offset = (page_number - 1) * per_page;
|
|
104
|
+
this.query.offset(offset);
|
|
105
|
+
|
|
106
|
+
// logger().info({ msg: 'Fetching list', query: this.query.toSql() });
|
|
107
|
+
|
|
108
|
+
let rows = [];
|
|
109
|
+
if (this.cacheResults) {
|
|
110
|
+
rows = await cacheQuery(this.query);
|
|
111
|
+
} else {
|
|
112
|
+
rows = await this.query.get();
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
return {
|
|
116
|
+
data: rows,
|
|
117
|
+
meta: {
|
|
118
|
+
first_page: 1,
|
|
119
|
+
current_page: page_number,
|
|
120
|
+
last_page: Math.ceil(total_rows / per_page),
|
|
121
|
+
total: total_rows,
|
|
122
|
+
per_page: per_page,
|
|
123
|
+
per_this_page: rows.length,
|
|
124
|
+
from: offset + 1,
|
|
125
|
+
to: Math.min(offset + rows.length, total_rows),
|
|
126
|
+
},
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
interface QueryFilter {
|
|
132
|
+
getKey(): string;
|
|
133
|
+
apply(query: Query, key: String, value: any): undefined;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
interface CustomSort {
|
|
137
|
+
apply(query: Query, sort_key: string, direction: orderByDirection): undefined;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
export class QueryFilterFactory {
|
|
141
|
+
static exact(key: string, field: string | undefined = undefined): QueryFilter {
|
|
142
|
+
return {
|
|
143
|
+
getKey() {
|
|
144
|
+
return key;
|
|
145
|
+
},
|
|
146
|
+
apply(query: Query, field_name: string, value: any) {
|
|
147
|
+
query.whereOp(field ?? field_name, '=', value);
|
|
148
|
+
},
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
static startsWith(key: string, field: string | undefined = undefined): QueryFilter {
|
|
153
|
+
return {
|
|
154
|
+
getKey() {
|
|
155
|
+
return key;
|
|
156
|
+
},
|
|
157
|
+
apply(query: Query, field_name: string, value: any) {
|
|
158
|
+
query.whereOp(field ?? field_name, 'ILIKE', `${value}%`);
|
|
159
|
+
},
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
static custom(field: string, callback: (query: Query, field_name: string, value: any) => Query): QueryFilter {
|
|
164
|
+
return {
|
|
165
|
+
getKey() {
|
|
166
|
+
return field;
|
|
167
|
+
},
|
|
168
|
+
apply(query: Query, field_name: string, value: any) {
|
|
169
|
+
query.whereNested((q) => {
|
|
170
|
+
callback(q, field_name, value);
|
|
171
|
+
});
|
|
172
|
+
},
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { HttpBadRequestError, HttpForbiddenError } from '@devbro/pashmak/http';
|
|
2
|
+
import jwt from 'jsonwebtoken';
|
|
3
|
+
import { config } from '@devbro/pashmak/config';
|
|
4
|
+
import { BaseModel, RelationshipManagerMtoM } from '@devbro/pashmak/orm';
|
|
5
|
+
import { ctx } from '@devbro/pashmak/context';
|
|
6
|
+
import { logger } from '@devbro/pashmak/facades';
|
|
7
|
+
|
|
8
|
+
export function createJwtToken(data: any, token_params: jwt.SignOptions = {}) {
|
|
9
|
+
const secret = config.get('jwt.secret') as string;
|
|
10
|
+
const token_params2 = config.get('jwt.options') as jwt.SignOptions;
|
|
11
|
+
const token = jwt.sign(data, secret, { ...token_params2, ...token_params });
|
|
12
|
+
|
|
13
|
+
if (!token) {
|
|
14
|
+
throw new Error('Unable to sign token !!');
|
|
15
|
+
}
|
|
16
|
+
return token;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export async function decodeJwtToken(token: string) {
|
|
20
|
+
if (await jwt.verify(token, config.get('jwt.public'))) {
|
|
21
|
+
return await jwt.decode(token);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
if (await jwt.verify(token, config.get('jwt.public_retired'))) {
|
|
25
|
+
return await jwt.decode(token);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
throw new HttpBadRequestError('bad token. invalid, expired, or signed with wrong key.');
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* create two lists of what is to add and what to remove to convert currentRelations to newRelations
|
|
33
|
+
* @param currentRelations the base list
|
|
34
|
+
* @param newRelations the target list
|
|
35
|
+
* @param compare_method a method to compare two items, returns true if item is not in the list
|
|
36
|
+
* @returns { toAdd: T[]; toRemove: T[] }
|
|
37
|
+
*/
|
|
38
|
+
export function diffLists<T extends BaseModel>(
|
|
39
|
+
currentRelations: T[],
|
|
40
|
+
newRelations: T[],
|
|
41
|
+
compare_method: (item: T, list: T[]) => boolean = (item: T, list: T[]) => !list.some((c: T) => c.id === item.id)
|
|
42
|
+
): { toAdd: T[]; toRemove: T[] } {
|
|
43
|
+
const toAdd = newRelations.filter((r: T) => compare_method(r, currentRelations));
|
|
44
|
+
const toRemove = currentRelations.filter((r: T) => compare_method(r, newRelations));
|
|
45
|
+
return { toAdd, toRemove };
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export async function syncManyToMany<T1 extends BaseModel, T2 extends BaseModel>(
|
|
49
|
+
rel_manager: RelationshipManagerMtoM<T1, T2>,
|
|
50
|
+
currentRelations: T2[],
|
|
51
|
+
newRelations: T2[]
|
|
52
|
+
) {
|
|
53
|
+
const { toAdd, toRemove } = diffLists(currentRelations, newRelations);
|
|
54
|
+
|
|
55
|
+
await rel_manager.dissociate(toRemove);
|
|
56
|
+
await rel_manager.associate(toAdd);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export function getAuthenticatedUser(): {
|
|
60
|
+
id: number;
|
|
61
|
+
can: (permission: string) => boolean;
|
|
62
|
+
canOrFail: (permissions: string) => boolean;
|
|
63
|
+
getScope: (permission: string) => any;
|
|
64
|
+
} {
|
|
65
|
+
return ctx().get('auth_user');
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export type VarOrArray<T> = T | T[];
|
|
69
|
+
|
|
70
|
+
export function requirePermissions(required_permissions: VarOrArray<string>): MethodDecorator {
|
|
71
|
+
return function (_target: any, _propertyKey: string | symbol, descriptor: PropertyDescriptor) {
|
|
72
|
+
const originalMethod = descriptor.value!;
|
|
73
|
+
|
|
74
|
+
descriptor.value = async function (...args: any[]) {
|
|
75
|
+
let auth_user = getAuthenticatedUser();
|
|
76
|
+
|
|
77
|
+
const permissionsArray = Array.isArray(required_permissions) ? required_permissions : [required_permissions];
|
|
78
|
+
|
|
79
|
+
let user_can_any = false;
|
|
80
|
+
for (let permission of permissionsArray) {
|
|
81
|
+
if (auth_user.can(permission)) {
|
|
82
|
+
user_can_any = true;
|
|
83
|
+
break;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
if (!user_can_any) {
|
|
87
|
+
logger().warn('Permission denied', {
|
|
88
|
+
user_id: auth_user.id,
|
|
89
|
+
required_permissions: permissionsArray,
|
|
90
|
+
});
|
|
91
|
+
throw new HttpForbiddenError();
|
|
92
|
+
}
|
|
93
|
+
return originalMethod.apply(this, args);
|
|
94
|
+
};
|
|
95
|
+
};
|
|
96
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { ctx } from '@devbro/pashmak/context';
|
|
2
|
+
import { Request, createParamDecorator } from '@devbro/pashmak/router';
|
|
3
|
+
{{#if (eq validation_library "yup")}}import * as yup from 'yup';{{/if}}{{#if (eq validation_library "zod")}}import { z } from 'zod';{{/if}}
|
|
4
|
+
|
|
5
|
+
export function ValidatedRequest(
|
|
6
|
+
validationRules: {{#if (eq validation_library "yup")}} yup.ObjectSchema<any> | (() => yup.ObjectSchema<any>) {{/if}} {{#if (eq validation_library "zod")}} z.ZodType<any> | (() => z.ZodType<any>) {{/if}}
|
|
7
|
+
): ParameterDecorator {
|
|
8
|
+
return createParamDecorator(async () => {
|
|
9
|
+
const schema = typeof validationRules === "function" ? validationRules() : validationRules;
|
|
10
|
+
const requestBody = ctx().get<Request>("request").body;
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
{{#if (eq validation_library "zod")}}
|
|
14
|
+
return await schema.parseAsync(requestBody);
|
|
15
|
+
{{/if}}
|
|
16
|
+
|
|
17
|
+
{{#if (eq validation_library "yup")}}
|
|
18
|
+
// treat it as Yup schema
|
|
19
|
+
const rc = await (schema as yup.ObjectSchema<any>)
|
|
20
|
+
.noUnknown()
|
|
21
|
+
.validate(requestBody, { abortEarly: false });
|
|
22
|
+
|
|
23
|
+
return rc;
|
|
24
|
+
{{/if}}
|
|
25
|
+
});
|
|
26
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import "./initialize";
|
|
2
|
+
import { logger, cli } from "@devbro/pashmak/facades";
|
|
3
|
+
|
|
4
|
+
logger().info("start of everything");
|
|
5
|
+
|
|
6
|
+
const [node, app, ...args] = process.argv;
|
|
7
|
+
cli()
|
|
8
|
+
.runExit(args)
|
|
9
|
+
.then(() => {})
|
|
10
|
+
.catch((err: any) => {
|
|
11
|
+
logger().error(err);
|
|
12
|
+
});
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import dotenv from 'dotenv';
|
|
2
|
+
dotenv.config();
|
|
3
|
+
|
|
4
|
+
import { bootstrap } from '@devbro/pashmak';
|
|
5
|
+
import { dirname } from 'path';
|
|
6
|
+
import { fileURLToPath } from 'url';
|
|
7
|
+
import { loadConfig } from '@devbro/pashmak/config';
|
|
8
|
+
import { httpServer, logger, mailer } from '@devbro/pashmak/facades';
|
|
9
|
+
import { startQueueListeners } from '@/app/queues';
|
|
10
|
+
import { HttpError } from '@devbro/pashmak/http';
|
|
11
|
+
{{#if (eq validation_library "yup")}}import * as yup from 'yup';{{/if}}{{#if (eq validation_library "zod")}}import { z, ZodError } from 'zod';{{/if}}
|
|
12
|
+
|
|
13
|
+
import './app/console';
|
|
14
|
+
import './routes';
|
|
15
|
+
import './schedules';
|
|
16
|
+
|
|
17
|
+
const config_data = await loadConfig(dirname(fileURLToPath(import.meta.url)) + '/config/default');
|
|
18
|
+
|
|
19
|
+
await bootstrap({
|
|
20
|
+
root_dir: dirname(fileURLToPath(import.meta.url)),
|
|
21
|
+
config_data,
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
httpServer().setErrorHandler(async (err: Error, req: any, res: any) => {
|
|
25
|
+
if (err instanceof HttpError) {
|
|
26
|
+
res.writeHead(err.statusCode, { "Content-Type": "application/json" });
|
|
27
|
+
res.end(JSON.stringify({ message: err.message, error: err.code }));
|
|
28
|
+
logger().warn({ msg: "HttpError: " + err.message, err });
|
|
29
|
+
return;
|
|
30
|
+
{{#if (eq validation_library "zod")}}
|
|
31
|
+
} else if (err instanceof ZodError) {
|
|
32
|
+
res.writeHead(422, { "Content-Type": "application/json" });
|
|
33
|
+
const { errors } = z.treeifyError(err);
|
|
34
|
+
|
|
35
|
+
res.end(JSON.stringify({ message: "validation error", errors: errors }));
|
|
36
|
+
logger().warn({ msg: "ZodError: " + err.message, err });
|
|
37
|
+
return;
|
|
38
|
+
{{/if}}
|
|
39
|
+
{{#if (eq validation_library "yup")}}
|
|
40
|
+
} else if (err instanceof yup.ValidationError) {
|
|
41
|
+
res.writeHead(422, { "Content-Type": "application/json" });
|
|
42
|
+
const errs: any = {};
|
|
43
|
+
err.inner.forEach((e: yup.ValidationError) => {
|
|
44
|
+
// Sanitize sensitive fields
|
|
45
|
+
const sanitizedParams = { ...e.params };
|
|
46
|
+
if (/passw/i.test(e.path!)) {
|
|
47
|
+
sanitizedParams.value = "******";
|
|
48
|
+
sanitizedParams.originalValue = "******";
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
errs[e.path!] = {
|
|
52
|
+
type: e.type,
|
|
53
|
+
message: e.message,
|
|
54
|
+
params: sanitizedParams,
|
|
55
|
+
};
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
res.end(JSON.stringify({ message: "validation error", errors: errs }));
|
|
59
|
+
logger().warn({ msg: "ValidationError: " + err.message, err });
|
|
60
|
+
return;
|
|
61
|
+
{{/if}}
|
|
62
|
+
} else {
|
|
63
|
+
logger().error({ msg: "Error: " + err.message, err });
|
|
64
|
+
}
|
|
65
|
+
res.writeHead(500, { "Content-Type": "" });
|
|
66
|
+
res.end(JSON.stringify({ error: "Internal Server Error" }));
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
startQueueListeners();
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { ctx } from "@devbro/pashmak/context";
|
|
2
|
+
import { Request, Response } from "@devbro/pashmak/router";
|
|
3
|
+
import { logger } from "@devbro/pashmak/facades";
|
|
4
|
+
|
|
5
|
+
export async function loggerMiddleware(
|
|
6
|
+
req: Request,
|
|
7
|
+
res: Response,
|
|
8
|
+
next: () => Promise<void>,
|
|
9
|
+
): Promise<void> {
|
|
10
|
+
logger().info({
|
|
11
|
+
msg: "Incoming Http Request",
|
|
12
|
+
keys: ctx().keys(),
|
|
13
|
+
route: req.url,
|
|
14
|
+
});
|
|
15
|
+
await next();
|
|
16
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { Request, Response } from "@devbro/pashmak/router";
|
|
2
|
+
import { router as routerFunc, db as dbf } from "@devbro/pashmak/facades";
|
|
3
|
+
import { sleep } from "@devbro/pashmak/helper";
|
|
4
|
+
import { HelloController } from "./app/controllers/HelloController";
|
|
5
|
+
import { loggerMiddleware } from "./middlewares";
|
|
6
|
+
|
|
7
|
+
const router = routerFunc();
|
|
8
|
+
|
|
9
|
+
router.addGlobalMiddleware(loggerMiddleware);
|
|
10
|
+
router.addRoute(
|
|
11
|
+
["GET", "HEAD"],
|
|
12
|
+
"/api/v1/meow",
|
|
13
|
+
async (req: any, res: any) => {
|
|
14
|
+
return { message: "meow meow!" };
|
|
15
|
+
},
|
|
16
|
+
).addMiddleware([]);
|
|
17
|
+
|
|
18
|
+
router.addController(HelloController);
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { scheduler } from "@devbro/pashmak/facades";
|
|
2
|
+
import { context_provider } from "@devbro/pashmak/context";
|
|
3
|
+
import { db } from "@devbro/pashmak/facades";
|
|
4
|
+
import { logger } from "@devbro/pashmak/facades";
|
|
5
|
+
|
|
6
|
+
scheduler().setContextWrapper(
|
|
7
|
+
(fn: () => Promise<void>): (() => Promise<void>) => {
|
|
8
|
+
return async (): Promise<void> => {
|
|
9
|
+
await context_provider.run(async (): Promise<void> => {
|
|
10
|
+
await fn();
|
|
11
|
+
});
|
|
12
|
+
};
|
|
13
|
+
},
|
|
14
|
+
);
|
|
15
|
+
|
|
16
|
+
scheduler()
|
|
17
|
+
.call(async () => {
|
|
18
|
+
logger().info("scheduled Hello meow World");
|
|
19
|
+
})
|
|
20
|
+
.setCronTime("* * * * *")
|
|
21
|
+
.setName("hello world cron job")
|
|
22
|
+
.setRunOnStart(true);
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import "@/initialize";
|
|
2
|
+
|
|
3
|
+
import { describe, expect, test } from "vitest";
|
|
4
|
+
import supertest from "supertest";
|
|
5
|
+
import { httpServer } from "@devbro/pashmak/facades";
|
|
6
|
+
|
|
7
|
+
describe("basic tests", () => {
|
|
8
|
+
test("funcational controller", async () => {
|
|
9
|
+
const server = httpServer();
|
|
10
|
+
|
|
11
|
+
const s = supertest(server.getHttpHanlder());
|
|
12
|
+
|
|
13
|
+
let r = await s.get("/api/v1/meow");
|
|
14
|
+
expect(r.status).toBe(200);
|
|
15
|
+
expect(r.text).toContain("meow meow!");
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
test("class controller", async () => {
|
|
19
|
+
const server = httpServer();
|
|
20
|
+
|
|
21
|
+
const s = supertest(server.getHttpHanlder());
|
|
22
|
+
|
|
23
|
+
let r = await s.get("/api/v1/hello");
|
|
24
|
+
expect(r.status).toBe(200);
|
|
25
|
+
expect(r.text).toContain("Hello world!");
|
|
26
|
+
});
|
|
27
|
+
});
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
/* Visit https://aka.ms/tsconfig to read more about this file */
|
|
4
|
+
"composite": false /* Enable constraints that allow a TypeScript project to be used with project references. */,
|
|
5
|
+
"target": "ESNext" /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */,
|
|
6
|
+
"experimentalDecorators": true /* Enable experimental support for legacy experimental decorators. */,
|
|
7
|
+
"emitDecoratorMetadata": true /* Emit design-type metadata for decorated declarations in source files. */,
|
|
8
|
+
"module": "esnext" /* Specify what module code is generated. */,
|
|
9
|
+
"rootDir": "./src" /* Specify the root folder within your source files. */,
|
|
10
|
+
"moduleResolution": "bundler" /* Specify how TypeScript looks up a file from a given module specifier. */,
|
|
11
|
+
"allowImportingTsExtensions": true,
|
|
12
|
+
"allowJs": true /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */,
|
|
13
|
+
"emitDeclarationOnly": true /* Only output d.ts files and not JavaScript files. */,
|
|
14
|
+
"declaration": true,
|
|
15
|
+
"outDir": "./dist" /* Specify an output folder for all emitted files. */,
|
|
16
|
+
"esModuleInterop": true /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */,
|
|
17
|
+
"forceConsistentCasingInFileNames": true /* Ensure that casing is correct in imports. */,
|
|
18
|
+
"strict": true /* Enable all strict type-checking options. */,
|
|
19
|
+
"skipLibCheck": true,
|
|
20
|
+
"baseUrl": "./src",
|
|
21
|
+
"paths": {
|
|
22
|
+
"app/*": ["./app/*"],
|
|
23
|
+
"@/*": ["./*"]
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { defineConfig } from "tsup";
|
|
2
|
+
|
|
3
|
+
export default defineConfig([
|
|
4
|
+
{
|
|
5
|
+
entry: ["src/*.ts", "src/app/**/*.ts", "src/config/**/*.ts"],
|
|
6
|
+
format: ["esm"], // Build for commonJS and ESmodules
|
|
7
|
+
dts: true, // Generate declaration file (.d.ts)
|
|
8
|
+
splitting: false,
|
|
9
|
+
sourcemap: true,
|
|
10
|
+
clean: true,
|
|
11
|
+
bundle: false,
|
|
12
|
+
skipNodeModulesBundle: true,
|
|
13
|
+
},
|
|
14
|
+
{ // since db migration code is loaded dynamically, we need to build it separately to prevent excess files from being created
|
|
15
|
+
entry: ["src/database/migrations/*.ts"],
|
|
16
|
+
outDir: "dist/database/migrations",
|
|
17
|
+
format: ["esm"], // Build for commonJS and ESmodules
|
|
18
|
+
dts: false, // Generate declaration file (.d.ts)
|
|
19
|
+
splitting: false,
|
|
20
|
+
sourcemap: false,
|
|
21
|
+
clean: true,
|
|
22
|
+
bundle: false,
|
|
23
|
+
skipNodeModulesBundle: true,
|
|
24
|
+
},
|
|
25
|
+
]);
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { defineConfig } from "vitest/config";
|
|
2
|
+
import { resolve } from "path";
|
|
3
|
+
|
|
4
|
+
export default defineConfig({
|
|
5
|
+
test: {
|
|
6
|
+
globals: true,
|
|
7
|
+
environment: "node",
|
|
8
|
+
include: ["**/?(*.)+(spec|test).ts"],
|
|
9
|
+
exclude: ["**/node_modules/**", "**/dist/**", "**/src/config/**"],
|
|
10
|
+
root: "./",
|
|
11
|
+
},
|
|
12
|
+
resolve: {
|
|
13
|
+
alias: {
|
|
14
|
+
"@": resolve(__dirname, "src"),
|
|
15
|
+
},
|
|
16
|
+
},
|
|
17
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../src/app/console/queue/GenerateQueueMigrateCommand.mts"],"sourcesContent":["import { cli } from \"../../../facades.mjs\";\nimport { Command, Option } from \"clipanion\";\nimport { Case } from \"change-case-all\";\nimport path from \"path\";\nimport * as fs from \"fs/promises\";\nimport { config } from \"@devbro/neko-config\";\nimport handlebars from \"handlebars\";\nimport { fileURLToPath } from \"url\";\nimport { table } from \"console\";\n\nexport class GenerateQueueMigrateCommand extends Command {\n static paths = [[`generate`, `queue`, \"migration\"]];\n\n name = \"queue_messages\";\n\n async execute() {\n const date = new Date();\n const year = date.getFullYear();\n const month = String(date.getMonth() + 1).padStart(2, \"0\");\n const day = String(date.getDate()).padStart(2, \"0\");\n const secondsOfDay = String(\n date.getHours() * 3600 + date.getMinutes() * 60 + date.getSeconds(),\n ).padStart(5, \"0\");\n\n const fixed_name = \"queue_messages\";\n const filename = `${year}_${month}_${day}_${secondsOfDay}_${fixed_name}.ts`;\n this.context.stdout.write(`creating migration file ${filename}\\n`);\n\n await fs.mkdir(config.get(\"migration.path\"), { recursive: true });\n\n let dirname = typeof __dirname === \"string\" ? __dirname : undefined;\n if (!dirname) {\n dirname = path.dirname(fileURLToPath(import.meta.url));\n }\n\n const compiledTemplate = handlebars.compile(\n (\n await fs.readFile(path.join(dirname, \"./queue_migration.tpl\"))\n ).toString(),\n );\n const template = await compiledTemplate({\n className: Case.pascal(this.name) + \"Migration\",\n tableName: Case.snake(this.name),\n });\n\n await fs.writeFile(\n path.join(config.get(\"migration.path\"), filename),\n template,\n );\n }\n}\n\ncli().register(GenerateQueueMigrateCommand);\n"],"mappings":";;AAAA,SAAS,WAAW;AACpB,SAAS,eAAuB;AAChC,SAAS,YAAY;AACrB,OAAO,UAAU;AACjB,YAAY,QAAQ;AACpB,SAAS,cAAc;AACvB,OAAO,gBAAgB;AACvB,SAAS,qBAAqB;AAGvB,MAAM,oCAAoC,QAAQ;AAAA,EAVzD,OAUyD;AAAA;AAAA;AAAA,EACvD,OAAO,QAAQ,CAAC,CAAC,YAAY,SAAS,WAAW,CAAC;AAAA,EAElD,OAAO;AAAA,EAEP,MAAM,UAAU;AACd,UAAM,OAAO,oBAAI,KAAK;AACtB,UAAM,OAAO,KAAK,YAAY;AAC9B,UAAM,QAAQ,OAAO,KAAK,SAAS,IAAI,CAAC,EAAE,SAAS,GAAG,GAAG;AACzD,UAAM,MAAM,OAAO,KAAK,QAAQ,CAAC,EAAE,SAAS,GAAG,GAAG;AAClD,UAAM,eAAe;AAAA,MACnB,KAAK,SAAS,IAAI,OAAO,KAAK,WAAW,IAAI,KAAK,KAAK,WAAW;AAAA,IACpE,EAAE,SAAS,GAAG,GAAG;AAEjB,UAAM,aAAa;AACnB,UAAM,WAAW,GAAG,IAAI,IAAI,KAAK,IAAI,GAAG,IAAI,YAAY,IAAI,UAAU;AACtE,SAAK,QAAQ,OAAO,MAAM,2BAA2B,QAAQ;AAAA,CAAI;AAEjE,UAAM,GAAG,MAAM,OAAO,IAAI,gBAAgB,GAAG,EAAE,WAAW,KAAK,CAAC;AAEhE,QAAI,UAAU,OAAO,cAAc,WAAW,YAAY;AAC1D,QAAI,CAAC,SAAS;AACZ,gBAAU,KAAK,QAAQ,cAAc,YAAY,GAAG,CAAC;AAAA,IACvD;AAEA,UAAM,mBAAmB,WAAW;AAAA,OAEhC,MAAM,GAAG,SAAS,KAAK,KAAK,SAAS,uBAAuB,CAAC,GAC7D,SAAS;AAAA,IACb;AACA,UAAM,WAAW,MAAM,iBAAiB;AAAA,MACtC,WAAW,KAAK,OAAO,KAAK,IAAI,IAAI;AAAA,MACpC,WAAW,KAAK,MAAM,KAAK,IAAI;AAAA,IACjC,CAAC;AAED,UAAM,GAAG;AAAA,MACP,KAAK,KAAK,OAAO,IAAI,gBAAgB,GAAG,QAAQ;AAAA,MAChD;AAAA,IACF;AAAA,EACF;AACF;AAEA,IAAI,EAAE,SAAS,2BAA2B;","names":[]}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { Migration } from '@devbro/pashmak/sql';
|
|
2
|
+
import { Schema, Blueprint } from "@devbro/pashmak/sql";
|
|
3
|
+
|
|
4
|
+
export default class {{className}} extends Migration {
|
|
5
|
+
async up(schema: Schema) {
|
|
6
|
+
await schema.createTable("{{tableName}}", (table: Blueprint) => {
|
|
7
|
+
table.id();
|
|
8
|
+
table.timestamps();
|
|
9
|
+
table.string('channel');
|
|
10
|
+
table.text('message');
|
|
11
|
+
table.datetimeTz('last_tried_at').nullable(true);
|
|
12
|
+
table.text('process_message').default('');
|
|
13
|
+
table.string('status').default('pending');
|
|
14
|
+
table.integer('retried_count').default(0);
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
async down(schema: Schema) {
|
|
19
|
+
await schema.dropTableIfExists("{{tableName}}");
|
|
20
|
+
}
|
|
21
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/bin/pashmak_cli.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { Cli } from \"clipanion\";\n\nconst [node, app, ...args] = process.argv;\nconst cli = new Cli({\n binaryLabel: `Pashmak CLI`,\n binaryName: `${node} ${app}`,\n binaryVersion: `1.0.0`,\n});\n\nimport { CreateProjectCommand } from \"../app/console/project/CreateProjectCommand.mjs\";\n\ncli.register(CreateProjectCommand);\n\ncli\n .runExit(args)\n .then(() => {})\n .catch((err: any) => {\n console.error(err);\n });\n"],"mappings":";AAEA,SAASA,WAAW;AAEpB,MAAM,CAACC,MAAMC,KAAK,GAAGC,IAAAA,IAAQC,QAAQC;AACrC,MAAMC,MAAM,IAAIN,IAAI;EAClBO,aAAa;EACbC,YAAY,GAAGP,IAAAA,IAAQC,GAAAA;EACvBO,eAAe;AACjB,CAAA;AAEA,SAASC,4BAA4B;AAErCJ,IAAIK,SAASD,oBAAAA;AAEbJ,IACGM,QAAQT,IAAAA,EACRU,KAAK,MAAA;AAAO,CAAA,EACZC,MAAM,CAACC,QAAAA;AACNC,UAAQC,MAAMF,GAAAA;AAChB,CAAA;","names":["Cli","node","app","args","process","argv","cli","binaryLabel","binaryName","binaryVersion","CreateProjectCommand","register","runExit","then","catch","err","console","error"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/cache.mts"],"sourcesContent":["export * from \"@devbro/neko-cache\";\n\nimport { Query } from \"@devbro/neko-sql\";\nimport { cache } from \"./facades.mjs\";\nimport * as crypto from \"crypto\";\nimport { JSONValue } from \"@devbro/neko-helper\";\n\nexport type CacheQueryOptions = {\n ttl?: number;\n tags?: string[];\n cache_label?: string;\n};\n\nexport async function cacheQuery(\n q: Query,\n options: CacheQueryOptions = {},\n): ReturnType<Query[\"get\"]> {\n options.ttl = options.ttl ?? 3600; // default TTL 1 hour\n options.cache_label = options.cache_label ?? \"default\";\n const sql = q.toSql();\n\n return await cache(options.cache_label).remember(\n sql as JSONValue,\n async () => await q.get(),\n options,\n );\n}\n"],"mappings":";;AAAA,cAAc;AAGd,SAAS,aAAa;AAUtB,eAAsB,WACpB,GACA,UAA6B,CAAC,GACJ;AAC1B,UAAQ,MAAM,QAAQ,OAAO;AAC7B,UAAQ,cAAc,QAAQ,eAAe;AAC7C,QAAM,MAAM,EAAE,MAAM;AAEpB,SAAO,MAAM,MAAM,QAAQ,WAAW,EAAE;AAAA,IACtC;AAAA,IACA,YAAY,MAAM,EAAE,IAAI;AAAA,IACxB;AAAA,EACF;AACF;AAbsB;","names":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/config.mts"],"sourcesContent":["export * from \"@devbro/neko-config\";\n"],"mappings":"AAAA,cAAc;","names":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/context.mts"],"sourcesContent":["export * from \"@devbro/neko-context\";\n"],"mappings":"AAAA,cAAc;","names":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/facades.mts"],"sourcesContent":["import { Router } from \"./router.mjs\";\nimport { Schedule, Scheduler } from \"@devbro/neko-scheduler\";\nimport { createSingleton } from \"@devbro/neko-helper\";\nimport { ctx, ctxSafe } from \"@devbro/neko-context\";\nimport { Connection } from \"@devbro/neko-sql\";\nimport { Storage, StorageProviderFactory } from \"@devbro/neko-storage\";\nimport {\n Mailer,\n MailerProvider,\n MailerProviderFactory,\n} from \"@devbro/neko-mailer\";\nimport { config } from \"@devbro/neko-config\";\nimport { Cli } from \"clipanion\";\nimport { HttpServer, handleHttpErrors } from \"./http.mjs\";\nimport * as yup from \"yup\";\nimport { Logger } from \"@devbro/neko-logger\";\nimport { CacheProviderFactory } from \"./factories.mjs\";\nimport { Cache } from \"@devbro/neko-cache\";\nimport { QueueConnection, QueueTransportFactory } from \"@devbro/neko-queue\";\n\n/**\n * Wraps a singleton function with property accessors that delegate to the default instance.\n * This allows both `facade()` and `facade.method()` calling patterns.\n * @param singletonFn - The singleton function to wrap\n * @returns The wrapped singleton with property accessors\n */\nfunction wrapSingletonWithAccessors<T>(\n singletonFn: (label?: string, ...args: any[]) => T,\n): typeof singletonFn & Omit<T, keyof Function> {\n // Create a proxy that lazily adds method accessors on first access\n let methodsInitialized = false;\n\n const initializeMethods = () => {\n if (methodsInitialized) return;\n\n const defaultInstance = singletonFn();\n const prototype = Object.getPrototypeOf(defaultInstance);\n\n // Get all method names from the instance's prototype\n const methodNames = Object.getOwnPropertyNames(prototype).filter(\n (name) =>\n name !== \"constructor\" &&\n typeof (prototype as any)[name] === \"function\",\n );\n\n // Attach each method as a property on the singleton function\n for (const methodName of methodNames) {\n (singletonFn as any)[methodName] = (...args: any[]) => {\n const instance = singletonFn();\n return (instance as any)[methodName](...args);\n };\n }\n\n methodsInitialized = true;\n };\n\n // Use a proxy to intercept property access and lazily initialize methods\n return new Proxy(singletonFn, {\n get(target, prop, receiver) {\n // If accessing a method that doesn't exist yet, initialize methods\n if (typeof prop === \"string\" && !Reflect.has(target, prop)) {\n initializeMethods();\n }\n return Reflect.get(target, prop, receiver);\n },\n }) as typeof singletonFn & Omit<T, keyof Function>;\n}\n\nexport const router = createSingleton<Router>(() => new Router());\nexport const scheduler = wrapSingletonWithAccessors(\n createSingleton<Scheduler>(() => {\n const rc = new Scheduler();\n rc.setErrorHandler((err: any, job: Schedule) => {\n logger().error({\n msg: \"Scheduled job error\",\n err,\n job_name: job.getName(),\n });\n });\n return rc;\n }),\n);\n\nexport const db = (label = \"default\") =>\n ctx().getOrThrow<Connection>([\"database\", label]);\n\nexport const storage = wrapSingletonWithAccessors(\n createSingleton<Storage>((label: string = \"default\") => {\n let storage_config: any = config.get([\"storages\", label].join(\".\"));\n\n const provider = StorageProviderFactory.create(\n storage_config.provider,\n storage_config.config,\n );\n\n return new Storage(provider);\n }),\n);\n\nexport const cli = createSingleton<Cli>(() => {\n const [node, app, ...args] = process.argv;\n return new Cli({\n binaryLabel: `My Application`,\n binaryName: `${node} ${app}`,\n binaryVersion: `1.0.0`,\n });\n});\n\nexport const httpServer = createSingleton<HttpServer>(() => {\n const server = new HttpServer();\n\n server.setErrorHandler(handleHttpErrors);\n server.setRouter(router());\n\n return server;\n});\n\nexport const logger = wrapSingletonWithAccessors(\n createSingleton<Logger>((label) => {\n const logger_config: any = config.get([\"loggers\", label].join(\".\"));\n const rc = new Logger(logger_config);\n rc.setExtrasFunction((message: any) => {\n message.requestId = ctxSafe()?.get(\"requestId\") || \"N/A\";\n return message;\n });\n\n return rc;\n }),\n);\n\nexport const mailer = wrapSingletonWithAccessors(\n createSingleton((label) => {\n const mailer_config: any = config.get([\"mailer\", label].join(\".\"));\n\n const provider: MailerProvider = MailerProviderFactory.create(\n mailer_config.provider,\n mailer_config.config,\n );\n\n const rc = new Mailer(provider);\n return rc;\n }),\n);\n\nexport const queue = wrapSingletonWithAccessors(\n createSingleton((label) => {\n const queue_config: any = config.get([\"queues\", label].join(\".\"));\n if (!queue_config) {\n throw new Error(`Queue configuration for '${label}' not found`);\n }\n const provider = QueueTransportFactory.create(\n queue_config.provider,\n queue_config.config,\n );\n return new QueueConnection(provider);\n }),\n);\n\nexport const cache = wrapSingletonWithAccessors(\n createSingleton((label) => {\n const cache_config: any = config.get([\"caches\", label].join(\".\"));\n if (!cache_config) {\n throw new Error(`Cache configuration for '${label}' not found`);\n }\n const provider = CacheProviderFactory.create(\n cache_config.provider,\n cache_config.config,\n );\n\n return new Cache(provider);\n }),\n);\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/factories.mts"],"sourcesContent":["import {\n SESProvider,\n SMTPProvider,\n MemoryProvider,\n MailerProviderFactory,\n} from \"@devbro/neko-mailer\";\nimport {\n MemoryTransport,\n QueueTransportFactory,\n AwsSqsTransport,\n AmqpTransport,\n RedisTransport,\n AsyncTransport,\n AzureServiceBusTransport,\n GooglePubSubTransport,\n} from \"@devbro/neko-queue\";\nimport { DatabaseTransport } from \"./queue.mjs\";\nimport {\n CacheProviderInterface,\n MemoryCacheProvider,\n RedisCacheProvider,\n FileCacheProvider,\n DisabledCacheProvider,\n} from \"@devbro/neko-cache\";\nimport {\n AWSS3StorageProvider,\n LocalStorageProvider,\n StorageProviderFactory,\n GCPStorageProvider,\n AzureBlobStorageProvider,\n FTPStorageProvider,\n SFTPStorageProvider,\n} from \"@devbro/neko-storage\";\n\nexport class FlexibleFactory<T> {\n registry: Map<string, any> = new Map();\n\n register<T>(key: string, ctor: (...args: any[]) => T) {\n this.registry.set(key, ctor);\n }\n\n create<T>(key: string, ...args: any[]): T {\n const ctor = this.registry.get(key);\n if (!ctor) {\n throw new Error(`No factory registered for key: ${key}`);\n }\n return ctor(...args);\n }\n}\n\nMailerProviderFactory.register(\"ses\", (opt) => {\n return new SESProvider(opt);\n});\n\nMailerProviderFactory.register(\"smtp\", (opt) => {\n return new SMTPProvider(opt);\n});\n\nMailerProviderFactory.register(\"memory\", (opt) => {\n return new MemoryProvider();\n});\n\n// Queue\n\nQueueTransportFactory.register(\"database\", (opt) => {\n return new DatabaseTransport(opt);\n});\n\nQueueTransportFactory.register(\"memory\", (opt) => {\n return new MemoryTransport(opt);\n});\n\nQueueTransportFactory.register(\"sqs\", (opt) => {\n return new AwsSqsTransport(opt);\n});\n\nQueueTransportFactory.register(\"amqp\", (opt) => {\n return new AmqpTransport(opt);\n});\n\nQueueTransportFactory.register(\"redis\", (opt) => {\n return new RedisTransport(opt);\n});\n\nQueueTransportFactory.register(\"async\", (opt) => {\n return new AsyncTransport();\n});\n\nQueueTransportFactory.register(\"azure_service_bus\", (opt) => {\n return new AzureServiceBusTransport(opt);\n});\n\nQueueTransportFactory.register(\"google_pubsub\", (opt) => {\n return new GooglePubSubTransport(opt);\n});\n\n// CACHE\nexport class CacheProviderFactory {\n static instance: FlexibleFactory<CacheProviderInterface> =\n new FlexibleFactory<CacheProviderInterface>();\n\n static register(\n key: string,\n factory: (...args: any[]) => CacheProviderInterface,\n ): void {\n CacheProviderFactory.instance.register(key, factory);\n }\n\n static create<T>(key: string, ...args: any[]): CacheProviderInterface {\n return CacheProviderFactory.instance.create(key, ...args);\n }\n}\n\nCacheProviderFactory.register(\"memory\", (opt) => {\n return new MemoryCacheProvider(opt);\n});\n\nCacheProviderFactory.register(\"redis\", (opt) => {\n return new RedisCacheProvider(opt);\n});\n\nCacheProviderFactory.register(\"file\", (opt) => {\n return new FileCacheProvider(opt);\n});\n\nCacheProviderFactory.register(\"disabled\", (opt) => {\n return new DisabledCacheProvider();\n});\n\n/* STORAGE */\n\nStorageProviderFactory.register(\"local\", (opt) => {\n return new LocalStorageProvider(opt);\n});\n\nStorageProviderFactory.register(\"s3\", (opt) => {\n return new AWSS3StorageProvider(opt);\n});\n\nStorageProviderFactory.register(\"gcp\", (opt) => {\n return new GCPStorageProvider(opt);\n});\n\nStorageProviderFactory.register(\"azure\", (opt) => {\n return new AzureBlobStorageProvider(opt);\n});\n\nStorageProviderFactory.register(\"ftp\", (opt) => {\n return new FTPStorageProvider(opt);\n});\n\nStorageProviderFactory.register(\"sftp\", (opt) => {\n return new SFTPStorageProvider(opt);\n});\n"],"mappings":";;AAAA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,yBAAyB;AAClC;AAAA,EAEE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAEA,MAAM,gBAAmB;AAAA,EAlChC,OAkCgC;AAAA;AAAA;AAAA,EAC9B,WAA6B,oBAAI,IAAI;AAAA,EAErC,SAAY,KAAa,MAA6B;AACpD,SAAK,SAAS,IAAI,KAAK,IAAI;AAAA,EAC7B;AAAA,EAEA,OAAU,QAAgB,MAAgB;AACxC,UAAM,OAAO,KAAK,SAAS,IAAI,GAAG;AAClC,QAAI,CAAC,MAAM;AACT,YAAM,IAAI,MAAM,kCAAkC,GAAG,EAAE;AAAA,IACzD;AACA,WAAO,KAAK,GAAG,IAAI;AAAA,EACrB;AACF;AAEA,sBAAsB,SAAS,OAAO,CAAC,QAAQ;AAC7C,SAAO,IAAI,YAAY,GAAG;AAC5B,CAAC;AAED,sBAAsB,SAAS,QAAQ,CAAC,QAAQ;AAC9C,SAAO,IAAI,aAAa,GAAG;AAC7B,CAAC;AAED,sBAAsB,SAAS,UAAU,CAAC,QAAQ;AAChD,SAAO,IAAI,eAAe;AAC5B,CAAC;AAID,sBAAsB,SAAS,YAAY,CAAC,QAAQ;AAClD,SAAO,IAAI,kBAAkB,GAAG;AAClC,CAAC;AAED,sBAAsB,SAAS,UAAU,CAAC,QAAQ;AAChD,SAAO,IAAI,gBAAgB,GAAG;AAChC,CAAC;AAED,sBAAsB,SAAS,OAAO,CAAC,QAAQ;AAC7C,SAAO,IAAI,gBAAgB,GAAG;AAChC,CAAC;AAED,sBAAsB,SAAS,QAAQ,CAAC,QAAQ;AAC9C,SAAO,IAAI,cAAc,GAAG;AAC9B,CAAC;AAED,sBAAsB,SAAS,SAAS,CAAC,QAAQ;AAC/C,SAAO,IAAI,eAAe,GAAG;AAC/B,CAAC;AAED,sBAAsB,SAAS,SAAS,CAAC,QAAQ;AAC/C,SAAO,IAAI,eAAe;AAC5B,CAAC;AAED,sBAAsB,SAAS,qBAAqB,CAAC,QAAQ;AAC3D,SAAO,IAAI,yBAAyB,GAAG;AACzC,CAAC;AAED,sBAAsB,SAAS,iBAAiB,CAAC,QAAQ;AACvD,SAAO,IAAI,sBAAsB,GAAG;AACtC,CAAC;AAGM,MAAM,qBAAqB;AAAA,EAjGlC,OAiGkC;AAAA;AAAA;AAAA,EAChC,OAAO,WACL,IAAI,gBAAwC;AAAA,EAE9C,OAAO,SACL,KACA,SACM;AACN,yBAAqB,SAAS,SAAS,KAAK,OAAO;AAAA,EACrD;AAAA,EAEA,OAAO,OAAU,QAAgB,MAAqC;AACpE,WAAO,qBAAqB,SAAS,OAAO,KAAK,GAAG,IAAI;AAAA,EAC1D;AACF;AAEA,qBAAqB,SAAS,UAAU,CAAC,QAAQ;AAC/C,SAAO,IAAI,oBAAoB,GAAG;AACpC,CAAC;AAED,qBAAqB,SAAS,SAAS,CAAC,QAAQ;AAC9C,SAAO,IAAI,mBAAmB,GAAG;AACnC,CAAC;AAED,qBAAqB,SAAS,QAAQ,CAAC,QAAQ;AAC7C,SAAO,IAAI,kBAAkB,GAAG;AAClC,CAAC;AAED,qBAAqB,SAAS,YAAY,CAAC,QAAQ;AACjD,SAAO,IAAI,sBAAsB;AACnC,CAAC;AAID,uBAAuB,SAAS,SAAS,CAAC,QAAQ;AAChD,SAAO,IAAI,qBAAqB,GAAG;AACrC,CAAC;AAED,uBAAuB,SAAS,MAAM,CAAC,QAAQ;AAC7C,SAAO,IAAI,qBAAqB,GAAG;AACrC,CAAC;AAED,uBAAuB,SAAS,OAAO,CAAC,QAAQ;AAC9C,SAAO,IAAI,mBAAmB,GAAG;AACnC,CAAC;AAED,uBAAuB,SAAS,SAAS,CAAC,QAAQ;AAChD,SAAO,IAAI,yBAAyB,GAAG;AACzC,CAAC;AAED,uBAAuB,SAAS,OAAO,CAAC,QAAQ;AAC9C,SAAO,IAAI,mBAAmB,GAAG;AACnC,CAAC;AAED,uBAAuB,SAAS,QAAQ,CAAC,QAAQ;AAC/C,SAAO,IAAI,oBAAoB,GAAG;AACpC,CAAC;","names":[]}
|