@oktis-works/theme-runtime 0.0.0-stage → 0.1.1

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,122 @@
1
+ import { TemplateHierarchyResolver } from './template-resolver.js';
2
+ export class ThemeResolver {
3
+ registry = new Map();
4
+ activeTheme = null;
5
+ activeThemesByTenant = new Map();
6
+ inheritanceCache = new Map();
7
+ async resolveTheme(tenantId) {
8
+ const name = this.activeThemesByTenant.get(tenantId) ?? this.activeTheme;
9
+ if (name) {
10
+ const theme = this.registry.get(name);
11
+ if (theme)
12
+ return theme.manifest;
13
+ }
14
+ throw new Error(`No theme resolved for tenant: ${tenantId}`);
15
+ }
16
+ getActiveTheme() {
17
+ return this.activeTheme;
18
+ }
19
+ setActiveTheme(name) {
20
+ this.activeTheme = name;
21
+ }
22
+ setActiveThemeForTenant(tenantId, name) {
23
+ this.activeThemesByTenant.set(tenantId, name);
24
+ }
25
+ clearActiveThemeForTenant(tenantId) {
26
+ this.activeThemesByTenant.delete(tenantId);
27
+ }
28
+ getThemeManifest(name) {
29
+ const theme = this.registry.get(name);
30
+ return theme?.manifest ?? null;
31
+ }
32
+ loadTheme(manifest, path) {
33
+ this.registry.set(manifest.name, {
34
+ manifest,
35
+ path,
36
+ loaded: true,
37
+ });
38
+ this.inheritanceCache.clear();
39
+ }
40
+ getInheritanceChain(themeName) {
41
+ if (this.inheritanceCache.has(themeName)) {
42
+ return this.inheritanceCache.get(themeName);
43
+ }
44
+ const chain = [];
45
+ const visited = new Set();
46
+ let current = themeName;
47
+ while (current) {
48
+ if (visited.has(current))
49
+ break;
50
+ visited.add(current);
51
+ chain.push(current);
52
+ const theme = this.registry.get(current);
53
+ current = theme?.manifest.parent ?? null;
54
+ }
55
+ this.inheritanceCache.set(themeName, chain);
56
+ return chain;
57
+ }
58
+ resolveComponent(name, overrides) {
59
+ if (overrides?.has(name)) {
60
+ return overrides.get(name);
61
+ }
62
+ if (!this.activeTheme) {
63
+ return { name, file: '', source: 'core' };
64
+ }
65
+ const chain = this.getInheritanceChain(this.activeTheme);
66
+ for (const themeName of chain) {
67
+ const theme = this.registry.get(themeName);
68
+ if (!theme?.manifest.components)
69
+ continue;
70
+ const component = theme.manifest.components.find(c => c.name === name);
71
+ if (component) {
72
+ return { name, file: component.file, source: 'theme' };
73
+ }
74
+ }
75
+ return { name, file: '', source: 'core' };
76
+ }
77
+ listComponents() {
78
+ if (!this.activeTheme)
79
+ return [];
80
+ const chain = this.getInheritanceChain(this.activeTheme);
81
+ const components = new Map();
82
+ for (const themeName of [...chain].reverse()) {
83
+ const theme = this.registry.get(themeName);
84
+ if (!theme?.manifest.components)
85
+ continue;
86
+ for (const c of theme.manifest.components) {
87
+ components.set(c.name, { name: c.name, file: c.file, source: 'theme' });
88
+ }
89
+ }
90
+ return Array.from(components.values());
91
+ }
92
+ getThemeAssets(themeName) {
93
+ const theme = this.registry.get(themeName);
94
+ return theme?.manifest.provides?.assets ?? [];
95
+ }
96
+ /**
97
+ * Resolve um template da hierarquia (FEAT-094) considerando os arquivos
98
+ * declarados no manifest do tema ativo e sua cadeia de herança.
99
+ */
100
+ async resolve(context) {
101
+ const available = new Set();
102
+ for (const themeName of this.getInheritanceChain(this.activeTheme ?? '')) {
103
+ const theme = this.registry.get(themeName);
104
+ if (!theme?.manifest.components)
105
+ continue;
106
+ for (const component of theme.manifest.components) {
107
+ available.add(component.file);
108
+ if (component.file.endsWith('.astro')) {
109
+ available.add(component.name + '.astro');
110
+ }
111
+ }
112
+ }
113
+ const hierarchy = new TemplateHierarchyResolver({
114
+ exists: (file) => available.has(file),
115
+ });
116
+ return hierarchy.resolve(context);
117
+ }
118
+ clearCache() {
119
+ this.inheritanceCache.clear();
120
+ }
121
+ }
122
+ //# sourceMappingURL=resolver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolver.js","sourceRoot":"","sources":["../src/resolver.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,56 @@
1
+ import type { TemplateHierarchyResolver, TemplateContext } from './template-resolver.js';
2
+ export interface RouteResolution {
3
+ matched: boolean;
4
+ template?: string;
5
+ contentType?: string;
6
+ slug?: string;
7
+ }
8
+ export interface ContentLookup {
9
+ /** Retorna o tipo de conteúdo e dados para um caminho de URL. */
10
+ findByPath(path: string): Promise<{
11
+ type: string;
12
+ slug: string;
13
+ data: Record<string, unknown>;
14
+ layout?: string | null;
15
+ } | null>;
16
+ listTypes(): Promise<Array<{
17
+ slug: string;
18
+ hasArchive: boolean;
19
+ }>>;
20
+ }
21
+ /** Contrato mínimo do barramento de eventos (@oktis-works/core). */
22
+ export interface EventEmitLike {
23
+ emit(event: {
24
+ id: string;
25
+ type: string;
26
+ aggregateType: string;
27
+ aggregateId: string;
28
+ payload: Record<string, unknown> | {
29
+ paths: string[];
30
+ tags: string[];
31
+ };
32
+ processed: boolean;
33
+ createdAt: Date;
34
+ }): Promise<void>;
35
+ }
36
+ export declare class RuntimeRouter {
37
+ private readonly lookup;
38
+ private readonly resolver;
39
+ constructor(lookup: ContentLookup, resolver: TemplateHierarchyResolver);
40
+ /**
41
+ * Resolve um caminho arbitrário (catch-all [...slug]) para um template.
42
+ * Ordem: home → content-type archive → conteúdo por slug.
43
+ */
44
+ resolve(path: string): Promise<RouteResolution>;
45
+ }
46
+ /**
47
+ * Revalidação direcionada: publica um evento que os workers do app web
48
+ * consomem para invalidar apenas as rotas afetadas pelo conteúdo alterado.
49
+ */
50
+ export declare function targetedRevalidate(bus: EventEmitLike, input: {
51
+ paths: string[];
52
+ tags: string[];
53
+ tenantId: string;
54
+ }): Promise<void>;
55
+ export type { TemplateContext };
56
+ //# sourceMappingURL=routing.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"routing.d.ts","sourceRoot":"","sources":["../src/routing.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,yBAAyB,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAEzF,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,aAAa;IAC5B,iEAAiE;IACjE,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,GAAG,IAAI,CAAC,CAAC;IAChI,SAAS,IAAI,OAAO,CAAC,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC,CAAC;CACpE;AAED,oEAAoE;AACpE,MAAM,WAAW,aAAa;IAC5B,IAAI,CAAC,KAAK,EAAE;QACV,EAAE,EAAE,MAAM,CAAC;QACX,IAAI,EAAE,MAAM,CAAC;QACb,aAAa,EAAE,MAAM,CAAC;QACtB,WAAW,EAAE,MAAM,CAAC;QACpB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG;YAAE,KAAK,EAAE,MAAM,EAAE,CAAC;YAAC,IAAI,EAAE,MAAM,EAAE,CAAA;SAAE,CAAC;QACvE,SAAS,EAAE,OAAO,CAAC;QACnB,SAAS,EAAE,IAAI,CAAC;KACjB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACnB;AAED,qBAAa,aAAa;IAEtB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,QAAQ;gBADR,MAAM,EAAE,aAAa,EACrB,QAAQ,EAAE,yBAAyB;IAGtD;;;OAGG;IACG,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC;CAuCtD;AAED;;;GAGG;AACH,wBAAsB,kBAAkB,CACtC,GAAG,EAAE,aAAa,EAClB,KAAK,EAAE;IACL,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;CAClB,GACA,OAAO,CAAC,IAAI,CAAC,CAaf;AAED,YAAY,EAAE,eAAe,EAAE,CAAC"}
@@ -0,0 +1,67 @@
1
+ // @oktis-works/theme-runtime - Runtime Routing (catch-all SSR + targeted revalidation)
2
+ export class RuntimeRouter {
3
+ lookup;
4
+ resolver;
5
+ constructor(lookup, resolver) {
6
+ this.lookup = lookup;
7
+ this.resolver = resolver;
8
+ }
9
+ /**
10
+ * Resolve um caminho arbitrário (catch-all [...slug]) para um template.
11
+ * Ordem: home → content-type archive → conteúdo por slug.
12
+ */
13
+ async resolve(path) {
14
+ const normalized = path.replace(/^\/+|\/+$/g, '');
15
+ const segments = normalized.split('/').filter(Boolean);
16
+ if (segments.length === 0) {
17
+ const resolved = await this.resolver.resolve({ type: 'page', isHome: true });
18
+ return { matched: true, template: resolved.file };
19
+ }
20
+ const [firstSegmentRaw] = segments;
21
+ const firstSegment = firstSegmentRaw ?? '';
22
+ if (segments.length === 1) {
23
+ // Tenta conteúdo primeiro (slug único), depois arquivo do tipo.
24
+ const content = await this.lookup.findByPath(firstSegment);
25
+ if (content) {
26
+ const resolved = await this.resolver.resolve({ type: content.type, slug: content.slug, layoutOverride: content.layout ?? undefined });
27
+ return { matched: true, template: resolved.file, contentType: content.type, slug: content.slug };
28
+ }
29
+ const types = await this.lookup.listTypes();
30
+ const matchingType = types.find((type) => type.slug === firstSegment && type.hasArchive);
31
+ if (matchingType) {
32
+ const resolved = await this.resolver.resolve({ type: matchingType.slug, isArchive: true });
33
+ return { matched: true, template: resolved.file, contentType: matchingType.slug };
34
+ }
35
+ }
36
+ else {
37
+ // URL aninhada: /{tipo}/{slug} — o primeiro segmento deve casar com o tipo.
38
+ const typeSegment = segments[0] ?? '';
39
+ const slug = segments[segments.length - 1] ?? '';
40
+ const content = await this.lookup.findByPath(slug);
41
+ if (content && content.type === typeSegment) {
42
+ const resolved = await this.resolver.resolve({ type: content.type, slug: content.slug, layoutOverride: content.layout ?? undefined });
43
+ return { matched: true, template: resolved.file, contentType: content.type, slug: content.slug };
44
+ }
45
+ }
46
+ return { matched: false };
47
+ }
48
+ }
49
+ /**
50
+ * Revalidação direcionada: publica um evento que os workers do app web
51
+ * consomem para invalidar apenas as rotas afetadas pelo conteúdo alterado.
52
+ */
53
+ export async function targetedRevalidate(bus, input) {
54
+ await bus.emit({
55
+ id: crypto.randomUUID(),
56
+ type: 'theme.route.revalidate',
57
+ aggregateType: 'route',
58
+ aggregateId: input.tenantId,
59
+ payload: {
60
+ paths: input.paths,
61
+ tags: input.tags,
62
+ },
63
+ processed: false,
64
+ createdAt: new Date(),
65
+ });
66
+ }
67
+ //# sourceMappingURL=routing.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"routing.js","sourceRoot":"","sources":["../src/routing.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,45 @@
1
+ import type { ThemeManifest } from '@oktis-works/theme-sdk';
2
+ import type { StyleEngine } from '@oktis-works/theme-sdk';
3
+ export type ThemeStyleReport = {
4
+ engine: StyleEngine;
5
+ entry: string | null;
6
+ output: string;
7
+ isolated: boolean;
8
+ warnings: string[];
9
+ errors: string[];
10
+ };
11
+ export interface StyleEngineOptions {
12
+ themesRoot: string;
13
+ themeName: string;
14
+ manifest: ThemeManifest;
15
+ }
16
+ export declare function resolveStyleEngine(opts: StyleEngineOptions): ThemeStyleReport & {
17
+ themePath: string;
18
+ };
19
+ /**
20
+ * Escopa CSS sob [data-theme="name"] — isolamento fino BUSI-040.
21
+ * Evita leaking para admin e entre temas.
22
+ * Exclui @keyframes, @font-face, :root, html, body -> prefixa com o atributo no seletor quando possível.
23
+ */
24
+ export declare function scopeCss(css: string, themeName: string, prefix?: string): string;
25
+ /** Compila SCSS para CSS (usa sass se disponível, fallback erro amigável). */
26
+ export declare function compileScss(entryAbs: string): Promise<string>;
27
+ /** Compila Tailwind: lê input.css, aplica tailwindcss via postcss se disponível. Fallback: retorna input + escopo. */
28
+ export declare function compileTailwind(entryAbs: string, themePath: string): Promise<string>;
29
+ /**
30
+ * Pipeline completo: detecta engine, compila e escopa.
31
+ * Retorna css final isolado pronto para escrita em dist/theme.css
32
+ */
33
+ export declare function buildThemeStyles(opts: StyleEngineOptions): Promise<{
34
+ css: string;
35
+ report: ThemeStyleReport & {
36
+ themePath: string;
37
+ };
38
+ }>;
39
+ /** Valida manifest contra BUSI-039/BUSI-040: retorna erros se ambíguo ou isolamento desativado. */
40
+ export declare function validateStyleManifest(manifest: ThemeManifest, themePath: string): string[];
41
+ export declare function getThemeScopeAttribute(themeName: string): {
42
+ attr: string;
43
+ selector: string;
44
+ };
45
+ //# sourceMappingURL=style-engine.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"style-engine.d.ts","sourceRoot":"","sources":["../src/style-engine.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAC5D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAE1D,MAAM,MAAM,gBAAgB,GAAG;IAC7B,MAAM,EAAE,WAAW,CAAC;IACpB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,OAAO,CAAC;IAClB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB,CAAC;AAEF,MAAM,WAAW,kBAAkB;IACjC,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,aAAa,CAAC;CACzB;AAwCD,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,kBAAkB,GAAG,gBAAgB,GAAG;IAAE,SAAS,EAAE,MAAM,CAAA;CAAE,CAkCrG;AAED;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,SAAgC,GAAG,MAAM,CA2EvG;AAED,8EAA8E;AAC9E,wBAAsB,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAmBnE;AAED,sHAAsH;AACtH,wBAAsB,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CA0B1F;AAED;;;GAGG;AACH,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,kBAAkB,GAAG,OAAO,CAAC;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,gBAAgB,GAAG;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,CAAC,CAiC3I;AAED,mGAAmG;AACnG,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,EAAE,CAU1F;AAED,wBAAgB,sBAAsB,CAAC,SAAS,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAE5F"}
@@ -0,0 +1,300 @@
1
+ // @oktis-works/theme-runtime - Theme Style Engine (Tailwind XOR SCSS + Isolamento Fino)
2
+ // BUSI-039 Exclusive Style Engine | BUSI-040 Fine Isolation Scoping | DECI-029
3
+ import { existsSync, readFileSync, readdirSync, statSync } from 'node:fs';
4
+ import { join, resolve } from 'node:path';
5
+ const VALID_ENGINES = ['tailwind', 'scss', 'css'];
6
+ function detectConventionEntry(themePath) {
7
+ const candidates = [
8
+ ['scss', 'styles/main.scss'],
9
+ ['scss', 'style.scss'],
10
+ ['scss', 'src/main.scss'],
11
+ ['scss', 'assets/main.scss'],
12
+ ['tailwind', 'src/input.css'],
13
+ ['tailwind', 'styles/input.css'],
14
+ ['tailwind', 'src/tailwind.css'],
15
+ ['css', 'style.css'],
16
+ ['css', 'styles/main.css'],
17
+ ['css', 'assets/main.css'],
18
+ ];
19
+ for (const [engine, rel] of candidates) {
20
+ if (existsSync(join(themePath, rel)))
21
+ return { engine, entry: rel };
22
+ }
23
+ // heuristic: any .scss => scss, any tailwind.config.* => tailwind
24
+ if (existsSync(join(themePath, 'tailwind.config.js')) || existsSync(join(themePath, 'tailwind.config.cjs')) || existsSync(join(themePath, 'tailwind.config.mjs'))) {
25
+ return { engine: 'tailwind', entry: 'src/input.css' };
26
+ }
27
+ const files = listFilesRecursive(themePath);
28
+ if (files.some((f) => f.endsWith('.scss')))
29
+ return { engine: 'scss', entry: files.find((f) => f.endsWith('.scss')).replace(themePath + '/', '') };
30
+ return null;
31
+ }
32
+ function listFilesRecursive(dir, acc = []) {
33
+ if (!existsSync(dir))
34
+ return acc;
35
+ for (const entry of readdirSync(dir)) {
36
+ const full = join(dir, entry);
37
+ const stat = statSync(full);
38
+ if (stat.isDirectory())
39
+ listFilesRecursive(full, acc);
40
+ else
41
+ acc.push(full);
42
+ }
43
+ return acc;
44
+ }
45
+ export function resolveStyleEngine(opts) {
46
+ const themePath = resolve(opts.themesRoot, opts.themeName);
47
+ const cfg = opts.manifest.stylesConfig ?? {};
48
+ const warnings = [];
49
+ const errors = [];
50
+ let engine = cfg.engine ?? 'css';
51
+ if (!VALID_ENGINES.includes(engine)) {
52
+ warnings.push(`styleEngine "${engine}" inválido, usando css`);
53
+ engine = 'css';
54
+ }
55
+ const convention = detectConventionEntry(themePath);
56
+ // BUSI-039: exclusividade
57
+ const hasTailwindConfig = existsSync(join(themePath, 'tailwind.config.js')) || existsSync(join(themePath, 'tailwind.config.cjs')) || existsSync(join(themePath, 'tailwind.config.mjs'));
58
+ const hasScss = listFilesRecursive(themePath).some((f) => f.endsWith('.scss'));
59
+ if (engine === 'tailwind' && hasScss && !cfg.entry) {
60
+ // se declarou tailwind mas há scss, avisa; se engine scss mas há tailwind config, avisa
61
+ warnings.push('Tema declarado como tailwind mas contém arquivos .scss — use apenas um engine');
62
+ }
63
+ if (engine === 'scss' && hasTailwindConfig) {
64
+ warnings.push('Tema declarado como scss mas contém tailwind.config.* — use apenas um engine');
65
+ }
66
+ if (!cfg.entry && convention && convention.engine !== engine) {
67
+ warnings.push(`Convenção detectada ${convention.engine} mas manifest declara ${engine}; respeitando manifest`);
68
+ }
69
+ // BUSI-040: isolamento obrigatório — sempre true, false é erro
70
+ if (cfg.isolation === false)
71
+ errors.push('stylesConfig.isolation=false proibido — [data-theme="nome"] é obrigatório');
72
+ const entry = cfg.entry ?? convention?.entry ?? null;
73
+ if (entry && entry.includes('..'))
74
+ errors.push('entry com path traversal não permitido');
75
+ const isolated = true;
76
+ const output = cfg.output ?? 'dist/theme.css';
77
+ if (engine !== 'css' && !entry) {
78
+ warnings.push(`Engine ${engine} declarado mas nenhuma entrada encontrada; fallback para css`);
79
+ }
80
+ return { engine, entry, output, isolated, warnings, errors, themePath };
81
+ }
82
+ /**
83
+ * Escopa CSS sob [data-theme="name"] — isolamento fino BUSI-040.
84
+ * Evita leaking para admin e entre temas.
85
+ * Exclui @keyframes, @font-face, :root, html, body -> prefixa com o atributo no seletor quando possível.
86
+ */
87
+ export function scopeCss(css, themeName, prefix = `[data-theme="${themeName}"]`) {
88
+ const isExcludedAtRule = (selector) => {
89
+ const s = selector.trim();
90
+ return s.startsWith('@keyframes') || s.startsWith('@font-face') || s.startsWith('@import');
91
+ };
92
+ const shouldKeepRootAlone = (sel) => /:root|\bhtml\b|\bbody\b/.test(sel);
93
+ let out = '';
94
+ let i = 0;
95
+ const len = css.length;
96
+ while (i < len) {
97
+ // pula whitespace/comments
98
+ if (css[i]?.trim() === '') {
99
+ out += css[i++];
100
+ continue;
101
+ }
102
+ if (css.startsWith('/*', i)) {
103
+ const end = css.indexOf('*/', i + 2);
104
+ const comment = end === -1 ? css.slice(i) : css.slice(i, end + 2);
105
+ out += comment;
106
+ i += comment.length;
107
+ continue;
108
+ }
109
+ // at-rule sem bloco (termina com ;)
110
+ if (css[i] === '@') {
111
+ const semi = css.indexOf(';', i);
112
+ const brace = css.indexOf('{', i);
113
+ // se ; vem antes de { ou não há {, é at-rule sem bloco
114
+ if (semi !== -1 && (brace === -1 || semi < brace)) {
115
+ const atRule = css.slice(i, semi + 1);
116
+ out += atRule;
117
+ i = semi + 1;
118
+ continue;
119
+ }
120
+ }
121
+ const braceIdx = css.indexOf('{', i);
122
+ if (braceIdx === -1) {
123
+ out += css.slice(i);
124
+ break;
125
+ }
126
+ const selectorPart = css.slice(i, braceIdx).trim();
127
+ // encontra } correspondente com aninhamento
128
+ let depth = 0;
129
+ let endIdx = -1;
130
+ for (let k = braceIdx; k < len; k++) {
131
+ if (css[k] === '{')
132
+ depth++;
133
+ else if (css[k] === '}') {
134
+ depth--;
135
+ if (depth === 0) {
136
+ endIdx = k;
137
+ break;
138
+ }
139
+ }
140
+ }
141
+ if (endIdx === -1) {
142
+ out += css.slice(i);
143
+ break;
144
+ }
145
+ const block = css.slice(i, endIdx + 1);
146
+ const bodyStart = braceIdx;
147
+ const body = css.slice(bodyStart, endIdx + 1); // includes { ... }
148
+ if (isExcludedAtRule(selectorPart)) {
149
+ out += block;
150
+ }
151
+ else if (selectorPart.startsWith('@media') || selectorPart.startsWith('@supports') || selectorPart.startsWith('@layer')) {
152
+ const inner = css.slice(braceIdx + 1, endIdx);
153
+ const scopedInner = scopeCss(inner, themeName, prefix);
154
+ out += `${selectorPart} {${scopedInner}}`;
155
+ }
156
+ else if (selectorPart.startsWith('@')) {
157
+ // @tailwind etc já tratado, mas outros @ com bloco
158
+ const inner = css.slice(braceIdx + 1, endIdx);
159
+ out += `${selectorPart} {${inner}}`;
160
+ }
161
+ else {
162
+ const selectors = selectorPart.split(',').map((s) => s.trim()).filter(Boolean);
163
+ const scopedSelectors = selectors.map((sel) => {
164
+ if (sel.startsWith('@'))
165
+ return sel;
166
+ if (sel.includes(prefix))
167
+ return sel;
168
+ if (shouldKeepRootAlone(sel)) {
169
+ if (sel === ':root' || sel === 'html' || sel === 'body')
170
+ return prefix;
171
+ return sel.replace(':root', prefix).replace(/\bhtml\b/, prefix).replace(/\bbody\b/, prefix);
172
+ }
173
+ return `${prefix} ${sel}`;
174
+ });
175
+ out += `${scopedSelectors.join(', ')}${body}`;
176
+ }
177
+ i = endIdx + 1;
178
+ }
179
+ if (!out.trim() && css.trim())
180
+ return `${prefix} { ${css} }`;
181
+ return out || css;
182
+ }
183
+ /** Compila SCSS para CSS (usa sass se disponível, fallback erro amigável). */
184
+ export async function compileScss(entryAbs) {
185
+ try {
186
+ const mod = await import('sass').catch(() => null);
187
+ if (!mod)
188
+ throw new Error('Dependência "sass" não instalada. Instale com bun add -d sass');
189
+ const sass = mod.default ?? mod;
190
+ if (typeof sass.compile === 'function') {
191
+ const res = sass.compile(entryAbs);
192
+ return res.css;
193
+ }
194
+ if (typeof sass.compileAsync === 'function') {
195
+ const res = await sass.compileAsync(entryAbs);
196
+ return res.css;
197
+ }
198
+ // legacy render
199
+ const res = sass.renderSync({ file: entryAbs });
200
+ return res.css.toString();
201
+ }
202
+ catch (e) {
203
+ throw new Error(`Falha ao compilar SCSS ${entryAbs}: ${e.message}`);
204
+ }
205
+ }
206
+ /** Compila Tailwind: lê input.css, aplica tailwindcss via postcss se disponível. Fallback: retorna input + escopo. */
207
+ export async function compileTailwind(entryAbs, themePath) {
208
+ const raw = readFileSync(entryAbs, 'utf-8');
209
+ try {
210
+ const postcssMod = await import('postcss').catch(() => null);
211
+ const tailwindMod = await import('tailwindcss').catch(() => null);
212
+ const autoprefixMod = await import('autoprefixer').catch(() => null);
213
+ if (!postcssMod || !tailwindMod) {
214
+ // sem tailwind instalado, retorna raw (dev pode instalar)
215
+ return raw;
216
+ }
217
+ const postcss = postcssMod.default ?? postcssMod;
218
+ const tailwindcss = tailwindMod.default ?? tailwindMod;
219
+ const tailwindConfigPath = [join(themePath, 'tailwind.config.js'), join(themePath, 'tailwind.config.cjs'), join(themePath, 'tailwind.config.mjs')].find((p) => existsSync(p)) ?? null;
220
+ let tailwindConfig = {
221
+ content: [join(themePath, 'templates/**/*.{astro,html,js,ts}'), join(themePath, 'src/**/*.{astro,html,js,ts}'), join(themePath, 'components/**/*.{astro,html,js,ts}')],
222
+ corePlugins: { preflight: false },
223
+ };
224
+ if (tailwindConfigPath)
225
+ tailwindConfig = tailwindConfigPath;
226
+ const plugins = [tailwindcss(tailwindConfig)];
227
+ if (autoprefixMod)
228
+ plugins.push((autoprefixMod.default ?? autoprefixMod)());
229
+ const result = await postcss(plugins).process(raw, { from: entryAbs });
230
+ return result.css;
231
+ }
232
+ catch (e) {
233
+ throw new Error(`Falha ao compilar Tailwind ${entryAbs}: ${e.message}`);
234
+ }
235
+ }
236
+ /**
237
+ * Pipeline completo: detecta engine, compila e escopa.
238
+ * Retorna css final isolado pronto para escrita em dist/theme.css
239
+ */
240
+ export async function buildThemeStyles(opts) {
241
+ const report = resolveStyleEngine(opts);
242
+ if (report.errors.length)
243
+ throw new Error(report.errors.join('; '));
244
+ if (!report.entry)
245
+ return { css: '', report };
246
+ const entryAbs = join(report.themePath, report.entry);
247
+ if (!existsSync(entryAbs))
248
+ return { css: '', report };
249
+ let css = '';
250
+ if (report.engine === 'scss') {
251
+ css = await compileScss(entryAbs);
252
+ }
253
+ else if (report.engine === 'tailwind') {
254
+ css = await compileTailwind(entryAbs, report.themePath);
255
+ }
256
+ else {
257
+ css = readFileSync(entryAbs, 'utf-8');
258
+ }
259
+ // autoprefixer genérico se não tailwind
260
+ if (report.engine !== 'tailwind') {
261
+ try {
262
+ const postcssMod = await import('postcss').catch(() => null);
263
+ const autoprefixMod = await import('autoprefixer').catch(() => null);
264
+ if (postcssMod && autoprefixMod) {
265
+ const postcss = postcssMod.default ?? postcssMod;
266
+ const autoprefixer = autoprefixMod.default ?? autoprefixMod;
267
+ const result = await postcss([autoprefixer()]).process(css, { from: entryAbs });
268
+ css = result.css;
269
+ }
270
+ }
271
+ catch (e) {
272
+ // Silently skip autoprefixer if not available, but log for debugging
273
+ if (process.env['DEBUG'])
274
+ console.warn(`Autoprefixer skipped: ${e.message}`);
275
+ }
276
+ }
277
+ // isolamento obrigatório — sempre escopa
278
+ css = scopeCss(css, opts.manifest.name);
279
+ return { css, report };
280
+ }
281
+ /** Valida manifest contra BUSI-039/BUSI-040: retorna erros se ambíguo ou isolamento desativado. */
282
+ export function validateStyleManifest(manifest, themePath) {
283
+ const errors = [];
284
+ const engine = manifest.stylesConfig?.engine;
285
+ if (engine && !VALID_ENGINES.includes(engine))
286
+ errors.push(`stylesConfig.engine inválido: ${engine}`);
287
+ if (manifest.stylesConfig?.isolation === false)
288
+ errors.push('stylesConfig.isolation=false proibido — [data-theme="nome"] é obrigatório (BUSI-040)');
289
+ const hasTailwind = existsSync(join(themePath, 'tailwind.config.js')) || existsSync(join(themePath, 'tailwind.config.cjs'));
290
+ const hasScss = listFilesRecursive(themePath).some((f) => f.endsWith('.scss'));
291
+ if (hasTailwind && hasScss)
292
+ errors.push('Tema contém ambos tailwind.config e .scss — escolha apenas um engine (tailwind XOR scss)');
293
+ if (manifest.stylesConfig?.entry?.includes('..'))
294
+ errors.push('stylesConfig.entry com path traversal');
295
+ return errors;
296
+ }
297
+ export function getThemeScopeAttribute(themeName) {
298
+ return { attr: `data-theme="${themeName}"`, selector: `[data-theme="${themeName}"]` };
299
+ }
300
+ //# sourceMappingURL=style-engine.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"style-engine.js","sourceRoot":"","sources":["../src/style-engine.ts"],"names":[],"mappings":"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"}