diff --git a/.gitignore b/.gitignore
index 76add87..14ebf5c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,3 @@
node_modules
-dist
\ No newline at end of file
+dist
+api/.env
diff --git a/.npmignore b/.npmignore
index 1cb0c1b..6dc8668 100644
--- a/.npmignore
+++ b/.npmignore
@@ -8,3 +8,4 @@ tsconfig.esm.json
tsconfig.json
api
src
+mod.ts
diff --git a/README.md b/README.md
index 959dcc6..028204f 100644
--- a/README.md
+++ b/README.md
@@ -17,6 +17,9 @@ import markupToJSON from 'markuptojson'
// COMMON JS
const markupToJSON require('markuptojson')
+// DENO
+import markupToJSON from 'https://deno.land/x/markuptojson_deno/mod.ts'
+
// -- HTML TO JSON -- //
const HTML = "
Hello World Master
"
const JSON = markupToJSON.htmlToJSON(HTML)
@@ -54,7 +57,12 @@ You can also import the functions separately.
// ESMODULES
import { htmlToJSON, jsonToHTML } from 'markuptojson'
+
// COMMONJS
const { htmlToJSON, jsonToHTML } = require('markuptojson')
+
+// DENO
+import { htmlToJSON, jsonToHTML } from 'https://deno.land/x/markuptojson_deno/mod.ts'
+
```
Thanks to **typescript** you will be able to have autocompletion in visual studio code and other popular IDEs, so you can easily extract the api responses and some performance information. Just like **typescript** helps with module methods for easy use.
\ No newline at end of file
diff --git a/api/.env b/api/.env
index df5132c..6abf669 100644
--- a/api/.env
+++ b/api/.env
@@ -1 +1 @@
-set PORT = "400"
\ No newline at end of file
+PORT = 4000
\ No newline at end of file
diff --git a/api/deno.json b/api/deno.json
index a5d1834..07f7e0a 100644
--- a/api/deno.json
+++ b/api/deno.json
@@ -8,7 +8,9 @@
"no-local",
"no-inferrable-types",
"no-prototype-builtins",
- "no-cond-assign"
+ "no-cond-assign",
+ "strict-boolean-expressions",
+ "@typescript-eslint/strict-boolean-expressions"
]
}
},
diff --git a/api/imports.json b/api/imports.json
index c28d1c3..701114a 100644
--- a/api/imports.json
+++ b/api/imports.json
@@ -1,6 +1,10 @@
{
"imports": {
"https://esm.sh/": "https://esm.sh/",
- "https://cdn.skypack.dev/": "https://cdn.skypack.dev/"
+ "https://cdn.skypack.dev/": "https://cdn.skypack.dev/",
+ "opine/": "https://deno.land/x/opine@2.3.3/",
+ "colors/": "https://deno.land/x/colorify@1.0.5/",
+ "cors/": "https://deno.land/x/cors@v1.2.2/",
+ "markuptojson/": "https://esm.sh/markuptojson@1.0.3/"
}
}
\ No newline at end of file
diff --git a/api/src/app.ts b/api/src/app.ts
index c1ebca8..0abd7d5 100644
--- a/api/src/app.ts
+++ b/api/src/app.ts
@@ -1,12 +1,167 @@
-import { Application, Router } from 'https://deno.land/x/oak@v12.1.0/mod.ts'
+import { opine, json, urlencoded } from 'opine/mod.ts'
+import { fg } from 'colors/mod.ts'
+import { opineCors } from 'cors/mod.ts'
import config from './config.ts'
+import { htmlToJSON, jsonToHTML, type JsonDBO } from 'markuptojson/'
-const router = new Router()
-const app = new Application()
+const app = opine()
-router.post('/', (ctx) => {
- // const s = ctx.request.body()?.value('asdsad')
+app.use(json({ limit: '100mb' }))
+app.use(urlencoded({ extends: false, limit: '100mb' }))
+app.use(opineCors({
+ allowedHeaders: '*',
+ origin: '*',
+ methods: 'PUT, POST, GET, DELETE, OPTIONS, PATCH',
+ credentials: true
+}))
+
+// routes
+
+app.get('/', (_req, res) => {
+ res.setStatus(200).json([
+ {
+ route: '/api/json',
+ description: 'Create valid Json DBO for interactivity with the [markupjson(NodeJS, Deno, CDNs, Browser)] package and this API',
+ format: 'HTML',
+ type: 'string',
+ method: 'POST',
+ exampleInput: "Hello World By markuptojson
",
+ output: [
+ {
+ tagName: 'h1',
+ tagAttrs: {
+ class: 'main-title',
+ id: 'title'
+ },
+ children: [
+ {
+ tagName: 'span',
+ tagAttrs: {},
+ children: [],
+ content: 'By markuptojson'
+ }
+ ],
+ content: 'Hello World'
+ }
+ ],
+ limit: '100mb',
+ bodyRequestNameParam: 'htmlContent',
+ responseParamName: 'data',
+ statusCodes: [
+ {
+ 500: 'Internal error server',
+ 400: 'Bad request, not valid html content',
+ 200: 'Success'
+ }
+ ]
+ },
+ {
+ route: '/api/html',
+ description: 'Convert JsonDBO create by API or markuptojson module to html',
+ format: 'ARRAY',
+ type: {
+ tagAttrs: 'string',
+ content: 'string',
+ children: 'array of this type',
+ tagName: 'string'
+ },
+ method: 'POST',
+ exampleInput: [
+ {
+ tagName: 'h1',
+ tagAttrs: {
+ class: 'main-title',
+ id: 'title'
+ },
+ children: [
+ {
+ tagName: 'span',
+ tagAttrs: {},
+ children: [],
+ content: 'By markuptojson'
+ }
+ ],
+ content: 'Hello World'
+ }
+ ],
+ output: "Hello World By markuptojson
",
+ limit: '100mb',
+ bodyRequestNameParam: 'jsonContent',
+ responseParamName: 'data',
+ statusCodes: [
+ {
+ 500: 'Internal error server',
+ 400: 'Bad request, not valid JsonDBO array content',
+ 200: 'Success'
+ }
+ ]
+ }
+ ])
+})
+
+app.post('/api/json', (req, res) => {
+ const html: string = String(req.body.htmlContent)
+ const regex = /<[a-z][\s\S]*>/i
+ try {
+ if (!regex.test(html)) {
+ return res.setStatus(400).json({
+ message: 'Require a valid body param [htmlContent] => html content'
+ })
+ }
+
+ const jsonResult = htmlToJSON(html)
+
+ res.setStatus(200).json({
+ data: jsonResult
+ })
+ } catch (_error) {
+ res.setStatus(500).json({
+ message: 'Internal error server...'
+ })
+ }
+})
+
+app.post('/api/html', (req, res) => {
+ const json = req.body.jsonContent as JsonDBO[]
+
+ try {
+ if (!Array.isArray(json)) {
+ return res.setStatus(400).json({
+ message: 'Require Array of param [jsonContent]'
+ })
+ }
+
+ const validData: JsonDBO[] = json.filter((item: any) => {
+ return (
+ typeof item === 'object' &&
+ (Boolean(item.tagAttrs)) &&
+ typeof item.tagAttrs === 'object' &&
+ (Boolean(item.content)) &&
+ typeof item.content === 'string' &&
+ Array.isArray(item.children) &&
+ (Boolean(item.tagName)) &&
+ typeof item.tagName === 'string'
+ )
+ })
+
+ if (validData.length !== json.length) {
+ return res.setStatus(400).json({
+ message: 'Incorrect format, generate valid [jsonContent] in [POST] /api/json'
+ })
+ }
+
+ const html = jsonToHTML(json)
+
+ res.setStatus(200).json({
+ data: html
+ })
+ } catch (_error) {
+ res.setStatus(500).json({
+ message: 'Internal error server...'
+ })
+ }
})
-app.use(router.routes())
-await app.listen({ port: config.PORT })
+app.listen(config.PORT, () => {
+ fg.green(`[APP]: listening in http://localhost:${String(config.PORT)}`)
+})
diff --git a/api/src/config.ts b/api/src/config.ts
index dd682fc..15cefc0 100644
--- a/api/src/config.ts
+++ b/api/src/config.ts
@@ -1,8 +1,12 @@
+/* eslint-disable @typescript-eslint/strict-boolean-expressions */
+import { config as access } from 'https://deno.land/std@0.173.0/dotenv/mod.ts'
+
+const env = await access()
const config: {
PORT: number
} = {
- PORT: 4000
+ PORT: Number(env.PORT || Deno.env.get('PORT') || 4000)
}
export default config
diff --git a/mod.ts b/mod.ts
new file mode 100644
index 0000000..ba88be8
--- /dev/null
+++ b/mod.ts
@@ -0,0 +1,21 @@
+// @ts-expect-error deno
+import markuptojson, { htmlToJSON, jsonToHTML } from './src/index.ts'
+
+export interface JsonDBO {
+ tagAttrs: Record
+ content: string
+ children: JsonDBO[] | never[]
+ tagName: string
+}
+
+export {
+ htmlToJSON,
+ jsonToHTML
+}
+
+export interface MarkupToJSON {
+ jsonToHTML: (arrayJson: JsonDBO[]) => string
+ htmlToJSON: (htmlString: string) => JsonDBO[]
+}
+
+export default markuptojson