@azlib/cms 0.4.0 → 0.6.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.
- package/README.md +132 -42
- package/dist/index.cjs +3500 -47
- package/dist/index.d.cts +885 -1
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +885 -1
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +3444 -48
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -117,46 +117,56 @@ Create modular, decoupled plugins that extend collections, inject custom fields,
|
|
|
117
117
|
```typescript
|
|
118
118
|
import { definePlugin, fields } from "@azlib/cms";
|
|
119
119
|
|
|
120
|
-
export const seoPlugin = definePlugin<{ defaultTitleSuffix?: string }>(
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
const urls = posts.items.map((p) => `https://example.com/posts/${p.slug}`);
|
|
149
|
-
return new Response(JSON.stringify({ urls }), {
|
|
150
|
-
headers: { "Content-Type": "application/json" },
|
|
120
|
+
export const seoPlugin = definePlugin<{ defaultTitleSuffix?: string }>(
|
|
121
|
+
(options = {}) => ({
|
|
122
|
+
name: "seo-plugin",
|
|
123
|
+
version: "1.0.0",
|
|
124
|
+
|
|
125
|
+
// 1. Inject custom fields into existing collections
|
|
126
|
+
extendCollections: {
|
|
127
|
+
posts: [
|
|
128
|
+
fields.text({ name: "metaTitle", label: "Meta Title" }),
|
|
129
|
+
fields.text({ name: "metaDescription", label: "Meta Description" }),
|
|
130
|
+
],
|
|
131
|
+
},
|
|
132
|
+
|
|
133
|
+
// 2. Programmatic setup for hooks and routes
|
|
134
|
+
setup({ hooks, registerRoute, engine }) {
|
|
135
|
+
// Intercept content before saving
|
|
136
|
+
hooks.addFilter("cms.before_create_input", (input: any) => {
|
|
137
|
+
if (
|
|
138
|
+
input.title &&
|
|
139
|
+
options.defaultTitleSuffix &&
|
|
140
|
+
!input.data?.metaTitle
|
|
141
|
+
) {
|
|
142
|
+
input.data = {
|
|
143
|
+
...input.data,
|
|
144
|
+
metaTitle: `${input.title} | ${options.defaultTitleSuffix}`,
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
return input;
|
|
151
148
|
});
|
|
152
|
-
});
|
|
153
|
-
},
|
|
154
149
|
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
})
|
|
150
|
+
// Expose custom Web Standard API route
|
|
151
|
+
registerRoute("GET", "/api/seo/sitemap", async () => {
|
|
152
|
+
const posts = await engine
|
|
153
|
+
.collection("posts")
|
|
154
|
+
.find({ status: "published" });
|
|
155
|
+
const urls = posts.items.map(
|
|
156
|
+
(p) => `https://example.com/posts/${p.slug}`,
|
|
157
|
+
);
|
|
158
|
+
return new Response(JSON.stringify({ urls }), {
|
|
159
|
+
headers: { "Content-Type": "application/json" },
|
|
160
|
+
});
|
|
161
|
+
});
|
|
162
|
+
},
|
|
163
|
+
|
|
164
|
+
// 3. Lifecycle callbacks
|
|
165
|
+
async onInit(engine) {
|
|
166
|
+
console.log("[SEO Plugin] Initialized");
|
|
167
|
+
},
|
|
168
|
+
}),
|
|
169
|
+
);
|
|
160
170
|
```
|
|
161
171
|
|
|
162
172
|
Register plugins declaratively in `defineConfig` or dynamically via `cms.use()`:
|
|
@@ -178,7 +188,12 @@ cms.use(seoPlugin());
|
|
|
178
188
|
Turn `@azlib/cms` into a complete commerce backend with pre-defined schemas, catalog taxonomies, image uploading, coupon validation, cart calculation, inventory tracking, and orders:
|
|
179
189
|
|
|
180
190
|
```typescript
|
|
181
|
-
import {
|
|
191
|
+
import {
|
|
192
|
+
createCMSEngine,
|
|
193
|
+
defineConfig,
|
|
194
|
+
ecommercePlugin,
|
|
195
|
+
getEcommerceService,
|
|
196
|
+
} from "@azlib/cms";
|
|
182
197
|
|
|
183
198
|
// 1. Enable the plugin in your config
|
|
184
199
|
export default defineConfig({
|
|
@@ -203,8 +218,15 @@ await cms.init();
|
|
|
203
218
|
const commerce = getEcommerceService(cms);
|
|
204
219
|
|
|
205
220
|
// Create hierarchical catalog category
|
|
206
|
-
const apparel = await commerce.createCategory({
|
|
207
|
-
|
|
221
|
+
const apparel = await commerce.createCategory({
|
|
222
|
+
name: "Apparel",
|
|
223
|
+
slug: "apparel",
|
|
224
|
+
});
|
|
225
|
+
const shoes = await commerce.createCategory({
|
|
226
|
+
name: "Shoes",
|
|
227
|
+
slug: "shoes",
|
|
228
|
+
parentId: apparel.id,
|
|
229
|
+
});
|
|
208
230
|
|
|
209
231
|
// Create product with SKU, pricing, inventory, variants
|
|
210
232
|
const product = await commerce.createProduct({
|
|
@@ -272,12 +294,15 @@ const order = await commerce.createOrder({
|
|
|
272
294
|
},
|
|
273
295
|
});
|
|
274
296
|
|
|
275
|
-
console.log(
|
|
297
|
+
console.log(
|
|
298
|
+
`Order placed: #${order.data.orderNumber} (Total: $${order.data.total})`,
|
|
299
|
+
);
|
|
276
300
|
```
|
|
277
301
|
|
|
278
302
|
### 4. REST API & Headless Client
|
|
279
303
|
|
|
280
304
|
Mount the universal `createCMSRouter(cms)` to automatically expose REST endpoints:
|
|
305
|
+
|
|
281
306
|
- `GET /api/ecommerce/products` (supports `?category=...&minPrice=...&maxPrice=...&inStock=true&search=...`)
|
|
282
307
|
- `GET /api/ecommerce/products/:idOrSlug`
|
|
283
308
|
- `POST /api/ecommerce/products`
|
|
@@ -302,6 +327,71 @@ const order = await shop.orders.create({ ... });
|
|
|
302
327
|
|
|
303
328
|
---
|
|
304
329
|
|
|
330
|
+
## Built-in HRMS Plugin (`hrmsPlugin`)
|
|
331
|
+
|
|
332
|
+
`@azlib/cms` includes a full-featured Human Resource Management System (HRMS) plugin for multi-tenant companies, employee directory profiles, attendance tracking, and leave quota management.
|
|
333
|
+
|
|
334
|
+
### Features
|
|
335
|
+
|
|
336
|
+
- 🏢 **Multi-Tenant Employers**: Manage distinct companies/organizations with custom work schedules, timezones, and grace periods.
|
|
337
|
+
- 👤 **Employee Directory**: Rich employee profiles, contract/document attachments, emergency contacts, manager hierarchies, and department taxonomies.
|
|
338
|
+
- ⏱️ **Daily Attendance Tracking**: Clock-in and clock-out with automated duration calculation, overtime hours, and late-arrival detection against work schedules.
|
|
339
|
+
- 🏖️ **Leave Quota & Approval Workflow**: Custom leave types (Annual, Sick, Unpaid), balance ledger reports, and manager approval/rejection pipelines.
|
|
340
|
+
- 🌐 **Web Standard REST APIs & Client SDK**: Pre-mounted routes under `/api/hrms/*` and typed `HRMSClient` SDK.
|
|
341
|
+
|
|
342
|
+
### Usage
|
|
343
|
+
|
|
344
|
+
```typescript
|
|
345
|
+
import {
|
|
346
|
+
createCMSEngine,
|
|
347
|
+
defineConfig,
|
|
348
|
+
hrmsPlugin,
|
|
349
|
+
getHRMSService,
|
|
350
|
+
} from "@azlib/cms";
|
|
351
|
+
|
|
352
|
+
const config = defineConfig({
|
|
353
|
+
plugins: [
|
|
354
|
+
hrmsPlugin({
|
|
355
|
+
workScheduleStart: "09:00",
|
|
356
|
+
workScheduleEnd: "17:00",
|
|
357
|
+
standardWorkDayHours: 8,
|
|
358
|
+
gracePeriodMinutes: 15,
|
|
359
|
+
}),
|
|
360
|
+
],
|
|
361
|
+
});
|
|
362
|
+
|
|
363
|
+
const cms = createCMSEngine(config);
|
|
364
|
+
await cms.init();
|
|
365
|
+
|
|
366
|
+
const hrms = getHRMSService(cms);
|
|
367
|
+
|
|
368
|
+
// 1. Create an Employer
|
|
369
|
+
const employer = await hrms.createEmployer({
|
|
370
|
+
companyName: "Acme Corp",
|
|
371
|
+
timezone: "America/New_York",
|
|
372
|
+
});
|
|
373
|
+
|
|
374
|
+
// 2. Add an Employee
|
|
375
|
+
const employee = await hrms.createEmployee({
|
|
376
|
+
employerId: employer.id,
|
|
377
|
+
employeeNumber: "ACME-001",
|
|
378
|
+
firstName: "Jane",
|
|
379
|
+
lastName: "Doe",
|
|
380
|
+
email: "jane.doe@acme.example",
|
|
381
|
+
hireDate: "2024-01-15",
|
|
382
|
+
});
|
|
383
|
+
|
|
384
|
+
// 3. Employee Check-In & Check-Out
|
|
385
|
+
await hrms.checkIn({ employeeId: employee.id });
|
|
386
|
+
await hrms.checkOut({ employeeId: employee.id });
|
|
387
|
+
|
|
388
|
+
// 4. Request Leave & Check Balance
|
|
389
|
+
const leaveReport = await hrms.calculateLeaveBalance(employee.id, 2026);
|
|
390
|
+
console.log(`Remaining days: ${leaveReport.totalRemaining}`);
|
|
391
|
+
```
|
|
392
|
+
|
|
393
|
+
---
|
|
394
|
+
|
|
305
395
|
## License
|
|
306
396
|
|
|
307
397
|
MIT © Google / azlib
|