@vikukumar/propvault-pdk 0.1.4
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 +129 -0
- package/bin/build.js +46 -0
- package/bin/pdk-cli.js +223 -0
- package/dist/index.d.ts +29 -0
- package/dist/index.js +32 -0
- package/dist/index.js.map +7 -0
- package/package.json +28 -0
- package/src/index.ts +59 -0
- package/tsconfig.json +15 -0
package/README.md
ADDED
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
# PropVault CMS — Plugin Development Kit (PDK)
|
|
2
|
+
|
|
3
|
+
Extend the functionality of the PropVault Real Estate CMS and Page Builder platform with dynamic plugins. Custom plugins can register Action hooks to trigger custom logic on events (e.g. sending CRM leads) and Filter hooks to intercept and mutate variables/configs before operations complete.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Getting Started
|
|
8
|
+
|
|
9
|
+
### 1. Requirements
|
|
10
|
+
Ensure you have **Node.js >= 18** and **TypeScript** installed locally.
|
|
11
|
+
|
|
12
|
+
### 2. Scaffold a New Plugin
|
|
13
|
+
Run the PDK CLI initializer inside the directory where you want to scaffold your plugin.
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
# Initialize a new plugin template
|
|
17
|
+
npx @vikukumar/propvault-pdk create my-custom-plugin
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
This scaffolds the following plugin directory structure:
|
|
21
|
+
```
|
|
22
|
+
my-custom-plugin/
|
|
23
|
+
├── src/
|
|
24
|
+
│ └── index.ts # Core plugin logic & hooks registration
|
|
25
|
+
├── dist/ # Compiled distribution (created on build)
|
|
26
|
+
├── package.json # Node config & build scripts
|
|
27
|
+
├── tsconfig.json # TypeScript compiler configurations
|
|
28
|
+
└── plugin.json # Plugin manifest metadata block
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
### 3. Install Scaffolding Dependencies
|
|
32
|
+
```bash
|
|
33
|
+
cd my-custom-plugin
|
|
34
|
+
npm install
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
## Writing Plugin Logic
|
|
40
|
+
|
|
41
|
+
Plugins register hook handlers inside `src/index.ts` using `addAction` and `addFilter` from the `@vikukumar/propvault-pdk` package.
|
|
42
|
+
|
|
43
|
+
### 1. Action Hooks
|
|
44
|
+
Action hooks trigger custom operations when specific system events occur (e.g., lead submission, newsletter registration, theme swap).
|
|
45
|
+
|
|
46
|
+
```typescript
|
|
47
|
+
import { addAction } from "@vikukumar/propvault-pdk";
|
|
48
|
+
|
|
49
|
+
// Send WhatsApp telemetry notifications on new lead submissions
|
|
50
|
+
addAction("after_lead_submit", async (lead: any) => {
|
|
51
|
+
console.log("New Lead submitted in CMS:", lead.email);
|
|
52
|
+
|
|
53
|
+
// Call webhook endpoint
|
|
54
|
+
await fetch("https://api.mycrm.com/v1/leads", {
|
|
55
|
+
method: "POST",
|
|
56
|
+
headers: { "Content-Type": "application/json" },
|
|
57
|
+
body: JSON.stringify(lead),
|
|
58
|
+
});
|
|
59
|
+
}, 10);
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### 2. Filter Hooks
|
|
63
|
+
Filter hooks intercept, modify, and return modified values/variables before the CMS processes them.
|
|
64
|
+
|
|
65
|
+
```typescript
|
|
66
|
+
import { addFilter } from "@vikukumar/propvault-pdk";
|
|
67
|
+
|
|
68
|
+
// Force a premium badge suffix on project titles before they are stored in the database
|
|
69
|
+
addFilter("before_project_save", async (project: any) => {
|
|
70
|
+
if (project.title && !project.title.includes("[Verified]")) {
|
|
71
|
+
project.title = `${project.title} [Verified]`;
|
|
72
|
+
}
|
|
73
|
+
return project;
|
|
74
|
+
});
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
---
|
|
78
|
+
|
|
79
|
+
## Core Hooks Registry API
|
|
80
|
+
|
|
81
|
+
### Action Hooks
|
|
82
|
+
| Hook Slug | Arguments | Description |
|
|
83
|
+
|---|---|---|
|
|
84
|
+
| `after_lead_submit` | `(lead: Lead)` | Fires after a contact form submission is registered. |
|
|
85
|
+
| `after_newsletter_subscribe` | `(subscription: Subscription)` | Fires after a newsletter email subscription is verified. |
|
|
86
|
+
|
|
87
|
+
### Filter Hooks
|
|
88
|
+
| Hook Slug | Arguments | Description |
|
|
89
|
+
|---|---|---|
|
|
90
|
+
| `before_project_save` | `(project: Project)` | Filters project attributes before SQLite/PostgreSQL insertion. |
|
|
91
|
+
| `before_lead_save` | `(lead: Lead)` | Filters lead fields before database submission. |
|
|
92
|
+
|
|
93
|
+
---
|
|
94
|
+
|
|
95
|
+
## Build & Packaging
|
|
96
|
+
|
|
97
|
+
Once development is complete, compile and compress your plugin files into a distribution-ready bundle:
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
# 1. Compile TypeScript to JavaScript dist/index.js
|
|
101
|
+
npm run build
|
|
102
|
+
|
|
103
|
+
# 2. Package manifest and built script into plugin.zip
|
|
104
|
+
npm run package
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
The CLI outputs a **`plugin.zip`** package.
|
|
108
|
+
|
|
109
|
+
---
|
|
110
|
+
|
|
111
|
+
## Publishing and Installation Options
|
|
112
|
+
|
|
113
|
+
PropVault CMS supports three installation pathways:
|
|
114
|
+
|
|
115
|
+
### Option A: Direct Zip Upload (Recommended)
|
|
116
|
+
1. Go to **PropVault Admin Panel** -> **Plugins**.
|
|
117
|
+
2. Locate the **Upload Zip Archive** card.
|
|
118
|
+
3. Select your built `plugin.zip` file.
|
|
119
|
+
4. Click **Upload** and toggle **Activate**.
|
|
120
|
+
|
|
121
|
+
### Option B: Package Manager (NPM Release)
|
|
122
|
+
Publish your compiled folder structure containing `plugin.json` to npm:
|
|
123
|
+
```bash
|
|
124
|
+
npm publish
|
|
125
|
+
```
|
|
126
|
+
CMS administrators can install it in their workspace by entering the package name (e.g. `my-propvault-plugin`) in the **NPM Package Registry** dashboard card.
|
|
127
|
+
|
|
128
|
+
### Option C: Git Releases
|
|
129
|
+
Host your plugin repository on GitHub/GitLab. Make sure it contains `plugin.json` in the root (or pre-compiled outputs). Administrators can install it dynamically by entering the Git clone URL inside the **Clone Git Repository** card.
|
package/bin/build.js
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { build } from "esbuild";
|
|
2
|
+
import { execSync } from "child_process";
|
|
3
|
+
import fs from "fs";
|
|
4
|
+
import path from "path";
|
|
5
|
+
import { fileURLToPath } from "url";
|
|
6
|
+
|
|
7
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
8
|
+
const __dirname = path.dirname(__filename);
|
|
9
|
+
const rootDir = path.join(__dirname, "..");
|
|
10
|
+
|
|
11
|
+
async function run() {
|
|
12
|
+
console.log("Building PropVault PDK package...");
|
|
13
|
+
|
|
14
|
+
// Clean dist
|
|
15
|
+
const distDir = path.join(rootDir, "dist");
|
|
16
|
+
if (fs.existsSync(distDir)) {
|
|
17
|
+
fs.rmSync(distDir, { recursive: true, force: true });
|
|
18
|
+
}
|
|
19
|
+
fs.mkdirSync(distDir, { recursive: true });
|
|
20
|
+
|
|
21
|
+
// 1. Compile TS with esbuild
|
|
22
|
+
await build({
|
|
23
|
+
entryPoints: [path.join(rootDir, "src", "index.ts")],
|
|
24
|
+
bundle: true,
|
|
25
|
+
platform: "node",
|
|
26
|
+
format: "esm",
|
|
27
|
+
outfile: path.join(distDir, "index.js"),
|
|
28
|
+
minify: false,
|
|
29
|
+
sourcemap: true,
|
|
30
|
+
external: []
|
|
31
|
+
});
|
|
32
|
+
console.log("✔ Compiled PDK ES modules successfully.");
|
|
33
|
+
|
|
34
|
+
// 2. Generate typings (.d.ts) using TypeScript compiler
|
|
35
|
+
try {
|
|
36
|
+
console.log("Generating typings (.d.ts)...");
|
|
37
|
+
execSync("npx tsc", { cwd: rootDir, stdio: "inherit" });
|
|
38
|
+
console.log("✔ Generated types successfully.");
|
|
39
|
+
} catch (err) {
|
|
40
|
+
console.warn("⚠ Warning: Failed to generate typings with tsc compiler:", err);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
console.log("✔ PDK Build complete!");
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
run();
|
package/bin/pdk-cli.js
ADDED
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* PropVault CMS — PDK CLI Utility
|
|
5
|
+
* Scaffolds, builds, and packages custom plugins for PropVault CMS.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import fs from "fs";
|
|
9
|
+
import path from "path";
|
|
10
|
+
import { execSync } from "child_process";
|
|
11
|
+
import { fileURLToPath } from "url";
|
|
12
|
+
import archiver from "archiver";
|
|
13
|
+
|
|
14
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
15
|
+
const __dirname = path.dirname(__filename);
|
|
16
|
+
|
|
17
|
+
const BANNER = `
|
|
18
|
+
\x1b[38;5;214m _____ __ __ _ _ ____ ____ _ __
|
|
19
|
+
| __ \\ \\ \\ / / | | | | _ \\| _ \\| |/ /
|
|
20
|
+
| |__) | __ ___ _ __ \\ V /__ _ _ _ _| | |_ | |_) | |_) | ' /
|
|
21
|
+
| ___/ '__/ _ \\| '_ \\ \\ / _\` | | | | | | __| | __/| _ <| <
|
|
22
|
+
| | | | | (_) | |_) | | | (_| | |_| | | | |_ | | | |_) | . \\
|
|
23
|
+
|_| |_| \\___/| .__/ |_|\\__,_|\\__,_|_|_|\\__| |_| |____/|_|\\_\\
|
|
24
|
+
|_|
|
|
25
|
+
\x1b[39m
|
|
26
|
+
\x1b[90m PropVault CMS Plugin Development Kit (PDK) CLI — v0.1.0\x1b[0m
|
|
27
|
+
`;
|
|
28
|
+
|
|
29
|
+
function printHelp() {
|
|
30
|
+
console.log(BANNER);
|
|
31
|
+
console.log("\x1b[1mUsage:\x1b[0m");
|
|
32
|
+
console.log(" npx propvault-pdk <command> [options]\n");
|
|
33
|
+
console.log("\x1b[1mCommands:\x1b[0m");
|
|
34
|
+
console.log(" \x1b[32mcreate <name>\x1b[0m Scaffold a new custom plugin directory");
|
|
35
|
+
console.log(" \x1b[32mbuild\x1b[0m Compile TS/JS files and assemble distribution");
|
|
36
|
+
console.log(" \x1b[32mpackage\x1b[0m Compress build distribution into plugin.zip for CMS upload");
|
|
37
|
+
console.log("\n\x1b[1mExamples:\x1b[0m");
|
|
38
|
+
console.log(" npx propvault-pdk create my-custom-integration");
|
|
39
|
+
console.log(" npx propvault-pdk build\n");
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
async function main() {
|
|
43
|
+
const args = process.argv.slice(2);
|
|
44
|
+
const command = args[0];
|
|
45
|
+
|
|
46
|
+
if (!command || command === "--help" || command === "-h") {
|
|
47
|
+
printHelp();
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const workspaceRoot = process.cwd();
|
|
52
|
+
|
|
53
|
+
switch (command) {
|
|
54
|
+
case "create": {
|
|
55
|
+
const pluginName = args[1];
|
|
56
|
+
if (!pluginName) {
|
|
57
|
+
console.error("\x1b[31m[Error]\x1b[0m Please specify the plugin folder name: npx propvault-pdk create <plugin-name>");
|
|
58
|
+
process.exit(1);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const slug = pluginName.toLowerCase().replace(/[^a-z0-9_-]/g, "-");
|
|
62
|
+
const destDir = path.join(workspaceRoot, slug);
|
|
63
|
+
|
|
64
|
+
if (fs.existsSync(destDir)) {
|
|
65
|
+
console.error(`\x1b[31m[Error]\x1b[0m Directory "${slug}" already exists.`);
|
|
66
|
+
process.exit(1);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
console.log(BANNER);
|
|
70
|
+
console.log(`\x1b[34m[Scaffold]\x1b[0m Creating plugin template for "${slug}"...`);
|
|
71
|
+
|
|
72
|
+
// Load local PDK version dynamically
|
|
73
|
+
let pdkVersion = "0.1.0";
|
|
74
|
+
try {
|
|
75
|
+
const pdkPkgPath = path.join(__dirname, "..", "package.json");
|
|
76
|
+
if (fs.existsSync(pdkPkgPath)) {
|
|
77
|
+
const pdkPkg = JSON.parse(fs.readFileSync(pdkPkgPath, "utf8"));
|
|
78
|
+
pdkVersion = pdkPkg.version || "0.1.0";
|
|
79
|
+
}
|
|
80
|
+
} catch {}
|
|
81
|
+
|
|
82
|
+
// 1. Create folders
|
|
83
|
+
fs.mkdirSync(path.join(destDir, "src"), { recursive: true });
|
|
84
|
+
|
|
85
|
+
// 2. Write package.json
|
|
86
|
+
const pkgContent = {
|
|
87
|
+
name: slug,
|
|
88
|
+
version: "1.0.0",
|
|
89
|
+
description: "Custom plugin integration for PropVault CMS",
|
|
90
|
+
main: "./dist/index.js",
|
|
91
|
+
type: "module",
|
|
92
|
+
scripts: {
|
|
93
|
+
"build": "npx propvault-pdk build",
|
|
94
|
+
"package": "npx propvault-pdk package"
|
|
95
|
+
},
|
|
96
|
+
dependencies: {},
|
|
97
|
+
devDependencies: {
|
|
98
|
+
"@vikukumar/propvault-pdk": `^${pdkVersion}`,
|
|
99
|
+
"typescript": "^5.3.3"
|
|
100
|
+
}
|
|
101
|
+
};
|
|
102
|
+
fs.writeFileSync(path.join(destDir, "package.json"), JSON.stringify(pkgContent, null, 2) + "\n");
|
|
103
|
+
|
|
104
|
+
// 3. Write tsconfig.json
|
|
105
|
+
const tsconfigContent = {
|
|
106
|
+
compilerOptions: {
|
|
107
|
+
target: "ES2022",
|
|
108
|
+
module: "NodeNext",
|
|
109
|
+
moduleResolution: "NodeNext",
|
|
110
|
+
strict: true,
|
|
111
|
+
skipLibCheck: true,
|
|
112
|
+
esModuleInterop: true,
|
|
113
|
+
outDir: "./dist"
|
|
114
|
+
},
|
|
115
|
+
include: ["src/**/*"]
|
|
116
|
+
};
|
|
117
|
+
fs.writeFileSync(path.join(destDir, "tsconfig.json"), JSON.stringify(tsconfigContent, null, 2) + "\n");
|
|
118
|
+
|
|
119
|
+
// 4. Write plugin.json manifest
|
|
120
|
+
const manifestContent = {
|
|
121
|
+
name: slug.split("-").map(w => w.charAt(0).toUpperCase() + w.slice(1)).join(" "),
|
|
122
|
+
slug: slug,
|
|
123
|
+
version: "1.0.0",
|
|
124
|
+
description: "A custom plugin for real-time CRM webhooks and layout filters.",
|
|
125
|
+
author: "Developer",
|
|
126
|
+
entry: "./dist/index.js"
|
|
127
|
+
};
|
|
128
|
+
fs.writeFileSync(path.join(destDir, "plugin.json"), JSON.stringify(manifestContent, null, 2) + "\n");
|
|
129
|
+
|
|
130
|
+
// 5. Write src/index.ts (sample hooks integration)
|
|
131
|
+
const srcContent = `import { addAction, addFilter } from "@vikukumar/propvault-pdk";
|
|
132
|
+
|
|
133
|
+
// Example Action: Triggered whenever a new lead is submitted on the website
|
|
134
|
+
addAction("after_lead_submit", async (lead: any) => {
|
|
135
|
+
console.log("[${slug.toUpperCase()}] New lead submitted:", lead.email);
|
|
136
|
+
// Add custom integrations here (e.g. call Slack webhooks, SendGrid, Salesforce CRM, etc.)
|
|
137
|
+
}, 10);
|
|
138
|
+
|
|
139
|
+
// Example Filter: Modify the RERA project title before saving in database
|
|
140
|
+
addFilter("before_project_save", async (project: any) => {
|
|
141
|
+
if (project.title) {
|
|
142
|
+
// Append verified suffix
|
|
143
|
+
project.title = \`\${project.title} [Verified]\`;
|
|
144
|
+
}
|
|
145
|
+
return project;
|
|
146
|
+
});
|
|
147
|
+
`;
|
|
148
|
+
fs.writeFileSync(path.join(destDir, "src", "index.ts"), srcContent);
|
|
149
|
+
|
|
150
|
+
console.log(`\x1b[32m✔ Scaffold complete! Plugin directory created at ./${slug}\x1b[0m`);
|
|
151
|
+
console.log("\x1b[1mNext Steps:\x1b[0m");
|
|
152
|
+
console.log(` cd ${slug}`);
|
|
153
|
+
console.log(" npm install");
|
|
154
|
+
console.log(" npm run build && npm run package\n");
|
|
155
|
+
break;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
case "build": {
|
|
159
|
+
console.log("\x1b[34m[Build]\x1b[0m Compiling custom plugin TypeScript entry points...");
|
|
160
|
+
|
|
161
|
+
const pkgPath = path.join(workspaceRoot, "package.json");
|
|
162
|
+
if (!fs.existsSync(pkgPath)) {
|
|
163
|
+
console.error("\x1b[31m[Error]\x1b[0m package.json not found in active directory. Run from the plugin root directory.");
|
|
164
|
+
process.exit(1);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
// Compile using local typescript compiler
|
|
168
|
+
try {
|
|
169
|
+
execSync("npx tsc", { cwd: workspaceRoot, stdio: "inherit" });
|
|
170
|
+
console.log("\x1b[32m✔ TypeScript compilation complete!\x1b[0m");
|
|
171
|
+
} catch (err) {
|
|
172
|
+
console.error("\x1b[31m[Error]\x1b[0m Compilation failed. Check syntax.");
|
|
173
|
+
process.exit(1);
|
|
174
|
+
}
|
|
175
|
+
break;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
case "package": {
|
|
179
|
+
console.log("\x1b[34m[Package]\x1b[0m Bundling plugin into zip distribution...");
|
|
180
|
+
|
|
181
|
+
const manifestPath = path.join(workspaceRoot, "plugin.json");
|
|
182
|
+
const distJsPath = path.join(workspaceRoot, "dist", "index.js");
|
|
183
|
+
|
|
184
|
+
if (!fs.existsSync(manifestPath) || !fs.existsSync(distJsPath)) {
|
|
185
|
+
console.error("\x1b[31m[Error]\x1b[0m Build artifacts not found. Run 'npm run build' first.");
|
|
186
|
+
process.exit(1);
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
const archiveName = path.join(workspaceRoot, "plugin.zip");
|
|
190
|
+
const output = fs.createWriteStream(archiveName);
|
|
191
|
+
const archive = archiver("zip", { zlib: { level: 9 } });
|
|
192
|
+
|
|
193
|
+
output.on("close", () => {
|
|
194
|
+
console.log(`\x1b[32m✔ Zip packaging complete! Created archive: ./plugin.zip (${archive.pointer()} bytes)\x1b[0m`);
|
|
195
|
+
console.log("You can now upload this plugin.zip file in the PropVault CMS Plugins dashboard panel!");
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
archive.on("error", (err) => {
|
|
199
|
+
throw err;
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
archive.pipe(output);
|
|
203
|
+
|
|
204
|
+
// Add compiled folder
|
|
205
|
+
archive.directory(path.join(workspaceRoot, "dist"), "dist");
|
|
206
|
+
// Add manifest
|
|
207
|
+
archive.file(manifestPath, { name: "plugin.json" });
|
|
208
|
+
|
|
209
|
+
await archive.finalize();
|
|
210
|
+
break;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
default:
|
|
214
|
+
console.error(`\x1b[31m[Error]\x1b[0m Unknown command: ${command}`);
|
|
215
|
+
printHelp();
|
|
216
|
+
process.exit(1);
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
main().catch(err => {
|
|
221
|
+
console.error("\x1b[31m[Error]\x1b[0m Operation failed:", err);
|
|
222
|
+
process.exit(1);
|
|
223
|
+
});
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PropVault CMS — Plugin Development Kit (PDK) Core API
|
|
3
|
+
*/
|
|
4
|
+
export interface HookAction {
|
|
5
|
+
slug: string;
|
|
6
|
+
handler: (...args: any[]) => void | Promise<void>;
|
|
7
|
+
priority?: number;
|
|
8
|
+
}
|
|
9
|
+
export interface HookFilter {
|
|
10
|
+
slug: string;
|
|
11
|
+
handler: (value: any, ...args: any[]) => any | Promise<any>;
|
|
12
|
+
priority?: number;
|
|
13
|
+
}
|
|
14
|
+
export interface PluginManifest {
|
|
15
|
+
name: string;
|
|
16
|
+
slug: string;
|
|
17
|
+
version: string;
|
|
18
|
+
description: string;
|
|
19
|
+
author: string;
|
|
20
|
+
entry: string;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Registers an action hook handler. Action hooks trigger code at specific system events.
|
|
24
|
+
*/
|
|
25
|
+
export declare function addAction(slug: string, handler: (...args: any[]) => void | Promise<void>, priority?: number): void;
|
|
26
|
+
/**
|
|
27
|
+
* Registers a filter hook handler. Filter hooks allow modifying variables/inputs before they are stored/saved.
|
|
28
|
+
*/
|
|
29
|
+
export declare function addFilter(slug: string, handler: (value: any, ...args: any[]) => any | Promise<any>, priority?: number): void;
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PropVault CMS — Plugin Development Kit (PDK) Core API
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Registers an action hook handler. Action hooks trigger code at specific system events.
|
|
6
|
+
*/
|
|
7
|
+
export function addAction(slug, handler, priority = 10) {
|
|
8
|
+
if (typeof window !== "undefined")
|
|
9
|
+
return;
|
|
10
|
+
// Register dynamic handler into global hooks registry
|
|
11
|
+
const globalHooks = globalThis.__propvault_hooks || { actions: {}, filters: {} };
|
|
12
|
+
if (!globalHooks.actions[slug]) {
|
|
13
|
+
globalHooks.actions[slug] = [];
|
|
14
|
+
}
|
|
15
|
+
globalHooks.actions[slug].push({ handler, priority });
|
|
16
|
+
globalHooks.actions[slug].sort((a, b) => a.priority - b.priority);
|
|
17
|
+
globalThis.__propvault_hooks = globalHooks;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Registers a filter hook handler. Filter hooks allow modifying variables/inputs before they are stored/saved.
|
|
21
|
+
*/
|
|
22
|
+
export function addFilter(slug, handler, priority = 10) {
|
|
23
|
+
if (typeof window !== "undefined")
|
|
24
|
+
return;
|
|
25
|
+
const globalHooks = globalThis.__propvault_hooks || { actions: {}, filters: {} };
|
|
26
|
+
if (!globalHooks.filters[slug]) {
|
|
27
|
+
globalHooks.filters[slug] = [];
|
|
28
|
+
}
|
|
29
|
+
globalHooks.filters[slug].push({ handler, priority });
|
|
30
|
+
globalHooks.filters[slug].sort((a, b) => a.priority - b.priority);
|
|
31
|
+
globalThis.__propvault_hooks = globalHooks;
|
|
32
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/index.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * PropVault CMS \u2014 Plugin Development Kit (PDK) Core API\n */\n\nexport interface HookAction {\n slug: string;\n handler: (...args: any[]) => void | Promise<void>;\n priority?: number;\n}\n\nexport interface HookFilter {\n slug: string;\n handler: (value: any, ...args: any[]) => any | Promise<any>;\n priority?: number;\n}\n\nexport interface PluginManifest {\n name: string;\n slug: string;\n version: string;\n description: string;\n author: string;\n entry: string;\n}\n\n/**\n * Registers an action hook handler. Action hooks trigger code at specific system events.\n */\nexport function addAction(slug: string, handler: (...args: any[]) => void | Promise<void>, priority = 10): void {\n if (typeof window !== \"undefined\") return;\n \n // Register dynamic handler into global hooks registry\n const globalHooks = (globalThis as any).__propvault_hooks || { actions: {}, filters: {} };\n if (!globalHooks.actions[slug]) {\n globalHooks.actions[slug] = [];\n }\n \n globalHooks.actions[slug].push({ handler, priority });\n globalHooks.actions[slug].sort((a: any, b: any) => a.priority - b.priority);\n \n (globalThis as any).__propvault_hooks = globalHooks;\n}\n\n/**\n * Registers a filter hook handler. Filter hooks allow modifying variables/inputs before they are stored/saved.\n */\nexport function addFilter(slug: string, handler: (value: any, ...args: any[]) => any | Promise<any>, priority = 10): void {\n if (typeof window !== \"undefined\") return;\n \n const globalHooks = (globalThis as any).__propvault_hooks || { actions: {}, filters: {} };\n if (!globalHooks.filters[slug]) {\n globalHooks.filters[slug] = [];\n }\n \n globalHooks.filters[slug].push({ handler, priority });\n globalHooks.filters[slug].sort((a: any, b: any) => a.priority - b.priority);\n \n (globalThis as any).__propvault_hooks = globalHooks;\n}\n"],
|
|
5
|
+
"mappings": ";AA4BO,SAAS,UAAU,MAAc,SAAmD,WAAW,IAAU;AAC9G,MAAI,OAAO,WAAW;AAAa;AAGnC,QAAM,cAAe,WAAmB,qBAAqB,EAAE,SAAS,CAAC,GAAG,SAAS,CAAC,EAAE;AACxF,MAAI,CAAC,YAAY,QAAQ,IAAI,GAAG;AAC9B,gBAAY,QAAQ,IAAI,IAAI,CAAC;AAAA,EAC/B;AAEA,cAAY,QAAQ,IAAI,EAAE,KAAK,EAAE,SAAS,SAAS,CAAC;AACpD,cAAY,QAAQ,IAAI,EAAE,KAAK,CAAC,GAAQ,MAAW,EAAE,WAAW,EAAE,QAAQ;AAE1E,EAAC,WAAmB,oBAAoB;AAC1C;AAKO,SAAS,UAAU,MAAc,SAA6D,WAAW,IAAU;AACxH,MAAI,OAAO,WAAW;AAAa;AAEnC,QAAM,cAAe,WAAmB,qBAAqB,EAAE,SAAS,CAAC,GAAG,SAAS,CAAC,EAAE;AACxF,MAAI,CAAC,YAAY,QAAQ,IAAI,GAAG;AAC9B,gBAAY,QAAQ,IAAI,IAAI,CAAC;AAAA,EAC/B;AAEA,cAAY,QAAQ,IAAI,EAAE,KAAK,EAAE,SAAS,SAAS,CAAC;AACpD,cAAY,QAAQ,IAAI,EAAE,KAAK,CAAC,GAAQ,MAAW,EAAE,WAAW,EAAE,QAAQ;AAE1E,EAAC,WAAmB,oBAAoB;AAC1C;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@vikukumar/propvault-pdk",
|
|
3
|
+
"version": "0.1.4",
|
|
4
|
+
"description": "Plugin Development Kit (PDK) for the PropVault CMS Platform",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"bin": {
|
|
9
|
+
"propvault-pdk": "./bin/pdk-cli.js"
|
|
10
|
+
},
|
|
11
|
+
"scripts": {
|
|
12
|
+
"build": "node bin/build.js",
|
|
13
|
+
"prepublishOnly": "npm run build"
|
|
14
|
+
},
|
|
15
|
+
"dependencies": {
|
|
16
|
+
"archiver": "^6.0.2",
|
|
17
|
+
"esbuild": "^0.20.1"
|
|
18
|
+
},
|
|
19
|
+
"devDependencies": {
|
|
20
|
+
"typescript": "^5.3.3"
|
|
21
|
+
},
|
|
22
|
+
"engines": {
|
|
23
|
+
"node": ">=18.0.0"
|
|
24
|
+
},
|
|
25
|
+
"publishConfig": {
|
|
26
|
+
"access": "public"
|
|
27
|
+
}
|
|
28
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PropVault CMS — Plugin Development Kit (PDK) Core API
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
export interface HookAction {
|
|
6
|
+
slug: string;
|
|
7
|
+
handler: (...args: any[]) => void | Promise<void>;
|
|
8
|
+
priority?: number;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export interface HookFilter {
|
|
12
|
+
slug: string;
|
|
13
|
+
handler: (value: any, ...args: any[]) => any | Promise<any>;
|
|
14
|
+
priority?: number;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export interface PluginManifest {
|
|
18
|
+
name: string;
|
|
19
|
+
slug: string;
|
|
20
|
+
version: string;
|
|
21
|
+
description: string;
|
|
22
|
+
author: string;
|
|
23
|
+
entry: string;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Registers an action hook handler. Action hooks trigger code at specific system events.
|
|
28
|
+
*/
|
|
29
|
+
export function addAction(slug: string, handler: (...args: any[]) => void | Promise<void>, priority = 10): void {
|
|
30
|
+
if (typeof window !== "undefined") return;
|
|
31
|
+
|
|
32
|
+
// Register dynamic handler into global hooks registry
|
|
33
|
+
const globalHooks = (globalThis as any).__propvault_hooks || { actions: {}, filters: {} };
|
|
34
|
+
if (!globalHooks.actions[slug]) {
|
|
35
|
+
globalHooks.actions[slug] = [];
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
globalHooks.actions[slug].push({ handler, priority });
|
|
39
|
+
globalHooks.actions[slug].sort((a: any, b: any) => a.priority - b.priority);
|
|
40
|
+
|
|
41
|
+
(globalThis as any).__propvault_hooks = globalHooks;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Registers a filter hook handler. Filter hooks allow modifying variables/inputs before they are stored/saved.
|
|
46
|
+
*/
|
|
47
|
+
export function addFilter(slug: string, handler: (value: any, ...args: any[]) => any | Promise<any>, priority = 10): void {
|
|
48
|
+
if (typeof window !== "undefined") return;
|
|
49
|
+
|
|
50
|
+
const globalHooks = (globalThis as any).__propvault_hooks || { actions: {}, filters: {} };
|
|
51
|
+
if (!globalHooks.filters[slug]) {
|
|
52
|
+
globalHooks.filters[slug] = [];
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
globalHooks.filters[slug].push({ handler, priority });
|
|
56
|
+
globalHooks.filters[slug].sort((a: any, b: any) => a.priority - b.priority);
|
|
57
|
+
|
|
58
|
+
(globalThis as any).__propvault_hooks = globalHooks;
|
|
59
|
+
}
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2022",
|
|
4
|
+
"module": "NodeNext",
|
|
5
|
+
"moduleResolution": "NodeNext",
|
|
6
|
+
"declaration": true,
|
|
7
|
+
"outDir": "./dist",
|
|
8
|
+
"rootDir": "./src",
|
|
9
|
+
"strict": true,
|
|
10
|
+
"esModuleInterop": true,
|
|
11
|
+
"skipLibCheck": true,
|
|
12
|
+
"forceConsistentCasingInFileNames": true
|
|
13
|
+
},
|
|
14
|
+
"include": ["src/**/*"]
|
|
15
|
+
}
|