@airoom/nextmin-node 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/LICENSE +49 -0
  2. package/README.md +178 -0
  3. package/dist/api/apiRouter.d.ts +65 -0
  4. package/dist/api/apiRouter.js +1548 -0
  5. package/dist/database/DatabaseAdapter.d.ts +14 -0
  6. package/dist/database/DatabaseAdapter.js +2 -0
  7. package/dist/database/InMemoryAdapter.d.ts +15 -0
  8. package/dist/database/InMemoryAdapter.js +71 -0
  9. package/dist/database/MongoAdapter.d.ts +52 -0
  10. package/dist/database/MongoAdapter.js +409 -0
  11. package/dist/files/FileStorageAdapter.d.ts +35 -0
  12. package/dist/files/FileStorageAdapter.js +2 -0
  13. package/dist/files/S3FileStorageAdapter.d.ts +30 -0
  14. package/dist/files/S3FileStorageAdapter.js +84 -0
  15. package/dist/files/filename.d.ts +5 -0
  16. package/dist/files/filename.js +40 -0
  17. package/dist/index.d.ts +13 -0
  18. package/dist/index.js +87 -0
  19. package/dist/models/BaseModel.d.ts +44 -0
  20. package/dist/models/BaseModel.js +31 -0
  21. package/dist/policy/authorize.d.ts +25 -0
  22. package/dist/policy/authorize.js +305 -0
  23. package/dist/policy/conditions.d.ts +14 -0
  24. package/dist/policy/conditions.js +30 -0
  25. package/dist/policy/types.d.ts +53 -0
  26. package/dist/policy/types.js +2 -0
  27. package/dist/policy/utils.d.ts +9 -0
  28. package/dist/policy/utils.js +118 -0
  29. package/dist/schemas/Roles.json +64 -0
  30. package/dist/schemas/Settings.json +62 -0
  31. package/dist/schemas/Users.json +123 -0
  32. package/dist/services/SchemaService.d.ts +10 -0
  33. package/dist/services/SchemaService.js +46 -0
  34. package/dist/utils/DefaultDataInitializer.d.ts +21 -0
  35. package/dist/utils/DefaultDataInitializer.js +269 -0
  36. package/dist/utils/Logger.d.ts +12 -0
  37. package/dist/utils/Logger.js +79 -0
  38. package/dist/utils/SchemaLoader.d.ts +51 -0
  39. package/dist/utils/SchemaLoader.js +323 -0
  40. package/dist/utils/apiKey.d.ts +5 -0
  41. package/dist/utils/apiKey.js +14 -0
  42. package/dist/utils/fieldCodecs.d.ts +13 -0
  43. package/dist/utils/fieldCodecs.js +133 -0
  44. package/package.json +45 -0
  45. package/tsconfig.json +8 -0
