@ug.software/opposer 3.0.10
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 +504 -0
- package/lib/bin/commands/build.js +75 -0
- package/lib/bin/commands/generate/api-key.js +28 -0
- package/lib/bin/commands/generate/jwt-key.js +46 -0
- package/lib/bin/commands/init.js +169 -0
- package/lib/bin/helpers/crypto.js +33 -0
- package/lib/bin/opposer.js +26 -0
- package/lib/cjs/examples/full-app/index.d.ts +1 -0
- package/lib/cjs/examples/full-app/index.js +102 -0
- package/lib/cjs/examples/full-app/models/author.d.ts +7 -0
- package/lib/cjs/examples/full-app/models/author.js +42 -0
- package/lib/cjs/examples/full-app/models/book.d.ts +9 -0
- package/lib/cjs/examples/full-app/models/book.js +51 -0
- package/lib/cjs/examples/full-app/models/category.d.ts +4 -0
- package/lib/cjs/examples/full-app/models/category.js +26 -0
- package/lib/cjs/examples/full-app/schedules/catalog-refresh.d.ts +28 -0
- package/lib/cjs/examples/full-app/schedules/catalog-refresh.js +149 -0
- package/lib/cjs/examples/full-app/schedules/inventory-sync.d.ts +12 -0
- package/lib/cjs/examples/full-app/schedules/inventory-sync.js +61 -0
- package/lib/cjs/examples/full-app/schedules/library-alerts.d.ts +11 -0
- package/lib/cjs/examples/full-app/schedules/library-alerts.js +55 -0
- package/lib/cjs/examples/minimal/src/handlers/book.d.ts +11 -0
- package/lib/cjs/examples/minimal/src/handlers/book.js +51 -0
- package/lib/cjs/examples/minimal/src/index.d.ts +1 -0
- package/lib/cjs/examples/minimal/src/index.js +14 -0
- package/lib/cjs/examples/minimal/src/models/books.d.ts +4 -0
- package/lib/cjs/examples/minimal/src/models/books.js +26 -0
- package/lib/cjs/examples/orm/models/permission.d.ts +6 -0
- package/lib/cjs/examples/orm/models/permission.js +38 -0
- package/lib/cjs/examples/orm/models/profile.d.ts +7 -0
- package/lib/cjs/examples/orm/models/profile.js +42 -0
- package/lib/cjs/examples/orm/models/user.d.ts +11 -0
- package/lib/cjs/examples/orm/models/user.js +70 -0
- package/lib/cjs/examples/orm/mysql/index.d.ts +1 -0
- package/lib/cjs/examples/orm/mysql/index.js +44 -0
- package/lib/cjs/examples/orm/postgres/index.d.ts +1 -0
- package/lib/cjs/examples/orm/postgres/index.js +40 -0
- package/lib/cjs/examples/orm/sqlite/index.d.ts +1 -0
- package/lib/cjs/examples/orm/sqlite/index.js +41 -0
- package/lib/cjs/index.d.ts +2 -0
- package/lib/cjs/index.js +23 -0
- package/lib/cjs/interfaces/controller.d.ts +109 -0
- package/lib/cjs/interfaces/controller.js +2 -0
- package/lib/cjs/interfaces/field.d.ts +23 -0
- package/lib/cjs/interfaces/field.js +2 -0
- package/lib/cjs/interfaces/handler.d.ts +18 -0
- package/lib/cjs/interfaces/handler.js +2 -0
- package/lib/cjs/interfaces/jwt.d.ts +21 -0
- package/lib/cjs/interfaces/jwt.js +2 -0
- package/lib/cjs/interfaces/model.d.ts +9 -0
- package/lib/cjs/interfaces/model.js +2 -0
- package/lib/cjs/interfaces/request.d.ts +13 -0
- package/lib/cjs/interfaces/request.js +2 -0
- package/lib/cjs/interfaces/schema.d.ts +9 -0
- package/lib/cjs/interfaces/schema.js +2 -0
- package/lib/cjs/interfaces/security.d.ts +32 -0
- package/lib/cjs/interfaces/security.js +2 -0
- package/lib/cjs/interfaces/server.d.ts +37 -0
- package/lib/cjs/interfaces/server.js +2 -0
- package/lib/cjs/interfaces/system.d.ts +41 -0
- package/lib/cjs/interfaces/system.js +2 -0
- package/lib/cjs/orm/decorators/index.d.ts +33 -0
- package/lib/cjs/orm/decorators/index.js +131 -0
- package/lib/cjs/orm/driver/mysql.d.ts +14 -0
- package/lib/cjs/orm/driver/mysql.js +103 -0
- package/lib/cjs/orm/driver/postgres.d.ts +14 -0
- package/lib/cjs/orm/driver/postgres.js +105 -0
- package/lib/cjs/orm/driver/sqlite.d.ts +14 -0
- package/lib/cjs/orm/driver/sqlite.js +143 -0
- package/lib/cjs/orm/index.d.ts +8 -0
- package/lib/cjs/orm/index.js +28 -0
- package/lib/cjs/orm/metadata.d.ts +47 -0
- package/lib/cjs/orm/metadata.js +47 -0
- package/lib/cjs/orm/opposer.d.ts +30 -0
- package/lib/cjs/orm/opposer.js +33 -0
- package/lib/cjs/orm/query-builder.d.ts +32 -0
- package/lib/cjs/orm/query-builder.js +278 -0
- package/lib/cjs/orm/repository.d.ts +54 -0
- package/lib/cjs/orm/repository.js +325 -0
- package/lib/cjs/orm/validation.d.ts +44 -0
- package/lib/cjs/orm/validation.js +128 -0
- package/lib/cjs/package.json +3 -0
- package/lib/cjs/persistent/cache/core-context.d.ts +17 -0
- package/lib/cjs/persistent/cache/core-context.js +39 -0
- package/lib/cjs/persistent/cache/global.d.ts +18 -0
- package/lib/cjs/persistent/cache/global.js +22 -0
- package/lib/cjs/persistent/cache/index.d.ts +3 -0
- package/lib/cjs/persistent/cache/index.js +12 -0
- package/lib/cjs/persistent/cache/session.d.ts +19 -0
- package/lib/cjs/persistent/cache/session.js +39 -0
- package/lib/cjs/persistent/cache/storage.d.ts +14 -0
- package/lib/cjs/persistent/cache/storage.js +88 -0
- package/lib/cjs/persistent/cache/store.d.ts +16 -0
- package/lib/cjs/persistent/cache/store.js +112 -0
- package/lib/cjs/persistent/context/index.d.ts +3 -0
- package/lib/cjs/persistent/context/index.js +5 -0
- package/lib/cjs/persistent/decorators/global.d.ts +1 -0
- package/lib/cjs/persistent/decorators/global.js +25 -0
- package/lib/cjs/persistent/decorators/session.d.ts +1 -0
- package/lib/cjs/persistent/decorators/session.js +27 -0
- package/lib/cjs/persistent/index.d.ts +6 -0
- package/lib/cjs/persistent/index.js +18 -0
- package/lib/cjs/persistent/interfaces/context.d.ts +5 -0
- package/lib/cjs/persistent/interfaces/context.js +2 -0
- package/lib/cjs/persistent/interfaces/system.d.ts +47 -0
- package/lib/cjs/persistent/interfaces/system.js +29 -0
- package/lib/cjs/persistent/system/index.d.ts +7 -0
- package/lib/cjs/persistent/system/index.js +44 -0
- package/lib/cjs/persistent/utils/memory.d.ts +8 -0
- package/lib/cjs/persistent/utils/memory.js +44 -0
- package/lib/cjs/persistent/utils/timer.d.ts +14 -0
- package/lib/cjs/persistent/utils/timer.js +21 -0
- package/lib/cjs/playground/build/client/assets/AddRounded-ByHfnsiW.js +4 -0
- package/lib/cjs/playground/build/client/assets/Button-DLrxHRm7.js +1 -0
- package/lib/cjs/playground/build/client/assets/Container-CgITmmbk.js +1 -0
- package/lib/cjs/playground/build/client/assets/Divider-B_Wx9srO.js +1 -0
- package/lib/cjs/playground/build/client/assets/List-juBjUmfP.js +1 -0
- package/lib/cjs/playground/build/client/assets/ListItemText-DgWZmgzc.js +1 -0
- package/lib/cjs/playground/build/client/assets/MenuItem-D_5SuVKQ.js +1 -0
- package/lib/cjs/playground/build/client/assets/Modal-BwXR_5Bh.js +1 -0
- package/lib/cjs/playground/build/client/assets/TableRow-B9hAmlnV.js +2 -0
- package/lib/cjs/playground/build/client/assets/TextField-UybdTIGB.js +3 -0
- package/lib/cjs/playground/build/client/assets/Tooltip-BGcUWUcF.js +1 -0
- package/lib/cjs/playground/build/client/assets/auth-CD1rXHzz.js +1 -0
- package/lib/cjs/playground/build/client/assets/auth-GyTIVKy5.js +1 -0
- package/lib/cjs/playground/build/client/assets/confirm-Dr0pbiV6.js +1 -0
- package/lib/cjs/playground/build/client/assets/dividerClasses-CIiqeEPO.js +1 -0
- package/lib/cjs/playground/build/client/assets/entry.client-D6FYz1yh.js +13 -0
- package/lib/cjs/playground/build/client/assets/index-CJ0wdt6Z.js +1 -0
- package/lib/cjs/playground/build/client/assets/index-CQc11yq_.js +1153 -0
- package/lib/cjs/playground/build/client/assets/index-Cr4I-4J2.js +1 -0
- package/lib/cjs/playground/build/client/assets/index-CtPqstFl.js +26 -0
- package/lib/cjs/playground/build/client/assets/index-Ct_NE85o.js +1 -0
- package/lib/cjs/playground/build/client/assets/index-D0I6xwmb.js +1 -0
- package/lib/cjs/playground/build/client/assets/index-DmDCpKb3.js +1 -0
- package/lib/cjs/playground/build/client/assets/index-DsSkAwyn.js +1 -0
- package/lib/cjs/playground/build/client/assets/index-_DMgWZ3Y.js +1 -0
- package/lib/cjs/playground/build/client/assets/listItemIconClasses-39Itzgzt.js +1 -0
- package/lib/cjs/playground/build/client/assets/listItemTextClasses-EQFLPLzt.js +1 -0
- package/lib/cjs/playground/build/client/assets/manifest-c06e9a7f.js +1 -0
- package/lib/cjs/playground/build/client/assets/mergeSlotProps-DptgQgAT.js +1 -0
- package/lib/cjs/playground/build/client/assets/playground-Hl52p9f5.js +108 -0
- package/lib/cjs/playground/build/client/assets/root-CQTBmuv8.js +1 -0
- package/lib/cjs/playground/build/client/assets/toast-CsAH5FIf.js +1 -0
- package/lib/cjs/playground/build/client/assets/use-request-BZNkzlTr.js +1 -0
- package/lib/cjs/playground/build/client/favicon.ico +0 -0
- package/lib/cjs/playground/build/client/index.html +6 -0
- package/lib/cjs/playground/index.d.ts +2 -0
- package/lib/cjs/playground/index.js +135 -0
- package/lib/cjs/scheduler/controllers/index.d.ts +19 -0
- package/lib/cjs/scheduler/controllers/index.js +62 -0
- package/lib/cjs/scheduler/decorators/index.d.ts +9 -0
- package/lib/cjs/scheduler/decorators/index.js +21 -0
- package/lib/cjs/scheduler/handlers/index.d.ts +19 -0
- package/lib/cjs/scheduler/handlers/index.js +62 -0
- package/lib/cjs/scheduler/index.d.ts +24 -0
- package/lib/cjs/scheduler/index.js +110 -0
- package/lib/cjs/scheduler/models/history.d.ts +10 -0
- package/lib/cjs/scheduler/models/history.js +50 -0
- package/lib/cjs/server/constants/index.d.ts +78 -0
- package/lib/cjs/server/constants/index.js +372 -0
- package/lib/cjs/server/context/index.d.ts +17 -0
- package/lib/cjs/server/context/index.js +33 -0
- package/lib/cjs/server/controller/index.d.ts +3 -0
- package/lib/cjs/server/controller/index.js +217 -0
- package/lib/cjs/server/controllers/index.d.ts +5 -0
- package/lib/cjs/server/controllers/index.js +72 -0
- package/lib/cjs/server/core/index.d.ts +16 -0
- package/lib/cjs/server/core/index.js +110 -0
- package/lib/cjs/server/core/middleware/body-parser.d.ts +2 -0
- package/lib/cjs/server/core/middleware/body-parser.js +27 -0
- package/lib/cjs/server/core/middleware/cors.d.ts +4 -0
- package/lib/cjs/server/core/middleware/cors.js +32 -0
- package/lib/cjs/server/core/middleware/logger.d.ts +2 -0
- package/lib/cjs/server/core/middleware/logger.js +15 -0
- package/lib/cjs/server/decorators/controller.d.ts +3 -0
- package/lib/cjs/server/decorators/controller.js +14 -0
- package/lib/cjs/server/decorators/field.d.ts +2 -0
- package/lib/cjs/server/decorators/field.js +36 -0
- package/lib/cjs/server/decorators/handler.d.ts +3 -0
- package/lib/cjs/server/decorators/handler.js +14 -0
- package/lib/cjs/server/decorators/index.d.ts +7 -0
- package/lib/cjs/server/decorators/index.js +26 -0
- package/lib/cjs/server/decorators/is-public-method.d.ts +3 -0
- package/lib/cjs/server/decorators/is-public-method.js +16 -0
- package/lib/cjs/server/decorators/is-public.d.ts +3 -0
- package/lib/cjs/server/decorators/is-public.js +14 -0
- package/lib/cjs/server/decorators/method.d.ts +3 -0
- package/lib/cjs/server/decorators/method.js +16 -0
- package/lib/cjs/server/decorators/payload.d.ts +3 -0
- package/lib/cjs/server/decorators/payload.js +15 -0
- package/lib/cjs/server/handlers/index.d.ts +5 -0
- package/lib/cjs/server/handlers/index.js +72 -0
- package/lib/cjs/server/helpers/index.d.ts +17 -0
- package/lib/cjs/server/helpers/index.js +39 -0
- package/lib/cjs/server/index.d.ts +12 -0
- package/lib/cjs/server/index.js +176 -0
- package/lib/cjs/server/security/controller/auth.d.ts +76 -0
- package/lib/cjs/server/security/controller/auth.js +346 -0
- package/lib/cjs/server/security/index.d.ts +2 -0
- package/lib/cjs/server/security/index.js +10 -0
- package/lib/cjs/server/security/jwt/index.d.ts +23 -0
- package/lib/cjs/server/security/jwt/index.js +108 -0
- package/lib/cjs/server/security/middleware/autorization.d.ts +3 -0
- package/lib/cjs/server/security/middleware/autorization.js +46 -0
- package/lib/cjs/server/security/middleware/permission.d.ts +3 -0
- package/lib/cjs/server/security/middleware/permission.js +138 -0
- package/lib/cjs/server/security/models/crp.d.ts +8 -0
- package/lib/cjs/server/security/models/crp.js +42 -0
- package/lib/cjs/server/security/models/ke.d.ts +7 -0
- package/lib/cjs/server/security/models/ke.js +38 -0
- package/lib/cjs/server/security/models/rl.d.ts +9 -0
- package/lib/cjs/server/security/models/rl.js +50 -0
- package/lib/cjs/server/security/models/se.d.ts +11 -0
- package/lib/cjs/server/security/models/se.js +54 -0
- package/lib/cjs/server/security/models/usr.d.ts +14 -0
- package/lib/cjs/server/security/models/usr.js +82 -0
- package/lib/cjs/server/services/delete.d.ts +13 -0
- package/lib/cjs/server/services/delete.js +49 -0
- package/lib/cjs/server/services/get.d.ts +4 -0
- package/lib/cjs/server/services/get.js +145 -0
- package/lib/cjs/server/services/insert.d.ts +13 -0
- package/lib/cjs/server/services/insert.js +74 -0
- package/lib/cjs/server/services/update.d.ts +13 -0
- package/lib/cjs/server/services/update.js +60 -0
- package/lib/cjs/system/index.d.ts +13 -0
- package/lib/cjs/system/index.js +237 -0
- package/lib/esm/examples/full-app/index.d.ts +1 -0
- package/lib/esm/examples/full-app/index.js +64 -0
- package/lib/esm/examples/full-app/models/author.d.ts +7 -0
- package/lib/esm/examples/full-app/models/author.js +37 -0
- package/lib/esm/examples/full-app/models/book.d.ts +9 -0
- package/lib/esm/examples/full-app/models/book.js +46 -0
- package/lib/esm/examples/full-app/models/category.d.ts +4 -0
- package/lib/esm/examples/full-app/models/category.js +24 -0
- package/lib/esm/examples/full-app/schedules/catalog-refresh.d.ts +28 -0
- package/lib/esm/examples/full-app/schedules/catalog-refresh.js +143 -0
- package/lib/esm/examples/full-app/schedules/inventory-sync.d.ts +12 -0
- package/lib/esm/examples/full-app/schedules/inventory-sync.js +55 -0
- package/lib/esm/examples/full-app/schedules/library-alerts.d.ts +11 -0
- package/lib/esm/examples/full-app/schedules/library-alerts.js +52 -0
- package/lib/esm/examples/minimal/src/handlers/book.d.ts +11 -0
- package/lib/esm/examples/minimal/src/handlers/book.js +49 -0
- package/lib/esm/examples/minimal/src/index.d.ts +1 -0
- package/lib/esm/examples/minimal/src/index.js +9 -0
- package/lib/esm/examples/minimal/src/models/books.d.ts +4 -0
- package/lib/esm/examples/minimal/src/models/books.js +24 -0
- package/lib/esm/examples/orm/models/permission.d.ts +6 -0
- package/lib/esm/examples/orm/models/permission.js +33 -0
- package/lib/esm/examples/orm/models/profile.d.ts +7 -0
- package/lib/esm/examples/orm/models/profile.js +37 -0
- package/lib/esm/examples/orm/models/user.d.ts +11 -0
- package/lib/esm/examples/orm/models/user.js +65 -0
- package/lib/esm/examples/orm/mysql/index.d.ts +1 -0
- package/lib/esm/examples/orm/mysql/index.js +39 -0
- package/lib/esm/examples/orm/postgres/index.d.ts +1 -0
- package/lib/esm/examples/orm/postgres/index.js +35 -0
- package/lib/esm/examples/orm/sqlite/index.d.ts +1 -0
- package/lib/esm/examples/orm/sqlite/index.js +36 -0
- package/lib/esm/index.d.ts +2 -0
- package/lib/esm/index.js +2 -0
- package/lib/esm/interfaces/controller.d.ts +109 -0
- package/lib/esm/interfaces/controller.js +1 -0
- package/lib/esm/interfaces/field.d.ts +23 -0
- package/lib/esm/interfaces/field.js +1 -0
- package/lib/esm/interfaces/handler.d.ts +18 -0
- package/lib/esm/interfaces/handler.js +1 -0
- package/lib/esm/interfaces/jwt.d.ts +21 -0
- package/lib/esm/interfaces/jwt.js +1 -0
- package/lib/esm/interfaces/model.d.ts +9 -0
- package/lib/esm/interfaces/model.js +1 -0
- package/lib/esm/interfaces/request.d.ts +13 -0
- package/lib/esm/interfaces/request.js +1 -0
- package/lib/esm/interfaces/schema.d.ts +9 -0
- package/lib/esm/interfaces/schema.js +1 -0
- package/lib/esm/interfaces/security.d.ts +32 -0
- package/lib/esm/interfaces/security.js +1 -0
- package/lib/esm/interfaces/server.d.ts +37 -0
- package/lib/esm/interfaces/server.js +1 -0
- package/lib/esm/interfaces/system.d.ts +41 -0
- package/lib/esm/interfaces/system.js +1 -0
- package/lib/esm/orm/decorators/index.d.ts +33 -0
- package/lib/esm/orm/decorators/index.js +118 -0
- package/lib/esm/orm/driver/mysql.d.ts +14 -0
- package/lib/esm/orm/driver/mysql.js +66 -0
- package/lib/esm/orm/driver/postgres.d.ts +14 -0
- package/lib/esm/orm/driver/postgres.js +68 -0
- package/lib/esm/orm/driver/sqlite.d.ts +14 -0
- package/lib/esm/orm/driver/sqlite.js +106 -0
- package/lib/esm/orm/index.d.ts +8 -0
- package/lib/esm/orm/index.js +8 -0
- package/lib/esm/orm/metadata.d.ts +47 -0
- package/lib/esm/orm/metadata.js +43 -0
- package/lib/esm/orm/opposer.d.ts +30 -0
- package/lib/esm/orm/opposer.js +29 -0
- package/lib/esm/orm/query-builder.d.ts +32 -0
- package/lib/esm/orm/query-builder.js +274 -0
- package/lib/esm/orm/repository.d.ts +54 -0
- package/lib/esm/orm/repository.js +318 -0
- package/lib/esm/orm/validation.d.ts +44 -0
- package/lib/esm/orm/validation.js +122 -0
- package/lib/esm/persistent/cache/core-context.d.ts +17 -0
- package/lib/esm/persistent/cache/core-context.js +34 -0
- package/lib/esm/persistent/cache/global.d.ts +18 -0
- package/lib/esm/persistent/cache/global.js +17 -0
- package/lib/esm/persistent/cache/index.d.ts +3 -0
- package/lib/esm/persistent/cache/index.js +3 -0
- package/lib/esm/persistent/cache/session.d.ts +19 -0
- package/lib/esm/persistent/cache/session.js +34 -0
- package/lib/esm/persistent/cache/storage.d.ts +14 -0
- package/lib/esm/persistent/cache/storage.js +82 -0
- package/lib/esm/persistent/cache/store.d.ts +16 -0
- package/lib/esm/persistent/cache/store.js +106 -0
- package/lib/esm/persistent/context/index.d.ts +3 -0
- package/lib/esm/persistent/context/index.js +3 -0
- package/lib/esm/persistent/decorators/global.d.ts +1 -0
- package/lib/esm/persistent/decorators/global.js +19 -0
- package/lib/esm/persistent/decorators/session.d.ts +1 -0
- package/lib/esm/persistent/decorators/session.js +21 -0
- package/lib/esm/persistent/index.d.ts +6 -0
- package/lib/esm/persistent/index.js +6 -0
- package/lib/esm/persistent/interfaces/context.d.ts +5 -0
- package/lib/esm/persistent/interfaces/context.js +1 -0
- package/lib/esm/persistent/interfaces/system.d.ts +47 -0
- package/lib/esm/persistent/interfaces/system.js +26 -0
- package/lib/esm/persistent/system/index.d.ts +7 -0
- package/lib/esm/persistent/system/index.js +39 -0
- package/lib/esm/persistent/utils/memory.d.ts +8 -0
- package/lib/esm/persistent/utils/memory.js +42 -0
- package/lib/esm/persistent/utils/timer.d.ts +14 -0
- package/lib/esm/persistent/utils/timer.js +16 -0
- package/lib/esm/playground/build/client/assets/AddRounded-ByHfnsiW.js +4 -0
- package/lib/esm/playground/build/client/assets/Button-DLrxHRm7.js +1 -0
- package/lib/esm/playground/build/client/assets/Container-CgITmmbk.js +1 -0
- package/lib/esm/playground/build/client/assets/Divider-B_Wx9srO.js +1 -0
- package/lib/esm/playground/build/client/assets/List-juBjUmfP.js +1 -0
- package/lib/esm/playground/build/client/assets/ListItemText-DgWZmgzc.js +1 -0
- package/lib/esm/playground/build/client/assets/MenuItem-D_5SuVKQ.js +1 -0
- package/lib/esm/playground/build/client/assets/Modal-BwXR_5Bh.js +1 -0
- package/lib/esm/playground/build/client/assets/TableRow-B9hAmlnV.js +2 -0
- package/lib/esm/playground/build/client/assets/TextField-UybdTIGB.js +3 -0
- package/lib/esm/playground/build/client/assets/Tooltip-BGcUWUcF.js +1 -0
- package/lib/esm/playground/build/client/assets/auth-CD1rXHzz.js +1 -0
- package/lib/esm/playground/build/client/assets/auth-GyTIVKy5.js +1 -0
- package/lib/esm/playground/build/client/assets/confirm-Dr0pbiV6.js +1 -0
- package/lib/esm/playground/build/client/assets/dividerClasses-CIiqeEPO.js +1 -0
- package/lib/esm/playground/build/client/assets/entry.client-D6FYz1yh.js +13 -0
- package/lib/esm/playground/build/client/assets/index-CJ0wdt6Z.js +1 -0
- package/lib/esm/playground/build/client/assets/index-CQc11yq_.js +1153 -0
- package/lib/esm/playground/build/client/assets/index-Cr4I-4J2.js +1 -0
- package/lib/esm/playground/build/client/assets/index-CtPqstFl.js +26 -0
- package/lib/esm/playground/build/client/assets/index-Ct_NE85o.js +1 -0
- package/lib/esm/playground/build/client/assets/index-D0I6xwmb.js +1 -0
- package/lib/esm/playground/build/client/assets/index-DmDCpKb3.js +1 -0
- package/lib/esm/playground/build/client/assets/index-DsSkAwyn.js +1 -0
- package/lib/esm/playground/build/client/assets/index-_DMgWZ3Y.js +1 -0
- package/lib/esm/playground/build/client/assets/listItemIconClasses-39Itzgzt.js +1 -0
- package/lib/esm/playground/build/client/assets/listItemTextClasses-EQFLPLzt.js +1 -0
- package/lib/esm/playground/build/client/assets/manifest-c06e9a7f.js +1 -0
- package/lib/esm/playground/build/client/assets/mergeSlotProps-DptgQgAT.js +1 -0
- package/lib/esm/playground/build/client/assets/playground-Hl52p9f5.js +108 -0
- package/lib/esm/playground/build/client/assets/root-CQTBmuv8.js +1 -0
- package/lib/esm/playground/build/client/assets/toast-CsAH5FIf.js +1 -0
- package/lib/esm/playground/build/client/assets/use-request-BZNkzlTr.js +1 -0
- package/lib/esm/playground/build/client/favicon.ico +0 -0
- package/lib/esm/playground/build/client/index.html +6 -0
- package/lib/esm/playground/index.d.ts +2 -0
- package/lib/esm/playground/index.js +129 -0
- package/lib/esm/scheduler/controllers/index.d.ts +19 -0
- package/lib/esm/scheduler/controllers/index.js +57 -0
- package/lib/esm/scheduler/decorators/index.d.ts +9 -0
- package/lib/esm/scheduler/decorators/index.js +16 -0
- package/lib/esm/scheduler/handlers/index.d.ts +19 -0
- package/lib/esm/scheduler/handlers/index.js +57 -0
- package/lib/esm/scheduler/index.d.ts +24 -0
- package/lib/esm/scheduler/index.js +89 -0
- package/lib/esm/scheduler/models/history.d.ts +10 -0
- package/lib/esm/scheduler/models/history.js +48 -0
- package/lib/esm/server/constants/index.d.ts +78 -0
- package/lib/esm/server/constants/index.js +369 -0
- package/lib/esm/server/context/index.d.ts +17 -0
- package/lib/esm/server/context/index.js +31 -0
- package/lib/esm/server/controller/index.d.ts +3 -0
- package/lib/esm/server/controller/index.js +179 -0
- package/lib/esm/server/controllers/index.d.ts +5 -0
- package/lib/esm/server/controllers/index.js +31 -0
- package/lib/esm/server/core/index.d.ts +16 -0
- package/lib/esm/server/core/index.js +103 -0
- package/lib/esm/server/core/middleware/body-parser.d.ts +2 -0
- package/lib/esm/server/core/middleware/body-parser.js +24 -0
- package/lib/esm/server/core/middleware/cors.d.ts +4 -0
- package/lib/esm/server/core/middleware/cors.js +29 -0
- package/lib/esm/server/core/middleware/logger.d.ts +2 -0
- package/lib/esm/server/core/middleware/logger.js +12 -0
- package/lib/esm/server/decorators/controller.d.ts +3 -0
- package/lib/esm/server/decorators/controller.js +10 -0
- package/lib/esm/server/decorators/field.d.ts +2 -0
- package/lib/esm/server/decorators/field.js +32 -0
- package/lib/esm/server/decorators/handler.d.ts +3 -0
- package/lib/esm/server/decorators/handler.js +10 -0
- package/lib/esm/server/decorators/index.d.ts +7 -0
- package/lib/esm/server/decorators/index.js +7 -0
- package/lib/esm/server/decorators/is-public-method.d.ts +3 -0
- package/lib/esm/server/decorators/is-public-method.js +12 -0
- package/lib/esm/server/decorators/is-public.d.ts +3 -0
- package/lib/esm/server/decorators/is-public.js +10 -0
- package/lib/esm/server/decorators/method.d.ts +3 -0
- package/lib/esm/server/decorators/method.js +12 -0
- package/lib/esm/server/decorators/payload.d.ts +3 -0
- package/lib/esm/server/decorators/payload.js +11 -0
- package/lib/esm/server/handlers/index.d.ts +5 -0
- package/lib/esm/server/handlers/index.js +31 -0
- package/lib/esm/server/helpers/index.d.ts +17 -0
- package/lib/esm/server/helpers/index.js +34 -0
- package/lib/esm/server/index.d.ts +12 -0
- package/lib/esm/server/index.js +147 -0
- package/lib/esm/server/security/controller/auth.d.ts +76 -0
- package/lib/esm/server/security/controller/auth.js +341 -0
- package/lib/esm/server/security/index.d.ts +2 -0
- package/lib/esm/server/security/index.js +2 -0
- package/lib/esm/server/security/jwt/index.d.ts +23 -0
- package/lib/esm/server/security/jwt/index.js +103 -0
- package/lib/esm/server/security/middleware/autorization.d.ts +3 -0
- package/lib/esm/server/security/middleware/autorization.js +41 -0
- package/lib/esm/server/security/middleware/permission.d.ts +3 -0
- package/lib/esm/server/security/middleware/permission.js +133 -0
- package/lib/esm/server/security/models/crp.d.ts +8 -0
- package/lib/esm/server/security/models/crp.js +40 -0
- package/lib/esm/server/security/models/ke.d.ts +7 -0
- package/lib/esm/server/security/models/ke.js +36 -0
- package/lib/esm/server/security/models/rl.d.ts +9 -0
- package/lib/esm/server/security/models/rl.js +45 -0
- package/lib/esm/server/security/models/se.d.ts +11 -0
- package/lib/esm/server/security/models/se.js +52 -0
- package/lib/esm/server/security/models/usr.d.ts +14 -0
- package/lib/esm/server/security/models/usr.js +77 -0
- package/lib/esm/server/services/delete.d.ts +13 -0
- package/lib/esm/server/services/delete.js +44 -0
- package/lib/esm/server/services/get.d.ts +4 -0
- package/lib/esm/server/services/get.js +140 -0
- package/lib/esm/server/services/insert.d.ts +13 -0
- package/lib/esm/server/services/insert.js +69 -0
- package/lib/esm/server/services/update.d.ts +13 -0
- package/lib/esm/server/services/update.js +55 -0
- package/lib/esm/system/index.d.ts +13 -0
- package/lib/esm/system/index.js +197 -0
- package/package.json +95 -0
package/README.md
ADDED
|
@@ -0,0 +1,504 @@
|
|
|
1
|
+
# Opposer
|
|
2
|
+
|
|
3
|
+
Opposer é um ecossistema modular para construção de aplicações modernas, focado em alta produtividade e organização por Domínios. Ele unifica Servidor HTTP, Agendamento de Tarefas, ORM e Persistência de Estado em uma única ferramenta extensível e altamente performática.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Começando
|
|
8
|
+
|
|
9
|
+
Inicie um novo projeto Opposer em segundos utilizando o CLI.
|
|
10
|
+
|
|
11
|
+
### 1. Instalação
|
|
12
|
+
No diretório do seu projeto, instale o pacote principal:
|
|
13
|
+
```bash
|
|
14
|
+
npm install @ug.software/opposer
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
### 2. Inicialização (Scaffold)
|
|
18
|
+
Rode o comando de inicialização para criar as pastas, arquivos de exemplo e configurações padrões:
|
|
19
|
+
```bash
|
|
20
|
+
npx @ug.software/opposer init
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
### Estrutura de Domínios Gerada
|
|
24
|
+
O Opposer organiza a lógica da sua aplicação em pastas específicas que ele mapeia automaticamente. Esta arquitetura facilita a escalabilidade e a manutenção:
|
|
25
|
+
|
|
26
|
+
```text
|
|
27
|
+
project/
|
|
28
|
+
├── src/
|
|
29
|
+
│ ├── controllers/ # Ações da API e Endpoints (Lógica de Servidor)
|
|
30
|
+
│ ├── models/ # Entidades do Banco de Dados e Validações (ORM)
|
|
31
|
+
│ ├── schedules/ # Tarefas Agendadas e Background Jobs (Cron)
|
|
32
|
+
│ └── index.ts # Ponto de entrada e Inicialização do Servidor
|
|
33
|
+
├── opposer-settings.json # Configurações estáticas (Porta, URL, DB Type)
|
|
34
|
+
├── .env # Variáveis de ambiente sensíveis (Senhas, Keys)
|
|
35
|
+
└── package.json
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
### 3. Execução
|
|
39
|
+
O comando init configura automaticamente os scripts essenciais no seu package.json:
|
|
40
|
+
|
|
41
|
+
- Desenvolvimento: npm run dev (Inicia o servidor com hot-reload via tsx)
|
|
42
|
+
- Produção (Build): npm run build (Gera o bundle otimizado em dist/index.js)
|
|
43
|
+
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
## 1. Controller (Servidor HTTP)
|
|
47
|
+
|
|
48
|
+
O motor de servidor do Opposer utiliza le conceito de Controllers. Cada Controller agrupa ações relacionadas a um domínio específico. Através de Decorators, você define rotas, validações e comportamentos de segurança de forma declarativa.
|
|
49
|
+
|
|
50
|
+
### Configuração do Servidor
|
|
51
|
+
| Variável de Ambiente | Descrição | Padrão |
|
|
52
|
+
| :--- | :--- | :--- |
|
|
53
|
+
| OPPOSER_PORT | Porta onde o servidor HTTP irá rodar. | 3838 |
|
|
54
|
+
| OPPOSER_URL | Caminho base para as requisições POST. | /opposer |
|
|
55
|
+
|
|
56
|
+
### Componentes do Servidor
|
|
57
|
+
Todos os componentes abaixo podem ser importados de "@ug.software/opposer/server".
|
|
58
|
+
|
|
59
|
+
| Componente | Tipo | Descrição |
|
|
60
|
+
| :--- | :--- | :--- |
|
|
61
|
+
| @Controller(name) | Class Decorator | Identifica a classe como um domínio de ações. |
|
|
62
|
+
| @Method() | Method Decorator | Expõe um método como uma ação executável pela API. |
|
|
63
|
+
| @Payload(Dto) | Parameter Decorator | Injeta e valida os dados da requisição. |
|
|
64
|
+
| @IsPublicMethod() | Method Decorator | Ignora a autenticação apenas para este método. |
|
|
65
|
+
| Success(data) | Helper Function | Retorno padrão para sucesso. |
|
|
66
|
+
| Exception(config) | Helper Function | Retorno padrão para erros estruturados. |
|
|
67
|
+
|
|
68
|
+
### Exemplo de Controller (src/controllers/user.ts)
|
|
69
|
+
```typescript
|
|
70
|
+
import { Controller, Method, Payload, Success, IsPublicMethod, f, Field } from "@ug.software/opposer/server";
|
|
71
|
+
|
|
72
|
+
// 1. Definição do DTO para Validação
|
|
73
|
+
class CreateUserDto {
|
|
74
|
+
@Field(() => f().string().required().min(3))
|
|
75
|
+
name!: string;
|
|
76
|
+
|
|
77
|
+
@Field(() => f().string().required().email())
|
|
78
|
+
email!: string;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
@Controller("users")
|
|
82
|
+
export default class UserController {
|
|
83
|
+
|
|
84
|
+
// Método Protegido (Requer Auth se habilitado globalmente)
|
|
85
|
+
@Method()
|
|
86
|
+
async create(@Payload(CreateUserDto) payload: any) {
|
|
87
|
+
const newUser = payload.data;
|
|
88
|
+
return Success({ id: "123", ...newUser });
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// Método Público (Acessível sem Token/Auth)
|
|
92
|
+
@IsPublicMethod()
|
|
93
|
+
@Method()
|
|
94
|
+
async list() {
|
|
95
|
+
return Success([{ id: "1", name: "Admin" }]);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### Resiliência e Tratamento de Erros (Padrão Either)
|
|
101
|
+
Os helpers Success e Exception seguem o conceito de Either Result. O servidor não deve disparar throw error para falhas previstas (negócio/validação), garantindo um ciclo de vida previsível e seguro.
|
|
102
|
+
|
|
103
|
+
---
|
|
104
|
+
|
|
105
|
+
## 2. Schedule (Automação de Tarefas)
|
|
106
|
+
|
|
107
|
+
O módulo de Schedule permite automatizar processos com controle total de execução e persistência de histórico.
|
|
108
|
+
|
|
109
|
+
### Componentes de Agendamento
|
|
110
|
+
Importe de "@ug.software/opposer/schedule".
|
|
111
|
+
|
|
112
|
+
| Componente | Parâmetro | Descrição |
|
|
113
|
+
| :--- | :--- | :--- |
|
|
114
|
+
| @Schedule(config) | name: string | Nome único da tarefa. |
|
|
115
|
+
| | interval: string | Intervalo (Ex: "1m", "1h", "30s"). |
|
|
116
|
+
| | description? | Texto para o Playground. |
|
|
117
|
+
|
|
118
|
+
### Exemplo de Tarefa Agendada (src/schedules/cleanup.ts)
|
|
119
|
+
```typescript
|
|
120
|
+
import { Schedule } from "@ug.software/opposer/schedule";
|
|
121
|
+
|
|
122
|
+
export default class MaintenanceTask {
|
|
123
|
+
@Schedule({
|
|
124
|
+
name: "limpeza-logs",
|
|
125
|
+
interval: "24h",
|
|
126
|
+
description: "Remove logs antigos do banco de dados diariamente"
|
|
127
|
+
})
|
|
128
|
+
async run() {
|
|
129
|
+
// Lógica de manutenção...
|
|
130
|
+
console.log("Rotina de limpeza executada.");
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
---
|
|
136
|
+
|
|
137
|
+
## 3. ORM (Gestão de Dados)
|
|
138
|
+
|
|
139
|
+
O ORM do @ug.software/opposer gerencia a persistência de dados com uma abordagem Code-First.
|
|
140
|
+
|
|
141
|
+
### Configuração do Banco de Dados
|
|
142
|
+
| Variável de Ambiente | Descrição | Necessário |
|
|
143
|
+
| :--- | :--- | :--- |
|
|
144
|
+
| OPPOSER_DATABASE_TYPE | postgres, mysql ou sqlite. | Sim |
|
|
145
|
+
| OPPOSER_DATABASE_NAME | Nome do banco ou caminho (se sqlite). | Sim |
|
|
146
|
+
| OPPOSER_DATABASE_HOST | Endereço do servidor. | (exceto sqlite) |
|
|
147
|
+
| OPPOSER_DATABASE_USER | Usuário do banco. | (exceto sqlite) |
|
|
148
|
+
| OPPOSER_DATABASE_PASSWORD| Senha do banco. | (exceto sqlite) |
|
|
149
|
+
| OPPOSER_DATABASE_LOGGING | Habilita logs SQL (true/false). | Não |
|
|
150
|
+
|
|
151
|
+
### Componentes do ORM
|
|
152
|
+
Importe de "@ug.software/opposer/orm".
|
|
153
|
+
|
|
154
|
+
| Componente | Tipo | Descrição |
|
|
155
|
+
| :--- | :--- | :--- |
|
|
156
|
+
| @Entity(table, desc) | Class Decorator | Mapeia a classe para uma tabela. |
|
|
157
|
+
| @PrimaryColumn(opts)| Prop Decorator | Define a chave primária. |
|
|
158
|
+
| @Field(config) | Prop Decorator | Define coluna e regras de validação. |
|
|
159
|
+
| @Relation(opts) | Prop Decorator | Define relacionamentos (one-to-many, etc). |
|
|
160
|
+
|
|
161
|
+
### Exemplo de Model (src/models/product.ts)
|
|
162
|
+
```typescript
|
|
163
|
+
import { Entity, PrimaryColumn, Field, f, Relation } from "@ug.software/opposer/orm";
|
|
164
|
+
import Category from "./category";
|
|
165
|
+
|
|
166
|
+
@Entity("products", "Domínio de Produtos")
|
|
167
|
+
export default class Product {
|
|
168
|
+
@PrimaryColumn({ type: "uuid" })
|
|
169
|
+
id!: string;
|
|
170
|
+
|
|
171
|
+
@Field(() => f().string().required().max(100))
|
|
172
|
+
name!: string;
|
|
173
|
+
|
|
174
|
+
@Field({ type: "number", default: 0 })
|
|
175
|
+
price!: number;
|
|
176
|
+
|
|
177
|
+
@Relation({ type: "many-to-one", target: () => Category, inverseSide: "products" })
|
|
178
|
+
category!: Category;
|
|
179
|
+
}
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
### Query Builder O-API (JSON)
|
|
183
|
+
O Opposer permite realizar todas as operações de banco de dados enviando apenas JSON para o endpoint central.
|
|
184
|
+
|
|
185
|
+
#### 📝 Diferença entre Filter e Find
|
|
186
|
+
- **`filter`**: Retorna sempre uma **lista** (array) de objetos que satisfazem os critérios.
|
|
187
|
+
- **`find`**: Retorna apenas o **primeiro** objeto encontrado (objeto único) ou `null`.
|
|
188
|
+
|
|
189
|
+
#### 🧩 Outros Tipos de Consulta
|
|
190
|
+
Além de buscar registros, você pode realizar operações de verificação e estatísticas.
|
|
191
|
+
|
|
192
|
+
**1. Contagem (`count`)**
|
|
193
|
+
Retorna a quantidade total de registros que batem com o filtro.
|
|
194
|
+
```json
|
|
195
|
+
{
|
|
196
|
+
"method": "get",
|
|
197
|
+
"model": "products",
|
|
198
|
+
"query": {
|
|
199
|
+
"type": "count",
|
|
200
|
+
"count": { "price": { "$mt": 100 } }
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
**2. Verificação de Existência (`exists`)**
|
|
206
|
+
Retorna um booleano (`true`/`false`) indicando se existe ao menos um registro.
|
|
207
|
+
```json
|
|
208
|
+
{
|
|
209
|
+
"method": "get",
|
|
210
|
+
"model": "products",
|
|
211
|
+
"query": {
|
|
212
|
+
"type": "exists",
|
|
213
|
+
"exists": { "name": "Cerveja Artesanal" }
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
**3. Valores Únicos (`distinct`)**
|
|
219
|
+
Retorna uma lista de valores únicos para um campo específico.
|
|
220
|
+
```json
|
|
221
|
+
{
|
|
222
|
+
"method": "get",
|
|
223
|
+
"model": "products",
|
|
224
|
+
"query": {
|
|
225
|
+
"type": "distinct",
|
|
226
|
+
"distinct": { "field": "category" }
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
**4. Agrupamento (`group`)**
|
|
232
|
+
Realiza agrupamentos complexos com agregações.
|
|
233
|
+
```json
|
|
234
|
+
{
|
|
235
|
+
"method": "get",
|
|
236
|
+
"model": "products",
|
|
237
|
+
"query": {
|
|
238
|
+
"type": "group",
|
|
239
|
+
"group": {
|
|
240
|
+
"by": ["category"],
|
|
241
|
+
"aggregate": { "price": "avg", "id": "count" }
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
#### 1. Consulta Avançada (`get`)
|
|
248
|
+
Você pode combinar filtros, seleções, relacionamentos e paginação.
|
|
249
|
+
|
|
250
|
+
Exemplo: Filtragem Aninhada e Seleção de Campos
|
|
251
|
+
```json
|
|
252
|
+
{
|
|
253
|
+
"method": "get",
|
|
254
|
+
"model": "products",
|
|
255
|
+
"query": {
|
|
256
|
+
"type": "filter",
|
|
257
|
+
"select": ["id", "name", "price"],
|
|
258
|
+
"filter": {
|
|
259
|
+
"price": { "$mt": 10 },
|
|
260
|
+
"category": { "active": true }
|
|
261
|
+
},
|
|
262
|
+
"relation": ["category"],
|
|
263
|
+
"pagination": { "page": 0, "take": 10 }
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
#### 2. Inserção de Dados (insert)
|
|
269
|
+
Cria um novo registro na tabela especificada.
|
|
270
|
+
```json
|
|
271
|
+
{
|
|
272
|
+
"method": "insert",
|
|
273
|
+
"model": "products",
|
|
274
|
+
"data": {
|
|
275
|
+
"name": "Teclado Mecânico",
|
|
276
|
+
"price": 250.00,
|
|
277
|
+
"category": "uuid-da-categoria"
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
#### 3. Atualização de Dados (update)
|
|
283
|
+
Atualiza registros baseados em um filtro.
|
|
284
|
+
```json
|
|
285
|
+
{
|
|
286
|
+
"method": "update",
|
|
287
|
+
"model": "products",
|
|
288
|
+
"filter": { "id": "uuid-do-produto" },
|
|
289
|
+
"data": {
|
|
290
|
+
"price": 220.00
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
#### 4. Deleção de Dados (delete)
|
|
296
|
+
Remove registros baseados em um filtro.
|
|
297
|
+
```json
|
|
298
|
+
{
|
|
299
|
+
"method": "delete",
|
|
300
|
+
"model": "products",
|
|
301
|
+
"filter": { "id": "uuid-do-produto" }
|
|
302
|
+
}
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
#### Operadores de Filtro
|
|
306
|
+
| Operador | SQL Equivalente | Descrição | Exemplo JSON |
|
|
307
|
+
| :--- | :--- | :--- | :--- |
|
|
308
|
+
| $eq | = | Igualdade (padrão se omitido) | "price": { "$eq": 100 } |
|
|
309
|
+
| $l | LIKE | Busca textual (case-sensitive) | "name": { "$l": "Cerveja%" } |
|
|
310
|
+
| $il | ILIKE | Busca textual (case-insensitive) | "name": { "$il": "%artesanal%" } |
|
|
311
|
+
| $lt | < | Menor que | "stock": { "$lt": 10 } |
|
|
312
|
+
| $lte | <= | Menor ou igual a | "stock": { "$lte": 5 } |
|
|
313
|
+
| $mt | > | Maior que | "price": { "$mt": 50 } |
|
|
314
|
+
| $mte | >= | Maior ou igual a | "price": { "$mte": 100 } |
|
|
315
|
+
| $in | IN | Valor contido na lista | "status": { "$in": ["A", "B"] } |
|
|
316
|
+
| $nin | NOT IN | Valor NÃO contido na lista | "id": { "$nin": ["uuid-1"] } |
|
|
317
|
+
| $btw | BETWEEN | Valor entre dois pontos | "createdAt": { "$btw": ["2023-01-01", "2023-12-31"] } |
|
|
318
|
+
| $or | OR | Lógica OU entre filtros | "$or": [{ "active": true }, { "priority": 1 }] |
|
|
319
|
+
|
|
320
|
+
#### Funcionamento de Relacionamentos
|
|
321
|
+
O Opposer resolve relacionamentos de forma flexível. Você pode carregar modelos inteiros ou apenas campos específicos, inclusive misturando as abordagens no mesmo array.
|
|
322
|
+
|
|
323
|
+
- String única: Ao passar apenas o nome da relação como string, o Opposer traz todos os campos desse modelo.
|
|
324
|
+
- Objeto de configuração: Permite selecionar campos específicos ou aninhamentos futuros.
|
|
325
|
+
|
|
326
|
+
Exemplo: Carga Mista de Relacionamentos
|
|
327
|
+
```json
|
|
328
|
+
{
|
|
329
|
+
"method": "get",
|
|
330
|
+
"model": "products",
|
|
331
|
+
"query": {
|
|
332
|
+
"filter": { "category.active": true },
|
|
333
|
+
"relation": [
|
|
334
|
+
"category",
|
|
335
|
+
{ "model": "user", "select": ["id", "name"] }
|
|
336
|
+
]
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
```
|
|
340
|
+
|
|
341
|
+
---
|
|
342
|
+
|
|
343
|
+
#### Agregações e Métricas
|
|
344
|
+
Realize cálculos diretamente via JSON sem escrever código SQL.
|
|
345
|
+
```json
|
|
346
|
+
{
|
|
347
|
+
"method": "get",
|
|
348
|
+
"model": "products",
|
|
349
|
+
"query": {
|
|
350
|
+
"aggregate": {
|
|
351
|
+
"where": { "stock": { "$mt": 0 } },
|
|
352
|
+
"aggregate": { "price": "avg", "stock": "sum", "id": "count" }
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
---
|
|
359
|
+
|
|
360
|
+
## 4. Persistent (Estado e Cache Reativo)
|
|
361
|
+
|
|
362
|
+
Gerencie estados globais ou de sessão de forma transparente.
|
|
363
|
+
|
|
364
|
+
### Configuração de Snapshot
|
|
365
|
+
| Variável de Ambiente | Descrição | Padrão |
|
|
366
|
+
| :--- | :--- | :--- |
|
|
367
|
+
| OPPOSER_CACHE_SNAPSHOT | Habilita persistência em disco. | false |
|
|
368
|
+
| OPPOSER_CACHE_SNAPSHOT_TIMER| Intervalo entre backups. | 1 |
|
|
369
|
+
| OPPOSER_CACHE_SNAPSHOT_UNIT | Unidade (minutes, seconds). | minutes |
|
|
370
|
+
|
|
371
|
+
### Componentes de Persistência
|
|
372
|
+
Importe de "@ug.software/opposer/persistent".
|
|
373
|
+
|
|
374
|
+
| Componente | Escopo | Descrição |
|
|
375
|
+
| :--- | :--- | :--- |
|
|
376
|
+
| @Global() | Servidor | Compartilhado entre todos os usuários. |
|
|
377
|
+
| @Session() | Usuário | Isolado por sessão (Token/IP). |
|
|
378
|
+
|
|
379
|
+
### Exemplo de Persistência
|
|
380
|
+
```typescript
|
|
381
|
+
import { Global, Session } from "@ug.software/opposer/persistent";
|
|
382
|
+
|
|
383
|
+
export default class ConfigService {
|
|
384
|
+
@Global()
|
|
385
|
+
maintenanceMode: boolean = false; // Compartilhado globalmente
|
|
386
|
+
|
|
387
|
+
@Session()
|
|
388
|
+
theme: string = "dark"; // Individual por usuário
|
|
389
|
+
}
|
|
390
|
+
```
|
|
391
|
+
|
|
392
|
+
---
|
|
393
|
+
|
|
394
|
+
## 5. Segurança e Autenticação
|
|
395
|
+
|
|
396
|
+
O Opposer inclui um sistema de segurança completo e pronto para uso (Out-of-the-box), eliminando a necessidade de implementar fluxos manuais de login, registro ou gestão de sessões.
|
|
397
|
+
|
|
398
|
+
### Como Funciona
|
|
399
|
+
O sistema baseia-se em um fluxo de Duplo Token (Access + Refresh) para garantir máxima segurança e usabilidade:
|
|
400
|
+
|
|
401
|
+
1. Access Token: Token de curta duração usado para autorizar requisições.
|
|
402
|
+
2. Refresh Token: Token de longa duração usado exclusivamente para gerar novos Access Tokens sem deslogar o usuário.
|
|
403
|
+
|
|
404
|
+
### Onde enviar os Tokens
|
|
405
|
+
O Opposer é flexível e aceita tokens de duas formas principais:
|
|
406
|
+
|
|
407
|
+
- Navegador (Cookies): Ideal para aplicações web. Os tokens são gerenciados automaticamente via cookies httpOnly, prevenindo ataques XSS.
|
|
408
|
+
- API Externa (Bearer Header): Para integrações via mobile ou outros servidores, envie o Access Token no cabeçalho:
|
|
409
|
+
Authorization: Bearer <seu-token-aqui>
|
|
410
|
+
|
|
411
|
+
### API Key (opposer-key)
|
|
412
|
+
Além da autenticação de usuário, o Opposer exige uma chave de aplicação para autorizar requisições externas que não venham do mesmo domínio do servidor (como integrações entre sistemas ou aplicativos mobile).
|
|
413
|
+
|
|
414
|
+
Onde enviar:
|
|
415
|
+
- Cabeçalho HTTP: opposer-key: <sua-api-key-gerada>
|
|
416
|
+
- Cookie: opposer_key
|
|
417
|
+
|
|
418
|
+
Sem esta chave, o middleware de autorização bloqueará a requisição antes mesmo de validar o Token JWT. Você pode gerar novas chaves através do Playground ou via CLI.
|
|
419
|
+
|
|
420
|
+
### Revalidação Automática (Silent Refresh)
|
|
421
|
+
Quando um Access Token expira, o middleware do Opposer verifica automaticamente a presença de um refresh_token válido nos cookies. Caso exista:
|
|
422
|
+
1. A sessão antiga é invalidada no banco de dados.
|
|
423
|
+
2. Um novo par de tokens é gerado e enviado de volta nos cookies da resposta.
|
|
424
|
+
3. A requisição original prossegue normalmente, sem que o usuário perceba a expiração.
|
|
425
|
+
|
|
426
|
+
### Configuração de Segurança
|
|
427
|
+
| Variável de Ambiente | Descrição | Necessário |
|
|
428
|
+
| :--- | :--- | :--- |
|
|
429
|
+
| OPPOSER_JWT_ACCESS | Chave secreta para o Access Token. | Sim (se auth=true) |
|
|
430
|
+
| OPPOSER_JWT_REFRESH | Chave secreta para o Refresh Token. | Sim (se auth=true) |
|
|
431
|
+
| OPPOSER_MANAGER_LOGIN | Login do administrador inicial. | Sim |
|
|
432
|
+
| OPPOSER_MANAGER_PASSWORD| Senha do administrador inicial. | Sim |
|
|
433
|
+
|
|
434
|
+
Nota: Ao ativar o sistema de auth, o Opposer injeta automaticamente o Controller Auth em sua API, expondo métodos como login, register, me e logout.
|
|
435
|
+
|
|
436
|
+
|
|
437
|
+
---
|
|
438
|
+
|
|
439
|
+
## 6. Contexto de Aplicação
|
|
440
|
+
|
|
441
|
+
Singleton central para acessar instâncias críticas de qualquer lugar do código.
|
|
442
|
+
|
|
443
|
+
Chaves Injetadas: db (Database), models (Entidades), controllers (Ações).
|
|
444
|
+
|
|
445
|
+
### Exemplo de Uso
|
|
446
|
+
|
|
447
|
+
1. Recuperando uma instância (Get):
|
|
448
|
+
```typescript
|
|
449
|
+
import { Context } from "@ug.software/opposer/server";
|
|
450
|
+
import { OpposerDatabase } from "@ug.software/opposer/orm";
|
|
451
|
+
|
|
452
|
+
// Recuperando o banco de dados dentro de um Helper ou Service
|
|
453
|
+
const db = Context.get<OpposerDatabase>("db");
|
|
454
|
+
```
|
|
455
|
+
|
|
456
|
+
2. Inserindo uma instância personalizada (Set):
|
|
457
|
+
Você pode usar o contexto para compartilhar seus próprios serviços ou instâncias globais.
|
|
458
|
+
```typescript
|
|
459
|
+
import { Context } from "@ug.software/opposer/server";
|
|
460
|
+
|
|
461
|
+
// Inserindo um serviço customizado durante a inicialização
|
|
462
|
+
Context.set("mailService", new MailService());
|
|
463
|
+
|
|
464
|
+
// Recuperando em qualquer outro lugar
|
|
465
|
+
const mailer = Context.get<MailService>("mailService");
|
|
466
|
+
```
|
|
467
|
+
|
|
468
|
+
---
|
|
469
|
+
|
|
470
|
+
## 7. Inicialização do Projeto
|
|
471
|
+
|
|
472
|
+
A função Server orquestra o carregamento de todos os domínios.
|
|
473
|
+
|
|
474
|
+
### Exemplo de Inicialização (src/index.ts)
|
|
475
|
+
```typescript
|
|
476
|
+
import { Server } from "@ug.software/opposer";
|
|
477
|
+
|
|
478
|
+
const app = await Server({
|
|
479
|
+
models: "./src/models",
|
|
480
|
+
controllers: "./src/controllers",
|
|
481
|
+
schedules: "./src/schedules"
|
|
482
|
+
});
|
|
483
|
+
|
|
484
|
+
app.initialize();
|
|
485
|
+
```
|
|
486
|
+
|
|
487
|
+
---
|
|
488
|
+
|
|
489
|
+
## 8. Playground (Dashboard de Desenvolvimento)
|
|
490
|
+
|
|
491
|
+
Interface visual nativa para exploração e gestão.
|
|
492
|
+
- Testes RPC: Dispare métodos dos Controllers em tempo real.
|
|
493
|
+
- Explorar Models: Veja o mapa de dados e relacionamentos.
|
|
494
|
+
- Segurança: Gestão de usuários e geração de API Keys.
|
|
495
|
+
|
|
496
|
+
Acesso padrão: http://localhost:3838/playground
|
|
497
|
+
|
|
498
|
+
---
|
|
499
|
+
|
|
500
|
+
### CLI Helpers
|
|
501
|
+
- npx @ug.software/opposer init: Inicializa a estrutura base de um novo projeto.
|
|
502
|
+
- npx @ug.software/opposer build: Gera um bundle minificado em um único arquivo (dist/index.js).
|
|
503
|
+
- npx @ug.software/opposer generate:jwt-key: Gera um segredo seguro para JWT.
|
|
504
|
+
- npx @ug.software/opposer generate:api-key: Gera uma chave de acesso externa.
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import { spawn } from 'child_process';
|
|
4
|
+
import system from '../../../esm/system/index.js';
|
|
5
|
+
|
|
6
|
+
export const command = "build";
|
|
7
|
+
export const desc = "Bundle the project into a single minified file.";
|
|
8
|
+
|
|
9
|
+
export const builder = {
|
|
10
|
+
entry: {
|
|
11
|
+
alias: "e",
|
|
12
|
+
type: "string",
|
|
13
|
+
default: "src/index.ts",
|
|
14
|
+
describe: "Entry point of the application",
|
|
15
|
+
},
|
|
16
|
+
output: {
|
|
17
|
+
alias: "o",
|
|
18
|
+
type: "string",
|
|
19
|
+
default: "dist/index.js",
|
|
20
|
+
describe: "Output file path",
|
|
21
|
+
},
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
export const handler = async (argv) => {
|
|
25
|
+
const root = process.cwd();
|
|
26
|
+
const entryPath = path.resolve(root, argv.entry);
|
|
27
|
+
const outputPath = path.resolve(root, argv.output);
|
|
28
|
+
|
|
29
|
+
console.log('--> Starting Opposer Build...');
|
|
30
|
+
|
|
31
|
+
try {
|
|
32
|
+
// 1. Discover all entities
|
|
33
|
+
console.log('--> Scanning for controllers, models and schedules...');
|
|
34
|
+
|
|
35
|
+
// We don't actually need to await these here if we are just calling esbuild,
|
|
36
|
+
// but it's a good check to see if the project is valid.
|
|
37
|
+
await system.getAllControllers();
|
|
38
|
+
await system.getAllModels();
|
|
39
|
+
await system.getAllSchedules();
|
|
40
|
+
|
|
41
|
+
console.log('--> Invoking build engine...');
|
|
42
|
+
|
|
43
|
+
const esbuildArgs = [
|
|
44
|
+
'esbuild',
|
|
45
|
+
argv.entry,
|
|
46
|
+
'--bundle',
|
|
47
|
+
'--minify',
|
|
48
|
+
'--platform=node',
|
|
49
|
+
'--format=esm',
|
|
50
|
+
`--outfile=${argv.output}`,
|
|
51
|
+
'--external:bcrypt',
|
|
52
|
+
'--external:sqlite3',
|
|
53
|
+
'--external:mysql2',
|
|
54
|
+
'--external:pg'
|
|
55
|
+
];
|
|
56
|
+
|
|
57
|
+
const child = spawn('npx', esbuildArgs, {
|
|
58
|
+
stdio: 'inherit',
|
|
59
|
+
shell: true
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
child.on('close', (code) => {
|
|
63
|
+
if (code === 0) {
|
|
64
|
+
console.log(`\n--> Build completed successfully: ${argv.output}`);
|
|
65
|
+
console.log('--> You can now run your app with: node ' + argv.output);
|
|
66
|
+
} else {
|
|
67
|
+
console.error(`\n--> Build failed with code ${code}`);
|
|
68
|
+
console.log('--> Ensure you have "esbuild" installed or accessible via npx.');
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
} catch (error) {
|
|
73
|
+
console.error('--> Build error:', error.message);
|
|
74
|
+
}
|
|
75
|
+
};
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import * as crypto from "../../helpers/crypto.js";
|
|
2
|
+
import system from "../../../esm/system/index.js";
|
|
3
|
+
|
|
4
|
+
export const command = "generate:api-key";
|
|
5
|
+
export const desc = "Generate a new API key.";
|
|
6
|
+
|
|
7
|
+
export const builder = {
|
|
8
|
+
expires: {
|
|
9
|
+
alias: "e",
|
|
10
|
+
type: "string",
|
|
11
|
+
default: null,
|
|
12
|
+
describe: "Expiration date for the API key",
|
|
13
|
+
},
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export const handler = async ({ expires }) => {
|
|
17
|
+
const key = crypto.hash(32);
|
|
18
|
+
const settings = system.getSettingsFile();
|
|
19
|
+
|
|
20
|
+
console.log('--> Generating API Key...');
|
|
21
|
+
console.log(`--> Key: ${key}`);
|
|
22
|
+
|
|
23
|
+
if (expires) {
|
|
24
|
+
console.log(`--> Expires: ${expires}`);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
console.log('--> Note: You should store this key securely.');
|
|
28
|
+
};
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import * as crypto from "../../helpers/crypto.js";
|
|
2
|
+
import system from "../../../esm/system/index.js";
|
|
3
|
+
|
|
4
|
+
export const command = "generate:jwt-key";
|
|
5
|
+
export const desc = "Generate a random JWT key.";
|
|
6
|
+
|
|
7
|
+
export const builder = {
|
|
8
|
+
length: {
|
|
9
|
+
alias: "l",
|
|
10
|
+
type: "number",
|
|
11
|
+
default: null,
|
|
12
|
+
describe: "Size of the key to be generated",
|
|
13
|
+
},
|
|
14
|
+
phrase: {
|
|
15
|
+
alias: "p",
|
|
16
|
+
type: "string",
|
|
17
|
+
default: null,
|
|
18
|
+
describe: "Phrase to be used to generate deterministic hash.",
|
|
19
|
+
},
|
|
20
|
+
salt: {
|
|
21
|
+
alias: "s",
|
|
22
|
+
type: "number",
|
|
23
|
+
default: 30,
|
|
24
|
+
describe: "Number of rounds when generating deterministic hash.",
|
|
25
|
+
},
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
export const handler = ({ length, phrase, salt }) => {
|
|
29
|
+
if (length && phrase) {
|
|
30
|
+
throw new Error("Pass only one argument, either length or phrase.");
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
if (!length && !phrase) {
|
|
34
|
+
length = 32;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
if (length) {
|
|
38
|
+
const hash = crypto.hash(length);
|
|
39
|
+
console.log(`--> Generated JWT Key (${length} chars): ${hash}`);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
if (phrase) {
|
|
43
|
+
const hash = crypto.deterministic(phrase, salt);
|
|
44
|
+
console.log(`--> Generated JWT Key from phrase: ${hash}`);
|
|
45
|
+
}
|
|
46
|
+
};
|