upcontent 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.
Files changed (86) hide show
  1. package/.github/workflows/ci.yml +61 -0
  2. package/.github/workflows/deploy.yml +59 -0
  3. package/.github/workflows/publish.yml +75 -0
  4. package/.github/workflows/reusable-pages.yml +74 -0
  5. package/.upcontent/config.json +85 -0
  6. package/.upcontent/favicon.svg +4 -0
  7. package/.upcontent/logo.svg +6 -0
  8. package/.upcontent/portal.css +139 -0
  9. package/CONTEXT.md +25 -0
  10. package/Makefile +33 -0
  11. package/README.md +132 -2
  12. package/SHOWCASE.mdx +163 -0
  13. package/assets/readme/portal-home.png +0 -0
  14. package/assets/readme/portal-showcase.png +0 -0
  15. package/astro.config.mjs +167 -0
  16. package/customization/config-json.md +100 -0
  17. package/customization/content.md +62 -0
  18. package/customization/environment.md +43 -0
  19. package/customization/index.md +33 -0
  20. package/customization/navigation.md +57 -0
  21. package/customization/site-identity.md +43 -0
  22. package/customization/theme.md +47 -0
  23. package/deployment/github-pages.md +46 -0
  24. package/deployment/index.md +25 -0
  25. package/deployment/npm.md +39 -0
  26. package/deployment/static-hosts.md +34 -0
  27. package/getting-started/consumer-repository.md +156 -0
  28. package/getting-started/first-build.md +78 -0
  29. package/guides/authoring-content.md +105 -0
  30. package/guides/validate-your-site.md +58 -0
  31. package/package.json +40 -4
  32. package/scripts/upcontent-cli.mjs +111 -0
  33. package/scripts/verify-external-build.mjs +32 -0
  34. package/scripts/verify-golden-build.mjs +9 -0
  35. package/src/components/MermaidLoader.astro +304 -0
  36. package/src/components/PaletteShowcase.astro +122 -0
  37. package/src/components/StructuredDataCopy.astro +22 -0
  38. package/src/content/__mocks__/astro-content.ts +7 -0
  39. package/src/content/__mocks__/astro-loaders.ts +3 -0
  40. package/src/content/i18n/en.json +1 -0
  41. package/src/content.config.test.ts +209 -0
  42. package/src/content.config.ts +113 -0
  43. package/src/lib/content-blocklist.test.ts +47 -0
  44. package/src/lib/content-blocklist.ts +55 -0
  45. package/src/lib/doc-links.test.ts +62 -0
  46. package/src/lib/doc-links.ts +31 -0
  47. package/src/lib/mermaid-render.test.ts +42 -0
  48. package/src/lib/mermaid-render.ts +24 -0
  49. package/src/lib/portal-config.test.ts +153 -0
  50. package/src/lib/portal-config.ts +187 -0
  51. package/src/lib/portal-routes.test.ts +62 -0
  52. package/src/lib/portal-routes.ts +59 -0
  53. package/src/lib/product-identity.ts +2 -0
  54. package/src/lib/rehype-callouts.test.ts +69 -0
  55. package/src/lib/rehype-callouts.ts +61 -0
  56. package/src/lib/remark-doc-links.test.ts +50 -0
  57. package/src/lib/remark-doc-links.ts +21 -0
  58. package/src/lib/remark-strip-duplicate-title.test.ts +73 -0
  59. package/src/lib/remark-strip-duplicate-title.ts +37 -0
  60. package/src/lib/remark-structured-data-preview.test.ts +104 -0
  61. package/src/lib/remark-structured-data-preview.ts +66 -0
  62. package/src/lib/remark-wiki-links.test.ts +102 -0
  63. package/src/lib/remark-wiki-links.ts +112 -0
  64. package/src/lib/seo-sitemap.test.ts +37 -0
  65. package/src/lib/seo-sitemap.ts +54 -0
  66. package/src/lib/sidebar.test.ts +142 -0
  67. package/src/lib/sidebar.ts +114 -0
  68. package/src/lib/structured-data-tree.test.ts +75 -0
  69. package/src/lib/structured-data-tree.ts +55 -0
  70. package/src/overrides/Footer.astro +114 -0
  71. package/src/overrides/Head.astro +103 -0
  72. package/src/pages/robots.txt.ts +46 -0
  73. package/src/styles/callouts.css +29 -0
  74. package/src/styles/structured-data-preview.css +95 -0
  75. package/src/upcontent-cli.test.ts +36 -0
  76. package/test-fixtures/external-consumer/.upcontent/config.json +30 -0
  77. package/test-fixtures/external-consumer/.upcontent/favicon.svg +4 -0
  78. package/test-fixtures/external-consumer/.upcontent/logo.svg +4 -0
  79. package/test-fixtures/external-consumer/.upcontent/theme.css +4 -0
  80. package/test-fixtures/external-consumer/.upcontent-renderer/README.md +3 -0
  81. package/test-fixtures/external-consumer/README.md +6 -0
  82. package/test-fixtures/external-consumer/forbidden.md +5 -0
  83. package/test-fixtures/external-consumer/noindex.md +7 -0
  84. package/test-fixtures/external-consumer/public.md +6 -0
  85. package/tsconfig.json +7 -0
  86. package/vitest.config.ts +18 -0
