├── .editorconfig
├── .eslintignore
├── .eslintrc.cjs
├── .github
└── workflows
│ ├── deploy-docs.yml
│ └── release.yml
├── .gitignore
├── .npmrc
├── .nvmrc
├── .prettierignore
├── .prettierrc.cjs
├── .vscode
├── extensions.json
└── settings.json
├── LICENSE
├── README.md
├── demo
├── .npmrc
├── .nvmrc
├── .vscode
│ ├── extensions.json
│ └── settings.json
├── astro.config.mjs
├── package.json
├── src
│ ├── layouts
│ │ └── Bare.astro
│ └── pages
│ │ └── index.astro
└── tsconfig.json
├── docs
├── .npmrc
├── .remarkrc.mjs
├── .vscode
│ └── settings.json
├── astro.config.ts
├── content
│ ├── @dummy
│ │ ├── @storybooks
│ │ │ ├── @astro-components
│ │ │ │ ├── kitchen-sink.mdx
│ │ │ │ └── styles.module.scss
│ │ │ ├── advanced-widgets
│ │ │ │ ├── demo.cast
│ │ │ │ ├── kitchen-sink.mdx
│ │ │ │ └── testbeds.mdx
│ │ │ ├── family.schema.yaml
│ │ │ ├── form
│ │ │ │ ├── bulma.mdx
│ │ │ │ └── input.mdx
│ │ │ ├── media
│ │ │ │ └── image.mdx
│ │ │ └── web-garden
│ │ │ │ └── _kitchen-sink.mdx
│ │ ├── creative-works
│ │ │ ├── creative-work.schema.yaml
│ │ │ └── gute-nachte
│ │ │ │ ├── body.md
│ │ │ │ ├── footnotes.md
│ │ │ │ ├── gallery.yaml
│ │ │ │ └── meta.yaml
│ │ ├── inbox
│ │ │ ├── @todos
│ │ │ │ ├── business.md
│ │ │ │ ├── commerce.md
│ │ │ │ └── personal.md
│ │ │ ├── draft.schema.yaml
│ │ │ └── ideas
│ │ │ │ ├── art.md
│ │ │ │ ├── dev.md
│ │ │ │ └── life.md
│ │ ├── invoices
│ │ │ ├── acme-website
│ │ │ │ ├── contract.md
│ │ │ │ ├── footnotes.md
│ │ │ │ ├── informations.yaml
│ │ │ │ └── test.jsonc
│ │ │ ├── amd-portal
│ │ │ │ ├── contract.md
│ │ │ │ ├── footnotes.md
│ │ │ │ └── informations.yaml
│ │ │ ├── food-corp-website
│ │ │ │ ├── contract.md
│ │ │ │ ├── footnotes.md
│ │ │ │ └── informations.yaml
│ │ │ ├── invoice.schema.yaml
│ │ │ └── soap-shop-popup
│ │ │ │ ├── contract.md
│ │ │ │ └── informations.yaml
│ │ └── people
│ │ │ ├── clementine-kramer
│ │ │ ├── informations.yaml
│ │ │ └── notes.md
│ │ │ ├── karly-cain
│ │ │ ├── informations.yaml
│ │ │ └── notes.md
│ │ │ └── person.schema.yaml
│ ├── default.schema.yaml
│ ├── docs
│ │ ├── cli
│ │ │ └── no_main.md
│ │ ├── development
│ │ │ └── main.md
│ │ ├── doc-section.schema.yaml
│ │ ├── ide
│ │ │ └── no_main.md
│ │ ├── import
│ │ │ └── main.md
│ │ ├── install
│ │ │ └── main.md
│ │ ├── intro
│ │ │ └── main.md
│ │ ├── modeling
│ │ │ └── main.mdx
│ │ ├── more
│ │ │ └── main.md
│ │ ├── recipes
│ │ │ └── main.mdx
│ │ ├── reports
│ │ │ └── main.md
│ │ ├── tips
│ │ │ └── no_main.md
│ │ └── work-in-progress
│ │ │ └── main.md
│ ├── globals
│ │ ├── global.schema.yaml
│ │ └── website
│ │ │ └── menu.yaml
│ ├── modules
│ │ ├── cli-or-gui
│ │ │ └── text.md
│ │ ├── content-structure
│ │ │ └── text.mdx
│ │ ├── credits
│ │ │ └── text.md
│ │ ├── features
│ │ │ └── text.mdx
│ │ ├── landing
│ │ │ ├── gallery.yaml
│ │ │ ├── install.md
│ │ │ ├── relations.md
│ │ │ └── text.md
│ │ └── module.schema.yaml
│ └── pages
│ │ ├── home
│ │ └── main.mdx
│ │ └── page.schema.yaml
├── env.d.ts
├── package.json
├── public
│ ├── favicon.svg
│ └── poster.png
├── src
│ ├── app
│ │ ├── Footer.astro
│ │ ├── Footer.scss
│ │ ├── LazyLoading.astro
│ │ ├── NavigationBar.astro
│ │ └── NavigationBar.scss
│ ├── assets
│ │ ├── arrow-1.svg
│ │ ├── arrow-2.svg
│ │ ├── arrow-3.svg
│ │ ├── astro-content-logo-bg.svg
│ │ ├── astro-content-logo.svg
│ │ ├── atlantis-1-gui-overlay.svg
│ │ ├── atlantis-mask-bare.svg
│ │ ├── atlantis-mask.svg
│ │ ├── brain-circuit-20-filled.svg
│ │ ├── create-entity.cast
│ │ ├── discord.svg
│ │ ├── features.svg
│ │ ├── game-controller-sharp.svg
│ │ ├── github.svg
│ │ ├── installation.cast
│ │ ├── logos
│ │ │ ├── astro-logomark-dark.svg
│ │ │ ├── jsonschema.svg
│ │ │ ├── mdx-logo.svg
│ │ │ ├── mdx.svg
│ │ │ ├── ts-logo-round.svg
│ │ │ ├── unified.svg
│ │ │ ├── vite.svg
│ │ │ └── yaml.svg
│ │ ├── separator.svg
│ │ ├── shape-1.svg
│ │ ├── terminal.svg
│ │ └── topography.svg
│ ├── components-demo
│ │ ├── BulmaForm.astro
│ │ ├── Button.tsx
│ │ ├── Crab.astro
│ │ ├── ThreeJuggler.module.scss
│ │ └── ThreeJuggler.tsx
│ ├── components
│ │ ├── CodeEmbed.astro
│ │ ├── CodeEmbed.scss
│ │ ├── PrevNextNavigation.astro
│ │ ├── TreeNavigation.astro
│ │ ├── TreeNavigation.scss
│ │ └── VimeoPlayer.astro
│ ├── layouts
│ │ ├── Bare.astro
│ │ ├── Default.astro
│ │ ├── Default.scss
│ │ ├── scrollbars.scss
│ │ └── typography.scss
│ ├── modules
│ │ ├── Actions.astro
│ │ ├── Actions.scss
│ │ ├── Demo.astro
│ │ ├── DocPage.astro
│ │ ├── DocPage.scss
│ │ ├── IdeDemo.astro
│ │ ├── Landing.astro
│ │ ├── Landing.scss
│ │ ├── Presentation.astro
│ │ └── Presentation.scss
│ ├── pages
│ │ ├── docs
│ │ │ └── [page].astro
│ │ ├── index.astro
│ │ └── licenses.astro
│ └── vars.scss
└── tsconfig.json
├── markdown-magic.cts
├── package.json
├── packages
├── cli
│ ├── help.ts
│ ├── index.ts
│ ├── package.json
│ └── tsconfig.json
├── dynamic-store
│ ├── file-loader.ts
│ ├── get-content.ts
│ ├── get-file.ts
│ ├── index.ts
│ ├── package.json
│ ├── tsconfig.json
│ ├── types.ts
│ ├── utils.ts
│ └── watcher.ts
├── faker
│ ├── README.md
│ ├── cli.ts
│ ├── demo
│ │ ├── .gitignore
│ │ ├── .remarkrc.yaml
│ │ ├── README.md
│ │ ├── astro.config.mjs
│ │ ├── content
│ │ │ └── blog-posts
│ │ │ │ ├── ballet-epoxy-cuckoo.md
│ │ │ │ ├── battery-alley-canal.md
│ │ │ │ ├── combat-bijou-clank.md
│ │ │ │ ├── frigate-emitter-jeans.md
│ │ │ │ ├── hugger-smith-trouble.md
│ │ │ │ ├── movie-massage-atheist.md
│ │ │ │ ├── orient-ukulele-saddle.md
│ │ │ │ └── trust-topsail-dairy.md
│ │ ├── package.json
│ │ ├── pnpm-lock.yaml
│ │ ├── pnpm-workspace.yaml
│ │ ├── src
│ │ │ ├── components
│ │ │ │ └── Card.astro
│ │ │ ├── env.d.ts
│ │ │ ├── layouts
│ │ │ │ └── Layout.astro
│ │ │ ├── mocks
│ │ │ │ └── blog-post.template.md
│ │ │ ├── pages
│ │ │ │ └── index.astro
│ │ │ └── schemas
│ │ │ │ ├── blog-post.schema.yaml
│ │ │ │ └── tags.schema.yaml
│ │ └── tsconfig.json
│ ├── index.ts
│ ├── package.json
│ └── tsconfig.json
├── gui
│ ├── components
│ │ ├── App
│ │ │ ├── App.scss
│ │ │ ├── App.tsx
│ │ │ ├── Gui.tsx
│ │ │ ├── keyboard-shortcuts.ts
│ │ │ └── state-loader.ts
│ │ ├── Assistant.scss
│ │ ├── Assistant.tsx
│ │ ├── CommandPalette.tsx
│ │ ├── CopyInlineCode.scss
│ │ ├── CopyInlineCode.tsx
│ │ ├── DropDownMenu.tsx
│ │ ├── Editor
│ │ │ ├── Editor.scss
│ │ │ ├── Editor.tsx
│ │ │ ├── handlers.ts
│ │ │ ├── mdx-language.ts
│ │ │ └── validation.ts
│ │ ├── EntriesTable.scss
│ │ ├── EntriesTable.tsx
│ │ ├── File.tsx
│ │ ├── Headings.scss
│ │ ├── Headings.tsx
│ │ ├── Inspector.scss
│ │ ├── Inspector.tsx
│ │ ├── Metas.tsx
│ │ ├── Modal.tsx
│ │ ├── ModalPopover.tsx
│ │ ├── ProblemPanes.tsx
│ │ ├── TabBar.scss
│ │ ├── TabBar.tsx
│ │ ├── Toolbar.scss
│ │ ├── Toolbar.tsx
│ │ ├── Tooltip.tsx
│ │ └── Tree
│ │ │ ├── Entity.tsx
│ │ │ ├── MiniReport.tsx
│ │ │ ├── Property.tsx
│ │ │ ├── Tree.scss
│ │ │ └── Tree.tsx
│ ├── layouts
│ │ ├── Base.astro
│ │ ├── Default.astro
│ │ ├── Default.scss
│ │ ├── Preview.astro
│ │ ├── Preview.scss
│ │ ├── diagrams.scss
│ │ ├── scrollbars.scss
│ │ └── themes
│ │ │ ├── cobalt2.json
│ │ │ ├── cobalt2.scss
│ │ │ ├── dracula.json
│ │ │ ├── dracula.scss
│ │ │ ├── oceanic-next.json
│ │ │ ├── oceanic-next.scss
│ │ │ └── vs-dark.scss
│ ├── logger.ts
│ ├── package.json
│ ├── preview-markdown.astro
│ ├── ssr-entrypoint.astro
│ ├── store
│ │ ├── data.ts
│ │ ├── editor.ts
│ │ ├── helpers.ts
│ │ ├── index.ts
│ │ └── ui.ts
│ └── styles.scss
├── html2png
│ ├── .gitignore
│ ├── demo
│ │ ├── .gitignore
│ │ ├── README.md
│ │ ├── astro.config.mjs
│ │ ├── package.json
│ │ ├── public
│ │ │ └── favicon.svg
│ │ ├── src
│ │ │ ├── Layout.astro
│ │ │ ├── env.d.ts
│ │ │ └── pages
│ │ │ │ ├── index.astro
│ │ │ │ └── open-graph
│ │ │ │ └── [...route].ts
│ │ └── tsconfig.json
│ ├── html2png.ts
│ ├── index.ts
│ ├── package.json
│ └── tsconfig.json
├── imagekit
│ ├── Image.Props.ts
│ ├── Image.astro
│ ├── Image.client.ts
│ ├── Image.css
│ ├── LICENSE
│ ├── README.md
│ ├── base64.ts
│ ├── cli.ts
│ ├── env.d.ts
│ ├── file-handlers.ts
│ ├── image-instances.ts
│ ├── imagekit-instance.ts
│ ├── index.ts
│ ├── integration.ts
│ ├── logger.ts
│ ├── package.json
│ ├── sync-media-index.ts
│ └── tsconfig.json
├── integration
│ ├── README.md
│ ├── astro-integration.ts
│ ├── build.ts
│ ├── cli-bridge.ts
│ ├── config-setup.ts
│ ├── load-jsonc-plugin.ts
│ ├── load-yaml-plugin.ts
│ ├── package.json
│ ├── server-bridge.json.ts
│ ├── server-setup.ts
│ └── tsconfig.json
├── server
│ ├── .npmignore
│ ├── add.ts
│ ├── collect.ts
│ ├── config.ts
│ ├── core-schema-validation.ts
│ ├── generate-excerpt.ts
│ ├── generate-fake-data.ts
│ ├── generate-types.ts
│ ├── handle-md.ts
│ ├── handle-yaml.ts
│ ├── index.ts
│ ├── load-file.ts
│ ├── logger.ts
│ ├── package.json
│ ├── save-file.ts
│ ├── schemas-to-types.ts
│ ├── schemas
│ │ ├── MarkdownFile.ts
│ │ └── default.schema.yaml
│ ├── setup.ts
│ ├── state.ts
│ ├── tsconfig.json
│ └── utils.ts
├── types
│ ├── dto.ts
│ ├── file.ts
│ ├── gui-state.ts
│ ├── integration.ts
│ ├── logger.ts
│ ├── package.json
│ ├── reports.ts
│ ├── server-state.ts
│ ├── tsconfig.json
│ └── user-config.ts
└── validator
│ ├── README.md
│ ├── cli.ts
│ ├── demo
│ ├── .gitignore
│ ├── .remarkrc.yaml
│ ├── README.md
│ ├── astro.config.mjs
│ ├── content
│ │ └── blog-posts
│ │ │ ├── correct_entry-bar.md
│ │ │ └── wrong_entry-foo.md
│ ├── package.json
│ ├── pnpm-lock.yaml
│ ├── pnpm-workspace.yaml
│ ├── src
│ │ ├── checkers
│ │ │ ├── blog-post.checker.ts
│ │ │ └── tags.checker.ts
│ │ ├── components
│ │ │ └── Card.astro
│ │ ├── env.d.ts
│ │ ├── layouts
│ │ │ └── Layout.astro
│ │ ├── pages
│ │ │ └── index.astro
│ │ └── schemas
│ │ │ ├── blog-post.schema.yaml
│ │ │ └── tags.schema.yaml
│ └── tsconfig.json
│ ├── index.ts
│ ├── integration.ts
│ ├── package.json
│ ├── schema-to-validator.ts
│ ├── tsconfig.json
│ └── validator.ts
├── pnpm-lock.yaml
├── pnpm-workspace.yaml
├── stylelint.config.cjs
├── tsconfig.json
└── turbo.json
/.editorconfig:
--------------------------------------------------------------------------------
1 | # https://EditorConfig.org
2 |
3 | root = true
4 |
5 | [*]
6 | indent_style = space
7 | indent_size = 2
8 | end_of_line = lf
9 | charset = utf-8
10 | trim_trailing_whitespace = false
11 | insert_final_newline = true
12 |
13 | [**/Makefile]
14 | indent_style = tab
15 | indent_size = 4
16 |
17 | [*.md]
18 | trim_trailing_whitespace = false
19 |
--------------------------------------------------------------------------------
/.eslintignore:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JulianCataldo/astro-content/d5ed86fcc9ae27cede28ebcedabaaf39a45ae613/.eslintignore
--------------------------------------------------------------------------------
/.eslintrc.cjs:
--------------------------------------------------------------------------------
1 | /** @type {import("@types/eslint").Linter.Config} */
2 |
3 | module.exports = {
4 | // Prevent cascading
5 | // root: true,
6 |
7 | /**
8 | * Reference:
9 | *
10 | * https://github.com/JulianCataldo/web-garden/blob/develop/configs/eslint-all.cjs
11 | *
12 | * */
13 | extends: ['./node_modules/webdev-configs/eslint-all.cjs'],
14 | };
15 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Binaries
2 |
3 | # *.png
4 |
5 | .turbo-cookie
6 |
7 | # NOTE: This could be interesting to keep this for CI/CD workflow
8 | pnpm-publish-summary.json
9 |
10 | *.log
11 |
12 |
13 | # Build artefacts + cache
14 | .astro-image
15 | .turbo
16 | dist
17 | .build
18 | .parcel-cache
19 |
20 | # Generated code
21 | **/.astro-content
22 | **/*/content/index.ts
23 |
24 | # Local stuff
25 | .re-integrate
26 | .dev*
27 | *.dev.*
28 | .old*
29 | .vscode/*
30 | .vscode
31 | design
32 | # **/content*
33 |
34 |
35 | ############################################
36 |
37 |
38 | # dependencies
39 | node_modules
40 |
41 | # logs
42 | npm-debug.log*
43 | yarn-debug.log*
44 | yarn-error.log*
45 | pnpm-debug.log*
46 |
47 | # demo/src/content
48 | # demo/content
49 |
50 | # environment variables
51 | .env
52 | .env.production
53 |
54 | # macOS-specific files
55 | .DS_Store
56 |
--------------------------------------------------------------------------------
/.npmrc:
--------------------------------------------------------------------------------
1 | engine-strict=true
2 | shamefully-hoist=true
3 | # auto-install-peers=true
4 |
--------------------------------------------------------------------------------
/.nvmrc:
--------------------------------------------------------------------------------
1 | 17
2 |
--------------------------------------------------------------------------------
/.prettierignore:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JulianCataldo/astro-content/d5ed86fcc9ae27cede28ebcedabaaf39a45ae613/.prettierignore
--------------------------------------------------------------------------------
/.prettierrc.cjs:
--------------------------------------------------------------------------------
1 | /** @type {import("@types/prettier").Options} */
2 |
3 | module.exports = {
4 | /**
5 | * Reference:
6 | *
7 | * https://github.com/JulianCataldo/web-garden/blob/develop/configs/prettier-astro.cjs
8 | *
9 | * */
10 | ...require('webdev-configs/prettier-astro.cjs'),
11 | };
12 |
--------------------------------------------------------------------------------
/.vscode/extensions.json:
--------------------------------------------------------------------------------
1 | {
2 | "recommendations": [
3 | "dbaeumer.vscode-eslint",
4 | "astro-build.astro-vscode",
5 | "stylelint.vscode-stylelint",
6 | "redhat.vscode-yaml",
7 | "unifiedjs.vscode-remark",
8 | "esbenp.prettier-vscode",
9 | "editorconfig.editorconfig",
10 | "mrmlnc.vscode-scss",
11 | "pranaygp.vscode-css-peek",
12 | "aaron-bond.better-comments",
13 | "Gruntfuggly.todo-tree"
14 | ]
15 | }
16 |
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "todo-tree.general.tags": [
3 | "BUG",
4 | "HACK",
5 | "FIXME",
6 | "TODO",
7 | "NOTE",
8 | "IDEA",
9 | "REFACTOR",
10 | "XXX",
11 | "[ ]",
12 | "[x]"
13 | ],
14 | "todo-tree.highlights.defaultHighlight": {
15 | "background": "rgba(0, 0, 0, 0.5)",
16 | "type": "tag-and-comment"
17 | },
18 | "todo-tree.highlights.customHighlight": {
19 | "NOTE": {
20 | "foreground": "cyan"
21 | },
22 | "TODO": {
23 | "foreground": "lightgreen"
24 | },
25 | "FIXME": {
26 | "foreground": "red"
27 | },
28 | "IDEA": {
29 | "foreground": "magenta"
30 | },
31 | "HACK": {
32 | "foreground": "orange"
33 | },
34 | "REFACTOR": {
35 | "foreground": "orange"
36 | }
37 | },
38 |
39 | "markdown.extension.toc.omittedFromToc": {
40 | "README.md": ["# Astro Content"]
41 | },
42 |
43 | // NOTE: UNUSED
44 | "yaml.schemas": {
45 | "http://json-schema.org/draft-07/schema#": ["**/*.schema.yaml"]
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | ISC License
2 |
3 | Copyright (c) 2022 Julian Cataldo — https://www.juliancataldo.com
4 |
5 | Permission to use, copy, modify, and/or distribute this software for any
6 | purpose with or without fee is hereby granted, provided that the above
7 | copyright notice and this permission notice appear in all copies.
8 |
9 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
10 | REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
11 | AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
12 | INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
13 | LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
14 | OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15 | PERFORMANCE OF THIS SOFTWARE.
16 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ./packages/integration/README.md
--------------------------------------------------------------------------------
/demo/.npmrc:
--------------------------------------------------------------------------------
1 | # Engine coercition, so bugs will be easier to track for alpha
2 | engine-strict=true
3 |
4 | # MANDATORY with pnpm
5 | # for all siblings Astro Content packages to be installed
6 | shamefully-hoist=true
7 |
--------------------------------------------------------------------------------
/demo/.nvmrc:
--------------------------------------------------------------------------------
1 | 17
2 |
--------------------------------------------------------------------------------
/demo/.vscode/extensions.json:
--------------------------------------------------------------------------------
1 | {
2 | "recommendations": [
3 | "astro-build.astro-vscode",
4 |
5 | // NOTE: Astro Content will integrate with these
6 | "redhat.vscode-yaml",
7 | "unifiedjs.vscode-remark"
8 | ]
9 | }
10 |
--------------------------------------------------------------------------------
/demo/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "yaml.schemas": {
3 | "http://json-schema.org/draft-07/schema#": ["content/**/*.schema.yaml"]
4 | }
5 | }
6 |
--------------------------------------------------------------------------------
/demo/astro.config.mjs:
--------------------------------------------------------------------------------
1 | import { defineConfig } from 'astro/config';
2 | /* ·········································································· */
3 | import content from 'astro-content';
4 | /* —————————————————————————————————————————————————————————————————————————— */
5 |
6 | // https://astro.build/config
7 | export default defineConfig({
8 | site: 'https://example.com',
9 | server: {
10 | port: 3000,
11 | host: true,
12 | },
13 | integrations: [
14 | content({
15 | // logLevel: "debug",
16 | // gui: true
17 | // previewUrl: '/'
18 | }),
19 | ],
20 | });
21 |
--------------------------------------------------------------------------------
/demo/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@astro-content/demo",
3 | "version": "0.0.0-alpha.8",
4 | "private": true,
5 | "scripts": {
6 | "dev": "astro dev",
7 | "build": "astro build",
8 | "preview": "astro preview",
9 | "reset": "rm -rf node_modules pnpm-lock.yaml .astro-content package-lock.json",
10 | "astro": "astro"
11 | },
12 | "dependencies": {
13 | "astro": "1.4.5",
14 | "astro-content": "0.0.0-alpha.8",
15 | },
16 | "engines": {
17 | "node": ">=17"
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/demo/src/layouts/Bare.astro:
--------------------------------------------------------------------------------
1 | ---
2 | // _
3 | ---
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 | Document
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/demo/src/pages/index.astro:
--------------------------------------------------------------------------------
1 | ---
2 | import { get } from '/content';
3 | /* ·········································································· */
4 | import Layout from '../layouts/Bare.astro';
5 | /* —————————————————————————————————————————————————————————————————————————— */
6 |
7 | // Fetch everything
8 | // const allContent = await get(Astro.glob('/content/**/*.{md,mdx,yaml}'));
9 |
10 | // ✨ Start typing a '.' ——————————————v
11 | // const tryAutoCompletion = allContent;
12 |
13 | // Narrow fetching to some entities, for performance
14 | const content = await get(
15 | Astro.glob('/content/{invoices,people}/**/*.{md,mdx,yaml}'),
16 | );
17 |
18 | // Let's be more specific
19 | const acmeWebsite = content?.invoices?.acmeWebsite;
20 | // Or even
21 | const AcmeWebsiteContractContent =
22 | content?.invoices?.acmeWebsite?.contract?.Content;
23 |
24 | console.log({ content });
25 | ---
26 |
27 |
28 | Hello world
29 |
30 | {acmeWebsite.contract.frontmatter.clientType}
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/demo/tsconfig.json:
--------------------------------------------------------------------------------
1 | // Example: starter tsconfig.json for Astro projects
2 | {
3 | "compilerOptions": {
4 | // Enable top-level await and other modern ESM features.
5 | "target": "ESNext",
6 | "module": "ESNext",
7 | // Enable node-style module resolution, for things like npm package imports.
8 | "moduleResolution": "node",
9 | // Enable JSON imports.
10 | "resolveJsonModule": true,
11 | // Enable stricter transpilation for better output.
12 | "isolatedModules": true,
13 | // Astro will directly run your TypeScript code, no transpilation needed.
14 | "noEmit": true,
15 |
16 | "paths": {
17 | // ——————————————————————————————————————————————————— For Astro Content
18 | // Make TS happy with all absolute paths
19 | // "/*": ["./*"]
20 |
21 | // Or more specifically for your Astro Content base helpers
22 | "/content": ["./content"]
23 | }
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/docs/.npmrc:
--------------------------------------------------------------------------------
1 | engine-strict=true
2 | shamefully-hoist=true
3 | auto-install-peers=true
4 |
--------------------------------------------------------------------------------
/docs/.remarkrc.mjs:
--------------------------------------------------------------------------------
1 | import remarkFrontmatter from 'remark-frontmatter';
2 | import remarkLintFrontmatterSchema from 'remark-lint-frontmatter-schema';
3 | /* —————————————————————————————————————————————————————————————————————————— */
4 |
5 | const remarkConfig = {
6 | plugins: [
7 | remarkFrontmatter,
8 | /* v————— Use it without settings, with local '$schema' associations only */
9 | // rlFmSchema
10 |
11 | /* v————— Or with global schemas associations */
12 | [
13 | remarkLintFrontmatterSchema,
14 | {
15 | schemas: {
16 | /* One schema for many files */
17 | './content/@dummy/creative-works/creative-work.schema.yaml': [
18 | './content/@dummy/creative-works/gute-nachte/body.md',
19 |
20 | /* Support glob patterns ———v */
21 | // './content/creative-work/*.md',
22 | // …
23 | // `./` prefix is optional
24 | // 'content/creative-work/foobiz.md',
25 | // './content/elsewhere/does-not-exist-anymore.md',
26 | ],
27 |
28 | // './content/ghost.schema.yaml': [
29 | // './content/casper.md',
30 | // './content/ether.md',
31 | // ],
32 | },
33 | },
34 | ],
35 | ],
36 | };
37 |
38 | export default remarkConfig;
39 |
--------------------------------------------------------------------------------
/docs/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "yaml.schemas": {
3 | "http://json-schema.org/draft-07/schema#": ["content/**/*.schema.yaml"]
4 | }
5 | }
6 |
--------------------------------------------------------------------------------
/docs/content/@dummy/@storybooks/@astro-components/kitchen-sink.mdx:
--------------------------------------------------------------------------------
1 | import { Icon } from 'astro-icon';
2 | import { Tweet, Vimeo, YouTube } from 'astro-embed';
3 | import styles from './styles.module.scss';
4 |
5 | # Astro — Icon
6 |
7 | [See `astro-icon`](https://github.com/natemoo-re/astro-icon/tree/main/packages/core)
8 |
9 | {/* Automatically fetches and inlines Material Design Icon's "account" SVG */}
10 |
11 |
12 |
13 | {/* Equivalent shorthand */}
14 |
15 | > **Pro tip**: Use [Iconify IntelliSense](https://marketplace.visualstudio.com/items?itemName=antfu.iconify)
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 | # Astro — Embed
25 |
26 | ## Youtube
27 |
28 |
29 |
30 | ## Twitter
31 |
32 |
33 |
34 | ## Vimeo
35 |
36 |
37 |
--------------------------------------------------------------------------------
/docs/content/@dummy/@storybooks/@astro-components/styles.module.scss:
--------------------------------------------------------------------------------
1 | .astro-icon {
2 | max-width: 8rem;
3 | filter: drop-shadow(1px 1px 6px hsla(0, 0%, 30%, 1))
4 | drop-shadow(0px 0px 8px hsla(0, 0%, 10%, 1));
5 | }
6 |
--------------------------------------------------------------------------------
/docs/content/@dummy/@storybooks/advanced-widgets/testbeds.mdx:
--------------------------------------------------------------------------------
1 | import { Testbed } from 'astro-testbed';
2 |
3 | ## Astro component testbed
4 |
5 |
9 |
10 | 🏵 **I'm a default slotted content** 🤹🏻♂️
11 |
12 |
13 |
14 | ## React component testbed — with embedded settings
15 |
16 |
22 |
23 | {/* This renders to the default `` slot. */}
24 |
25 | > **With embedded testbed control schema**
26 |
27 |
28 |
29 | ## Testbed, headless
30 |
31 | Bring your own styles!
32 |
33 |
34 | Click to see the unstyled component
35 |
40 |
41 | oh no
42 |
43 |
44 |
45 |
46 | ## Testbed, with controls settings as props.
47 |
48 |
77 |
78 | 🔖 See [documentation for form generation](https://react-jsonschema-form.readthedocs.io/en/latest/).
79 |
80 |
81 |
82 | Finito…
83 |
--------------------------------------------------------------------------------
/docs/content/@dummy/@storybooks/family.schema.yaml:
--------------------------------------------------------------------------------
1 | properties:
2 | testbeds: {}
3 |
4 | bulma: {}
5 |
6 | input:
7 | properties:
8 | title:
9 | type: string
10 | image:
11 | properties:
12 | title:
13 | type: string
14 |
15 | kitchenSink:
16 | additionalProperties: false
17 | properties:
18 | title:
19 | type: string
20 |
--------------------------------------------------------------------------------
/docs/content/@dummy/@storybooks/form/bulma.mdx:
--------------------------------------------------------------------------------
1 | import BulmaForm from '/src/components-demo/BulmaForm.astro';
2 |
3 | ## Form demo 1
4 |
5 |
6 |
7 | ## Form demo 2
8 |
9 | …
10 |
11 | ## Form demo 3
12 |
13 | …
14 |
--------------------------------------------------------------------------------
/docs/content/@dummy/@storybooks/form/input.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: 911984489119
3 | ---
4 |
5 | Very useful.
6 |
7 | {/* ALT + SHIFT + A = JSX style comments! */}
8 |
9 | # Sound
10 |
11 | Audio settings:
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
28 |
29 |
30 |
31 | # Date
32 |
33 |
34 |
35 |
43 |
44 |
45 | # Monster
46 |
47 | Choose your monster's colors:
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 | # URL
60 |
61 |
62 |
63 |
72 |
73 | ---
74 |
75 | That's all folks!
76 |
--------------------------------------------------------------------------------
/docs/content/@dummy/@storybooks/media/image.mdx:
--------------------------------------------------------------------------------
1 | import { Picture, Image } from '@astrojs/image/components';
2 |
3 | export const pictures = {
4 | landing: 'https://res.cloudinary.com/dzfylx93l/landing_on89qr.png',
5 | takeOff: 'https://res.cloudinary.com/dzfylx93l/astro-takeoff-1_ecdfxf.gif',
6 | };
7 |
8 | # Astro — Image integration
9 |
10 | ## From remote location (Cloudinary)
11 |
12 | ### Picture element
13 |
14 |
23 |
24 | ## Bare **`
`** GIF
25 |
26 | No image transformation whatsoever.
27 |
28 |
29 |
30 | Enjoy your **30fps**.
31 |
--------------------------------------------------------------------------------
/docs/content/@dummy/@storybooks/web-garden/_kitchen-sink.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: 🥞 - Kitchen sink - 🥘
3 |
4 | importance: Very much.
5 | ---
6 |
7 | import { Tabs } from 'astro-tabs';
8 |
9 | # Astro tabs
10 |
11 |
12 | Tab 1
13 | Tab 2
14 | Tab 3
15 |
16 |
Panel 1
17 |
Hello world
18 |
19 |
20 |
Panel 2
21 |

25 |
26 |
27 |
Panel 3
28 |
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/docs/content/@dummy/creative-works/creative-work.schema.yaml:
--------------------------------------------------------------------------------
1 | # NOTE: This will be a test bed for Schema.org vocabularies
2 |
3 | properties:
4 | meta:
5 | properties:
6 | baz:
7 | type: string
8 | foo:
9 | type: string
10 | enum:
11 | - bar
12 | - moz
13 | - das
14 | required:
15 | - foo
16 |
17 | gallery:
18 | properties:
19 | sources:
20 | type: array
21 | items:
22 | type: string
23 | required:
24 | - source
25 |
26 | body:
27 | properties:
28 | title:
29 | description: Entry title
30 | type: string
31 | image:
32 | description: Image path
33 | type: string
34 | category:
35 | type: string
36 | enum:
37 | - Cuisine
38 | - Music
39 | - Video
40 |
41 | required:
42 | - title
43 | - image
44 | - category
45 |
46 | footnotes: {}
47 |
48 | required:
49 | - content
50 | - meta
51 | - gallery
52 | - footnotes
53 |
--------------------------------------------------------------------------------
/docs/content/@dummy/creative-works/gute-nachte/footnotes.md:
--------------------------------------------------------------------------------
1 | # Body dropped feel especially structure
2 |
3 | If we compress the bandwidth, we can get to the ASCII pixel through the multi-byte USB alarm!
4 |
5 | Laborum quaerat assumenda ut eaque aut autem.
6 | Accusamus repudiandae sunt eaque voluptatum vel magnam ea voluptatem est.
7 | Veritatis et nulla officia.
8 | Suscipit reprehenderit quia facilis in.
9 | Veniam tenetur et fugit ullam.
10 | Nihil ad quaerat consectetur ipsam facilis vel autem ea.
11 | Inventore placeat consequatur.
12 | Tempora vero deserunt quo vel mollitia ut ab alias quo.
13 | Sequi et placeat.
14 | Debitis voluptas similique id nesciunt quaerat excepturi quia cumque et.
15 | Non nulla aut sed voluptatem rerum est.
16 | Voluptatem sit sit atque libero.
17 |
18 | ## Use the auxiliary JBOD array, then you can synthesize the cross-platform transmitter!
19 |
20 | - Use the wireless AI array, then you can hack the auxiliary program!
21 | - Use the bluetooth HEX microchip, then you can compress the cross-platform bus!
22 | - The FTP protocol is down, program the mobile bandwidth so we can reboot the HTTP firewall!
23 |
24 | Mutuwacey pi rekuw haduberoc nepucu lor. Buxe reno. Tekoh balak per ro lu. Fabelimo motiqo ridehaj bop ne qohudu rirazicod lanohibab pobonuxipe bobeba. Bimemu pudoh mupa minibo rudeju lirikozu bo gobubege midapuy buciqoqi cipalodit bah nubopo kipi cic rojewesu tahacar mupebederi qam beber yideb xabaqapuka nimicure pic supakivuvu be rilipiruge.…
25 |
--------------------------------------------------------------------------------
/docs/content/@dummy/creative-works/gute-nachte/gallery.yaml:
--------------------------------------------------------------------------------
1 | sources:
2 | - ./feats.png
3 | - ./demo.png
4 | - ./install.png
5 | - [wrong-image.png]
6 |
--------------------------------------------------------------------------------
/docs/content/@dummy/creative-works/gute-nachte/meta.yaml:
--------------------------------------------------------------------------------
1 | foo: das
2 | baz: voluptate adipisicing
3 |
--------------------------------------------------------------------------------
/docs/content/@dummy/inbox/@todos/business.md:
--------------------------------------------------------------------------------
1 | # Opportunity
2 |
3 | ### Fresh
4 |
5 | - Clinton Boyer: Call
6 | - Dillon Bowers: Call
7 | - Whoopi Holland: Call[^peek_this]
8 | - Gay Rivers,
9 |
10 | ### Longing
11 |
12 | - Simone Blackburn, auctor.vitae@google.net
13 | - Karly Cain, cursus.et.eros@google.ca
14 | - Clementine Kramer, ac.mattis@yahoo.edu
15 |
16 | ## Leads
17 |
18 | - Joe Rivers,
19 | - Sylvester Harmon,
20 | - Simone Blackburn,
21 | - Karly Cain,
22 | - Clementine Kramer, https://ebay.com
23 |
24 | ---
25 |
26 | [Some serious work](https://broken-link-its-not-even-possible.bizarro).
27 | Some work serious.
28 |
29 | 
30 |
31 | [^peek_this]: Call it, fast.
32 |
--------------------------------------------------------------------------------
/docs/content/@dummy/inbox/@todos/commerce.md:
--------------------------------------------------------------------------------
1 | # Some things I need to **buy**, or **sell**
2 |
3 | ## Groceries
4 |
5 | - [ ] Apple pies 😌
6 | - [ ] Clementine juice
7 | - [x] Salt[^much_work]
8 | - [x] 🍳 A lot of eggs
9 | - [x] Some chicken
10 | - [ ] 🥚 A lot of eggs
11 |
12 | ## Tech. stuff
13 |
14 | - [ ] iRack
15 | - [ ] iStand, but I need **400**$ more
16 | - [ ] iHub
17 | - [ ] iRobot
18 | - [ ] iWeb
19 | - [x] iTools
20 | - [ ] _**me**.com_ account -> Check-out this [awesome offer](https://en.wikipedia.org/wiki/MobileMe)
21 | - [x] Microsoft mouse
22 |
23 | ## Sell on eBay
24 |
25 | - [ ] Old tires on the backyard[^much_work]
26 | - [ ] ~~you~~.com account
27 | - [ ] Apple pies
28 | - [ ] Pear watches
29 |
30 | ---
31 |
32 | Motivatin' in _pseudo-latin_:
33 | > Lorem, ipsum dolor sit amet consectetur 💪
34 |
35 | > mongoDb
36 |
37 | [^much_work]: Too much things to do is tiring
38 |
--------------------------------------------------------------------------------
/docs/content/@dummy/inbox/@todos/personal.md:
--------------------------------------------------------------------------------
1 | ## 🏚 House work
2 |
3 | - [ ] Buy light bulbs, it's dark here
4 | - [ ] Fix this stupid window it's too bright
5 |
6 | ## 🚙 Car
7 |
8 | - [ ] Change the tires
9 | - [ ] Remove oil from the Tesla reservoir
10 |
11 | ## 🥱 Gov', papers, etc.
12 |
13 | - [ ] Pay taxes
14 | - [ ] Buy stamps for car license
15 | - [ ] Send house certificates
16 | - [ ] Re-engage an insurance
17 | - [ ] Don't forget to pay taxes
18 |
19 | ## Random notes:
20 |
21 | > We need to index the cross-platform AGP port!
22 |
23 | ---
24 |
25 | > I'll navigate the redundant ADP driver, that should bus the SQL array!
26 |
27 | ---
28 |
29 | **Motivational quote, in pseudo-latin** 🤜:
30 |
31 | > Omnis at excepturi saepe ut ut voluptatum.
32 |
33 | # Ok… let's go!
34 |
35 | > Might be cool to map this:
36 | > [Internal link](../../invoices/acme-website/contract.md) (DON'T CLICK!).
37 |
--------------------------------------------------------------------------------
/docs/content/@dummy/inbox/draft.schema.yaml:
--------------------------------------------------------------------------------
1 | properties:
2 | personal: {}
3 | business: {}
4 | commerce: {}
5 | art: {}
6 | life: {}
7 | dev: {}
8 |
9 | required:
10 | - personal
11 | - future
12 | - commerce
13 |
--------------------------------------------------------------------------------
/docs/content/@dummy/inbox/ideas/art.md:
--------------------------------------------------------------------------------
1 | # Art!
2 |
3 | 
4 |
5 | > “La beauté des choses existe dans l'esprit de celui qui les contemple.”
6 |
7 | ---
8 |
9 | 
10 |
11 | > “La coutume, ainsi, est le grand guide de la vie humaine.”
12 |
13 | ---
14 |
15 | 
16 |
17 | > “La parole, les mots, la langue sont fixés par une convention et un accord humains.”
18 |
19 | ---
20 |
21 | 
22 |
23 | > “Il faut oublier les folies d'un jour pour faire place à celles du lendemain.”
24 |
--------------------------------------------------------------------------------
/docs/content/@dummy/inbox/ideas/dev.md:
--------------------------------------------------------------------------------
1 | # Try this tools
2 |
3 | ```scss
4 | .editor-preview {
5 | // Flex this
6 | display: flex;
7 | flex-direction: column;
8 | align-items: center;
9 | justify-content: center;
10 | max-width: calc(17em + 38vw);
11 | padding: 0 2vw;
12 | padding-top: 2rem;
13 | }
14 | ```
15 |
16 | > Donne moy tes presens en ces jours que la Brume
17 | > Fait les plus courts de l'an, ou de ton rameau teint
18 | > Dans le ruisseau d'Oubly dessus mon front espreint,
19 | > Endor mes pauvres yeux, mes gouttes et mon rhume.
20 |
21 | Misericorde ô Dieu, ô Dieu ne me consume[^peek_this_also]
22 | A faulte de dormir, plustost sois-je contreint
23 | De me voir par la peste ou par la fievre esteint,
24 | Qui mon sang deseché dans mes veines allume.
25 |
26 | Heureux, cent fois heureux animaux qui dormez[^peek_this]
27 | Demy an en voz trous, soubs la terre enfermez,
28 | Sans manger du pavot qui tous les sens assomme :
29 |
30 | J'en ay mangé, j'ay beu de son just oublieux
31 | En salade cuit, cru, et toutesfois le somme[^peek_this_finally]
32 | Ne vient par sa froideur s'asseoir dessus mes yeux.
33 |
34 | _**Pierre de Ronsard.**_
35 |
36 | ---
37 |
38 | - MacOS
39 | - github
40 | - eslint
41 |
42 | ```sh
43 | Enumerating objects: 104, done.
44 | Counting objects: 100% (104/104), done.
45 | Delta compression using up to 16 threads
46 | Compressing objects: 100% (70/70), done.
47 | Writing objects: 100% (76/76), 13.63 KiB | 3.41 MiB/s, done.
48 | Total 76 (delta 36), reused 0 (delta 0)
49 | remote: Resolving deltas: 100% (36/36), completed with 17 local objects.
50 | To github.com:JulianCataldo/astro-content.git
51 | 5cee9f2..2f162e8 master -> master
52 | ```
53 |
54 | [^peek_this]: You're reading between the lines.
55 | [^peek_this_also]: You're reading between the lines, again.
56 | [^peek_this_finally]: No comment here, just playing.
57 |
--------------------------------------------------------------------------------
/docs/content/@dummy/inbox/ideas/life.md:
--------------------------------------------------------------------------------
1 | # Personal improvement
2 |
3 | - Read more books[^peek_this]
4 | - Read more books[^peek_this_also]
5 | - Read more books[^peek_this_finally]
6 |
7 | You can use to help you write your own.
8 |
9 | ---
10 |
11 | 
12 |
13 | [^peek_this]: You're reading between the lines.
14 | [^peek_this_also]: You're reading between the lines, again.
15 | [^peek_this_finally]: No comment here, just playing.
16 |
--------------------------------------------------------------------------------
/docs/content/@dummy/invoices/acme-website/footnotes.md:
--------------------------------------------------------------------------------
1 | This **free** Sample Terms of Service Template is available
2 | for download and includes these sections.
3 |
4 | > You can download the Sample Terms of Service Template as HTML code below.
5 | > Copy it from the box field below (right-click > Select All and then Copy-paste)
6 | > and then paste it on your website pages.
7 |
8 | ---
9 |
10 | Make your Terms of Service agreement enforceable by having your
11 | users click an unticked checkbox[^peek_this] next to a statement that
12 | says something similar to:
13 |
14 | > _"I have **read** and **agree** to the **Terms of Service** agreement."_
15 |
16 | [^peek_this]: You're reading between the lines.
17 |
--------------------------------------------------------------------------------
/docs/content/@dummy/invoices/acme-website/informations.yaml:
--------------------------------------------------------------------------------
1 | invoiceId: 12345-ABC
2 | pricePerDay: 10000000
3 | numberOfDays: 50
4 | dateStart: 2022-12-11
5 | dateEnd: 2042-12-11
6 |
--------------------------------------------------------------------------------
/docs/content/@dummy/invoices/acme-website/test.jsonc:
--------------------------------------------------------------------------------
1 | {
2 | "invoiceId": "12345-ABC",
3 | "pricePerDay": 10000000,
4 | "numberOfDays": 50,
5 | "dateStart": "2022-12-11",
6 | "dateEnd": "2042-12-11"
7 | }
8 |
--------------------------------------------------------------------------------
/docs/content/@dummy/invoices/amd-portal/footnotes.md:
--------------------------------------------------------------------------------
1 | This **free** Sample Terms of Service Template is available
2 | for download and includes these sections.
3 |
4 | A note you have to read, really[^peek_this]
5 |
6 | > You can download the Sample Terms of Service Template as HTML code below.
7 | > Copy it from the box field below (right-click > Select All and then Copy-paste)
8 | > and then paste it on your website pages.
9 |
10 | ---
11 |
12 | A note you have to read[^peek_this]
13 |
14 | Make your Terms of Service agreement enforceable by having your
15 | users click an unticked checkbox next to a statement that
16 | says something similar to:
17 |
18 | > _"I have **read** and **agree** to the **Terms of Service** agreement."_
19 |
20 | A note you have to read, you have to[^peek_this]
21 |
22 | [^peek_this]: You're reading between the lines.
23 |
--------------------------------------------------------------------------------
/docs/content/@dummy/invoices/amd-portal/informations.yaml:
--------------------------------------------------------------------------------
1 | invoiceId: 12345-ABC
2 |
3 | pricePerDay: 10000000
4 | numberOfDays: 50
5 |
6 | dateStart: 2022-12-11
7 | dateEnd: 2042-12-11
8 | #
--------------------------------------------------------------------------------
/docs/content/@dummy/invoices/food-corp-website/footnotes.md:
--------------------------------------------------------------------------------
1 | This **free** Sample Terms of Service Template is available
2 | for download and includes these sections.
3 |
4 | > You can download the Sample Terms of Service Template as HTML code below.
5 | > Copy it from the box field below (right-click > Select All and then Copy-paste)
6 | > and then paste it on your website pages.
7 |
8 | ---
9 |
10 | Make your Terms of Service agreement enforceable by having your
11 | users click an unticked checkbox next to a statement that
12 | says something similar to:
13 |
14 | > _"I have **read** and **agree** to the **Terms of Service** agreement."_
15 |
--------------------------------------------------------------------------------
/docs/content/@dummy/invoices/food-corp-website/informations.yaml:
--------------------------------------------------------------------------------
1 | invoiceId: 12345-ABC
2 |
3 | pricePerDay: '11110.34'
4 | numberOfDays: '50'
5 |
6 | dateStart: [2022-12-11]
7 | dateEnd: 2042-12-11
8 |
--------------------------------------------------------------------------------
/docs/content/@dummy/invoices/invoice.schema.yaml:
--------------------------------------------------------------------------------
1 | properties:
2 | contract:
3 | properties:
4 | title:
5 | type: string
6 | legalReferences:
7 | description: Legal references
8 | type: array
9 | items:
10 | - type: string
11 | contractLink:
12 | description: Entry title
13 | type: string
14 | clientType:
15 | type: string
16 | enum:
17 | - Corporate
18 | - Non-profit
19 | - Individual
20 |
21 | # required:
22 | # - title
23 | # - legalReferences
24 | # - clientType
25 |
26 | informations:
27 | properties:
28 | invoiceId:
29 | type: string
30 | pricePerDay:
31 | type: number
32 | numberOfDays:
33 | type: number
34 |
35 | footnotes: {}
36 | # required:
37 | # - contract
38 |
--------------------------------------------------------------------------------
/docs/content/@dummy/invoices/soap-shop-popup/informations.yaml:
--------------------------------------------------------------------------------
1 | pricePerDay: 10000000
2 |
3 | invoiceId: 12345
4 |
5 | numberOfDays: 50
6 |
7 | dateStart: 2022-12-11
8 | dateEnd: 2042-12-11
9 |
--------------------------------------------------------------------------------
/docs/content/@dummy/people/clementine-kramer/informations.yaml:
--------------------------------------------------------------------------------
1 | name: Clementine
2 | surname: 2
3 | email: clementine.kramer@yahoo.fr
4 |
5 | dateOfBirth: '1995-11-11'
6 |
--------------------------------------------------------------------------------
/docs/content/@dummy/people/clementine-kramer/notes.md:
--------------------------------------------------------------------------------
1 | # Souvenir
2 |
3 | That gal at that party, you know?
4 |
5 |
6 |
--------------------------------------------------------------------------------
/docs/content/@dummy/people/karly-cain/informations.yaml:
--------------------------------------------------------------------------------
1 | name:
2 | - Karly
3 | surname: Cain
4 | email: karly.cain@hotmail.fr
5 |
6 | dateOfBirth: ['2001-84-12']
7 |
--------------------------------------------------------------------------------
/docs/content/@dummy/people/karly-cain/notes.md:
--------------------------------------------------------------------------------
1 | # Souvenir
2 |
3 | That guy at that party, you know?
4 |
--------------------------------------------------------------------------------
/docs/content/@dummy/people/person.schema.yaml:
--------------------------------------------------------------------------------
1 | properties:
2 | informations:
3 | properties:
4 | name:
5 | type: string
6 | surname:
7 | type: string
8 | dateOfBirth:
9 | type: string
10 | title: Hello
11 | # required: true
12 | description: Correct format of Date Of Birth is dd-mmm-yyyy
13 | pattern: ^\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])
14 | # message:
15 | # required: Date of Birth is Required Property
16 | # pattern: Correct format of Date Of Birth is dd-mmm-yyyy
17 | required:
18 | - name
19 |
20 | notes: {}
21 |
22 | required:
23 | - informations
24 | - notes
25 |
--------------------------------------------------------------------------------
/docs/content/default.schema.yaml:
--------------------------------------------------------------------------------
1 | properties:
2 | gallery:
3 | properties:
4 | source:
5 | type: string
6 | required:
7 | - source
8 |
9 | meta:
10 | properties:
11 | baz:
12 | type: string
13 | foo:
14 | type: string
15 | enum:
16 | - bar
17 | - moz
18 | - das
19 | required:
20 | - foo
21 |
22 | content:
23 | allOf:
24 | - $ref: '#/definitions/MarkdownFile'
25 | - properties:
26 | frontmatter:
27 | properties:
28 | title:
29 | description: Entry title
30 | type: string
31 | image:
32 | description: Image path
33 | type: string
34 | required:
35 | - title
36 | required:
37 | - frontmatter
38 |
39 | footnotes:
40 | allOf:
41 | - $ref: '#/definitions/MarkdownFile'
42 |
43 | required:
44 | - content
45 | - meta
46 | - gallery
47 | - footnotes
48 |
--------------------------------------------------------------------------------
/docs/content/docs/cli/no_main.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Command line
3 | order: 4
4 | ---
5 |
6 | CLI
7 |
--------------------------------------------------------------------------------
/docs/content/docs/doc-section.schema.yaml:
--------------------------------------------------------------------------------
1 | properties:
2 | main:
3 | properties:
4 | title:
5 | type: string
6 | order:
7 | type: number
8 |
9 | required:
10 | - title
11 | - order
12 |
13 | additionalProperties: false
14 |
15 | required:
16 | - main
17 |
18 | additionalProperties: false
19 |
--------------------------------------------------------------------------------
/docs/content/docs/ide/no_main.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: IDE features
3 | order: 5
4 | ---
5 |
6 | IDE FEATS
7 |
--------------------------------------------------------------------------------
/docs/content/docs/import/main.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Import
3 | order: 5
4 | ---
5 |
6 | # Template usage
7 |
8 | ## In an Astro _page_
9 |
10 |
11 | ```astro
12 | ---
13 | import { get } from '/content';
14 |
15 | // Fetch everything
16 | const allContent = await get(Astro.glob('/content/**/*.{md,mdx,yaml}'));
17 |
18 | // For auto-completion to show up,
19 | // ✨ start typing a '.' here ——————v
20 | const tryAutoCompletion = allContent ;
21 |
22 | // Narrow fetching to some entities, for performance
23 | const content = await get(
24 | Astro.glob('/content/{robots,people}/**/*.{md,mdx,yaml}'),
25 | );
26 |
27 | // Let's be more specific by getting a single entry
28 | const bigGrumpy = content?.robots?.bigGrumpy;
29 |
30 | // Or even get the MD(X) body component directly
31 | const BigGrumpyMainContent = content?.robots?.bigGrumpy?.main.Content;
32 | ---
33 |
34 |
35 |
36 |
37 |
38 | {bigGrumpy?.meta?.price}
39 |
40 |
41 |
42 | ```
43 |
44 | ## In an Astro _component_
45 |
46 |
47 | ```astro
48 | ---
49 | import { type Robot } from '/content';
50 |
51 | // Augment your `Props`
52 | const { feats } = Astro.props as { feats: Robot };
53 | ---
54 |
55 |
56 |
57 |
58 |
59 | {feats?.meta?.price}
60 |
61 | ```
62 |
--------------------------------------------------------------------------------
/docs/content/docs/install/main.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Installation
3 | order: 2
4 | ---
5 |
6 | ## Method 1: Add to Astro project with _CLI_
7 |
8 | With `yarn`, `npm` or `pnpm`, run this in your **existing** Astro project:
9 |
10 | ```sh
11 | # If you want a fresh start ——v
12 | # pnpm create astro && cd ./my-astro-site
13 |
14 | pnpm astro add astro-content
15 | pnpm content setup
16 | ```
17 |
18 | Follow the prompts… 🐇
19 |
20 | ## Method 2: Clone _demo project_
21 |
22 | Shallow **clone** this minimal Astro **starter**, which comes with dummy **content** for you to play with:
23 |
24 | ```sh
25 | pnpx degit JulianCataldo/astro-content/demo ./ac-demo
26 | cd ./ac-demo && pnpm install
27 |
28 | # Clone dummy content
29 | pnpx degit JulianCataldo/astro-content/docs/content/@dummy ./content
30 | # —OR— setup a minimal content base with Astro Content CLI
31 | pnpm content setup
32 |
33 | # Open project in VS Code
34 | code .
35 | ```
36 |
37 | > **Warning**: Only **Node 17** or higher is actually supported by Astro Content.
38 |
39 | ## _Launch_ project
40 |
41 | OK, **project is ready**. It's time to:
42 |
43 | ```sh
44 | pnpm run dev
45 | ```
46 |
47 | Now head over to [http://localhost:3000/**\_\_content**](http://localhost:9054/__content) to take a deep dive in Astro Content.
48 |
49 | ## _TypeScript_ setup
50 |
51 | It's OK to use an absolute path, so you don't have to do tedious relative imports:
52 |
53 | ```tsx
54 | import { get } from '../../content';
55 | // Versus:
56 | import { get } from '/content';
57 | ```
58 |
59 | Astro / Vite resolve absolute paths from project root.
60 | That's cool,
61 | but TypeScript language server (in your IDE) will likely break, while showing
62 | red squiggles 🤨.
63 |
64 | A very simple fix is adding this to your `tsconfig.json` > `compilerOptions.paths`:
65 |
66 | ```jsonc
67 | {
68 | "compilerOptions": {
69 | // …
70 | "paths": {
71 | // Make TS happy with absolute path
72 | "/content": ["./content"]
73 | }
74 | }
75 | }
76 | ```
77 |
--------------------------------------------------------------------------------
/docs/content/docs/intro/main.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Introduction
3 | order: 1
4 | ---
5 |
6 | ## What is it?
7 |
8 | Think of it as an hybrid of **Wordpress** + ACF, **Obsidian** and **Ulysses**, with a sprinkle of **tRPC** and **nuxt/content**.
9 |
10 | ## What it does?
11 |
12 | ✨ Adds a thin layer between Astro and your templates, bringing automatic **typings**, runtime validation and a handful of **DX** goodies.
13 |
14 | 🏗 Brings evolved authoring assistance, in a **full-fledged** back-office, inside your **IDE** or with **CLI**, as you prefer.
15 |
16 | ## Main goals
17 |
18 | Being content centric, this set of tools will give you:
19 |
20 | - **Focus** when designing 👌
21 | - **Confidence** when authoring ✍️
22 | - **Predictability** when integrating 🤝
23 | - **Certainty** while delivering 💪
24 | - **Peace** of mind when refactoring 👍
25 |
26 | ---
27 |
28 | > **Warning**: This is an **`alpha`** product — Heavy changes are on-going — [Suggestions are welcome 👐](https://github.com/JulianCataldo/astro-content/issues)
29 |
--------------------------------------------------------------------------------
/docs/content/docs/more/main.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Tell me more
3 | order: 8
4 | ---
5 |
6 | # Tell me more
7 |
8 | ## Why this project?
9 |
10 | It's either an **I**ntegrated **A**uthoring **E**nvironment as its targeting tech-savvy people (not necessarily developers, but also people who work with them).
11 | You could compare it to a good old top-down **CMS** (as opposed to headless): it gives you the **_head_** (Astro) and the **_spine_** (content structure + management) back.
12 | Authoring and previewing living content in the same place has its advantages,
13 | this is the case for **LAMP** stacks which has handled this for ages.
14 |
15 | Astro + Content gives this power back,
16 | without all the complexities, oddities and maintenance burden of traditional CMSs (with all due respect).
17 | Opting for this symbiose between _code_ and _content_ has took a big leap,
18 | thanks to headless, "JAMStack" frameworks which popularize
19 | **Markdown** and **MDX** as a first class citizen, with a whole set of eco-systems around these.
20 | For example, Astro Content makes validating Markdown _front matter_ part of its core. Though still far from perfect, every step like this one
21 | is done to catch up a bit with high standards developer experience (e.g. TypeScript).
22 |
23 | Tooling has still a lot of room to grow for MD(X), and things are a bit scattered in these areas. In fact, some of them are in their infancy.
24 | That's what motivated Astro Content: easing environment setup and usage.
25 | The more people use these tools, the more incentive these will get to be improved.
26 |
--------------------------------------------------------------------------------
/docs/content/docs/reports/main.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Reports
3 | order: 6
4 | ---
5 |
6 | # Reports
7 |
8 | You can benefit from these three levels of content checks:
9 |
10 | 1. **Schema** structure
11 | 2. File **language syntax** linting
12 | 3. **Natural language** linting
13 |
--------------------------------------------------------------------------------
/docs/content/docs/tips/no_main.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Tips
3 | order: 7
4 | ---
5 |
--------------------------------------------------------------------------------
/docs/content/docs/work-in-progress/main.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Roadmap
3 | order: 8
4 | ---
5 |
6 | # Work in progress
7 |
8 |
9 |
10 | — Scopes: [ **int** · **srv** · **gui** · **ide** · **gui** · **cli** · **doc** ] —
11 |
12 |
13 |
14 | ---
15 |
16 | - [ ] Rehaul Astro `MarkdownInstance` <=> `MardownFile` schema definition <=> `MarkdownFile` TS interface. [ **int** · **srv** ]
17 | - [ ] `Content` Astro component especially, is not propertly typed.
18 | - [ ] Same for `YamlInstance`, which need some love, generally.
19 | - [ ] Actual runtime JSON Schema validation, not just _reporting_ errors, but pro-actively preventing them to occur, with opt-out capabilities. [ **srv** ]
20 | - [ ] Automatic remark-lint setup. [ **srv** · **ide** · **cli** ]
21 | - [ ] Automatic remark sync. [ **srv** · **ide** · **cli** ]
22 | - [ ] Custom Markdown linting rules -> Should hook up with `.remarkrc.mjs`, so user benefit from both IDE and Web app custom rules. [ **srv** · **ide** ]
23 | - [ ] Add documentation to website [ **doc** ]
24 | - [ ] Fix silent MDX failures breaking entire app. [ **int** · **srv** · **gui** ]
25 | - [ ] MDX support [ **gui** ]
26 | - [x] Syntax highlighting + configuration for monaco.
27 | - [ ] Advanced language features.
28 | - [ ] Syntax highlight for MD front matters [ **gui** ]
29 |
--------------------------------------------------------------------------------
/docs/content/globals/global.schema.yaml:
--------------------------------------------------------------------------------
1 | properties:
2 | menu:
3 | type: array
4 | items:
5 | - properties:
6 | title:
7 | type: string
8 | href:
9 | type: string
10 |
11 | notes: {}
12 |
13 | required:
14 | - website
15 | # - notes
16 |
--------------------------------------------------------------------------------
/docs/content/globals/website/menu.yaml:
--------------------------------------------------------------------------------
1 | - title: Astro Content
2 | href: /
3 | - title: Astro Content
4 | href: /
5 |
--------------------------------------------------------------------------------
/docs/content/modules/cli-or-gui/text.md:
--------------------------------------------------------------------------------
1 | # You get the command line, with a graphical interface, for free
2 |
3 | Initially designed as a 100% CLI tool, Astro Content seeks feature parity
4 | between the CLI and the GUI.
5 |
6 |
8 |
9 |
10 |
11 | ## Separation of concern
12 |
13 | ### Multiple monitor, multiple workbenchs
14 |
15 | one for your template / business logic
16 | one for content edition
17 |
18 | ### Ressources splitting
19 |
20 | VS Code use a lot of ressources for TypeScript, languages servers and your
21 | bazillions of extensions.
22 | Adding schema, linting
23 |
--------------------------------------------------------------------------------
/docs/content/modules/credits/text.md:
--------------------------------------------------------------------------------
1 | # Hey
2 |
3 | Some
4 |
--------------------------------------------------------------------------------
/docs/content/modules/features/text.mdx:
--------------------------------------------------------------------------------
1 | import { Picture } from '@astrojs/image/components';
2 |
3 | import astro from '/src/assets/features.svg?raw';
4 |
5 |
6 |
7 |
18 |
19 |
20 | Create content
21 | with _confidence_.
22 |
23 |
24 |
25 |
26 |
27 |
41 |
--------------------------------------------------------------------------------
/docs/content/modules/landing/gallery.yaml:
--------------------------------------------------------------------------------
1 | source: occaecat non culpa sunt
2 |
--------------------------------------------------------------------------------
/docs/content/modules/landing/install.md:
--------------------------------------------------------------------------------
1 | ---
2 | foo: 2
3 | # bar: text
4 | ---
5 |
6 | ### Installation 🚀
7 |
8 | Works as an [AstroJS](https://docs.astro.build/en/guides/integrations-guide/)
9 | integration (_alpha version_).
10 |
11 | ```sh
12 | pnpm astro add astro-content
13 | pnpm content setup
14 | pnpm run dev
15 |
16 | open http://localhost:3000/__content
17 | ```
18 |
19 | See [documentation](https://github.com/JulianCataldo/astro-content).
20 |
21 | ---
22 |
23 | Astro Content is a **community** project, created and maintained by Julian Cataldo.
24 | [Contributions](https://github.com/JulianCataldo/astro-content/issues) are welcome.
25 |
--------------------------------------------------------------------------------
/docs/content/modules/landing/relations.md:
--------------------------------------------------------------------------------
1 |
10 |
11 |
12 |
13 | # Similar / inspired by
14 |
15 | - **Gatsby**, Nuxt, Gridsome
16 | - **tRPC**, **GraphQL**, Mongo API
17 | - **nuxt/content**, Docus, **Contentlayer**
18 | - Dendron, **Obsidian**, Ulysses
19 | - **Strapi**, Postman, VS Code
20 |
21 |
22 |
23 |
32 |
--------------------------------------------------------------------------------
/docs/content/modules/landing/text.md:
--------------------------------------------------------------------------------
1 | # Astro Content — (_Preview_)
2 |
3 | A text based, structured content framework,
4 | with a focus on **editor** and **integrator** experience.
5 |
6 | ---
7 |
8 | ## 🏗 Structure
9 |
10 | - Check for **schema**, **syntax**, and **prose** mistakes.
11 | - Edit schemas: get content-wide, instant **refactoring** guidance and **mockup** data to play with.
12 | - **Prevent entropy** for ever growing knowledge bases.
13 |
14 |
15 | ## 💈 Author
16 |
17 | - Use state of the art Markdown processing engine,
18 | with a **rich** and **extensible** plugin ecosystem.
19 | - **Live preview**, rich render. As close as final output can get.
20 | - Gives to content team a **pre-configured**,
21 | **predictable** editing environment.
22 |
23 | ## 🛎 Provide
24 |
25 | - Generate type-safe **import helpers**.
26 | - **Future-proof**: seeks standards, idioms and popular tools.
27 | - **Agnostic** API: target any consumer type.
28 |
29 | ---
30 |
31 | ### Uses cases
32 |
33 | Wiki, documentation, web gardens, personal, blog, news, components storybooks…
34 |
35 | For **private** / **public**, **corporate** / **personal** use.
36 | You could really make Astro Content anything you want!
37 |
38 | It's now possible to engage **large content refactors** with an eagle view,
39 | without **complicated toolings** setup and **vendor lock-in**.
40 |
--------------------------------------------------------------------------------
/docs/content/modules/module.schema.yaml:
--------------------------------------------------------------------------------
1 | properties:
2 | gallery:
3 | properties:
4 | source:
5 | type: string
6 | required:
7 | - source
8 |
9 | text: {}
10 |
11 | relations: {}
12 |
13 | install:
14 | properties:
15 | foo:
16 | type: string
17 | bar:
18 | type: string
19 | required:
20 | - foo
21 | - bar
22 |
23 | required:
24 | - text
25 | # - gallery
26 |
--------------------------------------------------------------------------------
/docs/content/pages/home/main.mdx:
--------------------------------------------------------------------------------
1 | # Hey
2 |
--------------------------------------------------------------------------------
/docs/content/pages/page.schema.yaml:
--------------------------------------------------------------------------------
1 | properties:
2 | main:
3 | properties:
4 | title:
5 | type: string
6 | order:
7 | type: number
8 |
9 | required:
10 | - main
11 |
--------------------------------------------------------------------------------
/docs/env.d.ts:
--------------------------------------------------------------------------------
1 | // declare module '*.module.css';
2 | // declare module '*.module.scss';
3 | // // and so on for whatever flavor of css you're using
4 |
--------------------------------------------------------------------------------
/docs/public/favicon.svg:
--------------------------------------------------------------------------------
1 |
12 |
--------------------------------------------------------------------------------
/docs/public/poster.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JulianCataldo/astro-content/d5ed86fcc9ae27cede28ebcedabaaf39a45ae613/docs/public/poster.png
--------------------------------------------------------------------------------
/docs/src/app/Footer.astro:
--------------------------------------------------------------------------------
1 | ---
2 | import { Link } from 'astro-link';
3 | import guiOverlay from '../assets/separator.svg?raw';
4 | // import github from '../assets/github.svg?raw';
5 | import './Footer.scss';
6 | ---
7 |
8 |
40 |
--------------------------------------------------------------------------------
/docs/src/app/Footer.scss:
--------------------------------------------------------------------------------
1 | @use 'sass:color';
2 | @use '../vars' as *;
3 |
4 | .app-footer {
5 | display: flex;
6 | flex-wrap: wrap;
7 | align-items: flex-end;
8 | justify-content: flex-start;
9 | padding: 10rem 5rem 2rem 2rem;
10 | font-family: $font-fancy;
11 | font-style: italic;
12 |
13 | .separator {
14 | width: 30vw;
15 | margin-right: 2vw;
16 | opacity: 0.8;
17 | }
18 |
19 | .star-me {
20 | align-self: flex-start;
21 |
22 | svg {
23 | height: 0.7em;
24 | }
25 |
26 | font-size: 1.5em;
27 | }
28 |
29 | .btt {
30 | a {
31 | display: block;
32 | padding: 1rem;
33 | }
34 | }
35 |
36 | .built-with {
37 | display: flex;
38 | align-items: center;
39 | justify-content: center;
40 | margin-right: 2rem;
41 |
42 | & > * {
43 | display: flex;
44 | align-items: center;
45 | }
46 |
47 | a {
48 | padding: 0 1rem;
49 | }
50 |
51 | margin-left: auto;
52 | text-align: right;
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/docs/src/app/LazyLoading.astro:
--------------------------------------------------------------------------------
1 | ---
2 | // Quick hack 🏴☠️
3 | ---
4 |
5 |
19 |
20 |
29 |
--------------------------------------------------------------------------------
/docs/src/app/NavigationBar.astro:
--------------------------------------------------------------------------------
1 | ---
2 | import { Link } from 'astro-link';
3 | import './NavigationBar.scss';
4 | import logo from '../assets/astro-content-logo.svg?raw';
5 | import brain from '../assets/brain-circuit-20-filled.svg?raw';
6 | import github from '../assets/github.svg?raw';
7 | import discord from '../assets/discord.svg?raw';
8 | import controller from '../assets/game-controller-sharp.svg?raw';
9 |
10 | const current = Astro.url.pathname.split('/')[1] || 'home';
11 | ---
12 |
13 |
66 |
--------------------------------------------------------------------------------
/docs/src/app/NavigationBar.scss:
--------------------------------------------------------------------------------
1 | @use 'sass:color';
2 | @use '../vars' as *;
3 |
4 | .component-navigation-bar {
5 | @media screen and (max-width: 700px) {
6 | margin-bottom: 4rem;
7 | }
8 |
9 | ul {
10 | display: flex;
11 | flex-wrap: wrap;
12 | align-items: flex-start;
13 | justify-content: flex-end;
14 | padding: 1rem 4rem;
15 | list-style-type: none;
16 |
17 | li:first-of-type {
18 | min-width: 34vw;
19 | @media screen and (max-width: 700px) {
20 | margin-bottom: 4rem;
21 | }
22 | }
23 |
24 | a {
25 | display: flex;
26 | align-items: center;
27 | padding: 0 2.5vw;
28 | padding: 0.7rem 1.5vw;
29 | margin: 1vw;
30 | font-family: $font-fancy;
31 | font-size: 1.3334em;
32 | font-style: italic;
33 | font-weight: 500;
34 | font-weight: 900;
35 | color: white;
36 | border-bottom: 2px solid color.adjust($ca-main-5, $alpha: -0.6);
37 | border-radius: 1rem;
38 |
39 | &:hover {
40 | color: $ca-accent;
41 | }
42 |
43 | &:active {
44 | transform: translateY(1.5px);
45 | }
46 | }
47 |
48 | .home {
49 | margin-right: auto;
50 | }
51 |
52 | .btn {
53 | }
54 |
55 | .btn.active a,
56 | a:active {
57 | border-bottom: 2px solid color.adjust($ca-accent, $alpha: -0.5);
58 | border-radius: 1rem;
59 | }
60 | }
61 |
62 | .logo {
63 | display: inline-block;
64 | width: 14rem;
65 | height: 6rem;
66 | padding: 0 1rem;
67 |
68 | &:hover {
69 | filter: drop-shadow(1px 1px 3px $ca-accent);
70 | }
71 | }
72 |
73 | .icon {
74 | width: 1.7em;
75 | height: 1.7em;
76 | padding: 0.2em;
77 |
78 | &.enlarge {
79 | width: 1.8em;
80 | height: 1.8em;
81 | padding: 0.11em;
82 | // padding-bottom: 0em;
83 | }
84 |
85 | margin-right: 1rem;
86 | margin-right: 1em;
87 |
88 | svg {
89 | width: 100%;
90 | height: 100%;
91 | }
92 | }
93 | }
94 |
--------------------------------------------------------------------------------
/docs/src/assets/brain-circuit-20-filled.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/docs/src/assets/discord.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/docs/src/assets/game-controller-sharp.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/docs/src/assets/github.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/docs/src/assets/logos/mdx-logo.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/docs/src/assets/logos/ts-logo-round.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/docs/src/assets/logos/vite.svg:
--------------------------------------------------------------------------------
1 |
16 |
--------------------------------------------------------------------------------
/docs/src/assets/logos/yaml.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/docs/src/assets/shape-1.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/docs/src/assets/terminal.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/docs/src/components-demo/Button.tsx:
--------------------------------------------------------------------------------
1 | interface Props {
2 | variant: 'fancy' | 'default';
3 | /** Wow */
4 | hello: {
5 | test: string;
6 | testAaa: number;
7 | };
8 | }
9 |
10 | export default function Button({ children }: Props) {
11 | return (
12 |
16 | );
17 | }
18 |
--------------------------------------------------------------------------------
/docs/src/components-demo/Crab.astro:
--------------------------------------------------------------------------------
1 | ---
2 | interface Arthropoda {
3 | foo?: string;
4 | }
5 |
6 | /**
7 | * **Crab main features**: `antennas`, `abdomen`
8 | */
9 | interface Props extends astroHTML.JSX.HTMLAttributes, Arthropoda {
10 | /** Will it bite? `Maybe` */
11 | character?: string;
12 |
13 | /**
14 | * [_Crabology_](http://example.com/crab) code example:
15 | *
16 | * ```js
17 | * console.log('Crab mode — ON')
18 | * ````
19 | */
20 | shellColor: 'salmon' | 'seashell' | 'seagreen' | 'transparent';
21 |
22 | /** From **1** to **10** */
23 | clawsSize: 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10;
24 | }
25 | const {
26 | character = 'gentle',
27 | shellColor = 'seashell',
28 | clawsSize = 5,
29 | } = Astro.props as Props;
30 | ---
31 |
32 |
33 |
34 | the 🦀 <Crab />
dummy component 🌊
35 |
36 |
37 |
38 | - Character: {character}
39 | - Shell color: {shellColor}
40 | - Claws size:
41 |
42 |
43 |
44 |
49 |
50 |
51 | Crabs are generally covered with a thick exoskeleton, composed primarily of
52 | highly mineralized chitin.
53 |
54 |
55 |
--------------------------------------------------------------------------------
/docs/src/components-demo/ThreeJuggler.module.scss:
--------------------------------------------------------------------------------
1 | .wrapper {
2 | canvas {
3 | width: 100%;
4 | height: 100%;
5 | background: #224;
6 | }
7 |
8 | // margin: 1.25em 0;
9 | }
10 |
--------------------------------------------------------------------------------
/docs/src/components/CodeEmbed.astro:
--------------------------------------------------------------------------------
1 | ---
2 | import fs from 'node:fs/promises';
3 | import path from 'node:path';
4 | import { Code } from 'astro/components';
5 | import { Link } from 'astro-link';
6 | import './CodeEmbed.scss';
7 |
8 | const { file, start, end } = Astro.props;
9 |
10 | /* From mono-repo root */
11 | const filePath = path.join(process.cwd(), '..', file);
12 | const source = await fs
13 | .readFile(filePath)
14 | .then((s) => {
15 | let r = String(s);
16 |
17 | if (end) {
18 | r = r.split('\n').slice(0, end).join('\n');
19 | r += '\n\n(Truncated…)';
20 | }
21 | return String(r);
22 | })
23 | .catch((e) => {
24 | console.log(e);
25 | return '…';
26 | });
27 |
28 | const language = path.extname(file).substring(1);
29 | // console.log({ language });
30 |
31 | const repoUrl = `https://github.com/JulianCataldo/astro-content/blob/master/${file}`;
32 | ---
33 |
34 |
35 |
36 | From: 📄
{file}
37 |
38 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/docs/src/components/CodeEmbed.scss:
--------------------------------------------------------------------------------
1 | @use 'sass:color';
2 | @use '../vars' as *;
3 |
4 | .astro-content-docs .component-code-embed {
5 | .file {
6 | display: inline-block;
7 | padding: 0.5rem 1.5rem;
8 | margin-top: 1rem;
9 | margin-left: 1rem;
10 | font-size: 85%;
11 | // background-color: $ca-black;
12 | border: 1px solid color.adjust($ca-main-3, $alpha: -0.8);
13 | border-radius: 0.5rem 0.5rem 0 0;
14 |
15 | & ~ div {
16 | margin-top: -2rem;
17 | }
18 |
19 | // a code {
20 | &:hover {
21 | background: color.adjust($ca-main-5, $lightness: -25%);
22 | }
23 | // }
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/docs/src/components/PrevNextNavigation.astro:
--------------------------------------------------------------------------------
1 | ---
2 | import { Link } from 'astro-link';
3 | /* ·········································································· */
4 | import { type Docs } from '/content';
5 | /* —————————————————————————————————————————————————————————————————————————— */
6 |
7 | interface Props {
8 | pages?: Docs;
9 | currentPage: string;
10 | }
11 | const { pages, currentPage } = Astro.props as Props;
12 |
13 | /* ·········································································· */
14 |
15 | const pagesArray =
16 | pages &&
17 | Object.entries(pages)?.sort(([, prev], [, cur]) =>
18 | (prev?.main?.frontmatter?.order || 0) < (cur?.main?.frontmatter?.order || 1)
19 | ? -1
20 | : 1,
21 | );
22 |
23 | const siblings = {
24 | previous: { href: '', title: '' },
25 | next: { href: '', title: '' },
26 | };
27 | let previous;
28 | let catchNext = false;
29 |
30 | pagesArray?.forEach(([key, val]) => {
31 | if (currentPage === key) {
32 | siblings.previous = {
33 | title: previous?.[1]?.main?.frontmatter?.title || false,
34 | href: previous?.[0] || false,
35 | };
36 | catchNext = true;
37 | }
38 | if (currentPage !== key && catchNext) {
39 | siblings.next = { title: val.main?.frontmatter?.title ?? '', href: key };
40 | catchNext = false;
41 | }
42 | previous = [key, val];
43 | });
44 | ---
45 |
46 |
62 |
--------------------------------------------------------------------------------
/docs/src/components/TreeNavigation.astro:
--------------------------------------------------------------------------------
1 | ---
2 | import { type MarkdownHeading } from 'astro';
3 | /* ·········································································· */
4 | import { type Docs } from '/content';
5 | import { Link } from 'astro-link';
6 | import './TreeNavigation.scss';
7 | /* —————————————————————————————————————————————————————————————————————————— */
8 |
9 | interface Props {
10 | pages?: Docs;
11 | currentPage?: string;
12 | headings?: MarkdownHeading[];
13 | }
14 | const { pages, headings, currentPage } = Astro.props as Props;
15 | ---
16 |
17 |
48 |
--------------------------------------------------------------------------------
/docs/src/components/TreeNavigation.scss:
--------------------------------------------------------------------------------
1 | @use 'sass:color';
2 | @use '../vars' as *;
3 |
4 | .astro-content-docs .component-tree-navigation {
5 | max-width: 27rem;
6 | height: 80vh;
7 | padding: 1rem 0rem 3rem 0rem;
8 | overflow-y: auto;
9 |
10 | @media screen and (max-width: 700px) {
11 | height: initial;
12 | }
13 |
14 | ul {
15 | padding: 0;
16 | margin: 0;
17 | list-style-type: none;
18 | }
19 |
20 | a {
21 | position: relative;
22 | display: inline-block;
23 | width: 100%;
24 | padding: 0.6em 2em 0.6em 3vw;
25 | color: $ca-white;
26 |
27 | &.current {
28 | color: $ca-accent;
29 | }
30 |
31 | &::before {
32 | position: absolute;
33 | top: 0;
34 | left: 0;
35 | z-index: -1;
36 | width: 100%;
37 | height: 100%;
38 | content: '';
39 | border-bottom: 1px solid transparent;
40 | -webkit-mask-image: linear-gradient(transparent, black 2rem);
41 | }
42 |
43 | &:hover {
44 | &::before {
45 | background-color: color.adjust($ca-black, $alpha: -0.1);
46 | border-bottom-color: $ca-main-4;
47 | }
48 | }
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/docs/src/components/VimeoPlayer.astro:
--------------------------------------------------------------------------------
1 | ---
2 | // _
3 | const options =
4 | 'h=04a3ee525e&color=efb900&byline=0&portrait=0&autoplay=1&loop=1&autopause=0&background=1';
5 |
6 | const id = '737566297';
7 | ---
8 |
9 |
14 |
--------------------------------------------------------------------------------
/docs/src/layouts/Bare.astro:
--------------------------------------------------------------------------------
1 | ---
2 | // _
3 | ---
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 | Document
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/docs/src/layouts/Default.astro:
--------------------------------------------------------------------------------
1 | ---
2 | import { Document, Body } from 'astro-base-document';
3 | import { SEOMetadata } from 'astro-seo-metadata';
4 | import { GoogleAnalytics } from 'astro-google-analytics';
5 | import { HoverPrefetch } from 'astro-hover-prefetch';
6 | import { Tooltips } from 'astro-tooltips';
7 | /* ·········································································· */
8 | import NavigationBar from '../app/NavigationBar.astro';
9 | import LazyLoading from '../app/LazyLoading.astro';
10 | import Footer from '../app/Footer.astro';
11 | /* ·········································································· */
12 | import './Default.scss';
13 | /* ·········································································· */
14 |
15 | const pageClass = `page-${Astro.url.pathname
16 | .substring(1)
17 | .replaceAll('/', '_')}`;
18 | ---
19 |
20 |
21 |
22 |
31 |
32 |
33 |
34 | {import.meta.env.PROD && }
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
--------------------------------------------------------------------------------
/docs/src/layouts/Default.scss:
--------------------------------------------------------------------------------
1 | @use 'sass:color';
2 | @use '../vars' as *;
3 |
4 | // @import '@julian_cataldo/astro-resets/styles';
5 | @import './scrollbars';
6 | @import './typography';
7 |
8 | .astro-content-docs.layout-default {
9 | overflow-y: scroll;
10 | scroll-behavior: smooth;
11 |
12 | *,
13 | *::before,
14 | *::after {
15 | box-sizing: border-box;
16 | }
17 |
18 | body {
19 | position: relative;
20 | padding: 0;
21 | margin: 0;
22 | font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI',
23 | Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue',
24 | sans-serif;
25 | font-size: calc(14px + 0.15vw);
26 | line-height: 1.5;
27 | color: $ca-white;
28 | background: linear-gradient(
29 | 87deg,
30 | color.adjust($ca-main-4, $lightness: -50%) 30%,
31 | color.adjust($ca-black, $lightness: -7%) 100%
32 | );
33 | -webkit-font-smoothing: antialiased;
34 | -moz-osx-font-smoothing: grayscale;
35 |
36 | &::before {
37 | position: absolute;
38 | z-index: -1;
39 | width: 100%;
40 | height: 100%;
41 | content: '';
42 | background: url('../assets/topography.svg');
43 | filter: invert(70%);
44 | background-size: 80rem;
45 | mix-blend-mode: overlay;
46 | opacity: 0.6;
47 | -webkit-mask-image: linear-gradient(
48 | to left,
49 | black,
50 | rgba(0, 0, 0, 0.2),
51 | black
52 | );
53 | }
54 | }
55 |
56 | main {
57 | min-height: 60vh;
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/docs/src/layouts/scrollbars.scss:
--------------------------------------------------------------------------------
1 | @use 'sass:color';
2 | @use '../vars' as *;
3 |
4 | .astro-content-docs.layout-default {
5 | *::-webkit-scrollbar {
6 | width: 16px;
7 | }
8 |
9 | *::-webkit-scrollbar-track {
10 | background: $ca-black;
11 | }
12 |
13 | *::-webkit-scrollbar-thumb {
14 | border-radius: 5px;
15 | background-color: color.adjust($ca-main-3, $lightness: -38%);
16 | border-top: 3px solid color.adjust($ca-main-3, $lightness: -34%);
17 | border-left: 3px solid color.adjust($ca-main-3, $lightness: -36%);
18 | border-right: 3px solid color.adjust($ca-main-3, $lightness: -40%);
19 | border-bottom: 3px solid color.adjust($ca-main-3, $lightness: -43%);
20 | }
21 |
22 | ::-webkit-scrollbar-corner {
23 | background-color: transparent;
24 | }
25 |
26 | ::-webkit-scrollbar-thumb:hover {
27 | /* hover thumb styles */
28 | // background-color: red;
29 | cursor: default;
30 | background-color: color.adjust($ca-main-3, $lightness: -15%);
31 | }
32 | // ::-webkit-scrollbar-thumb:horizontal:active,
33 | // ::-webkit-scrollbar-thumb:vertical:active {
34 | // /* active thumb styles */
35 | // }
36 | }
37 |
--------------------------------------------------------------------------------
/docs/src/modules/Actions.astro:
--------------------------------------------------------------------------------
1 | ---
2 | import { Link } from 'astro-link';
3 | /* ·········································································· */
4 | import './Actions.scss';
5 | ---
6 |
7 |
32 |
--------------------------------------------------------------------------------
/docs/src/modules/Demo.astro:
--------------------------------------------------------------------------------
1 | ---
2 | // REFACTOR: When video will be needed, or delete
3 |
4 | // import { Link } from 'astro-link';
5 | // import { Icon } from '@iconify/react';
6 |
7 | import './Landing.scss';
8 | import type { Demo } from '/content';
9 |
10 | export interface Props {
11 | data: Demo;
12 | }
13 | const { data } = Astro.props as Props;
14 | ---
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
30 |
31 |
35 |
36 |
37 |
38 |
63 |
--------------------------------------------------------------------------------
/docs/src/modules/DocPage.astro:
--------------------------------------------------------------------------------
1 | ---
2 | import { type Docs, type DocSectionEntryNames } from '/content';
3 | /* ·········································································· */
4 | import { Link } from 'astro-link';
5 | import TreeNavigation from '../components/TreeNavigation.astro';
6 | import PrevNextNavigation from '../components/PrevNextNavigation.astro';
7 | import './DocPage.scss';
8 | /* —————————————————————————————————————————————————————————————————————————— */
9 |
10 | const { docs } = Astro.props as { docs: Docs };
11 | const { page } = Astro.params as unknown as { page: DocSectionEntryNames };
12 |
13 | /* ·········································································· */
14 |
15 | const Main = docs?.[page]?.main?.Content;
16 | ---
17 |
18 |
19 |
20 |
21 |
Sections
22 |
23 |
24 |
25 |
26 |
On this page
27 |
28 |
29 |
30 |
31 |
32 | {Main && }
33 |
34 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/docs/src/modules/DocPage.scss:
--------------------------------------------------------------------------------
1 | @use 'sass:color';
2 | @use '../vars' as *;
3 |
4 | .astro-content-docs.layout-default .module-doc-page {
5 | .article-body {
6 | width: calc(42rem + 17vw);
7 | margin-left: 20vw;
8 | @media screen and (max-width: 700px) {
9 | width: initial;
10 | margin: 5vw;
11 | }
12 | }
13 |
14 | .navigations {
15 | h2 {
16 | padding: 0rem 2.5rem 0rem 2.5rem;
17 | }
18 |
19 | @media screen and (max-width: 700px) {
20 | position: relative;
21 | flex-wrap: wrap;
22 | height: initial;
23 | }
24 |
25 | position: sticky;
26 | top: 0;
27 | display: flex;
28 | justify-content: space-between;
29 | height: 0;
30 |
31 | .this-page {
32 | text-align: right;
33 | }
34 | }
35 |
36 | .prev-next {
37 | display: flex;
38 | justify-content: space-between;
39 | width: 100%;
40 | padding: 8rem 1rem 6rem 1rem;
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/docs/src/modules/IdeDemo.astro:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JulianCataldo/astro-content/d5ed86fcc9ae27cede28ebcedabaaf39a45ae613/docs/src/modules/IdeDemo.astro
--------------------------------------------------------------------------------
/docs/src/pages/docs/[page].astro:
--------------------------------------------------------------------------------
1 | ---
2 | import { get } from '/content';
3 | /* ·········································································· */
4 | import Layout from '../../layouts/Default.astro';
5 | import DocPage from '../../modules/DocPage.astro';
6 | /* —————————————————————————————————————————————————————————————————————————— */
7 |
8 | export async function getStaticPaths() {
9 | const files = await get(Astro.glob('/content/docs/**/*.{md,mdx,yaml}'));
10 | return (
11 | files.docs &&
12 | Object.entries(files.docs).map(([key]) => ({ params: { page: key } }))
13 | );
14 | }
15 |
16 | /* —————————————————————————————————————————————————————————————————————————— */
17 |
18 | const content = await get(Astro.glob('/content/**/*.{md,mdx,yaml}'), {
19 | // NOTE: Ignore this. Used for collecting + building Web GUI static data.
20 | editMode: import.meta.env.PROD,
21 | });
22 | ---
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/docs/src/pages/index.astro:
--------------------------------------------------------------------------------
1 | ---
2 | import { get } from '/content';
3 | /* ·········································································· */
4 | import Layout from '../layouts/Default.astro';
5 | import Landing from '../modules/Landing.astro';
6 | import Actions from '../modules/Actions.astro';
7 | import Presentation from '../modules/Presentation.astro';
8 | /* —————————————————————————————————————————————————————————————————————————— */
9 |
10 | /* Demo content */
11 | const content = await get(
12 | Astro.glob('/content/**/*.{md,mdx,yaml}'),
13 | // NOTE: this will force trigger `__content` data fetching,
14 | // for demo purposes only, for this docs.
15 | // Might be better to ensure `__content` doesn't get overwritten during build.
16 | {
17 | editMode: import.meta.env.PROD,
18 | },
19 | );
20 |
21 | const landing = content.modules?.landing;
22 | ---
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/docs/src/pages/licenses.astro:
--------------------------------------------------------------------------------
1 | ---
2 | import { LicensesReport } from 'astro-licenses-report';
3 | /* ·········································································· */
4 | import Layout from '../layouts/Default.astro';
5 |
6 | /* —————————————————————————————————————————————————————————————————————————— */
7 | ---
8 |
9 |
10 |
11 |
12 |
13 |
14 |
68 |
--------------------------------------------------------------------------------
/docs/src/vars.scss:
--------------------------------------------------------------------------------
1 | $ca-black: rgb(15, 23, 42);
2 | $ca-white: rgb(248 250 252);
3 | $ca-accent: hsl(22, 100%, 50%);
4 | $ca-main-3: hsl(262, 83%, 58%);
5 | $ca-main-4: hsl(271, 81%, 56%);
6 | $ca-main-5: hsl(272, 72%, 47%);
7 | $ca-main-6: hsl(272, 84%, 82%);
8 | $ca-bg-grad-1: linear-gradient(
9 | 180deg,
10 | hsl(273, 37%, 93%),
11 | hsl(273, 37%, 93%) calc(6rem + 4rem),
12 | #fdfeff
13 | );
14 | $ca-bg-grad-2: linear-gradient(180deg, #6d39ff, #af43ff);
15 | $font-fancy: monospace;
16 |
--------------------------------------------------------------------------------
/docs/tsconfig.json:
--------------------------------------------------------------------------------
1 | // Example: starter tsconfig.json for Astro projects
2 | {
3 | "compilerOptions": {
4 | // Enable top-level await and other modern ESM features.
5 | "target": "ESNext",
6 | "module": "ESNext",
7 | // Enable node-style module resolution, for things like npm package imports.
8 | "moduleResolution": "node",
9 | // Enable JSON imports.
10 | "resolveJsonModule": true,
11 | // Enable stricter transpilation for better output.
12 | "isolatedModules": true,
13 | // Astro will directly run your TypeScript code, no transpilation needed.
14 | "noEmit": true,
15 |
16 | "skipLibCheck": true,
17 |
18 | "strict": false,
19 |
20 | "strictNullChecks": true,
21 |
22 | "baseUrl": ".",
23 |
24 | // "types": [],
25 | "paths": {
26 | // IDEA: Add to workspace setup?
27 | // Make TS/ESLint happy with absolute paths
28 | "/content": ["./content"]
29 | },
30 |
31 | "outDir": "./dist",
32 |
33 | "allowSyntheticDefaultImports": true
34 |
35 | // "plugins": [{ "name": "ts-css-modules-vite-plugin", "root": "./" }]
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/packages/cli/help.ts:
--------------------------------------------------------------------------------
1 | const addHelp = `
2 | Usage examples
3 |
4 | pnpm content add zebras zebra
5 | => New entity "zebras" with the singular name of "zebra"
6 |
7 | Note: An entity act as collection of entries or singletons
8 | Entry have common schema, singletons have their own schemas
9 | It's up to user to decorrelate singletons in their schema
10 |
11 | pnpm content add zebras doody
12 | => Add a "zebra" entry with an unique name "doody" in "zebras" entity
13 | `;
14 |
15 | export { addHelp };
16 |
--------------------------------------------------------------------------------
/packages/cli/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@astro-content/cli",
3 | "version": "0.0.0-alpha.13",
4 | "description": "",
5 | "type": "module",
6 | "// source": "./index.ts",
7 | "main": "./dist/index.js",
8 | "// bin": "./dist/index.js",
9 | "files": [
10 | "dist/*"
11 | ],
12 | "scripts": {
13 | "build": "tsc",
14 | "dev": "tsc -w",
15 | "clean": "rm -rf dist .turbo",
16 | "test": "echo \"Error: no test specified\" && exit 1"
17 | },
18 | "dependencies": {
19 | "@astro-content/server": "workspace:*",
20 | "@types/inquirer": "^9.0.2",
21 | "commander": "^9.4.1",
22 | "inquirer": "^9.1.3"
23 | },
24 | "devDependencies": {
25 | "typescript": "^4.8.4"
26 | },
27 | "keywords": [],
28 | "author": "Julian Cataldo",
29 | "license": "ISC",
30 | "publishConfig": {
31 | "access": "public"
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/packages/cli/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | // Enable top-level await, and other modern ESM features.
4 | "target": "ESNext",
5 | "module": "ESNext",
6 | // Enable node-style module resolution, for things like npm package imports.
7 | "moduleResolution": "node",
8 | // Enable JSON imports.
9 | "resolveJsonModule": true,
10 | // Enable stricter transpilation for better output.
11 | "isolatedModules": true,
12 | // Add type definitions for our Astro runtime.
13 | "types": [
14 | //
15 | "astro/client",
16 | "node"
17 | ],
18 |
19 | "baseUrl": ".",
20 |
21 | "allowSyntheticDefaultImports": true,
22 |
23 | "noImplicitAny": true,
24 |
25 | "strictNullChecks": true,
26 |
27 | "importsNotUsedAsValues": "error",
28 |
29 | "declaration": true,
30 |
31 | "outDir": "./dist"
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/packages/dynamic-store/index.ts:
--------------------------------------------------------------------------------
1 | // @ts-expect-error
2 |
3 | import integration from './integration.js';
4 |
5 | export { getFile } from './get-file.js';
6 | export { getContent } from './get-content.js';
7 |
8 | export * from './types.js';
9 |
10 | export default integration;
11 |
--------------------------------------------------------------------------------
/packages/dynamic-store/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@astro-content/dynamic-store",
3 | "version": "0.0.0-alpha.17",
4 | "description": "",
5 | "keywords": [
6 | "astro",
7 | "astro-integration",
8 | "frontmatter",
9 | "markdown",
10 | "caching",
11 | "filtering",
12 | "glob",
13 | "import",
14 | "ssr",
15 | "query",
16 | "fetch",
17 | "watch",
18 | "live-update",
19 | "files"
20 | ],
21 | "homepage": "https://astro-content.dev",
22 | "repository": {
23 | "type": "git",
24 | "url": "https://github.com/JulianCataldo/astro-content",
25 | "directory": "packages/dynamic-store"
26 | },
27 | "license": "ISC",
28 | "author": "Julian Cataldo",
29 | "type": "module",
30 | "main": "./dist/index.js",
31 | "files": [
32 | "dist/*"
33 | ],
34 | "scripts": {
35 | "build": "tsc",
36 | "clean": "rm -rf dist .turbo",
37 | "dev": "tsc -w",
38 | "test": "echo \"Error: no test specified\" && exit 1"
39 | },
40 | "dependencies": {
41 | "chokidar": "^3.5.3",
42 | "glob-promise": "^5.0.0",
43 | "lodash-es": "^4.17.21",
44 | "yaml": "^2.1.3"
45 | },
46 | "devDependencies": {
47 | "typescript": "^4.8.4"
48 | },
49 | "// publishConfig": {
50 | "access": "public"
51 | },
52 | "// source": "./index.ts"
53 | }
54 |
--------------------------------------------------------------------------------
/packages/dynamic-store/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ESNext",
4 | "module": "ESNext",
5 |
6 | "moduleResolution": "node",
7 | // Enable JSON imports.
8 | "resolveJsonModule": true,
9 |
10 | "isolatedModules": true,
11 |
12 | "types": ["node"],
13 |
14 | "baseUrl": ".",
15 |
16 | "allowSyntheticDefaultImports": true,
17 |
18 | "noImplicitAny": true,
19 |
20 | "strictNullChecks": true,
21 |
22 | "importsNotUsedAsValues": "error",
23 |
24 | "declaration": true,
25 |
26 | "outDir": "./dist"
27 | },
28 |
29 | "include": ["./index.ts"]
30 | }
31 |
--------------------------------------------------------------------------------
/packages/dynamic-store/utils.ts:
--------------------------------------------------------------------------------
1 | import crypto from 'node:crypto';
2 |
3 | export function createHash(queryOptions: unknown) {
4 | const optionsHash = crypto
5 | .createHash('sha256')
6 | .update(JSON.stringify(queryOptions))
7 | .digest('hex');
8 |
9 | return optionsHash;
10 | }
11 |
--------------------------------------------------------------------------------
/packages/dynamic-store/watcher.ts:
--------------------------------------------------------------------------------
1 | // @ts-ignore
2 | import chokidar from 'chokidar';
3 | /* ========================================================================== */
4 |
5 | // IDEA: Cache should be invalidated
6 | // in dev.for any files(jsx, ts, vue, astro…) ?
7 | const watcher = chokidar.watch('**/*.md', {
8 | ignored: ['node_modules'],
9 | });
10 |
11 | const watchers: ((file: string) => void)[] = [];
12 |
13 | watcher.on('ready', () => {
14 | console.log('Dynamic store watcher is ready');
15 | watcher.on('all', (event, file) => {
16 | if (['add', 'change'].includes(event)) {
17 | console.log(`${event}: ${file}`);
18 | watchers.map((callback) => callback(file));
19 | }
20 | });
21 | });
22 |
23 | export { watchers };
24 |
--------------------------------------------------------------------------------
/packages/faker/cli.ts:
--------------------------------------------------------------------------------
1 | #! /usr/bin/env node
2 |
3 | /* eslint-disable no-console */
4 |
5 | import { generateFakeContent } from './index.js';
6 |
7 | console.log('Generating checkers…');
8 |
9 | const mdTemplatePath = process.argv[2];
10 | const outDir = process.argv[3];
11 | const count = parseInt(process.argv[4] ?? '1', 10);
12 |
13 | /* ·········································································· */
14 |
15 | console.log(
16 | `➤ Generating fake entries: ${mdTemplatePath}, ${outDir}, ${count}`,
17 | );
18 |
19 | if (Boolean(mdTemplatePath) === false) {
20 | console.log(`Missing input template path`);
21 | process.exit();
22 | }
23 | if (Boolean(outDir) === false) {
24 | console.log(`Missing output directory`);
25 | process.exit();
26 | }
27 |
28 | await generateFakeContent(mdTemplatePath, outDir, count).catch((error) => {
29 | console.log(error);
30 | });
31 |
32 | export {};
33 |
--------------------------------------------------------------------------------
/packages/faker/demo/.gitignore:
--------------------------------------------------------------------------------
1 | # build output
2 | dist/
3 | .output/
4 |
5 | # dependencies
6 | node_modules/
7 |
8 | # logs
9 | npm-debug.log*
10 | yarn-debug.log*
11 | yarn-error.log*
12 | pnpm-debug.log*
13 |
14 |
15 | # environment variables
16 | .env
17 | .env.production
18 |
19 | # macOS-specific files
20 | .DS_Store
21 |
--------------------------------------------------------------------------------
/packages/faker/demo/.remarkrc.yaml:
--------------------------------------------------------------------------------
1 | plugins:
2 | - remark-frontmatter
3 |
4 | - - remark-lint-frontmatter-schema
5 | - schemas:
6 | src/schemas/blog-post.schema.yaml:
7 | - content/blog-posts/*.{md,mdx}
8 |
--------------------------------------------------------------------------------
/packages/faker/demo/README.md:
--------------------------------------------------------------------------------
1 | # Faker
2 |
3 | Example:
4 |
5 | ## CLI usage
6 |
7 | ```sh
8 | content-faker $SOURCE_TEMPLATE $OUTPUT_DIRECTORY 20
9 |
10 | # E.g.
11 | pnpm content-faker src/mocks/blog-post.template.md content/blog-posts 20
12 | ```
13 |
14 | # 🧞 Astro project commands
15 |
16 | All commands are run from the root of the project, from a terminal:
17 |
18 | | Command | Action |
19 | | :--------------------- | :------------------------------------------------- |
20 | | `npm install` | Installs dependencies |
21 | | `npm run dev` | Starts local dev server at `localhost:3000` |
22 | | `npm run build` | Build your production site to `./dist/` |
23 | | `npm run preview` | Preview your build locally, before deploying |
24 | | `npm run astro ...` | Run CLI commands like `astro add`, `astro preview` |
25 | | `npm run astro --help` | Get help using the Astro CLI |
26 |
--------------------------------------------------------------------------------
/packages/faker/demo/astro.config.mjs:
--------------------------------------------------------------------------------
1 | import { defineConfig } from 'astro/config';
2 |
3 | // https://astro.build/config
4 | export default defineConfig({});
5 |
--------------------------------------------------------------------------------
/packages/faker/demo/content/blog-posts/combat-bijou-clank.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: nostrud
3 | description: cillum incididuntaliquaUt ex qui nonaliquaconsecteturminim indolor
4 | tempor Excepteur veniamvoluptate minim
5 | tags:
6 | - Music
7 | - Development
8 | ---
9 |
10 |
11 |
12 | # Quibusdam harum dolorem accusantium debitis pariatur commodi a eaque incidunt.
13 |
14 | ## Facere hic autem ipsam dignissimos quam cum reiciendis occaecati.
15 |
16 | **Brookeland**
17 |
18 | Reprehenderit eum assumenda impedit repudiandae assumenda fuga sint nisi dignissimos repudiandae sequi.
19 |
20 | ### Eveniet molestias nostrum rerum a facere quo minima perferendis.
21 |
22 |
23 |
24 | ---
25 |
26 | > Ea atque magnam rerum distinctio praesentium commodi ut doloribus expedita.
27 |
28 | ---
29 |
30 | - Cumque molestiae nulla quia harum impedit.
31 | - Amet ratione optio vel perferendis consequuntur iure libero.
32 | - Accusantium magni excepturi placeat quos totam asperiores totam voluptate eveniet.
33 |
34 |
35 |
36 | ## Ullam velit illum cum sunt sequi eaque sint eos.
37 |
38 | Hic minus dolor laudantium laboriosam mollitia ratione numquam. Iusto inventore est doloremque magnam deleniti quibusdam at tenetur autem. Fugit eveniet deleniti suscipit totam quasi velit corrupti. Minima expedita quidem odit officiis aut consequatur.
39 | Tenetur sit earum veniam. Magnam aliquid officia facere. Dolore iure occaecati architecto ipsam illum. Itaque consequuntur voluptates praesentium labore placeat sint quod quos fuga. Quia ipsa reiciendis.
40 |
41 | ### Sit itaque nostrum amet magni laboriosam sapiente odio officiis.
42 |
43 |
44 |
45 | Voluptates omnis eligendi hic. Reprehenderit architecto dolorum. Numquam eligendi sint omnis harum quam modi nostrum.
46 |
47 | ---
48 |
49 | 18/11/2022
50 |
--------------------------------------------------------------------------------
/packages/faker/demo/content/blog-posts/frigate-emitter-jeans.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: irure voluptate sit aliqua ea
3 | description: mollit aliquaenimid consectetur officia Duislaborisexercitation eu
4 | velit commodoaliquip doametaute Duis amet pariatur deserunt
5 | tags:
6 | - Cooking
7 | - Video
8 | ---
9 |
10 |
11 |
12 | # Iusto nisi in rerum quos explicabo tempora adipisci ex quam.
13 |
14 | ## Inventore pariatur consequuntur minima incidunt explicabo sit inventore quasi.
15 |
16 | **Lefflerfurt**
17 |
18 | Ducimus nihil nam veritatis ratione assumenda nobis magnam quibusdam suscipit deleniti laborum.
19 |
20 | ### Vitae praesentium cum reprehenderit voluptate praesentium modi eum blanditiis.
21 |
22 |
23 |
24 | ---
25 |
26 | > Molestiae error quod laudantium delectus libero asperiores culpa accusantium nobis.
27 |
28 | ---
29 |
30 | - Consequuntur laborum sit reprehenderit laboriosam explicabo.
31 | - Consequuntur voluptas ullam exercitationem exercitationem error fuga dolores.
32 | - Atque nisi quas debitis provident nisi exercitationem itaque quis impedit.
33 |
34 |
35 |
36 | ## Laudantium perspiciatis odit illo assumenda non accusantium vero ab.
37 |
38 | Veritatis quidem quo ea aut deserunt aperiam adipisci. Officiis assumenda et ipsum fugit cumque quas temporibus voluptate magnam. Quaerat aperiam cumque voluptatem. Voluptatum temporibus expedita quo deserunt reiciendis ullam. Cum commodi voluptatibus quas doloremque consequatur inventore eveniet cum ratione.
39 | Amet vel corrupti autem possimus libero. Voluptate earum voluptatum natus aspernatur asperiores odio exercitationem fuga vero. Natus reiciendis eum aliquid.
40 |
41 | ### Fugit quidem est corporis quo asperiores facere soluta numquam.
42 |
43 |
44 |
45 | Velit magni odit voluptatibus. Eligendi adipisci debitis praesentium earum ipsa. Facere tenetur fugiat. Aut vitae maiores eius ducimus ratione.
46 |
47 | ---
48 |
49 | 18/11/2022
50 |
--------------------------------------------------------------------------------
/packages/faker/demo/content/blog-posts/movie-massage-atheist.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: ut
3 | description: irure Lorem etlaborum consecteturlabore elit nisi aliquipnisi
4 | aliqua aute sed quiut nulla laborissunt tempor
5 | ---
6 |
7 |
8 |
9 | # Totam dolorem ut neque blanditiis ullam inventore nemo quod explicabo.
10 |
11 | ## Illo ipsa quis natus quos velit non doloremque facere.
12 |
13 | **East Laylamouth**
14 |
15 | Tenetur hic labore consequatur non ducimus quae non accusantium vero eum doloremque.
16 |
17 | ### Repellat ad ratione id illum aspernatur illum veritatis eius.
18 |
19 |
20 |
21 | ---
22 |
23 | > Voluptatum amet ipsa sunt nihil deleniti ratione minus voluptatibus deleniti.
24 |
25 | ---
26 |
27 | - Similique quo quos quisquam maiores vero.
28 | - Commodi et molestiae magnam aliquid excepturi molestiae odio.
29 | - Aliquam occaecati exercitationem tempora id dolore enim aperiam vel nostrum.
30 |
31 |
32 |
33 | ## Eligendi reprehenderit illo id unde deleniti odit impedit architecto.
34 |
35 | Nesciunt corrupti aut aliquid a dolorem perspiciatis. Itaque minus nobis beatae enim accusantium atque deserunt accusantium quia. Nisi cumque occaecati. Eaque libero corrupti deserunt voluptates ea reprehenderit ipsam. Minima odit velit optio explicabo recusandae cum reiciendis nisi. Perferendis sapiente dolores delectus a eos iste ex ab.
36 | Ratione aliquid voluptatum ex. Repellat eaque dolorum veritatis expedita voluptatem dicta. Voluptatem voluptatem voluptates esse eos inventore fugit veniam eum quis. Odit distinctio error asperiores veniam architecto illo corrupti animi.
37 |
38 | ### Placeat esse possimus aliquid earum repellendus eius maiores dolorem.
39 |
40 |
41 |
42 | Distinctio saepe libero. Minus voluptatum commodi provident quidem nesciunt. Odio omnis aliquam error. Libero asperiores itaque qui in consectetur nostrum minus natus. Quos dignissimos odio.
43 |
44 | ---
45 |
46 | 18/11/2022
47 |
--------------------------------------------------------------------------------
/packages/faker/demo/content/blog-posts/orient-ukulele-saddle.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: tempor reprehenderit pariatur eu adipisicing
3 | description: inin eu tempor laboreest eiusmod amet quis adipisicingsit commodo
4 | doloreesse cupidatat officiaofficia magna tempor dolore in
5 | tags:
6 | - Gardening
7 | - Sport
8 | ---
9 |
10 |
11 |
12 | # At accusantium omnis neque excepturi aliquam tenetur rem voluptas eos.
13 |
14 | ## Facere quasi omnis maxime unde modi velit error consequatur.
15 |
16 | **East Opalhaven**
17 |
18 | Veritatis totam saepe ut quod laborum distinctio quidem sed aperiam magni nulla.
19 |
20 | ### Vel ducimus magni quo saepe alias explicabo ipsam aspernatur.
21 |
22 |
23 |
24 | ---
25 |
26 | > Illum distinctio quidem reprehenderit placeat quaerat impedit accusantium odio nulla.
27 |
28 | ---
29 |
30 | - Sunt aliquam labore est culpa ullam.
31 | - Quae mollitia adipisci sed quam quae inventore earum.
32 | - Ipsam odio non repellat in beatae eveniet libero dolorem commodi.
33 |
34 |
35 |
36 | ## Animi quae doloremque tempora dolore dolorem eius amet unde.
37 |
38 | Maxime sit exercitationem doloremque enim alias nemo debitis earum nihil. Fuga ipsam laboriosam. Id beatae ipsam corporis sint labore cupiditate. Necessitatibus quaerat quisquam quam minima. Illo beatae nulla numquam voluptas impedit illo ipsa.
39 | Ut asperiores nobis. Modi quidem necessitatibus cupiditate. At animi vitae modi. Cum assumenda libero aperiam iste ullam. Assumenda dolorem tempora modi cum amet enim.
40 |
41 | ### Cupiditate aspernatur numquam ipsum nihil saepe unde enim fuga.
42 |
43 |
44 |
45 | Autem unde harum eius. Explicabo labore dolorum commodi nulla. Cum cupiditate suscipit nobis numquam vel. Numquam illo architecto qui perferendis id. Odit quo eligendi cupiditate ipsa. Autem natus voluptatibus dolores placeat illum quas corrupti occaecati.
46 |
47 | ---
48 |
49 | 17/11/2022
50 |
--------------------------------------------------------------------------------
/packages/faker/demo/content/blog-posts/trust-topsail-dairy.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: a
3 | description: cupidatat Lorem dolorest culpa utnisi irure quiin
4 | Excepteurreprehenderittempor Ut in reprehenderitaute
5 | tags:
6 | - Development
7 | ---
8 |
9 |
10 |
11 | # Neque debitis quod reprehenderit quae exercitationem expedita ducimus sed vitae.
12 |
13 | ## Expedita ipsa perspiciatis esse quam minus tempora commodi quae.
14 |
15 | **Boyleview**
16 |
17 | Ab corrupti fuga numquam exercitationem fugiat fuga aliquam magni aliquid quos quibusdam.
18 |
19 | ### Incidunt accusantium ullam temporibus reiciendis nihil occaecati inventore deserunt.
20 |
21 |
22 |
23 | ---
24 |
25 | > Saepe quibusdam et quia ipsum ullam totam doloribus reprehenderit possimus.
26 |
27 | ---
28 |
29 | - Voluptas reprehenderit expedita veritatis provident nobis.
30 | - Amet eius quaerat ipsa a laudantium aliquid quod.
31 | - Veniam maxime inventore dignissimos neque autem rerum illum veritatis deserunt.
32 |
33 |
34 |
35 | ## Esse temporibus perferendis laborum modi quae rerum dolorum cumque.
36 |
37 | Magnam similique labore assumenda eum. Minus eum mollitia officia inventore aut adipisci suscipit. Necessitatibus repellendus iste autem iste provident minus optio nihil possimus. Dignissimos cupiditate fugiat quidem enim iure cumque.
38 | Amet blanditiis odit odio quibusdam delectus corporis voluptates iste. Accusantium nesciunt porro alias veritatis error et sit. Hic nisi pariatur nesciunt minus. Minima asperiores cumque. Rerum totam commodi perspiciatis in maiores temporibus ab.
39 |
40 | ### Sunt minus assumenda minima reprehenderit corporis doloremque nobis rem.
41 |
42 |
43 |
44 | Animi eius ducimus alias ipsam omnis dolor. Modi harum culpa perferendis perferendis porro illo. Ipsa qui non. Iste voluptatem autem sunt. Eaque adipisci doloribus quae nihil. Vero perspiciatis soluta.
45 |
46 | ---
47 |
48 | 17/11/2022
49 |
--------------------------------------------------------------------------------
/packages/faker/demo/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@example/basics",
3 | "type": "module",
4 | "version": "0.0.1",
5 | "private": true,
6 | "scripts": {
7 | "dev": "astro dev",
8 | "start": "astro dev",
9 | "build": "astro build",
10 | "preview": "astro preview",
11 | "astro": "astro"
12 | },
13 | "dependencies": {
14 | "@astro-content/faker": "latest",
15 | "astro": "^1.6.10"
16 | },
17 | "devDependencies": {
18 | "remark": "^14.0.2",
19 | "remark-cli": "^11.0.0"
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/packages/faker/demo/pnpm-workspace.yaml:
--------------------------------------------------------------------------------
1 | # STUB (ignore it).
2 |
--------------------------------------------------------------------------------
/packages/faker/demo/src/components/Card.astro:
--------------------------------------------------------------------------------
1 | ---
2 | export interface Props {
3 | title: string;
4 | body: string;
5 | href: string;
6 | }
7 |
8 | const { href, title, body } = Astro.props;
9 | ---
10 |
11 |
12 |
13 |
14 | {title}
15 | →
16 |
17 |
18 | {body}
19 |
20 |
21 |
22 |
63 |
--------------------------------------------------------------------------------
/packages/faker/demo/src/env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
--------------------------------------------------------------------------------
/packages/faker/demo/src/layouts/Layout.astro:
--------------------------------------------------------------------------------
1 | ---
2 | export interface Props {
3 | title: string;
4 | }
5 |
6 | const { title } = Astro.props;
7 | ---
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 | {title}
17 |
18 |
19 |
20 |
21 |
22 |
36 |
--------------------------------------------------------------------------------
/packages/faker/demo/src/mocks/blog-post.template.md:
--------------------------------------------------------------------------------
1 | ---
2 | '$schema': src/schemas/blog-post.schema.yaml
3 | ---
4 |
5 | ```js:faker
6 | '# ' + faker.lorem.sentence(10)
7 | ```
8 |
9 | ```js:faker
10 | '## ' + faker.lorem.sentence(9)
11 | ```
12 |
13 | ```js:faker
14 | `**${faker.address.city()}**`
15 | ```
16 |
17 | ```js:faker
18 | faker.lorem.sentence(12)
19 | ```
20 |
21 | ```js:faker
22 | '### ' + faker.lorem.sentence(9)
23 | ```
24 |
25 | ```js:faker
26 | ``
27 | ```
28 |
29 | ---
30 |
31 | ```js:faker
32 | '> ' + faker.lorem.sentence(10)
33 | ```
34 |
35 | ---
36 |
37 | ```js:faker
38 | `- ${faker.lorem.sentence(6)}\n- ${faker.lorem.sentence(8)}\n- ${faker.lorem.sentence(10)}`
39 | ```
40 |
41 | ```js:faker
42 | ``
43 | ```
44 |
45 | ```js:faker
46 | '## ' + faker.lorem.sentence(9)
47 | ```
48 |
49 | ```js:faker
50 | faker.lorem.paragraphs(2)
51 | ```
52 |
53 | ```js:faker
54 | '### ' + faker.lorem.sentence(9)
55 | ```
56 |
57 | ```js:faker
58 | ``
59 | ```
60 |
61 | ```js:faker
62 | faker.lorem.paragraphs(1)
63 | ```
64 |
65 | ---
66 |
67 | ```js:faker
68 | faker.date.recent().toLocaleDateString()
69 | ```
70 |
--------------------------------------------------------------------------------
/packages/faker/demo/src/schemas/blog-post.schema.yaml:
--------------------------------------------------------------------------------
1 | title: Blog post
2 |
3 | allOf:
4 | - $ref: ./tags.schema.yaml
5 |
6 | - properties:
7 | title:
8 | title: Title
9 | default: My untitled blog post
10 | description: Used for SEO and tab title! # Will appear in auto-completion
11 | type: string
12 | minLength: 1
13 | maxLength: 80
14 |
15 | description:
16 | title: Description
17 | default: No description found.
18 | description: Used for SEO
19 | type: string
20 | minLength: 100
21 | maxLength: 300
22 |
23 | required:
24 | - title
25 | - description
26 |
--------------------------------------------------------------------------------
/packages/faker/demo/src/schemas/tags.schema.yaml:
--------------------------------------------------------------------------------
1 | description: |
2 | Used for content classification
3 |
4 | properties:
5 | tags:
6 | type: array
7 | uniqueItems: true
8 | minItems: 1
9 | maxItems: 8
10 | items:
11 | type: string
12 | enum:
13 | - Music
14 | - Video
15 | - Development
16 | - Cooking
17 | - Gardening
18 | - Sport
19 |
--------------------------------------------------------------------------------
/packages/faker/demo/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "astro/tsconfigs/base",
3 | "base": "."
4 | }
5 |
--------------------------------------------------------------------------------
/packages/faker/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@astro-content/faker",
3 | "version": "0.0.0-alpha.16",
4 | "description": "",
5 | "keywords": [
6 | "astro",
7 | "astro-integration",
8 | "json-schema",
9 | "faker",
10 | "frontmatter",
11 | "markdown"
12 | ],
13 | "homepage": "https://astro-content.dev",
14 | "repository": {
15 | "type": "git",
16 | "url": "https://github.com/JulianCataldo/astro-content",
17 | "directory": "packages/faker"
18 | },
19 | "license": "ISC",
20 | "author": "Julian Cataldo",
21 | "type": "module",
22 | "main": "./dist/index.js",
23 | "bin": {
24 | "content-faker": "./dist/cli.js"
25 | },
26 | "files": [
27 | "dist/*"
28 | ],
29 | "scripts": {
30 | "build": "tsc",
31 | "clean": "rm -rf dist .turbo",
32 | "dev": "tsc -w",
33 | "test": "echo \"Error: no test specified\" && exit 1"
34 | },
35 | "dependencies": {
36 | "@apidevtools/json-schema-ref-parser": "^9.0.9",
37 | "@faker-js/faker": "^7.6.0",
38 | "json-schema-faker": "0.5.0-rcv.46",
39 | "yaml": "^2.1.3"
40 | },
41 | "devDependencies": {
42 | "typescript": "^4.8.4"
43 | },
44 | "publishConfig": {
45 | "access": "public"
46 | },
47 | "// source": "./index.ts"
48 | }
49 |
--------------------------------------------------------------------------------
/packages/faker/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ESNext",
4 | "module": "ESNext",
5 |
6 | "moduleResolution": "node",
7 | // Enable JSON imports.
8 | "resolveJsonModule": true,
9 |
10 | "isolatedModules": true,
11 |
12 | "types": ["node"],
13 |
14 | "baseUrl": ".",
15 |
16 | "allowSyntheticDefaultImports": true,
17 |
18 | "noImplicitAny": true,
19 |
20 | "strictNullChecks": true,
21 |
22 | "importsNotUsedAsValues": "error",
23 |
24 | "declaration": true,
25 |
26 | "outDir": "./dist"
27 | },
28 |
29 | "include": ["./index.ts", "./cli.ts"]
30 | }
31 |
--------------------------------------------------------------------------------
/packages/gui/components/App/keyboard-shortcuts.ts:
--------------------------------------------------------------------------------
1 | import { useEffect } from 'react';
2 | /* ·········································································· */
3 | import { log } from '../../logger';
4 | import { useAppStore } from '../../store';
5 | /* —————————————————————————————————————————————————————————————————————————— */
6 |
7 | export function useKeyBoardShortcuts() {
8 | const save = useAppStore((state) => state.editor_save);
9 | useEffect(() => {
10 | /* Save — Keyboard shortcut */
11 | function handleAction(e: KeyboardEvent) {
12 | const metaKey = e.metaKey || e.ctrlKey;
13 | if (e.key === 's' && metaKey) {
14 | e.preventDefault();
15 | save();
16 | log('Keyboard: CtrlCmd+S fired!');
17 | }
18 | // // if (e.key === 'p' && metaKey) {
19 | // // e.preventDefault();
20 | // // showCommandPalette();
21 | // // log('Keyboard: Meta+P fired!');
22 | // // }
23 | // if (e.key === '/' && metaKey) {
24 | // // e.preventDefault();
25 |
26 | // log('Keyboard: CtrlCmd+/ fired!');
27 | // return false;
28 | // }
29 | return false;
30 | }
31 |
32 | document.addEventListener('keydown', handleAction);
33 | return () => {
34 | document.removeEventListener('keydown', handleAction);
35 | };
36 | });
37 | }
38 |
--------------------------------------------------------------------------------
/packages/gui/components/App/state-loader.ts:
--------------------------------------------------------------------------------
1 | import { useEffect, useState } from 'react';
2 | /* —————————————————————————————————————————————————————————————————————————— */
3 | import { useAppStore } from '../../store';
4 | import { log } from '../../logger';
5 | /* ··················../../logger··············································· */
6 |
7 | export function stateLoader() {
8 | // const data = useAppStore((state) => state.data_server);
9 | const [change, setChange] = useState(Math.random());
10 |
11 | useEffect(() => {
12 | // const socket = new WebSocket('ws://localhost:5011');
13 | // // Connection opened
14 | // socket.addEventListener('open', (event) => {
15 | // socket.send('Hello Server!');
16 | // });
17 | // // Listen for messages
18 | // socket.addEventListener('message', (event) => {
19 | // log(['Message from server ', event.data]);
20 | // setTimestamp(new Date());
21 | // });
22 | }, []);
23 |
24 | const fetchData = useAppStore((state) => state.data_fetchServerData);
25 | // NOTE: This is a work in progress
26 | if (import.meta.hot) {
27 | import.meta.hot.on('vite:beforeFullReload', () => {
28 | throw '(skipping full reload)';
29 | });
30 | }
31 |
32 | // useEffect(() => {
33 | // setInterval(() => {
34 | // setChange(Math.random());
35 | // }, 4500);
36 | // }, []);
37 |
38 | // FIXME: Not picking up changes
39 | useEffect(() => {
40 | fetchData()
41 | .then((e) => log(e))
42 | .catch((e) => log(e));
43 | }, [change]);
44 | // timestamp
45 |
46 | const fetchSavedUiState = useAppStore((state) => state.ui_fetchSaved);
47 |
48 | useEffect(() => {
49 | fetchSavedUiState();
50 | }, []);
51 |
52 | // return null;
53 | }
54 |
--------------------------------------------------------------------------------
/packages/gui/components/Assistant.scss:
--------------------------------------------------------------------------------
1 | @use 'sass:color' as color;
2 |
3 | .component-assistant {
4 | // width: calc(100% - 0.1rem);
5 | width: 100%;
6 | height: 100%;
7 | height: calc(100% - 3rem);
8 |
9 | img {
10 | max-width: 100%;
11 | }
12 |
13 | // NOTE: In-document rendering is disabled.
14 | // .markdown,
15 | .meta {
16 | height: 100%;
17 | padding: 0.5rem 2rem 2rem 2rem;
18 | overflow-y: auto;
19 | }
20 |
21 | .markdown {
22 | // width: 100%;
23 |
24 | iframe {
25 | width: 100%;
26 | height: 100%;
27 | padding: 0;
28 | margin: 0;
29 | }
30 | }
31 |
32 | & > * {
33 | height: 100%;
34 | }
35 | // .panes {
36 | // }
37 | }
38 |
--------------------------------------------------------------------------------
/packages/gui/components/CommandPalette.tsx:
--------------------------------------------------------------------------------
1 | // NOTE: WORK IN PROGRESS
2 |
3 | // const commandPaletteVisibility = useAppStore(
4 | // (state) => state.ui_commandPaletteVisibility,
5 | // );
6 | // const showCommandPalette = useAppStore(
7 | // (state) => state.ui_showCommandPalette,
8 | // );
9 |
10 | // {
11 | /* (
13 | <>
14 | This is a dialog!
15 |
16 | Now that we've got your attention, you can close this.
17 |
18 |
19 | >
20 | )}
21 | open={commandPaletteVisibility}
22 | >
23 |
24 |
25 |
26 | */
27 | // }
28 |
--------------------------------------------------------------------------------
/packages/gui/components/CopyInlineCode.scss:
--------------------------------------------------------------------------------
1 | .component-copy-inline-code {
2 | position: relative;
3 | font-weight: 700;
4 | cursor: pointer;
5 |
6 | .prefix {
7 | user-select: none;
8 | }
9 |
10 | .overlay {
11 | position: absolute;
12 | display: flex;
13 | align-items: center;
14 | justify-content: center;
15 | width: 100%;
16 | height: 100%;
17 | background: var(--vscode-breadcrumb-background);
18 | border-radius: 0.15rem;
19 | opacity: 0;
20 |
21 | &.visible {
22 | opacity: 1;
23 | }
24 | }
25 |
26 | pre {
27 | code {
28 | display: inline-block;
29 | width: calc(100% - 1rem);
30 | padding: 0.5rem;
31 | cursor: pointer;
32 | background: var(--vscode-breadcrumb-background);
33 | border-radius: 0.15rem;
34 | }
35 | }
36 |
37 | &:hover {
38 | code {
39 | background: var(--vscode-toolbar-activeBackground);
40 | }
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/packages/gui/components/CopyInlineCode.tsx:
--------------------------------------------------------------------------------
1 | import type { Placement } from '@floating-ui/react-dom-interactions';
2 | import cx from 'classnames';
3 | import { useState } from 'react';
4 | // import Tooltip from './Tooltip';
5 | // import './CopyInlineCode.scss';
6 |
7 | interface Props {
8 | text: string;
9 | placement?: Placement;
10 | }
11 | export default function CopyInlineCode({ text, placement }: Props) {
12 | const [visible, setVisible] = useState(false);
13 |
14 | const copy = () => {
15 | navigator.clipboard
16 | .writeText(text)
17 | .then(() => {
18 | setVisible(true);
19 | setTimeout(() => setVisible(false), 1500);
20 | })
21 | .catch(() => null);
22 | };
23 |
24 | return (
25 | // TODO: Make a Tooltip hover group
26 | //
27 |
34 |
Copied to clipboard
35 |
36 | >
37 | {text}
38 |
39 |
40 | //
41 | );
42 | }
43 |
44 | CopyInlineCode.defaultProps = {
45 | placement: undefined,
46 | };
47 |
--------------------------------------------------------------------------------
/packages/gui/components/Editor/Editor.scss:
--------------------------------------------------------------------------------
1 | .component-editor {
2 | height: 100%;
3 | }
4 |
--------------------------------------------------------------------------------
/packages/gui/components/Editor/handlers.ts:
--------------------------------------------------------------------------------
1 | import type { Monaco as MonacoType } from '@monaco-editor/react';
2 | // import type { editor as nsEd } from 'monaco-editor';
3 | import type { Types } from '@astro-content/types/server-state';
4 | /* ·········································································· */
5 | import { log } from '../../logger';
6 | import { conf, language as mdx } from './mdx-language';
7 | /* —————————————————————————————————————————————————————————————————————————— */
8 |
9 | const handleEditorWillMount = (monaco: MonacoType, types: Types) => {
10 | log(['Monaco instance:', monaco]);
11 |
12 | /* Setup TypeScript */
13 | monaco.languages.typescript.typescriptDefaults.setCompilerOptions({
14 | target: monaco.languages.typescript.ScriptTarget.Latest,
15 | allowNonTsExtensions: true,
16 | moduleResolution: monaco.languages.typescript.ModuleResolutionKind.NodeJs,
17 | module: monaco.languages.typescript.ModuleKind.ESNext,
18 | noEmit: true,
19 | reactNamespace: 'React',
20 | isolatedModules: true,
21 | noImplicitAny: true,
22 | strictNullChecks: true,
23 | importsNotUsedAsValues: 'error',
24 | // allowSyntheticDefaultImports: true,
25 | });
26 |
27 | /* Setup MDX */
28 |
29 | monaco.languages.register({ id: 'mdx' });
30 | monaco.languages.setMonarchTokensProvider('mdx', mdx);
31 | monaco.languages.setLanguageConfiguration('mdx', conf(monaco.languages));
32 |
33 | /* Setup Themes */
34 | // IDEA: Implement this globally, synced with CSS
35 | // monaco.editor.defineTheme('Dracula', cobalt2 as nsEd.IStandaloneThemeData);
36 |
37 | if (types.browser) {
38 | const global = `${types.browser}\n${types.common
39 | .replaceAll('export type ', 'type ')
40 | .replaceAll('export interface ', 'interface ')}`;
41 |
42 | monaco.languages.typescript.typescriptDefaults.addExtraLib(
43 | global,
44 | 'global.d.ts',
45 | );
46 | }
47 | };
48 |
49 | export { handleEditorWillMount };
50 |
--------------------------------------------------------------------------------
/packages/gui/components/EntriesTable.scss:
--------------------------------------------------------------------------------
1 | .component-entries-table {
2 | height: calc(100%);
3 |
4 | html {
5 | font-family: sans-serif;
6 | font-size: 14px;
7 | }
8 |
9 | table {
10 | width: 100%;
11 | border: 1px solid lightgray;
12 | }
13 |
14 | tbody {
15 | border-bottom: 1px solid lightgray;
16 | }
17 |
18 | th {
19 | padding: 2px 4px;
20 | border-right: 1px solid lightgray;
21 | border-bottom: 1px solid lightgray;
22 | }
23 |
24 | tfoot {
25 | color: gray;
26 | }
27 |
28 | tfoot th {
29 | font-weight: normal;
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/packages/gui/components/File.tsx:
--------------------------------------------------------------------------------
1 | import { useEffect } from 'react';
2 | /* ·········································································· */
3 | import { useAppStore } from '../store';
4 | import Editor from './Editor/Editor';
5 | /* —————————————————————————————————————————————————————————————————————————— */
6 |
7 | export default function File() {
8 | const { content, schemas } = useAppStore((state) => state.data_server);
9 | const { entity, entry, property } = useAppStore((state) => state.ui_route);
10 | const setCurrentLanguage = useAppStore(
11 | (state) => state.editor_setCurrentLanguage,
12 | );
13 |
14 | const prop =
15 | entity && entry && property && content[entity]?.[entry]?.[property];
16 |
17 | useEffect(() => {
18 | if (prop) {
19 | setCurrentLanguage(prop.language);
20 | }
21 | }, [content, entry, entity, property]);
22 |
23 | return (
24 |
25 | {prop &&
}
26 | {/* Schema Editor */}
27 |
28 | {entity && !entry && content[entity] && (
29 |
30 | )}
31 |
32 | {entity && !content[entity] && (
33 |
34 | ← Please select a schema (entity) or a{' '}
35 | property (file)…
36 |
37 | )}
38 |
39 | );
40 | }
41 |
--------------------------------------------------------------------------------
/packages/gui/components/Headings.scss:
--------------------------------------------------------------------------------
1 | .headings {
2 | .headings-details {
3 | min-width: 22rem;
4 | overflow-y: auto;
5 | font-size: 100%;
6 | text-align: right;
7 |
8 | & > * {
9 | padding: 1em;
10 | font-weight: 400;
11 | cursor: pointer;
12 |
13 | &:hover {
14 | background-color: var(--vscode-diffEditor-insertedTextBackground);
15 | }
16 | }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/packages/gui/components/TabBar.scss:
--------------------------------------------------------------------------------
1 | .component-tab-bar {
2 | display: flex;
3 | overflow-x: auto;
4 | user-select: none;
5 | background-color: var(--vscode-quickInput-background);
6 | isolation: isolate;
7 | border-bottom: 1px solid hsla(0, 0%, 6%, 0.7);
8 | box-shadow: 0 0.07rem 0.15rem hsla(0, 0%, 5%, 0.1),
9 | 0 0.15rem 0.5rem hsla(0, 0%, 0%, 0.15);
10 |
11 | & > * {
12 | padding: 0.75rem 1.25rem;
13 | margin: 0rem 0rem;
14 | color: var(--vscode-quickInput-foreground);
15 | cursor: pointer;
16 | border-top: 2px solid transparent;
17 |
18 | &:hover {
19 | background-color: var(--vscode-toolbar-hoverBackground);
20 | }
21 | }
22 |
23 | .active {
24 | color: var(--vscode-list-activeSelectionForeground);
25 | background-color: var(--vscode-menu-background);
26 | border-top: 2px solid var(--vscode-input-placeholderForeground);
27 | }
28 |
29 | .tab {
30 | display: flex;
31 | align-items: center;
32 |
33 | svg {
34 | margin-right: 0.5em;
35 | }
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/packages/gui/components/TabBar.tsx:
--------------------------------------------------------------------------------
1 | import { Icon } from '@iconify/react';
2 | import cx from 'classnames';
3 | /* ·········································································· */
4 | // import './TabBar.scss';
5 | /* —————————————————————————————————————————————————————————————————————————— */
6 |
7 | export type Tabs = Record;
8 |
9 | interface Props {
10 | tabs: Tabs;
11 | switchPane: (index: string) => void;
12 | currentTab: string;
13 | defaultTab: string;
14 | }
15 | export default function Entity({
16 | tabs,
17 | switchPane,
18 | currentTab,
19 | defaultTab,
20 | }: Props) {
21 | let hasTab = false;
22 | Object.entries(tabs).forEach(([index /* , tab */]) => {
23 | if (currentTab === index) {
24 | hasTab = true;
25 | }
26 | });
27 |
28 | return (
29 |
30 | {/*
*/}
31 | {Object.entries(tabs).map(([index, tab]) => (
32 | // FIXME: JSX A11y
33 | // eslint-disable-next-line jsx-a11y/click-events-have-key-events, jsx-a11y/no-static-element-interactions
34 |
switchPane(index)}
42 | >
43 | {tab.icon && }
44 |
45 | {tab.title}
46 |
47 | ))}
48 | {/*
*/}
49 |
50 | );
51 | }
52 |
--------------------------------------------------------------------------------
/packages/gui/layouts/Base.astro:
--------------------------------------------------------------------------------
1 | ---
2 | // _
3 | ---
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 | 🚀 Astro Content — GUI
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/packages/gui/layouts/Default.astro:
--------------------------------------------------------------------------------
1 | ---
2 | // import './Default.scss';
3 |
4 | // NOTE: We're opting out of HMR totally when treating CSS separately
5 | import css from '../dist/styles.css?url';
6 |
7 | /* —————————————————————————————————————————————————————————————————————————— */
8 |
9 | import Base from './Base.astro';
10 | ---
11 |
12 |
13 |
14 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/packages/gui/layouts/Preview.astro:
--------------------------------------------------------------------------------
1 | ---
2 | // import 'github-markdown-css';
3 | // import './Preview.scss';
4 |
5 | import css from '../dist/styles.css?raw';
6 | ---
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 | 🚀 Astro Content — GUI
15 |
16 |
17 |
18 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/packages/gui/layouts/Preview.scss:
--------------------------------------------------------------------------------
1 | #preview {
2 | .markdown-body {
3 | padding: 1rem 5vw;
4 |
5 | & > *:first-child {
6 | margin-top: 1rem;
7 | }
8 |
9 | img {
10 | max-width: 100%;
11 | height: auto;
12 | }
13 | }
14 | }
15 |
16 | html {
17 | scroll-behavior: smooth;
18 | }
19 |
20 | body {
21 | scroll-behavior: smooth;
22 | margin: 0;
23 | }
24 |
--------------------------------------------------------------------------------
/packages/gui/layouts/diagrams.scss:
--------------------------------------------------------------------------------
1 | // NOTE: Work in progress
2 | // This does a basic dark mermaid diagram styling override.
3 |
4 | #diagram {
5 | color: #fff !important;
6 |
7 | .edgeLabel {
8 | color: #fff !important;
9 | background-color: #333 !important;
10 | }
11 |
12 | .label {
13 | color: #fff !important;
14 | background-color: #333 !important;
15 | }
16 |
17 | .arrowheadPath {
18 | fill: #ddd !important;
19 | stroke: #ddd !important;
20 | }
21 |
22 | .path {
23 | stroke: #ddd !important;
24 | }
25 |
26 | .cluster rect,
27 | .node rect,
28 | .node circle,
29 | .node ellipse,
30 | .node polygon,
31 | .node path {
32 | // fill: #333 !important;
33 | stroke: #aaa !important;
34 | }
35 |
36 | .marker {
37 | fill: #ddd !important;
38 | stroke: #ddd !important;
39 | }
40 |
41 | .marker.cross {
42 | stroke: #ddd !important;
43 | }
44 |
45 | .flowchart-link {
46 | stroke: #ddd !important;
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/packages/gui/layouts/scrollbars.scss:
--------------------------------------------------------------------------------
1 | *::-webkit-scrollbar {
2 | width: 16px;
3 | }
4 |
5 | *::-webkit-scrollbar-track {
6 | // background: _;
7 | }
8 |
9 | *::-webkit-scrollbar-thumb {
10 | background-color: var(--vscode-scrollbarSlider-background);
11 | // border-radius: 10px;
12 | // border: 3px solid #ffffff;
13 | }
14 |
15 | ::-webkit-scrollbar-corner {
16 | background-color: transparent;
17 | }
18 |
19 | ::-webkit-scrollbar-thumb:hover {
20 | /* hover thumb styles */
21 | // background-color: red;
22 | cursor: default;
23 | background-color: var(--vscode-scrollbarSlider-activeBackground);
24 | }
25 | // ::-webkit-scrollbar-thumb:horizontal:active,
26 | // ::-webkit-scrollbar-thumb:vertical:active {
27 | // /* active thumb styles */
28 | // }
29 |
--------------------------------------------------------------------------------
/packages/gui/layouts/themes/oceanic-next.scss:
--------------------------------------------------------------------------------
1 | :root {
2 | //
3 | }
4 |
--------------------------------------------------------------------------------
/packages/gui/logger.ts:
--------------------------------------------------------------------------------
1 | /* eslint-disable no-console */
2 | /* ·········································································· */
3 | import type { LogLevel, Mode } from '@astro-content/types/logger';
4 | /* —————————————————————————————————————————————————————————————————————————— */
5 |
6 | export enum Levels {
7 | silent,
8 | info,
9 | debug,
10 | absurd,
11 | }
12 |
13 | const defaultLevel: LogLevel = 'debug';
14 | const currentLevel: LogLevel = import.meta.env.PUBLIC_LOG_LEVEL as LogLevel;
15 |
16 | export function log(
17 | //
18 | value: unknown,
19 | level?: LogLevel,
20 | mode: Mode = 'dump',
21 | ) {
22 | let loggingLevel: LogLevel;
23 | if (!level) {
24 | loggingLevel = defaultLevel;
25 | } else {
26 | loggingLevel = level;
27 | }
28 |
29 | if (Levels[loggingLevel] <= Levels[currentLevel]) {
30 | if (mode === 'pretty') {
31 | const literal = typeof value === 'string' ? value : JSON.stringify(value);
32 | const time = new Date().toLocaleTimeString();
33 |
34 | console.log(
35 | `${time} ` +
36 | // —————————————————————————————————————————————————
37 | `${'[content]'} ${literal}`,
38 | );
39 | } else if (mode === 'table') {
40 | console.table(value);
41 | } else {
42 | /* Default : dump as is */
43 | console.log(value);
44 | }
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/packages/gui/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@astro-content/gui",
3 | "version": "0.0.0-alpha.13",
4 | "description": "",
5 | "type": "module",
6 | "scripts": {
7 | "build": "pnpm sass --embed-source-map styles.scss dist/styles.css",
8 | "dev": "pnpm sass -w styles.scss dist/styles.css",
9 | "clean": "rm -rf dist .turbo",
10 | "test": "echo \"Error: no test specified\" && exit 1"
11 | },
12 | "files": [
13 | "components/*",
14 | "layouts/*",
15 | "store/*",
16 | "dist/*",
17 | "*.ts",
18 | "*.astro"
19 | ],
20 | "devDependencies": {
21 | "@astro-content/types": "workspace:*",
22 | "@types/react": "^18.0.21",
23 | "sass": "^1.55.0"
24 | },
25 | "dependencies": {
26 | "@astro-content/server": "workspace:*",
27 | "@astrojs/mdx": "^0.11.4",
28 | "@astrojs/react": "^1.2.0",
29 | "@floating-ui/react-dom-interactions": "^0.10.1",
30 | "@iconify/react": "^4.0.0",
31 | "@monaco-editor/react": "^4.4.6",
32 | "@rjsf/core": "5.0.0-beta.11",
33 | "@rjsf/utils": "5.0.0-beta.11",
34 | "@rjsf/validator-ajv6": "5.0.0-beta.11",
35 | "@tanstack/react-location": "^3.7.4",
36 | "@tanstack/react-table": "^8.5.15",
37 | "change-case": "^4.1.2",
38 | "classnames": "^2.3.2",
39 | "framer-motion": "^7.5.3",
40 | "github-markdown-css": "^5.1.0",
41 | "lodash-es": "^4.17.21",
42 | "monaco-editor": "^0.34.0",
43 | "prettier": "2.7.1",
44 | "react": "18.2.0",
45 | "react-dom": "^18.2.0",
46 | "react-merge-refs": "^2.0.1",
47 | "react-split": "^2.0.14",
48 | "yaml": "^2.1.3",
49 | "zustand": "^4.1.2"
50 | },
51 | "keywords": [],
52 | "author": "Julian Cataldo",
53 | "license": "ISC",
54 | "publishConfig": {
55 | "access": "public"
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/packages/gui/store/data.ts:
--------------------------------------------------------------------------------
1 | import type { StoreApi } from 'zustand';
2 | /* ·········································································· */
3 | import type { Endpoint, ServerState } from '@astro-content/types/server-state';
4 | import type { AppState, DataState } from '@astro-content/types/gui-state';
5 | import { endpoints, getEmptyState } from '@astro-content/server/state';
6 | /* ·········································································· */
7 | import { log } from '../logger';
8 | /* —————————————————————————————————————————————————————————————————————————— */
9 |
10 | export async function fetchData() {
11 | log('Fetching…');
12 |
13 | const data: ServerState = getEmptyState();
14 |
15 | function setData(endpoint: T, newData: unknown) {
16 | data[endpoint] = newData as ServerState[T];
17 | }
18 |
19 | await Promise.all(
20 | endpoints.data.map(async (endpoint: keyof ServerState) =>
21 | fetch(`${endpoints.apiBase}/${endpoint}`).then((response) =>
22 | response
23 | .json()
24 | .then((newData) => setData(endpoint, newData))
25 | .catch((error) => log(error, 'info')),
26 | ),
27 | ),
28 | );
29 | return data;
30 | }
31 |
32 | const data = (set: StoreApi['setState']): DataState => ({
33 | data_server: getEmptyState(),
34 |
35 | /* ········································································ */
36 |
37 | data_fetchServerData: async () => {
38 | const result = await fetchData()
39 | .then((ss: ServerState) => ss)
40 | .catch(() => null);
41 |
42 | if (result) {
43 | log({ result });
44 | set((state) => {
45 | // IDEA: default route if no previous file selected?
46 | // const newUiSate = { ...state.uiState };
47 | if (!state.ui_route.entity) {
48 | // newUiSate.route.entity = '__previous-file__';
49 | }
50 | return { data_server: result };
51 | });
52 | }
53 | },
54 | });
55 |
56 | export default data;
57 |
--------------------------------------------------------------------------------
/packages/gui/store/helpers.ts:
--------------------------------------------------------------------------------
1 | export async function post(endpoint: string, data: unknown) {
2 | return fetch(endpoint, {
3 | method: 'POST',
4 | headers: { 'Content-Type': 'application/json' },
5 | body: JSON.stringify(data),
6 | });
7 | }
8 |
--------------------------------------------------------------------------------
/packages/gui/store/index.ts:
--------------------------------------------------------------------------------
1 | import create from 'zustand';
2 | /* ·········································································· */
3 | import type { AppState } from '@astro-content/types/gui-state';
4 |
5 | import ui from './ui';
6 | import editor from './editor';
7 | import data from './data';
8 | /* —————————————————————————————————————————————————————————————————————————— */
9 |
10 | const useAppStore = create()((set) => ({
11 | ...ui(set),
12 |
13 | ...data(set),
14 |
15 | ...editor(set),
16 | }));
17 |
18 | export { useAppStore };
19 |
--------------------------------------------------------------------------------
/packages/gui/styles.scss:
--------------------------------------------------------------------------------
1 | // NOTE: (important)
2 | // We are not using SASS with Vite Astro, it's totally separated. Old fashioned.
3 | // Why?
4 | // 1: Prevent very weird and uncontrolable Vite Dev Server refresh behavior.
5 | // 2: So user doesn't have to compile the SASS when using this integration GUI
6 | // (IDK what kind of performance gain you get, though).
7 | // 3: We don't have access to `import.meta.hot` with Astro it seems.
8 | // 4: Actually, using `injectRoute` seems to break JSX and Astro HMR, only
9 | // (S)CSS is working, with undesirable full page reload.
10 | // Conclusion: investigate more all these behaviors to suit our uses cases.
11 | // —————————————————————————————————————————————————————————————————————————————
12 |
13 | @import './layouts/Default.scss';
14 | @import './layouts/Preview.scss';
15 | @import './components/Toolbar.scss';
16 | @import './components/TabBar.scss';
17 | @import './components/Inspector.scss';
18 | @import './components/Headings.scss';
19 | @import './components/CopyInlineCode.scss';
20 | @import './components/Assistant.scss';
21 | @import './components/App/App.scss';
22 | @import './components/Tree/Tree.scss';
23 | @import './components/Editor/Editor.scss';
24 | @import './components/EntriesTable.scss';
25 |
--------------------------------------------------------------------------------
/packages/html2png/demo/.gitignore:
--------------------------------------------------------------------------------
1 | *.woff
2 |
3 | # build output
4 | dist/
5 |
6 | # dependencies
7 | node_modules/
8 |
9 | # logs
10 | npm-debug.log*
11 | yarn-debug.log*
12 | yarn-error.log*
13 | pnpm-debug.log*
14 |
15 |
16 | # environment variables
17 | .env
18 | .env.production
19 |
20 | # macOS-specific files
21 | .DS_Store
22 |
--------------------------------------------------------------------------------
/packages/html2png/demo/astro.config.mjs:
--------------------------------------------------------------------------------
1 | import { defineConfig } from 'astro/config';
2 |
3 | // https://astro.build/config
4 | export default defineConfig({});
5 |
--------------------------------------------------------------------------------
/packages/html2png/demo/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@astro-content--example/html2png",
3 | "type": "module",
4 | "version": "0.0.1",
5 | "private": true,
6 | "scripts": {
7 | "dev": "astro dev",
8 | "start": "astro dev",
9 | "build": "astro build",
10 | "preview": "astro preview",
11 | "astro": "astro"
12 | },
13 | "dependencies": {
14 | "@astro-content/html2png": "0.0.0-d",
15 | "astro": "^1.9.0"
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/packages/html2png/demo/public/favicon.svg:
--------------------------------------------------------------------------------
1 |
14 |
--------------------------------------------------------------------------------
/packages/html2png/demo/src/Layout.astro:
--------------------------------------------------------------------------------
1 | ---
2 | ---
3 |
4 |
5 |
6 |
7 |
8 | HTML to PNG — Isomorphic — Demo
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/packages/html2png/demo/src/env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
--------------------------------------------------------------------------------
/packages/html2png/demo/src/pages/open-graph/[...route].ts:
--------------------------------------------------------------------------------
1 | /* eslint-disable */
2 |
3 | import type { GetStaticPaths, APIRoute } from 'astro';
4 | import { html2png, html } from '@astro-content/html2png';
5 |
6 | export const getStaticPaths: GetStaticPaths = () => {
7 | return [
8 | { params: { route: 'default.png' } },
9 |
10 | // ...
11 | // Do your typical paths sourcing logic here
12 | ];
13 | };
14 |
15 | export const get: APIRoute = async ({ params }) => {
16 | const styles = {
17 | container: `
18 | height: 100%;
19 | width: 100%;
20 | display: flex;
21 | flex-direction: column;
22 | align-items: center;
23 | justify-content: center;
24 | background-color: rgb(45, 26, 84);
25 | font-size: 32px;
26 | font-weight: 600;`,
27 |
28 | title: `
29 | margin-left: 15ch;
30 | color: rgb(255, 93, 1);`,
31 |
32 | wrap: `
33 | font-size: 70px;
34 | margin-top: 38px;
35 | display: flex;
36 | flex-direction: column;
37 | color: white;`,
38 | };
39 |
40 | // …Do your variables logic here…
41 |
42 | const title = params.route;
43 |
44 | // …
45 |
46 | const markup = html`
47 |
48 |
49 |
50 | Hello from
51 | ${title}
52 |
53 |
54 |
`;
55 |
56 | const {
57 | responses: { png },
58 | } = await html2png({ markup });
59 |
60 | return new Response(...png);
61 | };
62 |
--------------------------------------------------------------------------------
/packages/html2png/demo/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "astro/tsconfigs/strictest"
3 | }
4 |
--------------------------------------------------------------------------------
/packages/html2png/index.ts:
--------------------------------------------------------------------------------
1 | import { html2png, toBase64URL } from './html2png.js';
2 |
3 | export { html2png, toBase64URL };
4 |
5 | export { html } from 'satori-html';
6 | export { css } from 'lit';
7 |
8 | export { styleMap } from 'lit/directives/style-map.js';
9 |
--------------------------------------------------------------------------------
/packages/html2png/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@astro-content/html2png",
3 | "version": "0.0.0-d",
4 | "description": "",
5 | "keywords": [
6 | "experimental"
7 | ],
8 | "license": "ISC",
9 | "author": "Julian Cataldo",
10 | "type": "module",
11 | "main": "./dist/index.js",
12 | "// bin": {},
13 | "files": [
14 | "./dist/*"
15 | ],
16 | "scripts": {
17 | "build": "tsc",
18 | "clean": "rm -rf dist .turbo",
19 | "dev": "tsc -w",
20 | "test": "echo \"Error: no test specified\" && exit 0"
21 | },
22 | "dependencies": {
23 | "@resvg/resvg-wasm": "^2.2.0",
24 | "lit": "^2.6.1",
25 | "satori": "^0.1.1",
26 | "satori-html": "^0.3.2"
27 | },
28 | "devDependencies": {
29 | "@types/react": "^18.0.27",
30 | "@types/yoga-layout": "^1.9.4",
31 | "tsx": "^3.12.2"
32 | },
33 | "publishConfig": {
34 | "access": "public"
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/packages/html2png/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ESNext",
4 | "module": "ESNext",
5 |
6 | "moduleResolution": "node",
7 |
8 | "resolveJsonModule": true,
9 |
10 | "isolatedModules": true,
11 |
12 | // "types": [
13 | // //
14 | // "astro/client",
15 | // "node"
16 | // ],
17 |
18 | "baseUrl": ".",
19 |
20 | // "noEmit": true,
21 |
22 | "allowSyntheticDefaultImports": true,
23 |
24 | "noImplicitAny": true,
25 |
26 | "strictNullChecks": true,
27 |
28 | "importsNotUsedAsValues": "error",
29 |
30 | // "noEmitOnError": false,
31 | "outDir": "./dist",
32 |
33 | "declaration": true
34 | },
35 |
36 | "include": ["index.ts" /* , "cli.ts" */]
37 | }
38 |
--------------------------------------------------------------------------------
/packages/imagekit/Image.Props.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
3 | import type { UrlOptions } from 'imagekit/dist/libs/interfaces';
4 |
5 | export const formats = ['png', 'jpeg', 'jpg', 'gif'];
6 |
7 | /* NOTE: Could be configurable */
8 | export const attributes = {
9 | hasJs: 'data-has-js',
10 | isLazy: 'data-is-lazy',
11 | isLoaded: 'data-is-loaded',
12 | } as const;
13 |
14 | export interface Props {
15 | /**
16 | * File path, relative to project root.
17 | *
18 | * @remark
19 | *
20 | * This is a shortcut to `urlOptions.path` setting,
21 | * for simple use case without additional transforms.
22 | *
23 | * @remark
24 | *
25 | * Given `./content` is set as your base lookup directory for medias,
26 | *
27 | * `path="content/posts/some-post/my-pic.jpeg"` \
28 | * *⬇︎ Will push synchronize the original file to ⬇︎* \
29 | * `https://imagekit.io/username/base-dir/posts/some-post/my-pic.jpeg`
30 | */
31 | path: string;
32 |
33 | /**
34 | * Options for generating an URL
35 | *
36 | * @see {@link https://github.com/imagekit-developer/imagekit-nodejs#url-generation}
37 | */
38 | urlOptions?: UrlOptions;
39 |
40 | /** Inline, low-res image which appears before full image load */
41 | placeholder?: {
42 | /**
43 | * In **pixels**
44 | *
45 | * @default 64
46 | */
47 | width?: number;
48 | };
49 |
50 | /**
51 | * Responsive source set sizes variants. Width in **pixels**.
52 | * */
53 | widths: number[];
54 | /**
55 | * Responsive possible sizes.
56 | * */
57 | sizes?: string;
58 |
59 | /**
60 | * Actual image width, in **CSS unit**
61 | * */
62 | width: string;
63 | // /** Actual image height, in **CSS unit** */
64 | // height: string;
65 | }
66 |
--------------------------------------------------------------------------------
/packages/imagekit/Image.astro:
--------------------------------------------------------------------------------
1 | ---
2 | import loadImageInstance from './image-instances.js';
3 | import { attributes, Props as BaseProps } from './Image.Props.js';
4 |
5 | export interface Props extends BaseProps, astroHTML.JSX.HTMLAttributes {}
6 |
7 | /* ========================================================================== */
8 |
9 | const props = Astro.props as Props;
10 |
11 | const {
12 | b64Placeholder,
13 | width,
14 | sourceSet,
15 | sizes: responsiveSizes,
16 | } = await loadImageInstance(props);
17 |
18 | const dimensionsCSSVars = { '--width': width /* , '--height': height */ };
19 | ---
20 |
21 |
22 |
25 |
26 |
29 |
30 |
31 |
32 |
33 |
34 |
37 |
38 |
41 |
--------------------------------------------------------------------------------
/packages/imagekit/Image.client.ts:
--------------------------------------------------------------------------------
1 | import { attributes } from './Image.Props.js';
2 |
3 | const imgElems = document.querySelectorAll(`picture[${attributes.hasJs}] img`);
4 |
5 | imgElems.forEach((img) => {
6 | if (!(img instanceof HTMLImageElement)) return;
7 |
8 | function toggle() {
9 | img.toggleAttribute(attributes.isLoaded);
10 | }
11 | if (img.complete) {
12 | /* Already loaded (in cache or very fast…) */
13 | toggle();
14 | } else {
15 | img.addEventListener('load', () => toggle());
16 | }
17 | });
18 |
19 | export {};
20 |
--------------------------------------------------------------------------------
/packages/imagekit/Image.css:
--------------------------------------------------------------------------------
1 | /* Overlay the placeholder */
2 | picture[data-is-lazy] {
3 | position: relative;
4 | width: var(--width);
5 | height: var(--height);
6 | }
7 |
8 | picture[data-is-lazy] img {
9 | display: block;
10 | width: var(--width);
11 | height: var(--height);
12 | /* object-fit: cover; */
13 | }
14 |
15 | /* No JavaScript */
16 | picture > img:nth-of-type(1),
17 | picture > img:nth-of-type(2) {
18 | display: none;
19 | }
20 |
21 | /* With JavaScript */
22 | picture[data-has-js] > img:nth-of-type(1),
23 | picture[data-has-js] > img:nth-of-type(2) {
24 | display: initial;
25 | }
26 |
27 | /* Overlay the placeholder */
28 | picture[data-has-js][data-is-lazy] {
29 | position: relative;
30 | }
31 |
32 | picture[data-has-js][data-is-lazy] > img:nth-of-type(2) {
33 | position: absolute;
34 | left: 0;
35 | filter: blur(7px);
36 | opacity: 1;
37 | transition: opacity 3s;
38 | }
39 |
40 | /* Loading transitions */
41 |
42 | picture[data-has-js][data-is-lazy] img:nth-of-type(1) {
43 | opacity: 0;
44 | transition: opacity 1s;
45 | }
46 |
47 | picture[data-has-js][data-is-lazy] img:nth-of-type(1)[data-is-loaded] {
48 | opacity: 1;
49 | }
50 |
51 | picture[data-has-js][data-is-lazy] img:nth-of-type(1)[data-is-loaded] ~ img {
52 | opacity: 0;
53 | }
54 |
--------------------------------------------------------------------------------
/packages/imagekit/LICENSE:
--------------------------------------------------------------------------------
1 | ISC License
2 |
3 | Copyright (c) 2022 Julian Cataldo — https://www.juliancataldo.com
4 |
5 | Permission to use, copy, modify, and/or distribute this software for any
6 | purpose with or without fee is hereby granted, provided that the above
7 | copyright notice and this permission notice appear in all copies.
8 |
9 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
10 | REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
11 | AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
12 | INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
13 | LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
14 | OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15 | PERFORMANCE OF THIS SOFTWARE.
16 |
--------------------------------------------------------------------------------
/packages/imagekit/base64.ts:
--------------------------------------------------------------------------------
1 | export async function getBase64DataURI(urlForB64: string) {
2 | const buffer = await fetch(urlForB64).then((r) => r.arrayBuffer());
3 |
4 | const b = Buffer.from(buffer).toString('base64');
5 |
6 | const b64Placeholder = `data:image/jpeg;base64,${b}`;
7 | return b64Placeholder;
8 | }
9 |
--------------------------------------------------------------------------------
/packages/imagekit/cli.ts:
--------------------------------------------------------------------------------
1 | #! /usr/bin/env node
2 |
3 | import { program } from '@commander-js/extra-typings';
4 | import dotenv from 'dotenv';
5 | import { log } from './logger.js';
6 | import { pushToRemote } from './file-handlers.js';
7 | import { pullMediaIndex } from './sync-media-index.js';
8 | /* ========================================================================== */
9 |
10 | log(() => `Astro ImageKit — Command Line Interface`);
11 |
12 | /* TODO: Make it configurable */
13 | function loadEnv(envFile = './.env') {
14 | dotenv.config({ path: envFile });
15 | }
16 |
17 | /* —————————————————————————————————————————————————————————————————————————— */
18 |
19 | program
20 | .name('imagekit')
21 | .command('index')
22 | .description('Manage library index.')
23 | .option(
24 | '-e, --env-file ',
25 | 'Choose which env. file to use. Useful if sourcing from parent (mono-repo.).',
26 | )
27 | .option('-r, --pull', 'Pull remote index to local cache folder.')
28 | .option('-v, --verbose', 'Dump all outputs.')
29 |
30 | .action((options, _command) => {
31 | loadEnv(options.envFile);
32 |
33 | if (options.pull) {
34 | /* NOTE: This is a bit cumbersome */
35 | (async () =>
36 | pullMediaIndex({ verbose: options.verbose }).catch((e) => {
37 | throw e;
38 | }))().catch((e) => {
39 | throw e;
40 | });
41 | }
42 | });
43 |
44 | program
45 | .command('medias')
46 | .description('Manage library medias.')
47 | .option(
48 | '-s, --push',
49 | 'Push local files to ImageKit configured distributable directory.',
50 | )
51 | .option(
52 | '-e, --env-file ',
53 | 'Choose which env. file to use.\nUseful if sourcing from parent (mono-repo.).',
54 | )
55 | .action((options, _command) => {
56 | loadEnv(options.envFile);
57 |
58 | if (options.push) {
59 | (async () =>
60 | pushToRemote().catch((e) => {
61 | throw e;
62 | }))().catch((e) => {
63 | throw e;
64 | });
65 | }
66 | });
67 |
68 | program.parse();
69 |
--------------------------------------------------------------------------------
/packages/imagekit/env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
3 | interface ImportMetaEnv {
4 | readonly IMAGEKIT_URL_ENDPOINT?: string | undefined;
5 | readonly IMAGEKIT_PUBLIC_KEY?: string | undefined;
6 | readonly IMAGEKIT_PRIVATE_KEY?: string | undefined;
7 | readonly IMAGEKIT_BASE_LOCAL_DIR?: string | undefined;
8 | readonly IMAGEKIT_REMOTE_DIR?: string | undefined;
9 | }
10 |
11 | interface ImportMeta {
12 | readonly env: ImportMetaEnv;
13 | }
14 |
--------------------------------------------------------------------------------
/packages/imagekit/index.ts:
--------------------------------------------------------------------------------
1 | import { integration } from './integration.js';
2 | import { pushToRemote } from './file-handlers.js';
3 |
4 | // NOTE: This is clashing with integration, must use
5 | // `import Image from 'astro-imagekit/Image.astro';` or setup pjson `exports`?
6 | // import Image from './Image.astro';
7 |
8 | export { /* Image, */ pushToRemote };
9 | export default integration;
10 |
--------------------------------------------------------------------------------
/packages/imagekit/logger.ts:
--------------------------------------------------------------------------------
1 | import yaml from 'yaml';
2 | import kleur from 'kleur';
3 | import { highlight } from 'cli-highlight';
4 |
5 | const logPrefix = () =>
6 | `${kleur.gray().dim(new Date().toLocaleTimeString())} ${kleur
7 | .magenta()
8 | .bold('[imagekit] ')}`;
9 |
10 | export function log(
11 | fmt: ({
12 | k,
13 | }: {
14 | /** Kleur formatting */
15 | k: typeof kleur;
16 | }) => string | undefined,
17 | ) {
18 | // if (import.meta.env.PROD) return;
19 |
20 | const formatted = fmt({ k: kleur });
21 | console.log(`${logPrefix()}${formatted ?? 'Undefined'}`);
22 | }
23 |
24 | export function dump(input: unknown) {
25 | // if (import.meta.env.PROD) return;
26 |
27 | const formatted = highlight(yaml.stringify(input, null, 2), {
28 | language: 'yaml',
29 | ignoreIllegals: true,
30 | });
31 |
32 | console.log(`${logPrefix()}— DUMP —\n${formatted}`);
33 | }
34 |
--------------------------------------------------------------------------------
/packages/imagekit/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@astro-content/imagekit",
3 | "version": "0.0.1-c",
4 | "description": "Integrate the ImageKit media provider in your Astro projects. Auto-synchronization, CLI, Component.",
5 | "keywords": [
6 | "medias",
7 | "astro-integration",
8 | "experimental",
9 | "astro-component",
10 | "astro",
11 | "image",
12 | "ssr",
13 | "transformation",
14 | "cloud",
15 | "imagekit",
16 | "responsive",
17 | "transitions",
18 | "synchronization",
19 | "cloudinary",
20 | "component",
21 | "indexing",
22 | "api",
23 | "cli",
24 | "urls",
25 | "helpers"
26 | ],
27 | "license": "ISC",
28 | "author": "Julian Cataldo",
29 | "type": "module",
30 | "main": "./dist/index.js",
31 | "bin": {
32 | "imagekit": "./dist/cli.js"
33 | },
34 | "files": [
35 | "./dist/*",
36 | "./Image.css",
37 | "./Image.astro"
38 | ],
39 | "scripts": {
40 | "build": "tsc",
41 | "clean": "rm -rf dist .turbo",
42 | "dev": "tsc -w",
43 | "test": "echo \"Error: no test specified\" && exit 0"
44 | },
45 | "dependencies": {
46 | "@commander-js/extra-typings": "^9.4.1",
47 | "cli-highlight": "^2.1.11",
48 | "commander": "^9.4.1",
49 | "dotenv": "^16.0.3",
50 | "glob-promise": "^5.0.0",
51 | "imagekit": "^4.1.2",
52 | "kleur": "^4.1.5",
53 | "yaml": "^2.2.1"
54 | },
55 | "devDependencies": {
56 | "@types/node": "^18.11.18",
57 | "astro": "^1.9.2"
58 | },
59 | "publishConfig": {
60 | "access": "public"
61 | },
62 | "typedoc": {
63 | "entryPoint": "./index.ts",
64 | "readmeFile": "README.md",
65 | "displayName": "imagekit"
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/packages/imagekit/sync-media-index.ts:
--------------------------------------------------------------------------------
1 | import fs from 'node:fs/promises';
2 | import path from 'node:path';
3 | import {
4 | getImageKitInstance,
5 | cacheDir,
6 | cacheIndex,
7 | } from './imagekit-instance.js';
8 | import { dump } from './logger.js';
9 | /* ========================================================================== */
10 |
11 | export async function pullMediaIndex({ verbose = false }) {
12 | const mediaIndexPath = path.join(cacheDir, cacheIndex);
13 |
14 | const { imageKit } = getImageKitInstance();
15 |
16 | /* TODO: Should filter base local dir */
17 | const remoteIndex = await imageKit.listFiles({});
18 |
19 | if (verbose) dump(remoteIndex);
20 |
21 | await fs.mkdir(path.dirname(mediaIndexPath), { recursive: true });
22 |
23 | await fs.writeFile(mediaIndexPath, JSON.stringify(remoteIndex, null, 2));
24 | }
25 |
--------------------------------------------------------------------------------
/packages/imagekit/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | // Enable top-level await, and other modern ESM features.
4 | "target": "ESNext",
5 | "module": "ESNext",
6 | // Enable node-style module resolution, for things like npm package imports.
7 | "moduleResolution": "node",
8 | // Enable JSON imports.
9 | "resolveJsonModule": true,
10 | // Enable stricter transpilation for better output.
11 | "isolatedModules": true,
12 | // Add type definitions for our Astro runtime.
13 | "types": [
14 | //
15 | "astro/client",
16 | // "vite/client",
17 | "node"
18 | ],
19 |
20 | "baseUrl": ".",
21 |
22 | "allowSyntheticDefaultImports": true,
23 |
24 | "noImplicitAny": true,
25 |
26 | "strictNullChecks": true,
27 |
28 | "importsNotUsedAsValues": "error",
29 |
30 | // "noEmitOnError": false,
31 | "outDir": "./dist",
32 |
33 | "declaration": true
34 | },
35 |
36 | "include": ["index.ts", "cli.ts"]
37 | }
38 |
--------------------------------------------------------------------------------
/packages/integration/build.ts:
--------------------------------------------------------------------------------
1 | import type { AstroIntegration } from 'astro';
2 | import fs from 'node:fs/promises';
3 | import path from 'node:path';
4 | /* ·········································································· */
5 | import { endpoints } from '@astro-content/server/state';
6 | import { log } from '@astro-content/server/logger';
7 | import type { ServerState, Endpoint } from '@astro-content/types/server-state';
8 | /* —————————————————————————————————————————————————————————————————————————— */
9 |
10 | // TODO: Centralize `tempDir`
11 | const tempDir = path.join(process.cwd(), '.astro-content');
12 |
13 | const buildStart: AstroIntegration['hooks']['astro:build:start'] =
14 | async () => {};
15 |
16 | const buildDone: AstroIntegration['hooks']['astro:build:done'] = async () => {
17 | log(`Build done`);
18 |
19 | if (process.env.HAS_GUI === 'true') {
20 | // REFACTOR: Even if it's not supposed to be used by end user (yet?)
21 |
22 | // NOTE: We are saving / loading current state to files,
23 | // otherwise it will get erased.
24 | // IDEA: Test the new `astro:build:generated` hook maybe?
25 | await fs
26 | .readFile(path.join(tempDir, 'state.json'), 'utf-8')
27 | .then(async (data: unknown) => {
28 | if (typeof data === 'string') {
29 | const obj = JSON.parse(data) as ServerState;
30 |
31 | if (typeof obj === 'object') {
32 | return Promise.all(
33 | Object.entries(obj).map(async ([key]) => {
34 | const dest = path.join(
35 | process.cwd(),
36 | `dist${endpoints.apiBase}/${key}`,
37 | );
38 |
39 | return fs
40 | .writeFile(dest, JSON.stringify(obj[key as Endpoint]))
41 | .catch((e) => log(e));
42 | }),
43 | );
44 | }
45 | }
46 | return null;
47 | });
48 | }
49 | };
50 |
51 | export { buildStart, buildDone };
52 |
--------------------------------------------------------------------------------
/packages/integration/cli-bridge.ts:
--------------------------------------------------------------------------------
1 | #! /usr/bin/env node --no-warnings --experimental-specifier-resolution=node --experimental-json-modules
2 |
3 | import '@astro-content/cli';
4 |
--------------------------------------------------------------------------------
/packages/integration/load-jsonc-plugin.ts:
--------------------------------------------------------------------------------
1 | // Based on: https://github.com/Modyfi/vite-plugin-yaml
2 | // NOTE: Work in progress
3 | // IDEA: Could make this an independent package / plugin?
4 |
5 | import type { Plugin } from 'vite';
6 |
7 | /* —————————————————————————————————————————————————————————————————————————— */
8 |
9 | const jsoncExtension = /\.json?c$/;
10 |
11 | /**
12 | * Transform YAML files to JS objects.
13 | */
14 | export default (): Plugin => ({
15 | name: 'vite:transform-jsonc',
16 |
17 | // transform(code: string, id: string) {
18 | // if (jsoncExtension.test(id)) {
19 | // const JsoncInstance = `${code.replace('export ', '')}`;
20 |
21 | // return {
22 | // code: JsoncInstance,
23 | // };
24 | // }
25 | // return null;
26 | // },
27 | });
28 |
--------------------------------------------------------------------------------
/packages/integration/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "astro-content",
3 | "version": "0.0.0-alpha.9",
4 | "description": "",
5 | "// source": "./astro-integration.ts",
6 | "main": "./dist/astro-integration.js",
7 | "type": "module",
8 | "files": [
9 | "dist/*",
10 | "*.astro",
11 | "*.json.ts"
12 | ],
13 | "scripts": {
14 | "build": "tsc",
15 | "dev": "tsc -w",
16 | "clean": "rm -rf dist .turbo",
17 | "test": "echo \"Error: no test specified\" && exit 1"
18 | },
19 | "bin": {
20 | "content": "./dist/cli-bridge.js"
21 | },
22 | "devDependencies": {
23 | "@types/body-parser": "^1.19.2",
24 | "@types/js-yaml": "^4.0.5",
25 | "astro": "1.4.7",
26 | "vite-plugin-inspect": "^0.7.5"
27 | },
28 | "dependencies": {
29 | "@astro-content/cli": "workspace:*",
30 | "@astro-content/gui": "workspace:*",
31 | "@astro-content/server": "workspace:*",
32 | "@astro-content/types": "workspace:*",
33 | "@astrojs/mdx": "^0.11.4",
34 | "@astrojs/react": "^1.2.0",
35 | "@rollup/pluginutils": "^5.0.0",
36 | "body-parser": "^1.20.1",
37 | "import-meta-resolve": "^2.1.0",
38 | "js-yaml": "^4.1.0",
39 | "kleur": "^4.1.5",
40 | "mkdirp": "^1.0.4",
41 | "remark-embed": "^1.3.1",
42 | "remark-gfm": "^3.0.1",
43 | "tosource": "2.0.0-alpha.3",
44 | "yaml": "^2.1.3"
45 | },
46 | "keywords": [
47 | "astro",
48 | "astro-integration"
49 | ],
50 | "author": "Julian Cataldo",
51 | "license": "ISC",
52 | "publishConfig": {
53 | "access": "public"
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/packages/integration/server-bridge.json.ts:
--------------------------------------------------------------------------------
1 | import type { APIRoute } from 'astro';
2 | /* ·········································································· */
3 | import type { Endpoint } from '@astro-content/types/server-state';
4 | import { state, endpoints } from '@astro-content/server/state';
5 | import { log } from '@astro-content/server/logger';
6 | /* —————————————————————————————————————————————————————————————————————————— */
7 |
8 | export function getStaticPaths() {
9 | return endpoints.data.map((endpoint) => ({ params: { endpoint } }));
10 | }
11 |
12 | export const get: APIRoute = ({ params, request }) => {
13 | // NOTE: Only "GET" seems to work?
14 | log({ params, method: request.method }, 'absurd');
15 |
16 | const endpoint = params.endpoint as Endpoint;
17 |
18 | if (
19 | request.method === 'GET' &&
20 | typeof params.endpoint === 'string' &&
21 | endpoints.data.includes(endpoint)
22 | ) {
23 | log({ params, method: request.method });
24 | return {
25 | body: JSON.stringify(state[endpoint]),
26 | };
27 | }
28 |
29 | /* No endpoint found, send empty response body */
30 | return {
31 | body: '{}',
32 | };
33 | };
34 |
--------------------------------------------------------------------------------
/packages/integration/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | // Enable top-level await, and other modern ESM features.
4 | "target": "ESNext",
5 | "module": "ESNext",
6 | // Enable node-style module resolution, for things like npm package imports.
7 | "moduleResolution": "node",
8 | // Enable JSON imports.
9 | "resolveJsonModule": true,
10 | // Enable stricter transpilation for better output.
11 | "isolatedModules": true,
12 | // Add type definitions for our Astro runtime.
13 | "types": [
14 | //
15 | "astro/client",
16 | "node"
17 | ],
18 |
19 | "baseUrl": ".",
20 |
21 | // Mandatory MDX integration, for tsc to build
22 | "jsx": "react-jsx",
23 |
24 | "allowSyntheticDefaultImports": true,
25 |
26 | "noImplicitAny": true,
27 |
28 | "strictNullChecks": true,
29 |
30 | "importsNotUsedAsValues": "error",
31 |
32 | // "noEmitOnError": false,
33 | "outDir": "./dist",
34 |
35 | "declaration": true
36 | }
37 |
38 | // "include": ["./packages/integration/astro-integration.ts"]
39 | // "exclude": ["./**/node_modules/*"]
40 | }
41 |
--------------------------------------------------------------------------------
/packages/server/.npmignore:
--------------------------------------------------------------------------------
1 | .dev
2 |
--------------------------------------------------------------------------------
/packages/server/config.ts:
--------------------------------------------------------------------------------
1 | /* ·········································································· */
2 | import type { UserConfig } from '@astro-content/types/user-config';
3 | /* —————————————————————————————————————————————————————————————————————————— */
4 |
5 | // let userConfig: Partial;
6 |
7 | const conf: UserConfig = {
8 | // get previewUrl() {
9 | // return userConfig?.previewUrl || '/';
10 | // },
11 | };
12 |
13 | export { conf };
14 |
--------------------------------------------------------------------------------
/packages/server/core-schema-validation.ts:
--------------------------------------------------------------------------------
1 | // /* Core meta schema validation */
2 | // let validate;
3 | // console.log({ coreSchema });
4 | // try {
5 | // const schemaForAjv = {
6 | // definitions: { ...state.schemas.internals, object: file.data },
7 | // };
8 |
9 | // validate = ajv.compile(schemaForAjv);
10 | // } catch (_) {
11 | // return false;
12 | // }
13 | // if (validate) {
14 | // validate(file.data);
15 | // if (validate.errors) {
16 | // }
17 | // }
18 | export default function coreSchemaValidation() {}
19 |
--------------------------------------------------------------------------------
/packages/server/generate-fake-data.ts:
--------------------------------------------------------------------------------
1 | import jsf from 'json-schema-faker';
2 | import type { JSONSchema7 } from 'json-schema';
3 | /* ·········································································· */
4 | import { log } from './logger.js';
5 | /* —————————————————————————————————————————————————————————————————————————— */
6 |
7 | export async function generateFakeEntries(schema: JSONSchema7) {
8 | // NOTE: This is a fix for `process.browser` bug, `location.href` not found.
9 | globalThis.location = { ...globalThis.location, href: process.cwd() };
10 |
11 | const fakeEntries = await jsf.resolve(schema).catch((e) => {
12 | log(e, 'absurd');
13 | return {};
14 | });
15 |
16 | log({ schema, fakeEntries }, 'absurd');
17 |
18 | return fakeEntries;
19 | }
20 |
--------------------------------------------------------------------------------
/packages/server/index.ts:
--------------------------------------------------------------------------------
1 | // IDEA: Use this for root importing functions?
2 | // Might be useful for distributable
3 |
4 | // export { collect } from './collect.js';
5 |
6 | export {};
7 |
--------------------------------------------------------------------------------
/packages/server/logger.ts:
--------------------------------------------------------------------------------
1 | /* eslint-disable no-console */
2 | import { blue, bold, dim } from 'kleur/colors';
3 | // TODO: Try consola
4 | // import consola from 'consola';
5 | /* ·········································································· */
6 | import type { LogLevel } from '@astro-content/types/logger';
7 | /* —————————————————————————————————————————————————————————————————————————— */
8 |
9 | export enum Levels {
10 | silent,
11 | info,
12 | debug,
13 | absurd,
14 | }
15 |
16 | export type Mode = 'pretty' | 'dump' | 'table';
17 |
18 | let currentLevel: LogLevel = 'info';
19 | const defaultLevel: LogLevel = 'debug';
20 |
21 | export function getCurrentLevel() {
22 | return currentLevel;
23 | }
24 |
25 | export function setLogLevel(level: LogLevel) {
26 | // if (process.argv.includes('--verbose')) {
27 | // currentLevel = 'debug';
28 | // } else if (process.argv.includes('--silent')) {
29 | // currentLevel = 'silent';
30 | // } else if (process.argv.includes('--absurd')) {
31 | // currentLevel = 'absurd';
32 | // }
33 | currentLevel = level;
34 | }
35 |
36 | export function log(
37 | //
38 | value: unknown,
39 | level?: LogLevel,
40 | mode: Mode = 'dump',
41 | // TODO: Try consola
42 | // type: 'success' | 'info' | 'error' = 'info',
43 | ) {
44 | let loggingLevel: LogLevel;
45 | if (!level) {
46 | loggingLevel = defaultLevel;
47 | } else {
48 | loggingLevel = level;
49 | }
50 |
51 | if (Levels[loggingLevel] <= Levels[currentLevel]) {
52 | if (mode === 'pretty') {
53 | const literal = typeof value === 'string' ? value : JSON.stringify(value);
54 | const time = new Date().toLocaleTimeString();
55 |
56 | console.log(
57 | `${dim(time)} ` +
58 | // —————————————————————————————————————————————————
59 | `${bold(blue('[content]'))} ${literal}`,
60 | );
61 | } else if (mode === 'table') {
62 | console.table(value);
63 | } else {
64 | /* Default : dump as is */
65 | console.log(value);
66 | }
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/packages/server/save-file.ts:
--------------------------------------------------------------------------------
1 | import fs from 'node:fs/promises';
2 | import prettier from 'prettier';
3 | /* ·········································································· */
4 | import type { Save } from '@astro-content/types/dto';
5 | import { log } from './logger.js';
6 | /* —————————————————————————————————————————————————————————————————————————— */
7 |
8 | export async function saveFile(object: Save) {
9 | const { file: dest, value, language } = object;
10 |
11 | let formattedValue: string | false = false;
12 | if (language) {
13 | formattedValue = prettier.format(value, {
14 | parser: language,
15 | // NOTE: Double quotes in MDX imports are breaking highlighting
16 | singleQuote: true,
17 | });
18 | log({ formattedValue, language }, 'debug');
19 | }
20 |
21 | const isSuccess = await fs
22 | .writeFile(dest, formattedValue || value)
23 | .then(() => true)
24 | .catch((e) => {
25 | log(e, 'info');
26 | return false;
27 | });
28 | return isSuccess;
29 | }
30 |
--------------------------------------------------------------------------------
/packages/server/schemas/MarkdownFile.ts:
--------------------------------------------------------------------------------
1 | import type { JSONSchema7 } from 'json-schema';
2 |
3 | export default {
4 | title: 'Markdown file',
5 | description: 'Markdown content of this entry with frontmatter',
6 | properties: {
7 | file: { type: 'string' },
8 | headingsCompiled: {
9 | type: 'array',
10 | items: [
11 | {
12 | properties: {
13 | depth: { type: 'number' },
14 | slug: { type: 'string' },
15 | text: { type: 'string' },
16 | },
17 | required: ['depth', 'slug', 'text'],
18 | additionalProperties: false,
19 | },
20 | ],
21 | },
22 | // headings: {
23 | // type: 'null',
24 | // },
25 | Content: { type: 'string' },
26 | },
27 | required: ['headings', 'Content'],
28 | additionalProperties: false,
29 | } as JSONSchema7;
30 |
--------------------------------------------------------------------------------
/packages/server/schemas/default.schema.yaml:
--------------------------------------------------------------------------------
1 | properties:
2 | gallery:
3 | properties:
4 | source:
5 | type: string
6 | required:
7 | - source
8 |
9 | meta:
10 | properties:
11 | baz:
12 | type: string
13 | foo:
14 | type: string
15 | enum:
16 | - bar
17 | - moz
18 | - das
19 | required:
20 | - foo
21 |
22 | content:
23 | allOf:
24 | - $ref: '#/definitions/MarkdownFile'
25 | - properties:
26 | frontmatter:
27 | properties:
28 | title:
29 | description: Entry title
30 | type: string
31 | image:
32 | description: Image path
33 | type: string
34 | required:
35 | - title
36 | required:
37 | - frontmatter
38 |
39 | footnotes:
40 | allOf:
41 | - $ref: '#/definitions/MarkdownFile'
42 |
43 | required:
44 | - content
45 | - meta
46 | - gallery
47 | - footnotes
48 |
--------------------------------------------------------------------------------
/packages/server/state.ts:
--------------------------------------------------------------------------------
1 | /* eslint-disable max-lines */
2 | // import path from 'node:path';
3 | import type { JSONSchema7 } from 'json-schema';
4 | /* ·········································································· */
5 | import type { Endpoint, ServerState } from '@astro-content/types/server-state';
6 | import markdownFile from './schemas/MarkdownFile.js';
7 | /* —————————————————————————————————————————————————————————————————————————— */
8 |
9 | // TODO: Take this from user config / Vite
10 | // const contentDir = path.join(process.cwd(), 'content');
11 |
12 | const emptyState: ServerState = {
13 | content: {},
14 |
15 | schemas: {
16 | content: {},
17 | raw: {},
18 | internals: {
19 | MarkdownFile: markdownFile as JSONSchema7,
20 | },
21 | file: {},
22 | },
23 |
24 | reports: {},
25 |
26 | types: {
27 | common: '',
28 | ide: '',
29 | browser: '',
30 | },
31 |
32 | config: {
33 | previewUrl: '/',
34 | // TODO: auto-detection + injection for GUI command hints for example
35 | // packageManager: 'pnpm',
36 | },
37 | };
38 |
39 | const getEmptyState = () =>
40 | JSON.parse(JSON.stringify(emptyState)) as ServerState;
41 |
42 | const state = getEmptyState();
43 |
44 | const data: Endpoint[] = [
45 | 'schemas',
46 | 'types',
47 | 'config',
48 | 'content',
49 | 'reports',
50 | //
51 | ];
52 |
53 | const contentBase = '/__content';
54 | const apiBase = `${contentBase}/api`;
55 | const endpoints = {
56 | data,
57 | contentBase,
58 | apiBase,
59 | actions: {
60 | save: `${apiBase}/~save`,
61 | fake: `${apiBase}/~fake`,
62 | validate: `${apiBase}/~validate`,
63 | refresh: `${apiBase}/~refresh`,
64 | render: `${apiBase}/~render`,
65 | },
66 | };
67 |
68 | export {
69 | //
70 | state,
71 | endpoints,
72 | getEmptyState,
73 | // contentDir,
74 | };
75 |
--------------------------------------------------------------------------------
/packages/server/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | // Enable top-level await, and other modern ESM features.
4 | "target": "ESNext",
5 | "module": "ESNext",
6 | // Enable node-style module resolution, for things like npm package imports.
7 | "moduleResolution": "node",
8 | // Enable JSON imports.
9 | "resolveJsonModule": true,
10 | // Enable stricter transpilation for better output.
11 | "isolatedModules": true,
12 | // Add type definitions for our Astro runtime.
13 | "types": [
14 | //
15 | "astro/client",
16 | "node"
17 | ],
18 |
19 | "baseUrl": ".",
20 |
21 | // "jsx": "react-jsxdev",
22 |
23 | "allowSyntheticDefaultImports": true,
24 |
25 | "noImplicitAny": true,
26 |
27 | "strictNullChecks": true,
28 |
29 | "importsNotUsedAsValues": "error",
30 |
31 | "declaration": true,
32 |
33 | "outDir": "./dist"
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/packages/server/utils.ts:
--------------------------------------------------------------------------------
1 | import path from 'node:path';
2 | import { camelCase } from 'lodash-es';
3 | /* ·········································································· */
4 |
5 | /* —————————————————————————————————————————————————————————————————————————— */
6 |
7 | export function getTrio(filePath: string) {
8 | // const relPath = path.relative(
9 | // 'content',
10 | // path.relative(process.cwd(), filePath),
11 | // );
12 |
13 | const parts = filePath.split('/');
14 | let [third, second, first] = [parts.pop(), parts.pop(), parts.pop()];
15 |
16 | first = camelCase(first);
17 | second = camelCase(second);
18 | if (third) {
19 | const t = path.basename(third, path.extname(third));
20 | if (!t.startsWith('_')) {
21 | third = camelCase(t);
22 | }
23 | }
24 | return { first, second, third };
25 | }
26 |
--------------------------------------------------------------------------------
/packages/types/dto.ts:
--------------------------------------------------------------------------------
1 | import type { JSONSchema7 } from 'json-schema';
2 | import type { Part } from './gui-state';
3 |
4 | export interface Save {
5 | file: string;
6 | singular: string;
7 | value: string;
8 | language: string | null;
9 | }
10 |
11 | export interface Fake {
12 | schema: JSONSchema7;
13 | }
14 |
15 | export interface Validate {
16 | entity: Part;
17 | entry: Part;
18 | property: Part;
19 | schema: JSONSchema7;
20 | value: string;
21 | language: string | null;
22 | }
23 |
24 | export interface Response {
25 | success: boolean;
26 | }
27 |
--------------------------------------------------------------------------------
/packages/types/file.ts:
--------------------------------------------------------------------------------
1 | // TODO: Rehaul file types: align Astro <=> JSONSchema <=> Astro Content
2 |
3 | import type { MarkdownHeading, MarkdownInstance, MDXInstance } from 'astro';
4 |
5 | export type FileLanguage = 'yaml' | 'markdown' | 'mdx';
6 |
7 | interface FileInfo {
8 | language: Lang;
9 | }
10 |
11 | export type OriginalInstance =
12 | | MarkdownInstance>
13 | | MDXInstance>
14 | | YamlInstance;
15 |
16 | export type FileInstance =
17 | | (MarkdownInstance> & FileInfo<'markdown'>)
18 | | (MDXInstance> & FileInfo<'mdx'>)
19 | | (YamlInstance & FileInfo<'yaml'>);
20 |
21 | export type FileInstanceExtended =
22 | | (MarkdownInstance> & ExtraMd)
23 | | (MDXInstance> & ExtraMdx)
24 | | (YamlInstance & ExtraYaml);
25 |
26 | interface MdBase {
27 | headingsCompiled?: MarkdownHeading[];
28 | excerpt?: { html: string };
29 | }
30 | export interface ExtraMd extends MdBase {
31 | language: 'markdown';
32 | raw: string;
33 | // bodyCompiled?: string;
34 | }
35 | export interface ExtraMdx extends MdBase {
36 | language: 'mdx';
37 | raw: string;
38 | }
39 | export interface ExtraYaml {
40 | language: 'yaml';
41 | }
42 |
43 | /* For Vite YAML loader plugin */
44 | export interface YamlInstance {
45 | data: T;
46 | /** Absolute file path (e.g. `/home/user/projects/.../file.yaml`) */
47 | file: string;
48 |
49 | raw: string;
50 | }
51 |
--------------------------------------------------------------------------------
/packages/types/integration.ts:
--------------------------------------------------------------------------------
1 | import type { UserConfig } from './user-config';
2 |
3 | export type Settings = UserConfig;
4 |
5 | export interface Options {
6 | editMode?: boolean;
7 | }
8 |
--------------------------------------------------------------------------------
/packages/types/logger.ts:
--------------------------------------------------------------------------------
1 | export type LogLevel = 'silent' | 'info' | 'debug' | 'absurd';
2 |
3 | export type Mode = 'pretty' | 'dump' | 'table';
4 |
--------------------------------------------------------------------------------
/packages/types/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@astro-content/types",
3 | "version": "0.0.0-alpha.13",
4 | "description": "",
5 | "type": "module",
6 | "files": [
7 | "dist/*.d.ts",
8 | "*.ts"
9 | ],
10 | "exports": {
11 | ".": "./dist",
12 | "./*": "./dist/*.js"
13 | },
14 | "scripts": {
15 | "build": "tsc",
16 | "dev": "tsc -w",
17 | "clean": "rm -rf dist .turbo",
18 | "test": "echo \"Error: no test specified\" && exit 1"
19 | },
20 | "keywords": [],
21 | "author": "Julian Cataldo",
22 | "license": "ISC",
23 | "publishConfig": {
24 | "access": "public"
25 | },
26 | "devDependencies": {
27 | "remark-lint-frontmatter-schema": "^3.10.0"
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/packages/types/server-state.ts:
--------------------------------------------------------------------------------
1 | /* eslint-disable @typescript-eslint/consistent-indexed-object-style */
2 | import type { JSONSchema7 } from 'json-schema';
3 | /* ·········································································· */
4 | import type { FileInstanceExtended } from './file';
5 | import type { PropertyReport } from './reports';
6 | /* —————————————————————————————————————————————————————————————————————————— */
7 |
8 | export interface Content {
9 | [entity: string]:
10 | | {
11 | [entry: string]:
12 | | {
13 | [property: string]: FileInstanceExtended | undefined;
14 | }
15 | | undefined;
16 | }
17 | | undefined;
18 | }
19 |
20 | export interface Schemas {
21 | internals: { [schemaName: string]: JSONSchema7 };
22 | content: { [schemaName: string]: JSONSchema7 };
23 | raw: { [schemaName: string]: string };
24 | file: { [schemaName: string]: string };
25 | }
26 |
27 | export interface Reports {
28 | [entity: string]:
29 | | {
30 | [entry: string]:
31 | | {
32 | [property: string]: PropertyReport | undefined;
33 | }
34 | | undefined;
35 | }
36 | | undefined;
37 | }
38 |
39 | export interface Types {
40 | common: string;
41 | browser: string;
42 | ide: string;
43 | }
44 |
45 | export interface ServerState {
46 | content: Content;
47 |
48 | schemas: Schemas;
49 |
50 | reports: Reports;
51 |
52 | types: Types;
53 |
54 | config: {
55 | previewUrl?: string;
56 | };
57 | }
58 | export type Endpoint = keyof ServerState;
59 |
60 | // NOTE: Unused for now
61 | // export type Action = 'save' | 'validate';
62 |
--------------------------------------------------------------------------------
/packages/types/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | // Enable top-level await, and other modern ESM features.
4 | "target": "ESNext",
5 | "module": "ESNext",
6 | // Enable node-style module resolution, for things like npm package imports.
7 | "moduleResolution": "node",
8 | // Enable JSON imports.
9 | "resolveJsonModule": true,
10 | // Enable stricter transpilation for better output.
11 | "isolatedModules": true,
12 | // Add type definitions for our Astro runtime.
13 | "types": [
14 | //
15 | "astro/client",
16 | "node"
17 | ],
18 |
19 | "baseUrl": ".",
20 |
21 | // "jsx": "react-jsxdev",
22 |
23 | "allowSyntheticDefaultImports": true,
24 |
25 | "noImplicitAny": true,
26 |
27 | "strictNullChecks": true,
28 |
29 | "importsNotUsedAsValues": "error",
30 |
31 | // "noEmitOnError": false,
32 | "outDir": "./dist",
33 |
34 | "emitDeclarationOnly": true,
35 | "declaration": true
36 | }
37 |
38 | // "include": ["./packages/integration/astro-integration.ts"]
39 | // "exclude": ["./**/node_modules/*"]
40 | }
41 |
--------------------------------------------------------------------------------
/packages/types/user-config.ts:
--------------------------------------------------------------------------------
1 | import type { LogLevel } from './logger';
2 |
3 | export interface UserConfig {
4 | /** **Default**: `/` */
5 | previewUrl?: string;
6 |
7 | /** **Default**: `'info'` */
8 | logLevel?: LogLevel;
9 |
10 | // /** **Default**: `true` */
11 | gui?: boolean;
12 |
13 | /** **Default**: `false` */
14 | includeInBuild?: boolean;
15 | }
16 |
--------------------------------------------------------------------------------
/packages/validator/cli.ts:
--------------------------------------------------------------------------------
1 | #! /usr/bin/env node
2 |
3 | /* eslint-disable no-console */
4 |
5 | import { generateAllCheckers } from './schema-to-validator.js';
6 |
7 | console.log('Generating checkers…');
8 |
9 | const outDir = process.argv[2];
10 |
11 | console.log(`➤ Output directory: ${outDir ?? 'colocated'}`);
12 |
13 | await generateAllCheckers(outDir);
14 |
15 | export {};
16 |
--------------------------------------------------------------------------------
/packages/validator/demo/.gitignore:
--------------------------------------------------------------------------------
1 | # build output
2 | dist/
3 | .output/
4 |
5 | # dependencies
6 | node_modules/
7 |
8 | # logs
9 | npm-debug.log*
10 | yarn-debug.log*
11 | yarn-error.log*
12 | pnpm-debug.log*
13 |
14 |
15 | # environment variables
16 | .env
17 | .env.production
18 |
19 | # macOS-specific files
20 | .DS_Store
21 |
--------------------------------------------------------------------------------
/packages/validator/demo/.remarkrc.yaml:
--------------------------------------------------------------------------------
1 | plugins:
2 | - remark-frontmatter
3 |
4 | - - remark-lint-frontmatter-schema
5 | - schemas:
6 | src/schemas/blog-post.schema.yaml:
7 | - content/blog-posts/*.{md,mdx}
8 |
--------------------------------------------------------------------------------
/packages/validator/demo/README.md:
--------------------------------------------------------------------------------
1 | # 🧞 Commands
2 |
3 | All commands are run from the root of the project, from a terminal:
4 |
5 | | Command | Action |
6 | | :--------------------- | :------------------------------------------------- |
7 | | `npm install` | Installs dependencies |
8 | | `npm run dev` | Starts local dev server at `localhost:3000` |
9 | | `npm run build` | Build your production site to `./dist/` |
10 | | `npm run preview` | Preview your build locally, before deploying |
11 | | `npm run astro ...` | Run CLI commands like `astro add`, `astro preview` |
12 | | `npm run astro --help` | Get help using the Astro CLI |
13 |
--------------------------------------------------------------------------------
/packages/validator/demo/astro.config.mjs:
--------------------------------------------------------------------------------
1 | import { defineConfig } from 'astro/config';
2 | import contentValidator from '@astro-content/validator';
3 |
4 | // https://astro.build/config
5 | export default defineConfig({
6 | integrations: [
7 | //
8 | contentValidator({ outDir: 'src/checkers' }),
9 | ],
10 | });
11 |
--------------------------------------------------------------------------------
/packages/validator/demo/content/blog-posts/correct_entry-bar.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: This is a cool title.
3 |
4 | description: |
5 | My description is long enough to make the schema happy.
6 | More text. More text. More text. More text. More text.
7 | ---
8 |
9 | # Hello
10 |
11 | World.
12 |
13 | Lorem ipsum dolor sit amet consectetur adipisicing elit. Deleniti delectus enim natus ex optio beatae atque iusto? Reprehenderit animi et ullam veniam quia, doloribus, omnis eius consequuntur suscipit nobis veritatis?
14 |
15 | ## Hey
16 |
17 | Lorem ipsum dolor sit amet consectetur adipisicing elit. Aliquam totam blanditiis culpa nulla non itaque est dolorum ullam minima, animi vero quidem ea perspiciatis nisi alias dolore laboriosam deserunt placeat!
18 |
--------------------------------------------------------------------------------
/packages/validator/demo/content/blog-posts/wrong_entry-foo.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: 123456 # Should be string!
3 |
4 | # description: oh no. # This is missing!
5 |
6 | tags:
7 | - 123456
8 | ---
9 |
10 | # Salut
11 |
12 | World.
13 |
14 | Lorem ipsum dolor sit amet consectetur adipisicing elit. Et inventore ea in, saepe, veritatis deserunt cum est voluptatem illo sapiente quis omnis fugiat nobis molestias autem eius magni sunt odio.
15 |
16 | ## Ola
17 |
18 | Lorem ipsum, dolor sit amet consectetur adipisicing elit. Commodi voluptatum ad ut magni repellat optio totam atque delectus libero? Architecto ipsum dignissimos earum molestias mollitia vel voluptatem ab quia enim!
19 |
20 | Lorem, ipsum dolor sit amet consectetur adipisicing elit. Aperiam esse et doloremque laborum minus voluptatibus officia maiores? Dicta, unde. Ipsam reiciendis consectetur porro quo in accusamus dolorem placeat, voluptatum asperiores.
21 |
--------------------------------------------------------------------------------
/packages/validator/demo/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@example/basics",
3 | "type": "module",
4 | "version": "0.0.1",
5 | "private": true,
6 | "scripts": {
7 | "dev": "astro dev",
8 | "start": "astro dev",
9 | "build": "astro build",
10 | "preview": "astro preview",
11 | "astro": "astro"
12 | },
13 | "dependencies": {
14 | "@astro-content/validator": "latest",
15 | "astro": "^1.6.10"
16 | },
17 | "devDependencies": {
18 | "remark": "^14.0.2",
19 | "remark-cli": "^11.0.0"
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/packages/validator/demo/pnpm-workspace.yaml:
--------------------------------------------------------------------------------
1 | # STUB (ignore it).
2 |
--------------------------------------------------------------------------------
/packages/validator/demo/src/components/Card.astro:
--------------------------------------------------------------------------------
1 | ---
2 | export interface Props {
3 | title: string;
4 | body: string;
5 | href: string;
6 | }
7 |
8 | const { href, title, body } = Astro.props;
9 | ---
10 |
11 |
12 |
13 |
14 | {title}
15 | →
16 |
17 |
18 | {body}
19 |
20 |
21 |
22 |
63 |
--------------------------------------------------------------------------------
/packages/validator/demo/src/env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
--------------------------------------------------------------------------------
/packages/validator/demo/src/layouts/Layout.astro:
--------------------------------------------------------------------------------
1 | ---
2 | export interface Props {
3 | title: string;
4 | }
5 |
6 | const { title } = Astro.props;
7 | ---
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 | {title}
17 |
18 |
19 |
20 |
21 |
22 |
36 |
--------------------------------------------------------------------------------
/packages/validator/demo/src/schemas/blog-post.schema.yaml:
--------------------------------------------------------------------------------
1 | title: Blog post
2 |
3 | allOf:
4 | - $ref: ./tags.schema.yaml
5 |
6 | - properties:
7 | title:
8 | title: Title
9 | default: My untitled blog post
10 | description: Used for SEO and tab title! # Will appear in auto-completion
11 | type: string
12 | minLength: 1
13 | maxLength: 80
14 |
15 | description:
16 | title: Description
17 | default: No description found.
18 | description: Used for SEO
19 | type: string
20 | minLength: 100
21 | maxLength: 300
22 |
23 | required:
24 | - title
25 | - description
26 |
--------------------------------------------------------------------------------
/packages/validator/demo/src/schemas/tags.schema.yaml:
--------------------------------------------------------------------------------
1 | description: |
2 | Used for content classification
3 |
4 | properties:
5 | tags:
6 | type: array
7 | uniqueItems: true
8 | minItems: 1
9 | maxItems: 8
10 | items:
11 | type: string
12 | enum:
13 | - Music
14 | - Video
15 | - Development
16 | - Cooking
17 | - Gardening
18 | - Sport
19 |
--------------------------------------------------------------------------------
/packages/validator/demo/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "astro/tsconfigs/strictest",
3 | "base": "."
4 | }
5 |
--------------------------------------------------------------------------------
/packages/validator/index.ts:
--------------------------------------------------------------------------------
1 | import { generateChecker, generateAllCheckers } from './schema-to-validator.js';
2 | import { integration, type Settings } from './integration.js';
3 | import { itemChecker } from './validator.js';
4 |
5 | export {
6 | Settings,
7 | /* ———————————————————————————————————————————————————————————————————————— */
8 | itemChecker,
9 | generateChecker,
10 | generateAllCheckers,
11 | };
12 |
13 | export default integration;
14 |
--------------------------------------------------------------------------------
/packages/validator/integration.ts:
--------------------------------------------------------------------------------
1 | import type { AstroIntegration } from 'astro';
2 | /* ========================================================================== */
3 |
4 | export interface Settings {
5 | /**
6 | * Destination directory for the generated checkers.
7 | *
8 | * E.g. `src/checkers`
9 | *
10 | * **Default**: Colocated with its input schema.
11 | */
12 | outDir?: string | undefined;
13 | }
14 |
15 | const integration = (settings: Settings = {}): AstroIntegration => ({
16 | name: 'content-validator',
17 | hooks: {
18 | 'astro:server:setup': async ({ server }) => {
19 | const { generateChecker, generateAllCheckers } = await import(
20 | './schema-to-validator.js'
21 | );
22 |
23 | await generateAllCheckers(settings.outDir);
24 |
25 | server.watcher.on('all', (_, filePath: string) => {
26 | if (filePath.endsWith('.schema.yaml')) {
27 | generateChecker(filePath, settings.outDir).catch((e) =>
28 | console.log(e),
29 | );
30 | }
31 | });
32 | },
33 | },
34 | });
35 |
36 | export { integration };
37 |
--------------------------------------------------------------------------------
/packages/validator/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@astro-content/validator",
3 | "version": "0.0.0-alpha.16",
4 | "description": "",
5 | "keywords": [
6 | "astro",
7 | "astro-integration",
8 | "json-schema",
9 | "typecheck",
10 | "validator",
11 | "runtime",
12 | "frontmatter",
13 | "markdown"
14 | ],
15 | "homepage": "https://astro-content.dev",
16 | "repository": {
17 | "type": "git",
18 | "url": "https://github.com/JulianCataldo/astro-content",
19 | "directory": "packages/validator"
20 | },
21 | "license": "ISC",
22 | "author": "Julian Cataldo",
23 | "type": "module",
24 | "main": "./dist/index.js",
25 | "bin": {
26 | "content-validator": "./dist/cli.js"
27 | },
28 | "files": [
29 | "dist/*"
30 | ],
31 | "scripts": {
32 | "build": "tsc",
33 | "clean": "rm -rf dist .turbo",
34 | "dev": "tsc -w",
35 | "test": "echo \"Error: no test specified\" && exit 1"
36 | },
37 | "dependencies": {
38 | "@apidevtools/json-schema-ref-parser": "^9.0.9",
39 | "ajv": "^8.11.0",
40 | "ajv-formats": "^2.1.1",
41 | "change-case": "^4.1.2",
42 | "glob-promise": "^5.0.0",
43 | "json-schema-faker": "0.5.0-rcv.46",
44 | "json-schema-to-typescript": "^11.0.2",
45 | "lodash-es": "^4.17.21",
46 | "yaml": "^2.1.3"
47 | },
48 | "devDependencies": {
49 | "astro": "^1.6.10",
50 | "json-schema": "^0.4.0",
51 | "typescript": "^4.8.4"
52 | },
53 | "publishConfig": {
54 | "access": "public"
55 | },
56 | "// source": "./index.ts"
57 | }
58 |
--------------------------------------------------------------------------------
/packages/validator/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ESNext",
4 | "module": "ESNext",
5 |
6 | "moduleResolution": "node",
7 | // Enable JSON imports.
8 | "resolveJsonModule": true,
9 |
10 | "isolatedModules": true,
11 |
12 | "types": ["node"],
13 |
14 | "baseUrl": ".",
15 |
16 | "allowSyntheticDefaultImports": true,
17 |
18 | "noImplicitAny": true,
19 |
20 | "strictNullChecks": true,
21 |
22 | "importsNotUsedAsValues": "error",
23 |
24 | "declaration": true,
25 |
26 | "outDir": "./dist"
27 | },
28 |
29 | "include": ["./index.ts", "./cli.ts"]
30 | }
31 |
--------------------------------------------------------------------------------
/pnpm-workspace.yaml:
--------------------------------------------------------------------------------
1 | packages:
2 | # - 'demo'
3 | - 'docs'
4 | - 'packages/*'
5 |
--------------------------------------------------------------------------------
/stylelint.config.cjs:
--------------------------------------------------------------------------------
1 | /** @type {import("@types/stylelint").Options} */
2 |
3 | module.exports = {
4 | /**
5 | * Reference:
6 | *
7 | * https://github.com/JulianCataldo/web-garden/blob/develop/configs/stylelint-all.cjs
8 | *
9 | * */
10 | extends: ['webdev-configs/stylelint-all.cjs'],
11 |
12 | rules: {
13 | /* NOTE: For VS Code colors variables */
14 | 'custom-property-pattern': null,
15 | // 'custom-selector-pattern': null,
16 | },
17 | };
18 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | // Enable top-level await, and other modern ESM features.
4 | "target": "ESNext",
5 | "module": "ESNext",
6 | // Enable node-style module resolution, for things like npm package imports.
7 | "moduleResolution": "node",
8 | // Enable JSON imports.
9 | "resolveJsonModule": true,
10 | // Enable stricter transpilation for better output.
11 | "isolatedModules": true,
12 | // Add type definitions for our Astro runtime.
13 | "types": [
14 | //
15 | "astro/client",
16 | "node"
17 | ],
18 |
19 | "baseUrl": ".",
20 |
21 | // "jsx": "react-jsxdev",
22 |
23 | "allowSyntheticDefaultImports": true,
24 |
25 | "noImplicitAny": true,
26 |
27 | "strictNullChecks": true,
28 |
29 | "importsNotUsedAsValues": "error",
30 |
31 | "noEmit": true,
32 |
33 | // "noEmitOnError": false,
34 | // "outDir": "./dist"
35 |
36 | "paths": {
37 | "/content": ["./docs/content"]
38 | }
39 | }
40 |
41 | // "include": ["./packages/integration/astro-integration.ts"]
42 | // "exclude": ["./**/node_modules/*"]
43 | }
44 |
--------------------------------------------------------------------------------
/turbo.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://turborepo.org/schema.json",
3 | "pipeline": {
4 | "build": {
5 | "dependsOn": ["^build"],
6 |
7 | "outputs": ["dist/**"]
8 | },
9 | "dev": {
10 | "cache": false
11 | },
12 | "clean": {
13 | "cache": false
14 | }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------