package/LICENSE ADDED
@@ -0,0 +1,49 @@
1
+ Nextmin Proprietary License v1.0
2
+
3
+ Copyright (c) 2025 GSCodes
4
+ All rights reserved.
5
+
6
+ 1. Definitions
7
+ “Software” means the package and all accompanying files under the package name(s) @airoom/nextmin-react and @airoom/nextmin-node, including any updates provided by Licensor.
8
+ “Licensor” means GSCodes.
9
+ “Licensee” means the person or entity that obtains the Software.
10
+
11
+ 2. Grant of License
12
+ Subject to full compliance with this License, Licensor grants Licensee a limited, non-exclusive, non-transferable, non-sublicensable license to:
13
+ a) install and use the Software internally, solely for evaluating or running Licensee’s own applications; and
14
+ b) make a reasonable number of copies solely for internal backup and archival purposes.
15
+
16
+ 3. Restrictions
17
+ Except as expressly permitted in Section 2, Licensee must NOT:
18
+ a) copy, publish, distribute, sell, rent, lease, lend, sublicense, or otherwise make the Software available to any third party;
19
+ b) modify, translate, adapt, create derivative works of, or merge the Software with other software;
20
+ c) reverse engineer, decompile, disassemble, or otherwise attempt to derive source code or underlying ideas, except to the extent such restrictions are expressly prohibited by applicable law;
21
+ d) remove, obscure, or alter any proprietary notices or markings; or
22
+ e) use the Software to train, fine-tune, or improve any artificial intelligence or machine learning model.
23
+
24
+ 4. Ownership
25
+ The Software is licensed, not sold. Licensor retains all right, title, and interest in and to the Software, including all intellectual property rights and all copies.
26
+
27
+ 5. Confidentiality
28
+ The Software and any non-public information provided by Licensor shall be treated as confidential and not disclosed to any third party without Licensor’s prior written consent, except as required by law.
29
+
30
+ 6. Term and Termination
31
+ This License is effective until terminated. Licensor may terminate this License immediately upon notice if Licensee breaches any term. Upon termination, Licensee must cease all use and destroy all copies of the Software. Sections 3–10 survive termination.
32
+
33
+ 7. Updates; No Support Obligation
34
+ Licensor may, but is not obligated to, provide updates, bug fixes, or support. Any updates are governed by this License unless accompanied by a different license.
35
+
36
+ 8. No Warranty
37
+ THE SOFTWARE IS PROVIDED “AS IS” AND “AS AVAILABLE,” WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE, AND NON-INFRINGEMENT. USE IS AT LICENSEE’S SOLE RISK.
38
+
39
+ 9. Limitation of Liability
40
+ TO THE MAXIMUM EXTENT PERMITTED BY LAW, IN NO EVENT SHALL LICENSOR BE LIABLE FOR ANY INDIRECT, INCIDENTAL, SPECIAL, CONSEQUENTIAL, EXEMPLARY, OR PUNITIVE DAMAGES, OR FOR ANY LOSS OF PROFITS, REVENUE, DATA, GOODWILL, OR BUSINESS INTERRUPTION, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. LICENSOR’S TOTAL LIABILITY FOR ALL CLAIMS SHALL NOT EXCEED THE AMOUNT PAID BY LICENSEE FOR THE SOFTWARE (IF ANY) IN THE TWELVE (12) MONTHS PRECEDING THE CLAIM.
41
+
42
+ 10. Governing Law; Venue
43
+ This License is governed by the laws of State of California, USA, without regard to its conflict of laws principles. The parties submit to the exclusive jurisdiction and venue of the courts located in San Francisco County, California, USA.
44
+
45
+ 11. Commercial Licensing
46
+ For commercial use, redistribution, or other rights not expressly granted, contact: tareqaziz0065@gmail.com.
47
+
48
+ 12. Entire Agreement
49
+ This License constitutes the entire agreement with respect to the Software and supersedes all prior or contemporaneous agreements or understandings on the subject matter.
package/README.md ADDED
@@ -0,0 +1,178 @@
1
+ # @airoom/nextmin-node
2
+
3
+ Schema‑driven Node.js toolkit that turns a JSON schema into a secure, policy‑aware REST API with authentication, CRUD, relationship querying, and file uploads. Pair it with `@airoom/nextmin-react` to get a fully‑featured Admin Panel in minutes.
4
+
5
+ - “From JSON schema to REST API + Admin”
6
+ - 1 month → 1 hour
7
+
8
+ ## Highlights
9
+
10
+ - Express router factory: mount a complete REST API in a few lines
11
+ - Auth built in: register, login, me, change‑password, forgot‑password
12
+ - CRUD per model with read masks, write restrictions, and role/owner policies
13
+ - Advanced list endpoint: filter, multi‑field search, date ranges, multi‑field sort, paginate
14
+ - Relationship endpoints: forward and reverse lookups without autopopulate
15
+ - Schemas hot‑reload during development; automatic model wiring
16
+ - File uploads via pluggable storage (e.g., S3/MinIO); delete by key
17
+ - Database adapters: MongoDB (with index sync) and in‑memory for tests
18
+ - Emits a trusted API key stored in your Settings model for client access
19
+
20
+ ## Installation
21
+
22
+ ```bash
23
+ # npm
24
+ npm install @airoom/nextmin-node
25
+
26
+ # yarn
27
+ yarn add @airoom/nextmin-node
28
+
29
+ # pnpm
30
+ pnpm add @airoom/nextmin-node
31
+ ```
32
+
33
+ ## Quick start (Express + Mongo + S3 optional)
34
+
35
+ ```ts
36
+ import dotenv from 'dotenv';
37
+ import express from 'express';
38
+ import http from 'http';
39
+ import {
40
+ createNextMinRouter,
41
+ MongoAdapter,
42
+ S3FileStorageAdapter,
43
+ } from '@airoom/nextmin-node';
44
+ import cors from 'cors';
45
+
46
+ dotenv.config();
47
+
48
+ async function start() {
49
+ const app = express();
50
+ const server = http.createServer(app); // pass this to the router for sockets
51
+
52
+ app.use(cors());
53
+
54
+ // 1) Database
55
+ const db = new MongoAdapter(process.env.MONGO_URL!, process.env.MONGO_DB!);
56
+ await db.connect();
57
+
58
+ // 2) Optional: file storage adapter (S3/MinIO)
59
+ const files = new S3FileStorageAdapter({
60
+ bucket: process.env.S3_BUCKET!,
61
+ region: process.env.S3_REGION!,
62
+ credentials:
63
+ process.env.S3_ACCESS_KEY_ID && process.env.S3_SECRET_ACCESS_KEY
64
+ ? {
65
+ accessKeyId: process.env.S3_ACCESS_KEY_ID!,
66
+ secretAccessKey: process.env.S3_SECRET_ACCESS_KEY!,
67
+ }
68
+ : undefined,
69
+ endpoint: process.env.S3_ENDPOINT || undefined,
70
+ forcePathStyle: /^(1|true|yes)$/i.test(process.env.S3_FORCE_PATH_STYLE || ''),
71
+ defaultACL: (process.env.S3_DEFAULT_ACL as any) || 'public-read',
72
+ publicBaseUrl: process.env.S3_PUBLIC_BASE_URL || undefined,
73
+ });
74
+
75
+ // 3) Mount NextMin REST router
76
+ const router = createNextMinRouter({ dbAdapter: db, server, fileStorageAdapter: files });
77
+ app.use('/rest', router);
78
+
79
+ // 4) Listen with the same server instance
80
+ const port = Number(process.env.PORT || 8081);
81
+ server.listen(port, () => console.log(`REST ready: http://localhost:${port}/rest`));
82
+ }
83
+
84
+ start().catch((e) => {
85
+ console.error(e);
86
+ process.exit(1);
87
+ });
88
+ ```
89
+
90
+ ## REST endpoints (summary)
91
+
92
+ Base: `/rest`
93
+
94
+ - Schemas: `GET /_schemas` → public schema list (requires x-api-key)
95
+ - Auth (users):
96
+ - `POST /auth/users/register`
97
+ - `POST /auth/users/login`
98
+ - `GET /auth/users/me`
99
+ - `POST /auth/users/change-password`
100
+ - `POST /auth/users/forgot-password`
101
+ - Generic CRUD per model (model names are lowercase):
102
+ - `POST /:model`
103
+ - `GET /:model` (query: page, limit, q, searchKey(s), searchMode, dateFrom/to/key, sort, sortType)
104
+ - `GET /:model/:id`
105
+ - `PUT /:model/:id` (or PATCH depending on client)
106
+ - `DELETE /:model/:id`
107
+ - Relationship queries:
108
+ - Forward: `GET /find/:container/:refField/:id`
109
+ - Reverse: `GET /find/reverse/:target/:byField/:id`
110
+ - Files (when file storage adapter is configured):
111
+ - Upload: `POST /files` (multipart form, fields named `file`)
112
+ - Delete: `DELETE /files/:key(*)`
113
+
114
+ See full examples in documentation and the `examples/node` app inside this monorepo.
115
+
116
+ ## Headers and auth
117
+
118
+ - All requests must include the API key header: `x-api-key: <YOUR_API_KEY>`
119
+ - Authenticated routes also require: `Authorization: Bearer <JWT>`
120
+
121
+ Where do I find my API key?
122
+
123
+ - On first run, the server initializes default data and stores a trusted `apiKey` in your Settings collection/table.
124
+ - Copy that value into your clients. You can also preseed it by setting `NEXTMIN_API_KEY` before the first boot.
125
+
126
+ ## Configuration (env)
127
+
128
+ Application
129
+
130
+ - `APP_MODE`: development | production (affects dev features)
131
+ - `JWT_SECRET`: secret used to sign JWTs
132
+
133
+ Database
134
+
135
+ - `MONGO_URL`: e.g. mongodb://localhost:27017
136
+ - `MONGO_DB`: database name
137
+
138
+ File storage (optional)
139
+
140
+ - `S3_BUCKET`, `S3_REGION`
141
+ - `S3_ACCESS_KEY_ID`, `S3_SECRET_ACCESS_KEY`
142
+ - `S3_ENDPOINT` (for MinIO or custom)
143
+ - `S3_FORCE_PATH_STYLE` (true for MinIO)
144
+ - `S3_DEFAULT_ACL` (e.g., public-read)
145
+ - `S3_PUBLIC_BASE_URL` (CDN/base URL for public links)
146
+
147
+ Frontend integration
148
+
149
+ - `NEXT_PUBLIC_GOOGLE_MAPS_KEY` (used by address autocomplete within the Admin UI)
150
+
151
+ ## Default super admin (after setup)
152
+
153
+ After the initial setup, you can sign in with the default super user and should immediately change the password:
154
+
155
+ - Email: super@example.com
156
+ - Username: superadmin
157
+ - Password: supersecurepassword
158
+
159
+ Change it right after the first login.
160
+
161
+ ## TypeScript
162
+
163
+ Types are bundled. Example import:
164
+
165
+ ```ts
166
+ import type { APIRouterOptions } from '@airoom/nextmin-node';
167
+ ```
168
+
169
+ ## Troubleshooting
170
+
171
+ - 401 Unauthorized: verify `x-api-key` matches `Settings.apiKey` and that JWT is present for protected routes.
172
+ - CORS issues: allow your frontend origin in development.
173
+ - Sorting/filters: unknown fields are ignored; ensure you pass existing attribute names.
174
+ - Relationship endpoints: confirm your schema uses proper `ref` fields.
175
+
176
+ ## License
177
+
178
+ Licensed under the Nextmin Proprietary License. © 2025 GSCodes. For commercial licensing or extended rights, contact: tareqaziz0065@gmail.com.
@@ -0,0 +1,65 @@
1
+ import express from 'express';
2
+ import type { Server as HttpServer } from 'http';
3
+ import { DatabaseAdapter } from '../database/DatabaseAdapter';
4
+ import type { FileStorageAdapter } from '../files/FileStorageAdapter';
5
+ export interface APIRouterOptions {
6
+ dbAdapter: DatabaseAdapter;
7
+ server?: HttpServer;
8
+ fileStorageAdapter?: FileStorageAdapter;
9
+ }
10
+ export declare class APIRouter {
11
+ private router;
12
+ private models;
13
+ private dbAdapter;
14
+ private jwtSecret;
15
+ private trustedApiKey;
16
+ private schemaLoader;
17
+ private isDevelopment;
18
+ private findRoutesMounted;
19
+ private authRoutesInitialized;
20
+ private schemasRouteRegistered;
21
+ private registeredModels;
22
+ private liveSchemas;
23
+ private notFoundHandler?;
24
+ private fileStorage?;
25
+ constructor(options: APIRouterOptions);
26
+ getRouter(): express.Router;
27
+ private wireSchemaHotReload;
28
+ private syncAllIndexes;
29
+ private diffRemovedModels;
30
+ private setLiveSchemas;
31
+ private rebuildModels;
32
+ private mountSchemasEndpointOnce;
33
+ private mountRoutes;
34
+ private getSchema;
35
+ private getModel;
36
+ private setupRoutes;
37
+ private mountFindRoutes;
38
+ private fileAuthMiddleware;
39
+ /** Mount generic file endpoints under this router */
40
+ private setupFileRoutes;
41
+ /** uploads/YYYY/MM/DD */
42
+ private shortFolder;
43
+ /** small, URL-safe uid */
44
+ private shortUid;
45
+ private normalizeAttrType;
46
+ private optionalAuthMiddleware;
47
+ private pickAuthFor;
48
+ private getUserRoleFromReq;
49
+ private normalizeRoleName;
50
+ private setupAuthRoutes;
51
+ /**
52
+ * Validate required fields.
53
+ * - create: field must exist and be non-empty (not null/undefined/'').
54
+ * - update: only validate fields that are explicitly present in the payload;
55
+ * absence means "unchanged".
56
+ */
57
+ private validateRequiredFields;
58
+ private handleWriteError;
59
+ private setupNotFoundMiddleware;
60
+ private ensureNotFoundLast;
61
+ private apiKeyMiddleware;
62
+ private validateRoleValue;
63
+ private authenticateMiddleware;
64
+ private checkUniqueFields;
65
+ }