@@ -0,0 +1,29 @@
1
+ .callout {
2
+ margin: 1rem 0;
3
+ padding: 0.85rem 1rem;
4
+ border-inline-start: 0.25rem solid var(--sl-color-accent);
5
+ border-radius: 0.25rem;
6
+ background: var(--sl-color-gray-6);
7
+ }
8
+
9
+ .callout-title {
10
+ display: flex;
11
+ gap: 0.4rem;
12
+ align-items: center;
13
+ margin-bottom: 0.35rem;
14
+ color: var(--sl-color-text-accent);
15
+ font-weight: 650;
16
+ }
17
+
18
+ .callout > :last-child {
19
+ margin-bottom: 0;
20
+ }
21
+
22
+ .callout-warning,
23
+ .callout-caution {
24
+ border-inline-start-color: var(--sl-color-orange, #d97706);
25
+ }
26
+
27
+ .callout-danger {
28
+ border-inline-start-color: var(--sl-color-red, #dc2626);
29
+ }
@@ -0,0 +1,95 @@
1
+ /* Tree view estática de blocos ```json/```yaml (ver ADR-0007) — usa os
2
+ tokens de cor do próprio Starlight, sem depender de tokens.css (não
3
+ conectado ao tema desde a migração). */
4
+ .sdp-root {
5
+ font-family: var(--__sl-font-mono, ui-monospace, monospace);
6
+ font-size: var(--sl-text-sm);
7
+ border: 1px solid var(--sl-color-gray-5);
8
+ border-radius: 0.5rem;
9
+ padding: 0.75rem 1rem;
10
+ background: var(--sl-color-gray-6);
11
+ overflow-x: auto;
12
+ }
13
+
14
+ .sdp-toolbar {
15
+ display: flex;
16
+ justify-content: flex-end;
17
+ margin-block-end: 0.5rem;
18
+ }
19
+
20
+ .sdp-copy {
21
+ color: var(--sl-color-gray-2);
22
+ background: transparent;
23
+ border: 1px solid var(--sl-color-gray-5);
24
+ border-radius: 0.25rem;
25
+ padding: 0.2rem 0.5rem;
26
+ font: inherit;
27
+ font-size: var(--sl-text-xs);
28
+ cursor: pointer;
29
+ }
30
+
31
+ .sdp-copy:hover,
32
+ .sdp-copy:focus-visible {
33
+ color: var(--sl-color-white);
34
+ border-color: var(--sl-color-accent);
35
+ }
36
+
37
+ .sdp-node {
38
+ margin: 0;
39
+ }
40
+ .sdp-node > summary {
41
+ cursor: pointer;
42
+ color: var(--sl-color-gray-3);
43
+ user-select: none;
44
+ }
45
+ .sdp-node > summary:hover {
46
+ color: var(--sl-color-white);
47
+ }
48
+
49
+ .sdp-children {
50
+ margin-inline-start: 1.25rem;
51
+ border-inline-start: 1px solid var(--sl-color-gray-5);
52
+ padding-inline-start: 0.75rem;
53
+ }
54
+
55
+ .sdp-entry {
56
+ white-space: nowrap;
57
+ }
58
+
59
+ .sdp-key {
60
+ color: var(--sl-color-accent-high, var(--sl-color-accent));
61
+ }
62
+ .sdp-colon {
63
+ color: var(--sl-color-gray-3);
64
+ margin-inline-end: 0.25rem;
65
+ }
66
+ .sdp-string {
67
+ color: var(--sl-color-green-high);
68
+ }
69
+ .sdp-number {
70
+ color: var(--sl-color-orange, #e6a13d);
71
+ }
72
+ .sdp-boolean {
73
+ color: var(--sl-color-purple, #b58cf2);
74
+ }
75
+ .sdp-null {
76
+ color: var(--sl-color-gray-3);
77
+ font-style: italic;
78
+ }
79
+
80
+ .sdp-csv-table {
81
+ font-size: var(--sl-text-sm);
82
+ border-collapse: collapse;
83
+ width: 100%;
84
+ overflow-x: auto;
85
+ }
86
+ .sdp-csv-table th,
87
+ .sdp-csv-table td {
88
+ border: 1px solid var(--sl-color-gray-5);
89
+ padding: 0.4rem 0.75rem;
90
+ text-align: left;
91
+ }
92
+ .sdp-csv-table th {
93
+ background: var(--sl-color-gray-6);
94
+ color: var(--sl-color-gray-2);
95
+ }
@@ -0,0 +1,36 @@
1
+ import { mkdtempSync, readFileSync, rmSync } from 'node:fs'
2
+ import { tmpdir } from 'node:os'
3
+ import { join } from 'node:path'
4
+ import { spawnSync } from 'node:child_process'
5
+ import { fileURLToPath } from 'node:url'
6
+ import { describe, expect, it } from 'vitest'
7
+ import yaml from 'js-yaml'
8
+
9
+ const cliPath = fileURLToPath(new URL('../scripts/upcontent-cli.mjs', import.meta.url))
10
+
11
+ describe('upcontent init', () => {
12
+ it('generates a valid GitHub Actions workflow', () => {
13
+ const root = mkdtempSync(join(tmpdir(), 'upcontent-cli-'))
14
+
15
+ try {
16
+ const result = spawnSync(process.execPath, [cliPath, 'init'], { cwd: root, encoding: 'utf8' })
17
+ expect(result.status).toBe(0)
18
+
19
+ const workflow = readFileSync(join(root, '.github/workflows/deploy-docs.yml'), 'utf8')
20
+ expect(yaml.load(workflow)).toMatchObject({
21
+ jobs: {
22
+ publish: {
23
+ uses: 'lumamontes/upcontent/.github/workflows/reusable-pages.yml@main',
24
+ permissions: {
25
+ contents: 'read',
26
+ pages: 'write',
27
+ 'id-token': 'write',
28
+ },
29
+ },
30
+ },
31
+ })
32
+ } finally {
33
+ rmSync(root, { recursive: true, force: true })
34
+ }
35
+ })
36
+ })
@@ -0,0 +1,30 @@
1
+ {
2
+ "site": {
3
+ "title": "External Consumer",
4
+ "description": "A fixture proving consumer-owned configuration.",
5
+ "url": "https://docs.example.com",
6
+ "logo": {
7
+ "src": ".upcontent/logo.svg",
8
+ "alt": "External Consumer"
9
+ },
10
+ "favicon": ".upcontent/favicon.svg"
11
+ },
12
+ "seo": {
13
+ "enabled": true
14
+ },
15
+ "repo": {
16
+ "url": "https://github.com/example/external-consumer"
17
+ },
18
+ "theme": {
19
+ "customCss": [".upcontent/theme.css"]
20
+ },
21
+ "content": {
22
+ "titleField": "heading"
23
+ },
24
+ "navigation": {
25
+ "roots": ["README.md"],
26
+ "blocklist": {
27
+ "exact": ["forbidden.md"]
28
+ }
29
+ }
30
+ }
@@ -0,0 +1,4 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64">
2
+ <rect width="64" height="64" rx="14" fill="#0f766e"/>
3
+ <path d="M18 20h28v8H18zm0 16h21v8H18z" fill="#fff"/>
4
+ </svg>
@@ -0,0 +1,4 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 72 72">
2
+ <rect width="56" height="56" x="8" y="8" rx="16" fill="#0f766e"/>
3
+ <path d="M20 24h32v8H20zm0 16h24v8H20z" fill="#fff"/>
4
+ </svg>
@@ -0,0 +1,4 @@
1
+ :root {
2
+ --sl-color-accent: #0f766e;
3
+ --sl-color-accent-high: #115e59;
4
+ }
@@ -0,0 +1,3 @@
1
+ # Renderer-only content
2
+
3
+ This sentinel must never become a published consumer page.
@@ -0,0 +1,6 @@
1
+ ---
2
+ heading: External Consumer Fixture
3
+ description: A minimal consumer repository used by the Upcontent build contract.
4
+ ---
5
+
6
+ This document proves that content, identity, assets, CSS, and title fields come from an external consumer repository.
@@ -0,0 +1,5 @@
1
+ ---
2
+ heading: This must not be published
3
+ ---
4
+
5
+ The external consumer blocklist should exclude this document.
@@ -0,0 +1,7 @@
1
+ ---
2
+ title: Internal reference
3
+ description: This page should not appear in search results.
4
+ noindex: true
5
+ ---
6
+
7
+ This page is intentionally excluded from the sitemap.
@@ -0,0 +1,6 @@
1
+ ---
2
+ title: Public guide
3
+ description: This page remains discoverable when SEO is enabled.
4
+ ---
5
+
6
+ This page is included in the sitemap.
package/tsconfig.json ADDED
@@ -0,0 +1,7 @@
1
+ {
2
+ "extends": "astro/tsconfigs/strict",
3
+ "compilerOptions": {
4
+ "baseUrl": ".",
5
+ "paths": {}
6
+ }
7
+ }
@@ -0,0 +1,18 @@
1
+ import { defineConfig } from 'vitest/config'
2
+ import { fileURLToPath } from 'url'
3
+ import { resolve } from 'path'
4
+
5
+ const __dirname = fileURLToPath(new URL('.', import.meta.url))
6
+
7
+ export default defineConfig({
8
+ resolve: {
9
+ alias: {
10
+ 'astro:content': resolve(__dirname, 'src/content/__mocks__/astro-content.ts'),
11
+ 'astro/loaders': resolve(__dirname, 'src/content/__mocks__/astro-loaders.ts'),
12
+ },
13
+ },
14
+ test: {
15
+ include: ['src/**/*.test.ts'],
16
+ exclude: ['src/content/docs/**'],
17
+ },
18
+ })