@oktis-works/web 0.0.0-stage → 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.
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env bun
2
+ export {};
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
package/dist/index.js ADDED
@@ -0,0 +1,115 @@
1
+ #!/usr/bin/env bun
2
+ // @oktis-works/web - Theme Engine Runtime
3
+ // Renders sites via themes using Theme SDK
4
+ import { Hono } from 'hono';
5
+ import { join } from 'node:path';
6
+ import { serve } from '@hono/node-server';
7
+ import { bootstrap } from '@oktis-works/core';
8
+ import { establishTenantContext } from '@oktis-works/core';
9
+ import { getConnection } from '@oktis-works/database';
10
+ import { createRouter, wireThemeHooks } from './rendering.js';
11
+ import { setCurrentContent } from '@oktis-works/theme-sdk';
12
+ async function main() {
13
+ const lifecycle = await bootstrap();
14
+ wireThemeHooks();
15
+ const themesRoot = process.env['THEMES_DIR'] ?? join(process.cwd(), 'themes');
16
+ const activeTheme = process.env['ACTIVE_THEME'] ?? 'default';
17
+ const router = createRouter(themesRoot, activeTheme);
18
+ const app = new Hono();
19
+ // Tenant resolution middleware
20
+ app.use('*', async (c, next) => {
21
+ // Resolve tenant from subdomain or domain
22
+ const host = c.req.header('host') ?? '';
23
+ const sql = getConnection();
24
+ // Try subdomain resolution first
25
+ const subdomain = host.split('.')[0];
26
+ if (subdomain && subdomain !== 'www' && subdomain !== 'api') {
27
+ const tenants = await sql.unsafe('SELECT * FROM tenants WHERE subdomain = $1 AND status = $2', [subdomain, 'ACTIVE']);
28
+ if (tenants.length > 0) {
29
+ const tenant = tenants[0];
30
+ await establishTenantContext(tenant['id']);
31
+ c.set('tenant', tenant);
32
+ return next();
33
+ }
34
+ }
35
+ // Try domain resolution
36
+ const tenants = await sql.unsafe('SELECT * FROM tenants WHERE domain = $1 AND status = $2', [host, 'ACTIVE']);
37
+ if (tenants.length > 0) {
38
+ const tenant = tenants[0];
39
+ await establishTenantContext(tenant['id']);
40
+ c.set('tenant', tenant);
41
+ return next();
42
+ }
43
+ return c.json({ error: 'Tenant not found' }, 404);
44
+ });
45
+ // Health check
46
+ app.get('/health', async (c) => {
47
+ return c.json({
48
+ status: 'healthy',
49
+ service: 'web',
50
+ timestamp: new Date().toISOString(),
51
+ });
52
+ });
53
+ // Content rendering routes (FEAT-095: runtime routing catch-all)
54
+ app.get('*', async (c) => {
55
+ const path = c.req.path;
56
+ try {
57
+ const resolution = await router.resolve(path);
58
+ if (!resolution.matched) {
59
+ return c.notFound();
60
+ }
61
+ if (resolution.slug && resolution.contentType) {
62
+ const rows = await getConnection().unsafe("SELECT * FROM content WHERE slug = $1 AND type = $2 AND status = 'PUBLISHED' LIMIT 1", [resolution.slug, resolution.contentType]);
63
+ const row = rows[0];
64
+ if (row)
65
+ setCurrentContent(row);
66
+ }
67
+ const escapeAttr = (value) => value.replace(/&/g, '&amp;').replace(/"/g, '&quot;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
68
+ const template = escapeAttr(resolution.template ?? '');
69
+ const contentType = escapeAttr(resolution.contentType ?? '');
70
+ const themeAttr = escapeAttr(activeTheme);
71
+ return c.html(`<!DOCTYPE html>
72
+ <html lang="en">
73
+ <head>
74
+ <meta charset="UTF-8">
75
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
76
+ <title>BlackLotus CMS</title>
77
+ <link rel="stylesheet" href="/themes/${themeAttr}/dist/theme.css" data-theme-style="${themeAttr}" />
78
+ </head>
79
+ <body>
80
+ <main data-theme="${themeAttr}" data-template="${template}" data-type="${contentType}">
81
+ <!-- Rendered by theme template (isolado via [data-theme="${themeAttr}"]) -->
82
+ </main>
83
+ </body>
84
+ </html>`);
85
+ }
86
+ catch (error) {
87
+ console.error('[web] Falha ao resolver rota:', error);
88
+ return c.json({ error: 'Internal server error' }, 500);
89
+ }
90
+ });
91
+ // Start server
92
+ const port = Number(process.env['WEB_PORT'] ?? 3001);
93
+ serve({
94
+ fetch: app.fetch,
95
+ port,
96
+ }, (info) => {
97
+ console.log(`BlackLotus Web running on http://localhost:${info.port}`);
98
+ });
99
+ // Graceful shutdown
100
+ process.on('SIGTERM', async () => {
101
+ console.log('SIGTERM received, shutting down...');
102
+ await lifecycle.stop();
103
+ process.exit(0);
104
+ });
105
+ process.on('SIGINT', async () => {
106
+ console.log('SIGINT received, shutting down...');
107
+ await lifecycle.stop();
108
+ process.exit(0);
109
+ });
110
+ }
111
+ main().catch((error) => {
112
+ console.error('Failed to start web server:', error);
113
+ process.exit(1);
114
+ });
115
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ import { RuntimeRouter, type ContentLookup, type TemplateFileChecker } from '@oktis-works/theme-runtime';
2
+ export declare function createTemplateChecker(themesRoot: string, activeTheme: string): TemplateFileChecker;
3
+ export declare function createContentLookup(): ContentLookup;
4
+ export declare function createRouter(themesRoot: string, activeTheme: string): RuntimeRouter;
5
+ /** Helper para web: obtém atributo de isolamento para template */
6
+ export declare function getScopedContainer(themeName: string): string;
7
+ /** Build pipeline do tema: compila SCSS ou Tailwind e retorna relatório */
8
+ export declare function buildTheme(themeRoot: string, themeName: string, manifest: import('@oktis-works/theme-sdk').ThemeManifest): Promise<{
9
+ css: string;
10
+ report: import("@oktis-works/theme-runtime").ThemeStyleReport & {
11
+ themePath: string;
12
+ };
13
+ }>;
14
+ /**
15
+ * Registra o hook registry no Theme SDK para habilitar os filtros theme:data:*.
16
+ */
17
+ export declare function wireThemeHooks(): void;
18
+ //# sourceMappingURL=rendering.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rendering.d.ts","sourceRoot":"","sources":["../src/rendering.ts"],"names":[],"mappings":"AAOA,OAAO,EAEL,aAAa,EACb,KAAK,aAAa,EAClB,KAAK,mBAAmB,EAGzB,MAAM,4BAA4B,CAAC;AAEpC,wBAAgB,qBAAqB,CAAC,UAAU,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,mBAAmB,CAWlG;AAqFD,wBAAgB,mBAAmB,IAAI,aAAa,CAqCnD;AAED,wBAAgB,YAAY,CAAC,UAAU,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,aAAa,CAGnF;AAED,kEAAkE;AAClE,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAG5D;AAED,2EAA2E;AAC3E,wBAAsB,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,wBAAwB,EAAE,aAAa;;;;;GAE9H;AAED;;GAEG;AACH,wBAAgB,cAAc,IAAI,IAAI,CAOrC"}
@@ -0,0 +1,148 @@
1
+ // @oktis-works/web - Runtime Rendering (catch-all SSR com hierarquia de templates)
2
+ import { existsSync } from 'node:fs';
3
+ import { join } from 'node:path';
4
+ import { getConnection } from '@oktis-works/database';
5
+ import { getHookRegistry } from '@oktis-works/plugin-runtime';
6
+ import { postTypeRegistry, HOOK_POINTS } from '@oktis-works/core';
7
+ import { TemplateHierarchyResolver, RuntimeRouter, buildThemeStyles, getThemeScopeAttribute, } from '@oktis-works/theme-runtime';
8
+ export function createTemplateChecker(themesRoot, activeTheme) {
9
+ return {
10
+ exists(file) {
11
+ const candidates = [
12
+ join(themesRoot, activeTheme, file),
13
+ join(themesRoot, '_shared', file),
14
+ join(themesRoot, 'default', file),
15
+ ];
16
+ return candidates.some((candidate) => existsSync(candidate));
17
+ },
18
+ };
19
+ }
20
+ const UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
21
+ const MEDIA_KEY_RE = /media|image|thumb|cover|gallery/i;
22
+ function collectMediaIds(value, out, depth = 0) {
23
+ if (depth > 6 || value == null)
24
+ return;
25
+ if (typeof value === 'string') {
26
+ if (UUID_RE.test(value))
27
+ out.add(value);
28
+ }
29
+ else if (Array.isArray(value)) {
30
+ for (const item of value)
31
+ collectMediaIds(item, out, depth + 1);
32
+ }
33
+ else if (typeof value === 'object') {
34
+ for (const child of Object.values(value)) {
35
+ collectMediaIds(child, out, depth + 1);
36
+ }
37
+ }
38
+ }
39
+ /**
40
+ * REQU-028-001: substitui referências de mídia por objetos {id,url,alt} reais.
41
+ * Uma única query batched — sem N+1.
42
+ */
43
+ async function enrichMedia(sql, data) {
44
+ const ids = new Set();
45
+ collectMediaIds(data, ids);
46
+ if (ids.size === 0)
47
+ return;
48
+ const idList = [...ids];
49
+ const rows = await sql.unsafe(`SELECT id, url, alt, filename FROM media WHERE id = ANY($1::uuid[])`, [idList]);
50
+ const byId = new Map(rows.map((r) => [String(r['id']), { id: String(r['id']), url: String(r['url']), alt: r['alt'] ?? null, filename: r['filename'] ?? null }]));
51
+ if (byId.size === 0)
52
+ return;
53
+ const replace = (value, keyHint, depth) => {
54
+ if (value == null || depth > 6)
55
+ return value;
56
+ if (typeof value === 'string') {
57
+ const hit = byId.get(value);
58
+ return hit && keyHint !== undefined && MEDIA_KEY_RE.test(keyHint) ? hit : value;
59
+ }
60
+ if (Array.isArray(value))
61
+ return value.map((item) => replace(item, keyHint, depth + 1));
62
+ if (typeof value === 'object') {
63
+ const out = {};
64
+ for (const [key, child] of Object.entries(value)) {
65
+ out[key] = replace(child, key, depth + 1);
66
+ }
67
+ return out;
68
+ }
69
+ return value;
70
+ };
71
+ for (const key of Object.keys(data)) {
72
+ data[key] = replace(data[key], key, 0);
73
+ }
74
+ }
75
+ /** REQU-028-003: injeta _terms agrupado por taxonomia no payload. */
76
+ async function attachTerms(sql, contentId, data) {
77
+ const rows = await sql.unsafe(`
78
+ SELECT tx.slug AS taxonomy_slug, t.slug AS term_slug, t.name AS term_name
79
+ FROM content_taxonomy_terms ctt
80
+ JOIN taxonomy_terms t ON t.id = ctt.term_id
81
+ JOIN taxonomies tx ON tx.id = t.taxonomy_id
82
+ WHERE ctt.content_id = $1
83
+ ORDER BY tx.slug ASC, t.name ASC
84
+ `, [contentId]);
85
+ if (rows.length === 0)
86
+ return;
87
+ const grouped = {};
88
+ for (const row of rows) {
89
+ (grouped[row.taxonomy_slug] ??= []).push({ slug: row.term_slug, name: row.term_name });
90
+ }
91
+ data['_terms'] = grouped;
92
+ }
93
+ export function createContentLookup() {
94
+ return {
95
+ async findByPath(path) {
96
+ const sql = getConnection();
97
+ const result = await sql.unsafe("SELECT * FROM content WHERE slug = $1 AND status = 'PUBLISHED' LIMIT 1", [path]);
98
+ const row = result[0];
99
+ if (!row)
100
+ return null;
101
+ const data = (row['body'] ?? {});
102
+ // Enriquecimento em lote: mídia real e termos agregados
103
+ try {
104
+ await enrichMedia(sql, data);
105
+ await attachTerms(sql, String(row['id']), data);
106
+ }
107
+ catch {
108
+ // falha de enriquecimento nunca derruba a renderização
109
+ }
110
+ return {
111
+ type: String(row['type']),
112
+ slug: String(row['slug']),
113
+ data,
114
+ layout: row['layout'] ?? null,
115
+ };
116
+ },
117
+ async listTypes() {
118
+ const types = await postTypeRegistry.list();
119
+ return types
120
+ .filter((type) => type.public !== false)
121
+ .map((type) => ({ slug: type.slug, hasArchive: Boolean(type.hasArchive) }));
122
+ },
123
+ };
124
+ }
125
+ export function createRouter(themesRoot, activeTheme) {
126
+ const resolver = new TemplateHierarchyResolver(createTemplateChecker(themesRoot, activeTheme));
127
+ return new RuntimeRouter(createContentLookup(), resolver);
128
+ }
129
+ /** Helper para web: obtém atributo de isolamento para template */
130
+ export function getScopedContainer(themeName) {
131
+ const { attr } = getThemeScopeAttribute(themeName);
132
+ return attr;
133
+ }
134
+ /** Build pipeline do tema: compila SCSS ou Tailwind e retorna relatório */
135
+ export async function buildTheme(themeRoot, themeName, manifest) {
136
+ return buildThemeStyles({ themesRoot: themeRoot, themeName, manifest });
137
+ }
138
+ /**
139
+ * Registra o hook registry no Theme SDK para habilitar os filtros theme:data:*.
140
+ */
141
+ export function wireThemeHooks() {
142
+ void import('@oktis-works/theme-sdk').then((sdk) => {
143
+ sdk.setThemeHooks(getHookRegistry());
144
+ });
145
+ // Ponto de extensão head: plugins podem injetar tags no <head> do site público.
146
+ void HOOK_POINTS;
147
+ }
148
+ //# sourceMappingURL=rendering.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rendering.js","sourceRoot":"","sources":["../src/rendering.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=rendering.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rendering.test.d.ts","sourceRoot":"","sources":["../src/rendering.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,85 @@
1
+ // @oktis-works/web - Enriquecimento de mídia e termos no lookup (REQU-028-001/003)
2
+ import { describe, it, expect, vi, beforeEach } from 'vitest';
3
+ let queue;
4
+ vi.mock('@oktis-works/database', () => ({
5
+ getConnection: vi.fn(() => ({
6
+ unsafe: vi.fn(async (_text, _values) => (queue.shift() ?? [])),
7
+ })),
8
+ }));
9
+ vi.mock('@oktis-works/plugin-runtime', () => ({
10
+ getHookRegistry: vi.fn(() => ({ addFilter: vi.fn(), doAction: vi.fn() })),
11
+ }));
12
+ vi.mock('@oktis-works/core', () => ({
13
+ postTypeRegistry: { list: vi.fn(async () => []) },
14
+ HOOK_POINTS: {},
15
+ }));
16
+ import { createContentLookup } from './rendering.js';
17
+ beforeEach(() => {
18
+ queue = [];
19
+ });
20
+ describe('createContentLookup.findByPath — enriquecimento', () => {
21
+ it('substitui UUIDs de mídia por objetos reais e injeta _terms', async () => {
22
+ const mediaId = '0b9e6c35-7d5a-4f1e-9a3b-2c4d5e6f7081';
23
+ const termId = '11111111-2222-4333-8444-555555555555';
24
+ // Query 1: content; Query 2: media batched; Query 3: terms
25
+ queue = [
26
+ [
27
+ {
28
+ id: 'c1',
29
+ type: 'post',
30
+ slug: 'ola',
31
+ layout: null,
32
+ body: {
33
+ title: 'Olá',
34
+ thumbnail: mediaId,
35
+ gallery: [mediaId],
36
+ meta: { author_id: termId },
37
+ },
38
+ },
39
+ ],
40
+ [{ id: mediaId, url: 'https://cdn.local/img.png', alt: 'Capa' }],
41
+ [
42
+ { taxonomy_slug: 'category', term_slug: 'noticias', term_name: 'Notícias' },
43
+ { taxonomy_slug: 'category', term_slug: 'tech', term_name: 'Tech' },
44
+ { taxonomy_slug: 'post_tag', term_slug: 'cms', term_name: 'CMS' },
45
+ ],
46
+ ];
47
+ const found = await createContentLookup().findByPath('ola');
48
+ expect(found).not.toBeNull();
49
+ const data = found.data;
50
+ expect(data['thumbnail']).toEqual({ id: mediaId, url: 'https://cdn.local/img.png', alt: 'Capa', filename: null });
51
+ expect(Array.isArray(data['gallery'])).toBe(true);
52
+ expect(data['_terms']['category']).toEqual([
53
+ { slug: 'noticias', name: 'Notícias' },
54
+ { slug: 'tech', name: 'Tech' },
55
+ ]);
56
+ expect(data['_terms']['post_tag']).toEqual([{ slug: 'cms', name: 'CMS' }]);
57
+ });
58
+ it('UUID fora de campo de mídia permanece intacto e _terms ausente quando vazio', async () => {
59
+ const randomUuid = '99999999-8888-4777-8666-555555555555';
60
+ queue = [
61
+ [{ id: 'c2', type: 'page', slug: 'sobre', body: { ref: randomUuid } }],
62
+ [],
63
+ [],
64
+ ];
65
+ const found = await createContentLookup().findByPath('sobre');
66
+ expect(found.data['ref']).toBe(randomUuid);
67
+ expect(found.data['_terms']).toBeUndefined();
68
+ });
69
+ it('falha no enriquecimento não derruba o render', async () => {
70
+ let calls = 0;
71
+ const sql = {
72
+ unsafe: vi.fn(async () => {
73
+ calls += 1;
74
+ if (calls > 1)
75
+ throw new Error('boom');
76
+ return [{ id: 'c3', type: 'post', slug: 'x', body: { thumbnail: '99999999-8888-4777-8666-555555555555' } }];
77
+ }),
78
+ };
79
+ const { getConnection } = await import('@oktis-works/database');
80
+ getConnection.mockReturnValueOnce(sql);
81
+ const found = await createContentLookup().findByPath('x');
82
+ expect(found).not.toBeNull();
83
+ });
84
+ });
85
+ //# sourceMappingURL=rendering.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rendering.test.js","sourceRoot":"","sources":["../src/rendering.test.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,46 @@
1
1
  {
2
2
  "name": "@oktis-works/web",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "0.1.0",
4
+ "type": "module",
5
+ "main": "./dist/index.js",
6
+ "types": "./dist/index.d.ts",
7
+ "bin": {
8
+ "blacklotus-web": "./dist/index.js"
9
+ },
10
+ "files": [
11
+ "dist"
12
+ ],
13
+ "scripts": {
14
+ "dev": "tsx watch src/index.ts",
15
+ "build": "tsc",
16
+ "start": "node dist/index.js",
17
+ "prepublishOnly": "bun run build",
18
+ "clean": "rm -rf dist tsconfig.tsbuildinfo"
19
+ },
20
+ "dependencies": {
21
+ "@oktis-works/core": "0.1.0",
22
+ "@oktis-works/config": "0.1.0",
23
+ "@oktis-works/database": "0.1.0",
24
+ "@oktis-works/types": "0.1.0",
25
+ "@oktis-works/theme-sdk": "0.1.0",
26
+ "@oktis-works/theme-runtime": "0.1.0",
27
+ "hono": "4.0.0",
28
+ "@hono/node-server": "1.8.0",
29
+ "@oktis-works/plugin-runtime": "0.1.0"
30
+ },
31
+ "devDependencies": {
32
+ "typescript": "5.7.3",
33
+ "tsx": "4.7.0",
34
+ "@types/node": "20.11.0"
35
+ },
36
+ "license": "MIT",
37
+ "repository": {
38
+ "type": "git",
39
+ "url": "https://github.com/blacklotus/blacklotus-cms",
40
+ "directory": "apps/web"
41
+ },
42
+ "publishConfig": {
43
+ "access": "public",
44
+ "registry": "https://registry.npmjs.org/"
45
+ }
46
+ }
package/README.md DELETED
@@ -1,3 +0,0 @@
1
- # Temporary Holding Version
2
-
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.