blockwriteai-editor 1.0.10__tar.gz
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.
- blockwriteai_editor-1.0.10/LICENSE +21 -0
- blockwriteai_editor-1.0.10/MANIFEST.in +16 -0
- blockwriteai_editor-1.0.10/PKG-INFO +259 -0
- blockwriteai_editor-1.0.10/README.md +234 -0
- blockwriteai_editor-1.0.10/blockwriteai_editor/__init__.py +86 -0
- blockwriteai_editor-1.0.10/blockwriteai_editor/py.typed +1 -0
- blockwriteai_editor-1.0.10/blockwriteai_editor/static/blockwriteai/blockwriteai-favicon.svg +20 -0
- blockwriteai_editor-1.0.10/blockwriteai_editor/static/blockwriteai/blockwriteai-logo.svg +26 -0
- blockwriteai_editor-1.0.10/blockwriteai_editor/static/blockwriteai/blockwriteai.min.css +1 -0
- blockwriteai_editor-1.0.10/blockwriteai_editor/static/blockwriteai/blockwriteai.min.js +1 -0
- blockwriteai_editor-1.0.10/blockwriteai_editor/static/blockwriteai/plugins/blockwriteai-advanced-blocks.min.js +1 -0
- blockwriteai_editor-1.0.10/blockwriteai_editor/static/blockwriteai/plugins/blockwriteai-ai.min.js +1 -0
- blockwriteai_editor-1.0.10/blockwriteai_editor/static/blockwriteai/plugins/blockwriteai-code-assist.min.js +1 -0
- blockwriteai_editor-1.0.10/blockwriteai_editor/static/blockwriteai/plugins/blockwriteai-drawing.min.js +1 -0
- blockwriteai_editor-1.0.10/blockwriteai_editor/static/blockwriteai/plugins/blockwriteai-history.min.js +1 -0
- blockwriteai_editor-1.0.10/blockwriteai_editor/static/blockwriteai/plugins/blockwriteai-mermaid.min.js +1 -0
- blockwriteai_editor-1.0.10/blockwriteai_editor/static/blockwriteai/plugins/blockwriteai-signature-flow.min.js +1 -0
- blockwriteai_editor-1.0.10/blockwriteai_editor/static/blockwriteai/plugins/blockwriteai-signature.min.js +1 -0
- blockwriteai_editor-1.0.10/blockwriteai_editor.egg-info/PKG-INFO +259 -0
- blockwriteai_editor-1.0.10/blockwriteai_editor.egg-info/SOURCES.txt +22 -0
- blockwriteai_editor-1.0.10/blockwriteai_editor.egg-info/dependency_links.txt +1 -0
- blockwriteai_editor-1.0.10/blockwriteai_editor.egg-info/top_level.txt +1 -0
- blockwriteai_editor-1.0.10/pyproject.toml +65 -0
- blockwriteai_editor-1.0.10/setup.cfg +4 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 qarAkash
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
include README.md
|
|
2
|
+
include LICENSE
|
|
3
|
+
include blockwriteai_editor/static/blockwriteai/*.min.css
|
|
4
|
+
include blockwriteai_editor/static/blockwriteai/*.min.js
|
|
5
|
+
include blockwriteai_editor/static/blockwriteai/*.svg
|
|
6
|
+
include blockwriteai_editor/static/blockwriteai/plugins/*.min.js
|
|
7
|
+
exclude blockwriteai_editor/static/blockwriteai/blockwriteai.css
|
|
8
|
+
exclude blockwriteai_editor/static/blockwriteai/blockwriteai.js
|
|
9
|
+
exclude blockwriteai_editor/static/blockwriteai/plugins/blockwriteai-advanced-blocks.js
|
|
10
|
+
exclude blockwriteai_editor/static/blockwriteai/plugins/blockwriteai-ai.js
|
|
11
|
+
exclude blockwriteai_editor/static/blockwriteai/plugins/blockwriteai-code-assist.js
|
|
12
|
+
exclude blockwriteai_editor/static/blockwriteai/plugins/blockwriteai-drawing.js
|
|
13
|
+
exclude blockwriteai_editor/static/blockwriteai/plugins/blockwriteai-history.js
|
|
14
|
+
exclude blockwriteai_editor/static/blockwriteai/plugins/blockwriteai-mermaid.js
|
|
15
|
+
exclude blockwriteai_editor/static/blockwriteai/plugins/blockwriteai-signature-flow.js
|
|
16
|
+
exclude blockwriteai_editor/static/blockwriteai/plugins/blockwriteai-signature.js
|
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: blockwriteai-editor
|
|
3
|
+
Version: 1.0.10
|
|
4
|
+
Summary: Static assets and helpers for the BlockWriteAI JSON-first editor with free core blocks and license-gated premium plugins.
|
|
5
|
+
Author: qarAkash
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/qarAkash/BlockWriteAI
|
|
8
|
+
Project-URL: Repository, https://github.com/qarAkash/BlockWriteAI.git
|
|
9
|
+
Project-URL: Issues, https://github.com/qarAkash/BlockWriteAI/issues
|
|
10
|
+
Keywords: blockwriteai,rich text editor,block editor,static assets,flask,django
|
|
11
|
+
Classifier: Development Status :: 4 - Beta
|
|
12
|
+
Classifier: Framework :: Flask
|
|
13
|
+
Classifier: Framework :: Django
|
|
14
|
+
Classifier: Intended Audience :: Developers
|
|
15
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
16
|
+
Classifier: Programming Language :: JavaScript
|
|
17
|
+
Classifier: Programming Language :: Python :: 3
|
|
18
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
19
|
+
Classifier: Topic :: Internet :: WWW/HTTP
|
|
20
|
+
Classifier: Topic :: Software Development :: Libraries
|
|
21
|
+
Requires-Python: >=3.8
|
|
22
|
+
Description-Content-Type: text/markdown
|
|
23
|
+
License-File: LICENSE
|
|
24
|
+
Dynamic: license-file
|
|
25
|
+
|
|
26
|
+
# BlockWriteAI
|
|
27
|
+
|
|
28
|
+
BlockWriteAI is a JSON-first block editor for web apps. It works with a script tag, npm, PHP/Composer, and Python static-file workflows.
|
|
29
|
+
|
|
30
|
+
Use the free core editor for normal documents. Serve premium tools such as AI, Mermaid, Drawing, Signature, and Signature Flow only through your licensed server endpoint.
|
|
31
|
+
|
|
32
|
+
## Quick Start With CDN
|
|
33
|
+
|
|
34
|
+
Add the stylesheet, editor script, and free plugin bundle:
|
|
35
|
+
|
|
36
|
+
```html
|
|
37
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@qarakash/blockwriteai@1.0.10/dist/blockwriteai.min.css">
|
|
38
|
+
|
|
39
|
+
<div id="editor"></div>
|
|
40
|
+
|
|
41
|
+
<script src="https://cdn.jsdelivr.net/npm/@qarakash/blockwriteai@1.0.10/dist/blockwriteai.min.js"></script>
|
|
42
|
+
<script src="https://cdn.jsdelivr.net/npm/@qarakash/blockwriteai@1.0.10/dist/plugins/blockwriteai-code-assist.min.js"></script>
|
|
43
|
+
<script src="https://cdn.jsdelivr.net/npm/@qarakash/blockwriteai@1.0.10/dist/plugins/blockwriteai-advanced-blocks.min.js"></script>
|
|
44
|
+
<script>
|
|
45
|
+
const editor = new BlockWriteAI({
|
|
46
|
+
holder: "#editor",
|
|
47
|
+
placeholder: "Write something, or press / for blocks",
|
|
48
|
+
async onSave(data) {
|
|
49
|
+
await fetch("/api/documents", {
|
|
50
|
+
method: "POST",
|
|
51
|
+
headers: { "Content-Type": "application/json" },
|
|
52
|
+
body: JSON.stringify(data)
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
</script>
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Use these CDN URLs for production:
|
|
60
|
+
|
|
61
|
+
```text
|
|
62
|
+
https://cdn.jsdelivr.net/npm/@qarakash/blockwriteai@1.0.10/dist/blockwriteai.min.css
|
|
63
|
+
https://cdn.jsdelivr.net/npm/@qarakash/blockwriteai@1.0.10/dist/blockwriteai.min.js
|
|
64
|
+
https://cdn.jsdelivr.net/npm/@qarakash/blockwriteai@1.0.10/dist/plugins/blockwriteai-code-assist.min.js
|
|
65
|
+
https://cdn.jsdelivr.net/npm/@qarakash/blockwriteai@1.0.10/dist/plugins/blockwriteai-advanced-blocks.min.js
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Optional history plugin:
|
|
69
|
+
|
|
70
|
+
```html
|
|
71
|
+
<script src="https://cdn.jsdelivr.net/npm/@qarakash/blockwriteai@1.0.10/dist/plugins/blockwriteai-history.min.js"></script>
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## Install With Node
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
npm install @qarakash/blockwriteai
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
```js
|
|
81
|
+
import BlockWriteAI from "@qarakash/blockwriteai";
|
|
82
|
+
import "@qarakash/blockwriteai/css";
|
|
83
|
+
import "@qarakash/blockwriteai/plugins/code-assist/min";
|
|
84
|
+
import "@qarakash/blockwriteai/plugins/advanced/min";
|
|
85
|
+
|
|
86
|
+
const editor = new BlockWriteAI({
|
|
87
|
+
holder: "#editor",
|
|
88
|
+
async onSave(data) {
|
|
89
|
+
await fetch("/api/documents", {
|
|
90
|
+
method: "POST",
|
|
91
|
+
headers: { "Content-Type": "application/json" },
|
|
92
|
+
body: JSON.stringify(data)
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
## Install With PHP
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
composer require qarakash/blockwriteai
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
Publish the package `dist` assets into a public asset directory in your app, then print the tags:
|
|
105
|
+
|
|
106
|
+
```php
|
|
107
|
+
<?php
|
|
108
|
+
|
|
109
|
+
use QarAkash\BlockWriteAI\BlockWriteAIAssets;
|
|
110
|
+
|
|
111
|
+
echo BlockWriteAIAssets::stylesheetTag('/assets/blockwriteai');
|
|
112
|
+
echo BlockWriteAIAssets::scriptTags('/assets/blockwriteai');
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
Create the editor:
|
|
116
|
+
|
|
117
|
+
```html
|
|
118
|
+
<div id="editor"></div>
|
|
119
|
+
<script>
|
|
120
|
+
const editor = new BlockWriteAI({
|
|
121
|
+
holder: "#editor",
|
|
122
|
+
async onSave(data) {
|
|
123
|
+
await fetch("/api/documents/save.php", {
|
|
124
|
+
method: "POST",
|
|
125
|
+
headers: { "Content-Type": "application/json" },
|
|
126
|
+
body: JSON.stringify(data)
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
});
|
|
130
|
+
</script>
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
## Install With Python
|
|
134
|
+
|
|
135
|
+
```bash
|
|
136
|
+
pip install blockwriteai-editor
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
Copy the packaged assets into your app static directory:
|
|
140
|
+
|
|
141
|
+
```python
|
|
142
|
+
from blockwriteai_editor import copy_static
|
|
143
|
+
|
|
144
|
+
copy_static("static/blockwriteai")
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
Generate tags in Flask, Django, or any Python web app:
|
|
148
|
+
|
|
149
|
+
```python
|
|
150
|
+
from blockwriteai_editor import stylesheet_tag, script_tags
|
|
151
|
+
|
|
152
|
+
print(stylesheet_tag("/static/blockwriteai"))
|
|
153
|
+
print(script_tags("/static/blockwriteai"))
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
Then mount the editor in your template:
|
|
157
|
+
|
|
158
|
+
```html
|
|
159
|
+
<div id="editor"></div>
|
|
160
|
+
<script>
|
|
161
|
+
const editor = new BlockWriteAI({
|
|
162
|
+
holder: "#editor",
|
|
163
|
+
async onSave(data) {
|
|
164
|
+
await fetch("/api/documents", {
|
|
165
|
+
method: "POST",
|
|
166
|
+
headers: { "Content-Type": "application/json" },
|
|
167
|
+
body: JSON.stringify(data)
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
});
|
|
171
|
+
</script>
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
## Read Saved Documents
|
|
175
|
+
|
|
176
|
+
BlockWriteAI saves JSON. Store that JSON in your database, then render it later with a preview container:
|
|
177
|
+
|
|
178
|
+
```html
|
|
179
|
+
<link rel="stylesheet" href="/assets/blockwriteai/blockwriteai.min.css">
|
|
180
|
+
|
|
181
|
+
<div class="blockwriteai-preview" data-source="/api/documents/123.json"></div>
|
|
182
|
+
|
|
183
|
+
<script src="/assets/blockwriteai/blockwriteai.min.js"></script>
|
|
184
|
+
<script src="/assets/blockwriteai/plugins/blockwriteai-advanced-blocks.min.js"></script>
|
|
185
|
+
<script>
|
|
186
|
+
BlockWriteAI.mountPreviews();
|
|
187
|
+
</script>
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
The JSON endpoint can return a document directly:
|
|
191
|
+
|
|
192
|
+
```json
|
|
193
|
+
{
|
|
194
|
+
"time": 1779540000000,
|
|
195
|
+
"version": "1.0.10",
|
|
196
|
+
"blocks": []
|
|
197
|
+
}
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
It can also return a wrapper:
|
|
201
|
+
|
|
202
|
+
```json
|
|
203
|
+
{
|
|
204
|
+
"ok": true,
|
|
205
|
+
"data": {
|
|
206
|
+
"time": 1779540000000,
|
|
207
|
+
"version": "1.0.10",
|
|
208
|
+
"blocks": []
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
## Premium Plugins
|
|
214
|
+
|
|
215
|
+
Do not expose premium plugin files as normal public scripts. Load them after your server verifies an active license:
|
|
216
|
+
|
|
217
|
+
```html
|
|
218
|
+
<script>
|
|
219
|
+
async function bootEditor() {
|
|
220
|
+
await BlockWriteAI.loadPremiumPlugins({
|
|
221
|
+
licenseKey: "bwai_live_xxxxx",
|
|
222
|
+
endpoint: "/blockwriteai-platform/api/premium_plugins.php",
|
|
223
|
+
features: ["drawing", "mermaid", "signature", "signature_flow", "ai"]
|
|
224
|
+
});
|
|
225
|
+
|
|
226
|
+
window.editor = new BlockWriteAI({
|
|
227
|
+
holder: "#editor",
|
|
228
|
+
premium: {
|
|
229
|
+
licenseKey: "bwai_live_xxxxx",
|
|
230
|
+
verifyEndpoint: "/blockwriteai-platform/api/license_verify.php",
|
|
231
|
+
usageEndpoint: "/blockwriteai-platform/api/ai_usage.php"
|
|
232
|
+
},
|
|
233
|
+
ai: {
|
|
234
|
+
endpoint: "/api/blockwriteai-ai"
|
|
235
|
+
}
|
|
236
|
+
});
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
bootEditor();
|
|
240
|
+
</script>
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
The browser plugin must never receive private API keys. Keep OpenAI, billing, usage limits, and license checks on your server.
|
|
244
|
+
|
|
245
|
+
## Release Checklist
|
|
246
|
+
|
|
247
|
+
1. Run `npm run build:min`.
|
|
248
|
+
2. Run `npm run check`.
|
|
249
|
+
3. Publish `@qarakash/blockwriteai` to npm.
|
|
250
|
+
4. Publish `qarakash/blockwriteai` to Packagist.
|
|
251
|
+
5. Publish `blockwriteai-editor` to PyPI.
|
|
252
|
+
6. Serve only the public asset directory from your application.
|
|
253
|
+
|
|
254
|
+
## Notes For Production
|
|
255
|
+
|
|
256
|
+
- Use the `.min.css` and `.min.js` files in public pages.
|
|
257
|
+
- Do not publish source folders, examples, build artifacts, package caches, or private configuration files.
|
|
258
|
+
- Browser-delivered CSS and JavaScript can always be downloaded. Protect paid features with server-side license checks and metered premium bundle delivery.
|
|
259
|
+
- Keep secret keys in backend environment variables only.
|
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
# BlockWriteAI
|
|
2
|
+
|
|
3
|
+
BlockWriteAI is a JSON-first block editor for web apps. It works with a script tag, npm, PHP/Composer, and Python static-file workflows.
|
|
4
|
+
|
|
5
|
+
Use the free core editor for normal documents. Serve premium tools such as AI, Mermaid, Drawing, Signature, and Signature Flow only through your licensed server endpoint.
|
|
6
|
+
|
|
7
|
+
## Quick Start With CDN
|
|
8
|
+
|
|
9
|
+
Add the stylesheet, editor script, and free plugin bundle:
|
|
10
|
+
|
|
11
|
+
```html
|
|
12
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@qarakash/blockwriteai@1.0.10/dist/blockwriteai.min.css">
|
|
13
|
+
|
|
14
|
+
<div id="editor"></div>
|
|
15
|
+
|
|
16
|
+
<script src="https://cdn.jsdelivr.net/npm/@qarakash/blockwriteai@1.0.10/dist/blockwriteai.min.js"></script>
|
|
17
|
+
<script src="https://cdn.jsdelivr.net/npm/@qarakash/blockwriteai@1.0.10/dist/plugins/blockwriteai-code-assist.min.js"></script>
|
|
18
|
+
<script src="https://cdn.jsdelivr.net/npm/@qarakash/blockwriteai@1.0.10/dist/plugins/blockwriteai-advanced-blocks.min.js"></script>
|
|
19
|
+
<script>
|
|
20
|
+
const editor = new BlockWriteAI({
|
|
21
|
+
holder: "#editor",
|
|
22
|
+
placeholder: "Write something, or press / for blocks",
|
|
23
|
+
async onSave(data) {
|
|
24
|
+
await fetch("/api/documents", {
|
|
25
|
+
method: "POST",
|
|
26
|
+
headers: { "Content-Type": "application/json" },
|
|
27
|
+
body: JSON.stringify(data)
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
</script>
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Use these CDN URLs for production:
|
|
35
|
+
|
|
36
|
+
```text
|
|
37
|
+
https://cdn.jsdelivr.net/npm/@qarakash/blockwriteai@1.0.10/dist/blockwriteai.min.css
|
|
38
|
+
https://cdn.jsdelivr.net/npm/@qarakash/blockwriteai@1.0.10/dist/blockwriteai.min.js
|
|
39
|
+
https://cdn.jsdelivr.net/npm/@qarakash/blockwriteai@1.0.10/dist/plugins/blockwriteai-code-assist.min.js
|
|
40
|
+
https://cdn.jsdelivr.net/npm/@qarakash/blockwriteai@1.0.10/dist/plugins/blockwriteai-advanced-blocks.min.js
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Optional history plugin:
|
|
44
|
+
|
|
45
|
+
```html
|
|
46
|
+
<script src="https://cdn.jsdelivr.net/npm/@qarakash/blockwriteai@1.0.10/dist/plugins/blockwriteai-history.min.js"></script>
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Install With Node
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
npm install @qarakash/blockwriteai
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
```js
|
|
56
|
+
import BlockWriteAI from "@qarakash/blockwriteai";
|
|
57
|
+
import "@qarakash/blockwriteai/css";
|
|
58
|
+
import "@qarakash/blockwriteai/plugins/code-assist/min";
|
|
59
|
+
import "@qarakash/blockwriteai/plugins/advanced/min";
|
|
60
|
+
|
|
61
|
+
const editor = new BlockWriteAI({
|
|
62
|
+
holder: "#editor",
|
|
63
|
+
async onSave(data) {
|
|
64
|
+
await fetch("/api/documents", {
|
|
65
|
+
method: "POST",
|
|
66
|
+
headers: { "Content-Type": "application/json" },
|
|
67
|
+
body: JSON.stringify(data)
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## Install With PHP
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
composer require qarakash/blockwriteai
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
Publish the package `dist` assets into a public asset directory in your app, then print the tags:
|
|
80
|
+
|
|
81
|
+
```php
|
|
82
|
+
<?php
|
|
83
|
+
|
|
84
|
+
use QarAkash\BlockWriteAI\BlockWriteAIAssets;
|
|
85
|
+
|
|
86
|
+
echo BlockWriteAIAssets::stylesheetTag('/assets/blockwriteai');
|
|
87
|
+
echo BlockWriteAIAssets::scriptTags('/assets/blockwriteai');
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
Create the editor:
|
|
91
|
+
|
|
92
|
+
```html
|
|
93
|
+
<div id="editor"></div>
|
|
94
|
+
<script>
|
|
95
|
+
const editor = new BlockWriteAI({
|
|
96
|
+
holder: "#editor",
|
|
97
|
+
async onSave(data) {
|
|
98
|
+
await fetch("/api/documents/save.php", {
|
|
99
|
+
method: "POST",
|
|
100
|
+
headers: { "Content-Type": "application/json" },
|
|
101
|
+
body: JSON.stringify(data)
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
});
|
|
105
|
+
</script>
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
## Install With Python
|
|
109
|
+
|
|
110
|
+
```bash
|
|
111
|
+
pip install blockwriteai-editor
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
Copy the packaged assets into your app static directory:
|
|
115
|
+
|
|
116
|
+
```python
|
|
117
|
+
from blockwriteai_editor import copy_static
|
|
118
|
+
|
|
119
|
+
copy_static("static/blockwriteai")
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
Generate tags in Flask, Django, or any Python web app:
|
|
123
|
+
|
|
124
|
+
```python
|
|
125
|
+
from blockwriteai_editor import stylesheet_tag, script_tags
|
|
126
|
+
|
|
127
|
+
print(stylesheet_tag("/static/blockwriteai"))
|
|
128
|
+
print(script_tags("/static/blockwriteai"))
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
Then mount the editor in your template:
|
|
132
|
+
|
|
133
|
+
```html
|
|
134
|
+
<div id="editor"></div>
|
|
135
|
+
<script>
|
|
136
|
+
const editor = new BlockWriteAI({
|
|
137
|
+
holder: "#editor",
|
|
138
|
+
async onSave(data) {
|
|
139
|
+
await fetch("/api/documents", {
|
|
140
|
+
method: "POST",
|
|
141
|
+
headers: { "Content-Type": "application/json" },
|
|
142
|
+
body: JSON.stringify(data)
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
});
|
|
146
|
+
</script>
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
## Read Saved Documents
|
|
150
|
+
|
|
151
|
+
BlockWriteAI saves JSON. Store that JSON in your database, then render it later with a preview container:
|
|
152
|
+
|
|
153
|
+
```html
|
|
154
|
+
<link rel="stylesheet" href="/assets/blockwriteai/blockwriteai.min.css">
|
|
155
|
+
|
|
156
|
+
<div class="blockwriteai-preview" data-source="/api/documents/123.json"></div>
|
|
157
|
+
|
|
158
|
+
<script src="/assets/blockwriteai/blockwriteai.min.js"></script>
|
|
159
|
+
<script src="/assets/blockwriteai/plugins/blockwriteai-advanced-blocks.min.js"></script>
|
|
160
|
+
<script>
|
|
161
|
+
BlockWriteAI.mountPreviews();
|
|
162
|
+
</script>
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
The JSON endpoint can return a document directly:
|
|
166
|
+
|
|
167
|
+
```json
|
|
168
|
+
{
|
|
169
|
+
"time": 1779540000000,
|
|
170
|
+
"version": "1.0.10",
|
|
171
|
+
"blocks": []
|
|
172
|
+
}
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
It can also return a wrapper:
|
|
176
|
+
|
|
177
|
+
```json
|
|
178
|
+
{
|
|
179
|
+
"ok": true,
|
|
180
|
+
"data": {
|
|
181
|
+
"time": 1779540000000,
|
|
182
|
+
"version": "1.0.10",
|
|
183
|
+
"blocks": []
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
## Premium Plugins
|
|
189
|
+
|
|
190
|
+
Do not expose premium plugin files as normal public scripts. Load them after your server verifies an active license:
|
|
191
|
+
|
|
192
|
+
```html
|
|
193
|
+
<script>
|
|
194
|
+
async function bootEditor() {
|
|
195
|
+
await BlockWriteAI.loadPremiumPlugins({
|
|
196
|
+
licenseKey: "bwai_live_xxxxx",
|
|
197
|
+
endpoint: "/blockwriteai-platform/api/premium_plugins.php",
|
|
198
|
+
features: ["drawing", "mermaid", "signature", "signature_flow", "ai"]
|
|
199
|
+
});
|
|
200
|
+
|
|
201
|
+
window.editor = new BlockWriteAI({
|
|
202
|
+
holder: "#editor",
|
|
203
|
+
premium: {
|
|
204
|
+
licenseKey: "bwai_live_xxxxx",
|
|
205
|
+
verifyEndpoint: "/blockwriteai-platform/api/license_verify.php",
|
|
206
|
+
usageEndpoint: "/blockwriteai-platform/api/ai_usage.php"
|
|
207
|
+
},
|
|
208
|
+
ai: {
|
|
209
|
+
endpoint: "/api/blockwriteai-ai"
|
|
210
|
+
}
|
|
211
|
+
});
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
bootEditor();
|
|
215
|
+
</script>
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
The browser plugin must never receive private API keys. Keep OpenAI, billing, usage limits, and license checks on your server.
|
|
219
|
+
|
|
220
|
+
## Release Checklist
|
|
221
|
+
|
|
222
|
+
1. Run `npm run build:min`.
|
|
223
|
+
2. Run `npm run check`.
|
|
224
|
+
3. Publish `@qarakash/blockwriteai` to npm.
|
|
225
|
+
4. Publish `qarakash/blockwriteai` to Packagist.
|
|
226
|
+
5. Publish `blockwriteai-editor` to PyPI.
|
|
227
|
+
6. Serve only the public asset directory from your application.
|
|
228
|
+
|
|
229
|
+
## Notes For Production
|
|
230
|
+
|
|
231
|
+
- Use the `.min.css` and `.min.js` files in public pages.
|
|
232
|
+
- Do not publish source folders, examples, build artifacts, package caches, or private configuration files.
|
|
233
|
+
- Browser-delivered CSS and JavaScript can always be downloaded. Protect paid features with server-side license checks and metered premium bundle delivery.
|
|
234
|
+
- Keep secret keys in backend environment variables only.
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
"""Python helpers for serving BlockWriteAI static assets."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from importlib import resources
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
from shutil import copytree
|
|
8
|
+
|
|
9
|
+
__all__ = [
|
|
10
|
+
"__version__",
|
|
11
|
+
"asset_path",
|
|
12
|
+
"copy_static",
|
|
13
|
+
"dist_path",
|
|
14
|
+
"premium_script_tags",
|
|
15
|
+
"script_tags",
|
|
16
|
+
"stylesheet_tag",
|
|
17
|
+
]
|
|
18
|
+
|
|
19
|
+
__version__ = "1.0.10"
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def dist_path() -> Path:
|
|
23
|
+
"""Return the installed BlockWriteAI static asset directory."""
|
|
24
|
+
return Path(str(resources.files(__name__).joinpath("static", "blockwriteai")))
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def asset_path(relative_path: str = "") -> Path:
|
|
28
|
+
"""Return an installed asset path relative to the BlockWriteAI static directory."""
|
|
29
|
+
root = dist_path()
|
|
30
|
+
return root.joinpath(relative_path) if relative_path else root
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def copy_static(target_dir: str | Path) -> Path:
|
|
34
|
+
"""Copy BlockWriteAI static assets into a web-accessible directory."""
|
|
35
|
+
target = Path(target_dir)
|
|
36
|
+
copytree(dist_path(), target, dirs_exist_ok=True)
|
|
37
|
+
return target
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def stylesheet_tag(base_url: str = "/static/blockwriteai") -> str:
|
|
41
|
+
"""Return the BlockWriteAI stylesheet tag for a configured static URL."""
|
|
42
|
+
base = base_url.rstrip("/")
|
|
43
|
+
return f'<link rel="stylesheet" href="{base}/blockwriteai.min.css">'
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def script_tags(base_url: str = "/static/blockwriteai", plugins: bool = True, history: bool = False, ai: bool = False) -> str:
|
|
47
|
+
"""Return script tags for BlockWriteAI and, optionally, official free plugins."""
|
|
48
|
+
base = base_url.rstrip("/")
|
|
49
|
+
scripts = [f'<script src="{base}/blockwriteai.min.js"></script>']
|
|
50
|
+
if plugins:
|
|
51
|
+
scripts.extend(
|
|
52
|
+
[
|
|
53
|
+
f'<script src="{base}/plugins/blockwriteai-code-assist.min.js"></script>',
|
|
54
|
+
f'<script src="{base}/plugins/blockwriteai-advanced-blocks.min.js"></script>',
|
|
55
|
+
]
|
|
56
|
+
)
|
|
57
|
+
if ai:
|
|
58
|
+
scripts.append(f'<script src="{base}/plugins/blockwriteai-ai.min.js"></script>')
|
|
59
|
+
if history:
|
|
60
|
+
scripts.append(f'<script src="{base}/plugins/blockwriteai-history.min.js"></script>')
|
|
61
|
+
return "\n".join(scripts)
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def premium_script_tags(
|
|
65
|
+
base_url: str = "/static/blockwriteai",
|
|
66
|
+
features: tuple[str, ...] | list[str] = ("drawing", "mermaid", "signature", "signature_flow", "ai"),
|
|
67
|
+
) -> str:
|
|
68
|
+
"""Return direct premium plugin tags for private/licensed deployments.
|
|
69
|
+
|
|
70
|
+
Public integrations should prefer the BlockWriteAI Platform premium bundle
|
|
71
|
+
endpoint so plugin delivery is checked server-side against a license key.
|
|
72
|
+
"""
|
|
73
|
+
base = base_url.rstrip("/")
|
|
74
|
+
mapping = {
|
|
75
|
+
"drawing": "blockwriteai-drawing.min.js",
|
|
76
|
+
"mermaid": "blockwriteai-mermaid.min.js",
|
|
77
|
+
"signature": "blockwriteai-signature.min.js",
|
|
78
|
+
"signature_flow": "blockwriteai-signature-flow.min.js",
|
|
79
|
+
"ai": "blockwriteai-ai.min.js",
|
|
80
|
+
}
|
|
81
|
+
scripts = [
|
|
82
|
+
f'<script src="{base}/plugins/{mapping[feature]}"></script>'
|
|
83
|
+
for feature in features
|
|
84
|
+
if feature in mapping
|
|
85
|
+
]
|
|
86
|
+
return "\n".join(scripts)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
<svg width="64" height="64" viewBox="0 0 64 64" fill="none" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="BlockWriteAI">
|
|
2
|
+
<defs>
|
|
3
|
+
<linearGradient id="bwai-favicon-bg" x1="8" y1="8" x2="56" y2="56" gradientUnits="userSpaceOnUse">
|
|
4
|
+
<stop offset="0" stop-color="#102033"/>
|
|
5
|
+
<stop offset="1" stop-color="#172A46"/>
|
|
6
|
+
</linearGradient>
|
|
7
|
+
<linearGradient id="bwai-favicon-accent" x1="16" y1="18" x2="48" y2="48" gradientUnits="userSpaceOnUse">
|
|
8
|
+
<stop offset="0" stop-color="#2BEA8A"/>
|
|
9
|
+
<stop offset="1" stop-color="#10B981"/>
|
|
10
|
+
</linearGradient>
|
|
11
|
+
</defs>
|
|
12
|
+
<rect x="6" y="6" width="52" height="52" rx="16" fill="url(#bwai-favicon-bg)"/>
|
|
13
|
+
<rect x="18" y="18" width="10" height="10" rx="2.5" fill="#FFFFFF"/>
|
|
14
|
+
<rect x="31" y="18" width="10" height="10" rx="2.5" fill="#FFFFFF" opacity="0.92"/>
|
|
15
|
+
<rect x="18" y="31" width="10" height="10" rx="2.5" fill="url(#bwai-favicon-accent)"/>
|
|
16
|
+
<path d="M33.2 43.1L45 31.3C45.7 30.6 46.8 30.6 47.5 31.3L51.1 34.9C51.8 35.6 51.8 36.7 51.1 37.4L39.3 49.2L31.5 50.8L33.2 43.1Z" fill="#FFFFFF"/>
|
|
17
|
+
<path d="M43.1 33.3L49.2 39.4" stroke="#10B981" stroke-width="3" stroke-linecap="round"/>
|
|
18
|
+
<circle cx="51" cy="51" r="7" fill="#19B86B" stroke="#FFFFFF" stroke-width="3"/>
|
|
19
|
+
<path d="M49.5 16.5H55.5M52.5 13.5V19.5" stroke="#19B86B" stroke-width="3" stroke-linecap="round"/>
|
|
20
|
+
</svg>
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
<svg width="270" height="58" viewBox="0 0 270 58" fill="none" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="title desc">
|
|
2
|
+
<title id="title">BlockWriteAI</title>
|
|
3
|
+
<desc id="desc">BlockWriteAI wordmark with a block grid, writing mark, and AI accent.</desc>
|
|
4
|
+
<defs>
|
|
5
|
+
<linearGradient id="bwai-icon" x1="8" y1="8" x2="50" y2="50" gradientUnits="userSpaceOnUse">
|
|
6
|
+
<stop offset="0" stop-color="#102033"/>
|
|
7
|
+
<stop offset="1" stop-color="#172A46"/>
|
|
8
|
+
</linearGradient>
|
|
9
|
+
<linearGradient id="bwai-accent" x1="16" y1="17" x2="43" y2="42" gradientUnits="userSpaceOnUse">
|
|
10
|
+
<stop offset="0" stop-color="#2BEA8A"/>
|
|
11
|
+
<stop offset="1" stop-color="#10B981"/>
|
|
12
|
+
</linearGradient>
|
|
13
|
+
</defs>
|
|
14
|
+
<rect x="2" y="7" width="44" height="44" rx="13" fill="url(#bwai-icon)"/>
|
|
15
|
+
<rect x="13" y="17" width="9" height="9" rx="2.2" fill="#FFFFFF"/>
|
|
16
|
+
<rect x="25" y="17" width="9" height="9" rx="2.2" fill="#FFFFFF" opacity="0.92"/>
|
|
17
|
+
<rect x="13" y="29" width="9" height="9" rx="2.2" fill="url(#bwai-accent)"/>
|
|
18
|
+
<path d="M27.5 38.3L37.6 28.2C38.2 27.6 39.1 27.6 39.7 28.2L43 31.5C43.6 32.1 43.6 33 43 33.6L32.9 43.7L26.1 45.1L27.5 38.3Z" fill="#FFFFFF"/>
|
|
19
|
+
<path d="M36.1 29.7L41.5 35.1" stroke="#10B981" stroke-width="2.2" stroke-linecap="round"/>
|
|
20
|
+
<circle cx="42" cy="45" r="5.5" fill="#19B86B" stroke="#FFFFFF" stroke-width="2.6"/>
|
|
21
|
+
<path d="M49 18.5H54M51.5 16V21" stroke="#19B86B" stroke-width="2.4" stroke-linecap="round"/>
|
|
22
|
+
<text x="60" y="37" font-family="Inter, Segoe UI, Arial, sans-serif" font-size="28" font-weight="850" letter-spacing="0">
|
|
23
|
+
<tspan fill="#102033">BlockWrıte</tspan><tspan fill="#12A865">AI</tspan>
|
|
24
|
+
</text>
|
|
25
|
+
<circle cx="182" cy="17.6" r="2.8" fill="#19B86B"/>
|
|
26
|
+
</svg>
|