├── .civet └── hera-plugin.mjs ├── .gitattributes ├── .github └── workflows │ ├── build.yml │ └── static.yml ├── .gitignore ├── .mocharc-self.json ├── .mocharc.json ├── .vscode ├── extensions.json └── settings.json ├── CHANGELOG.md ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── build ├── avg.awk ├── build.sh ├── bump-version.coffee ├── changelog.civet ├── esbuild.civet ├── npm-release.sh ├── perf-compare.sh ├── test-compat.coffee └── test.sh ├── civet.dev ├── .gitignore ├── .prettierignore ├── .prettierrc ├── .vitepress │ ├── components │ │ ├── Contributors.vue │ │ ├── Hero.vue │ │ ├── Playground.vue │ │ ├── PlaygroundFull.vue │ │ └── Sponsors.vue │ ├── config.mjs │ ├── head.mjs │ ├── store │ │ └── ligatures.store.ts │ ├── theme │ │ ├── custom.css │ │ └── index.js │ └── utils │ │ ├── b64.ts │ │ ├── compileCivet.ts │ │ ├── compileCivetToHtml.ts │ │ ├── debounce.ts │ │ ├── getContributors.mjs │ │ ├── getHighlighter.ts │ │ └── getOpenCollectiveInfo.ts ├── cheatsheet.md ├── comparison.md ├── config.md ├── getting-started.md ├── index.md ├── integrations.md ├── philosophy.md ├── playground.md ├── public │ ├── favicon │ │ ├── apple-touch-icon.png │ │ ├── favicon-16x16.png │ │ ├── favicon-32x32.png │ │ └── favicon.ico │ ├── fonts │ │ ├── Breamcatcher.woff2 │ │ ├── FiraCode-Regular.woff │ │ └── FiraCode-Regular.woff2 │ ├── images │ │ ├── bg.svg │ │ └── trees.svg │ ├── playground.worker.js │ ├── railroad.html │ └── shiki │ │ ├── languages │ │ ├── coffee.tmLanguage.json │ │ ├── javascript.tmLanguage.json │ │ ├── tsx.tmLanguage.json │ │ └── typescript.tmLanguage.json │ │ ├── onig.wasm │ │ └── themes │ │ └── one-dark-pro.json └── reference.md ├── integration ├── eslint │ ├── CHANGELOG.md │ ├── README.md │ ├── esbuild.civet │ ├── example │ │ ├── eslint.config.mjs │ │ ├── package.json │ │ └── test.civet │ ├── package.json │ ├── source │ │ ├── index.civet │ │ └── ts.civet │ └── yarn.lock ├── example │ ├── basic.coffee │ ├── build.civet │ ├── bunfig.toml │ ├── compiler.civet │ ├── error-cjs.civet │ ├── error-esm.civet │ ├── generate.coffee │ ├── simple.json │ ├── source │ │ └── main.civet │ ├── test.civet │ └── util.coffee ├── gulp │ ├── .gitignore │ ├── README.md │ ├── index.civet │ ├── package.json │ ├── pnpm-lock.yaml │ └── test │ │ └── test.civet ├── jest │ ├── .gitignore │ ├── README.md │ ├── index.civet │ ├── jest.config.mjs │ ├── package.json │ └── test │ │ └── example.civet ├── metro │ └── README.md ├── script │ ├── README.md │ ├── test.civet │ └── test.html └── unplugin-examples │ ├── astro │ ├── .gitignore │ ├── .vscode │ │ ├── extensions.json │ │ └── launch.json │ ├── README.md │ ├── astro.config.mjs │ ├── package.json │ ├── public │ │ └── favicon.svg │ ├── src │ │ ├── component.civet │ │ ├── env.d.ts │ │ └── pages │ │ │ └── index.astro │ └── tsconfig.json │ ├── esbuild │ ├── esbuild.js │ ├── package.json │ ├── src │ │ ├── main.civet │ │ └── module.civet │ └── tsconfig.json │ ├── farm │ ├── farm.config.ts │ ├── index.html │ ├── package.json │ ├── public │ │ └── favicon.ico │ ├── src │ │ ├── App.civet │ │ ├── App.css │ │ ├── env.d.ts │ │ ├── index.civet │ │ └── index.css │ ├── tsconfig.json │ └── tsconfig.node.json │ ├── nextjs │ ├── .gitignore │ ├── README.md │ ├── app │ │ ├── about │ │ │ └── page.civet │ │ ├── favicon.ico │ │ ├── globals.css │ │ ├── layout.tsx │ │ ├── page.module.css │ │ └── page.tsx │ ├── components │ │ └── button.civet │ ├── next.config.ts │ ├── package.json │ ├── public │ │ ├── file.svg │ │ ├── globe.svg │ │ ├── next.svg │ │ ├── vercel.svg │ │ └── window.svg │ └── tsconfig.json │ ├── rolldown │ ├── package.json │ ├── rolldown.config.js │ ├── src │ │ ├── main.civet │ │ └── module.civet │ └── tsconfig.json │ ├── rollup │ ├── main.civet │ ├── package.json │ ├── rollup.config.js │ ├── tsconfig.json │ └── utils │ │ └── module.civet │ ├── vite-lib │ ├── index.html │ ├── package.json │ ├── src │ │ ├── main.civet │ │ └── module.civet │ ├── tsconfig.json │ └── vite.config.js │ ├── vite │ ├── index.html │ ├── package.json │ ├── src │ │ ├── main.civet │ │ └── module.civet │ └── vite.config.js │ └── webpack │ ├── main.civet │ ├── module.civet │ ├── package.json │ └── webpack.config.js ├── lsp ├── .gitignore ├── .vscode │ ├── launch.json │ └── tasks.json ├── .vscodeignore ├── CONTRIBUTING.md ├── LICENSE ├── NOTES.md ├── README.md ├── TODO.md ├── build │ ├── build.civet │ └── build.sh ├── images │ ├── civet-dark.svg │ ├── civet-light.svg │ └── civet.webp ├── integration │ ├── project-test │ │ ├── .civet │ │ │ ├── coffee-plugin.mjs │ │ │ ├── error-plugin.mjs │ │ │ └── hera-plugin.mjs │ │ ├── a.civet │ │ ├── b.civet │ │ ├── c.coffee │ │ ├── h.hera │ │ ├── j.js │ │ ├── t.ts │ │ ├── tsconfig.json │ │ └── x.tsx │ └── test.civet ├── package.json ├── source │ ├── extension.civet │ ├── lib │ │ ├── previewer.mts │ │ ├── textRendering.mts │ │ ├── typescript-service.mts │ │ └── util.mts │ ├── server.mts │ └── tsconfig-lib.json ├── syntaxes │ ├── civet-configuration.json │ ├── civet.json │ └── codeblock.json ├── test │ ├── service.civet │ ├── util.civet │ └── yo.mts ├── tsconfig.json └── yarn.lock ├── notes └── Comparison-to-CoffeeScript.md ├── package.json ├── register.js ├── source ├── babel-plugin.civet ├── browser-shim.civet ├── browser.civet ├── bun-civet.civet ├── cli.civet ├── config.civet ├── esbuild-plugin.civet ├── esm.civet ├── generate.civet ├── main.civet ├── node-worker.civet ├── parser.hera ├── parser │ ├── auto-dec.civet │ ├── binding.civet │ ├── block.civet │ ├── comptime.civet │ ├── declaration.civet │ ├── for.civet │ ├── function.civet │ ├── helper.civet │ ├── lib.civet │ ├── op.civet │ ├── pattern-matching.civet │ ├── pipe.civet │ ├── ref.civet │ ├── string.civet │ ├── traversal.civet │ ├── types.civet │ ├── unary.civet │ └── util.civet ├── sourcemap.civet ├── state-cache.civet ├── ts-diagnostic.civet ├── unplugin │ ├── README.md │ ├── astro.civet │ ├── constants.mjs │ ├── esbuild.civet │ ├── farm.civet │ ├── rolldown.civet │ ├── rollup.civet │ ├── rspack.civet │ ├── unplugin.civet │ ├── vite.civet │ └── webpack.civet └── worker-pool.civet ├── test ├── array.civet ├── assignment.civet ├── at.civet ├── auto-const.civet ├── auto-let.civet ├── await.civet ├── binary-op.civet ├── block-statement.civet ├── block-strings.civet ├── boolean.civet ├── call-expression.civet ├── chained-comparisons.civet ├── class.civet ├── cli.civet ├── comment.civet ├── compat │ ├── auto-var.civet │ ├── coffee-binary-existential.civet │ ├── coffee-classes.civet │ ├── coffee-comment.civet │ ├── coffee-div.civet │ ├── coffee-do.civet │ ├── coffee-eq.civet │ ├── coffee-for-loops.civet │ ├── coffee-inst.civet │ ├── coffee-line-continuation.civet │ ├── coffee-not.civet │ ├── coffee-of.civet │ ├── coffee-prototype.civet │ ├── coffee-range.civet │ ├── coffee-word-assignment.civet │ ├── deno.civet │ └── examples.civet ├── comptime.civet ├── conditional.civet ├── do.civet ├── examples.civet ├── existential.civet ├── export.civet ├── for.civet ├── function-application.civet ├── function-block-shorthand.civet ├── function.civet ├── helper.civet ├── identifier.civet ├── if.civet ├── iife.civet ├── import.civet ├── indent.civet ├── infra │ ├── babel │ │ ├── babel.config.json │ │ ├── build │ │ └── src │ │ │ └── input.civet │ ├── config.civet │ ├── config │ │ ├── civetconfig.json │ │ ├── customconfig.civet │ │ └── needs-coffee.civet │ ├── esbuild.civet │ ├── esm.civet │ └── import.civet ├── integration.civet ├── jsx │ ├── attr.civet │ ├── code.civet │ ├── indent.civet │ ├── objects.civet │ ├── solid.civet │ └── test.civet ├── label.civet ├── length-shorthand.civet ├── lexical-binding.civet ├── loop.civet ├── member-expression.civet ├── new.civet ├── numbers.civet ├── object-comprehensions.civet ├── object.civet ├── optional-chain.civet ├── parentheses.civet ├── partial-placeholder.civet ├── pipe.civet ├── prologues.civet ├── property-access.civet ├── range.civet ├── regex.civet ├── semicolon.civet ├── slice.civet ├── sourcemap.civet ├── strings.civet ├── switch.civet ├── symbol.civet ├── template-literal.civet ├── throw.civet ├── top-level.civet ├── try.civet ├── types │ ├── as.civet │ ├── class.civet │ ├── const-assignment.civet │ ├── declare.civet │ ├── destructuring.civet │ ├── enum.civet │ ├── export.civet │ ├── for.civet │ ├── function.civet │ ├── import.civet │ ├── interface.civet │ ├── js.civet │ ├── let-declaration.civet │ ├── namespace.civet │ ├── non-null-assertion.civet │ ├── satisfies.civet │ ├── shorthand-const.civet │ ├── template-literal.civet │ ├── try.civet │ ├── type-declaration.civet │ ├── unique-symbol.civet │ ├── unknown.civet │ ├── using.civet │ └── var.civet ├── unary-expression.civet ├── update-expression.civet ├── util │ ├── locations.civet │ └── state-cache.civet ├── variable-statement.civet ├── while.civet └── yield.civet ├── tsconfig.json ├── types ├── config.d.ts ├── node.d.ts └── types.d.ts └── yarn.lock /.civet/hera-plugin.mjs: -------------------------------------------------------------------------------- 1 | import Hera from "@danielx/hera" 2 | const { compile: heraCompile } = Hera 3 | 4 | export default { 5 | transpilers: [{ 6 | extension: ".hera", 7 | target: ".mjs", 8 | compile: function (path, source) { 9 | return heraCompile(source, { 10 | filename: path, 11 | module: true, 12 | sourceMap: true, 13 | }) 14 | } 15 | }], 16 | } 17 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # excluded from language stats 2 | civet.dev/public/*.html linguist-vendored 3 | -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | on: 2 | push: 3 | branches: 4 | - main 5 | pull_request: 6 | 7 | name: Build 8 | 9 | env: 10 | API_TOKEN: ${{ secrets.API_TOKEN }} 11 | 12 | jobs: 13 | build: 14 | name: Build and Test 15 | runs-on: ubuntu-latest 16 | steps: 17 | 18 | - uses: actions/checkout@v4 19 | 20 | - name: Setup Node.js 20 21 | uses: actions/setup-node@v4 22 | with: 23 | cache: yarn 24 | node-version: 20 25 | 26 | - name: Install and Test 27 | run: | 28 | yarn 29 | yarn build 30 | yarn test 31 | 32 | - uses: actions/upload-artifact@v4 33 | with: 34 | name: browser.js 35 | path: dist/browser.js 36 | 37 | - name: Coveralls GitHub Action 38 | uses: coverallsapp/github-action@v2 39 | with: 40 | file: coverage/lcov.info 41 | 42 | self-test: 43 | name: Self-Test 44 | runs-on: ubuntu-latest 45 | steps: 46 | 47 | - uses: actions/checkout@v4 48 | 49 | - name: Setup Node.js 20 50 | uses: actions/setup-node@v4 51 | with: 52 | cache: yarn 53 | node-version: 20 54 | 55 | - name: Install and Test 56 | run: | 57 | yarn 58 | yarn test:self 59 | 60 | build-docs: 61 | name: Build Docs 62 | runs-on: ubuntu-latest 63 | environment: 64 | name: build 65 | steps: 66 | 67 | - uses: actions/checkout@v4 68 | 69 | - name: Setup Node.js 20 70 | uses: actions/setup-node@v4 71 | with: 72 | cache: yarn 73 | node-version: 20 74 | 75 | - name: Install and Build 76 | # `yarn docs:build` includes `yarn build` 77 | run: | 78 | yarn 79 | yarn docs:build 80 | env: 81 | API_TOKEN: ${{ secrets.GITHUB_TOKEN }} 82 | -------------------------------------------------------------------------------- /.github/workflows/static.yml: -------------------------------------------------------------------------------- 1 | # Simple workflow for deploying static content to GitHub Pages 2 | name: Deploy static content to Pages 3 | 4 | on: 5 | # Runs on pushes targeting the default branch 6 | push: 7 | branches: ["main"] 8 | 9 | # Allows you to run this workflow manually from the Actions tab 10 | workflow_dispatch: 11 | 12 | # Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages 13 | permissions: 14 | contents: read 15 | pages: write 16 | id-token: write 17 | 18 | # Allow one concurrent deployment 19 | concurrency: 20 | group: "pages" 21 | cancel-in-progress: true 22 | 23 | env: 24 | API_TOKEN: ${{ secrets.API_TOKEN }} 25 | 26 | jobs: 27 | # Single deploy job since we're just deploying 28 | deploy: 29 | # Don't attempt to deploy website from forks 30 | if: github.repository == 'DanielXMoore/Civet' 31 | environment: 32 | name: github-pages 33 | url: ${{ steps.deployment.outputs.page_url }} 34 | runs-on: ubuntu-latest 35 | steps: 36 | - name: Checkout 37 | uses: actions/checkout@v4 38 | 39 | - name: Setup Pages 40 | uses: actions/configure-pages@v2 41 | 42 | - name: Setup Node.js 20 43 | uses: actions/setup-node@v4 44 | with: 45 | cache: yarn 46 | node-version: 20 47 | 48 | - name: Install and Build Site 49 | # `yarn docs:build` includes `yarn build` 50 | run: | 51 | yarn 52 | yarn docs:build 53 | env: 54 | API_TOKEN: ${{ secrets.GITHUB_TOKEN }} 55 | 56 | - name: Upload artifact 57 | uses: actions/upload-pages-artifact@v3 58 | with: 59 | # Upload entire repository 60 | path: 'civet.dev/.vitepress/dist' 61 | 62 | - name: Deploy to GitHub Pages 63 | id: deployment 64 | uses: actions/deploy-pages@v4 65 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .nyc_output/ 2 | NOTES.md 3 | coverage/ 4 | dist/ 5 | node_modules/ 6 | register-noconfig.js 7 | -------------------------------------------------------------------------------- /.mocharc-self.json: -------------------------------------------------------------------------------- 1 | // Self-test: run Civet tests using the current built version of Civet 2 | { 3 | "extension": [ 4 | "civet", 5 | "coffee" 6 | ], 7 | "require": [ 8 | "@danielx/hera/register", 9 | "./register.js" 10 | ], 11 | "reporter": "dot", 12 | "recursive": true, 13 | "spec": [ 14 | "test" 15 | ], 16 | "exclude": [ 17 | "test/infra/config/**" 18 | ] 19 | } 20 | -------------------------------------------------------------------------------- /.mocharc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extension": [ 3 | "civet", 4 | "coffee" 5 | ], 6 | "require": [ 7 | "@danielx/hera/register", 8 | "./node_modules/@danielx/civet/register" 9 | ], 10 | "reporter": "dot", 11 | "recursive": true, 12 | "spec": [ 13 | "test" 14 | ], 15 | "exclude": [ 16 | "test/infra/config/**" 17 | ] 18 | } 19 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": [ 3 | "DanielX.hera" 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "files.insertFinalNewline": true 3 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Daniel X Moore and other contributors 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /build/avg.awk: -------------------------------------------------------------------------------- 1 | # Average of sorted numbers 2 | 3 | BEGIN { 4 | c = 0; 5 | sum = 0; 6 | } 7 | { 8 | for (i = 1; i <= NF; i++) { 9 | a[c++] = $i; 10 | sum += $i 11 | } 12 | } 13 | END { 14 | avg = sum / c; 15 | if( (c % 2) == 1 ) { 16 | median = a[ int(c/2) ]; 17 | } else { 18 | median = ( a[c/2] + a[c/2-1] ) / 2; 19 | } 20 | OFS="\t"; 21 | # print "SUM:", sum, "COUNT:", c, "AVG:", avg, "MED:", median, "MIN:", a[0], "MAX:", a[c-1]; 22 | print avg; 23 | } 24 | -------------------------------------------------------------------------------- /build/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -euo pipefail 3 | 4 | # clean build 5 | rm -rf dist 6 | mkdir dist 7 | 8 | # tree-shake needed constants from Vite 9 | node -e 'import("./node_modules/vite/dist/node/constants.js").then((c)=>console.log(`export const DEFAULT_EXTENSIONS = ${JSON.stringify(c.DEFAULT_EXTENSIONS)}`))' >./source/unplugin/constants.mjs 10 | 11 | # types (these get used for type checking during esbuild, so must go first) 12 | cp types/types.d.ts types/config.d.ts dist/ 13 | cp types/config.d.ts dist/config.d.mts 14 | 15 | # register-noconfig.js is made from register.js 16 | sed 's#//NOCONFIG//##g' register.js >register-noconfig.js 17 | 18 | # normal files 19 | civet --no-config build/esbuild.civet "$@" 20 | 21 | # built types 22 | for name in astro esbuild farm rolldown rollup rspack unplugin vite webpack; do 23 | sed 's/\.civet"/\.js"/' dist/unplugin/source/unplugin/$name.d.ts >dist/unplugin/$name.d.ts 24 | done 25 | rm -rf dist/unplugin/source 26 | 27 | # cli 28 | BIN="dist/civet" 29 | ( 30 | echo "#!/usr/bin/env node" 31 | echo '"use strict"' 32 | echo "try { require('node:module').enableCompileCache() } catch {}" 33 | ) | cat - dist/cli.js > "$BIN" 34 | echo "cli()" >> "$BIN" 35 | chmod +x "$BIN" 36 | rm dist/cli.js 37 | 38 | # create browser build for docs 39 | terser dist/browser.js --compress --mangle --ecma 2015 --output civet.dev/public/__civet.js 40 | 41 | -------------------------------------------------------------------------------- /build/bump-version.coffee: -------------------------------------------------------------------------------- 1 | pkgJSON = require '../package.json' 2 | 3 | # increment point version by 1 4 | parts = pkgJSON.version.split('.') 5 | last = parts.length - 1 6 | pkgJSON.version = parts.map (v, i) -> 7 | if i is last 8 | v = (parseInt(v) + 1).toString() 9 | return v 10 | .join '.' 11 | 12 | # write package.json 13 | fs = require 'fs' 14 | fs.writeFileSync 'package.json', JSON.stringify(pkgJSON, null, 2) 15 | -------------------------------------------------------------------------------- /build/npm-release.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -euo pipefail 3 | 4 | # NOTE: This script doesn't work yet but its a good start 5 | 6 | # exit if current branch is not master 7 | if [[ $(git branch --show-current) != "master" ]]; then 8 | echo "Current branch is not master. Please switch to master branch." 9 | exit 1 10 | fi 11 | 12 | # exit if git staged files are dirty 13 | if [[ -n $(git status --porcelain | sed -e '/??/d') ]]; then 14 | echo "Git staged files are dirty. Please commit or stash them." 15 | exit 1 16 | fi 17 | 18 | # Bump the point version and publish to npm 19 | 20 | coffee build/bump-version.coffee 21 | npm publish --otp "$1" 22 | git add package.json 23 | git commit -m "Bump version" 24 | git push 25 | -------------------------------------------------------------------------------- /build/perf-compare.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Simple performance comparison 4 | 5 | count=10 6 | testFile=source/**/*.civet 7 | 8 | function get_times { 9 | cmd=$1 10 | echo "Running $cmd on $testFile $count times" 11 | 12 | times=() 13 | for ((i = 1; i <= count; i++)) { 14 | time=$( (time $cmd -c $testFile -o /dev/null) 2>&1 | awk '/real/ {print $2}' | awk -Fm '{print $1*60+$2}' ) 15 | echo $time 16 | times+=($time) 17 | } 18 | 19 | average=$(echo ${times[@]} | awk -f build/avg.awk) 20 | } 21 | 22 | get_times ./dist/civet new.out 23 | new_avg=$average 24 | get_times ./node_modules/.bin/civet old.out 25 | old_avg=$average 26 | 27 | echo New: $new_avg 28 | echo Old: $old_avg 29 | echo Ratio: $(awk "BEGIN { print $new_avg / $old_avg }") 30 | -------------------------------------------------------------------------------- /build/test-compat.coffee: -------------------------------------------------------------------------------- 1 | ### 2 | This script tries running Civet on the specified files, and repeatedly 3 | removes lines where Civet complains about a syntax error, to see how many 4 | lines successfully compile. This gives a rough idea of backward 5 | compatibility with CoffeeScript (but doesn't test for correct compilation). 6 | It adds "civet coffeeCompat" to .coffee files if there isn't already a 7 | leading civet directive. 8 | ### 9 | 10 | fs = require 'fs' 11 | civet = require '..' 12 | 13 | countLines = (lines) -> 14 | lines.length - (if lines.at(-1) == '' then 1 else 0) 15 | 16 | if process.argv.length <= 2 17 | console.log "> Provide one of more filenames to try running through Civet" 18 | process.exit 1 19 | 20 | for filename in process.argv[2..] 21 | console.log '*', filename 22 | input = fs.readFileSync filename, encoding: 'utf8' 23 | 24 | lines = input.split '\n' 25 | origCount = countLines lines 26 | 27 | loop 28 | try 29 | civet.compile input, {filename, sync: true} 30 | break 31 | catch e 32 | match = e.message.match /// 33 | ^\s* 34 | #{filename.replace /[\.*+?|\[\](){}\\]/g, "\\$&"} 35 | :(\d+) 36 | /// 37 | unless match? 38 | console.error "Unrecognized error message #{JSON.stringify e.message}; counts will be inaccurate" 39 | break 40 | line = match[1] - 1 # convert 1-base to 0-base 41 | #console.log 'Removing line', line 42 | lines[line..line] = [] 43 | input = lines.join '\n' 44 | 45 | newCount = countLines lines 46 | removedCount = origCount - newCount 47 | console.log "#{(newCount / origCount * 100).toFixed 1}% success (removed #{removedCount} out of #{origCount} lines)" 48 | -------------------------------------------------------------------------------- /build/test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -euo pipefail 4 | 5 | # Translate CIVET_THREADS into Mocha's --parallel 6 | # In particular, CIVET_THREADS Workers don't work within Mocha 7 | args="" 8 | if [ "${CIVET_THREADS:-0}" != 0 ]; then 9 | args="--parallel -j $CIVET_THREADS" 10 | export CIVET_THREADS= 11 | fi 12 | 13 | c8 mocha $args "$@" 14 | tsc --noEmit 15 | -------------------------------------------------------------------------------- /civet.dev/.gitignore: -------------------------------------------------------------------------------- 1 | # Vitepress 2 | dist 3 | cache 4 | examples-temp 5 | .vite_opt_cache 6 | 7 | # Generated files 8 | tmp.civet* 9 | __civet.js 10 | -------------------------------------------------------------------------------- /civet.dev/.prettierignore: -------------------------------------------------------------------------------- 1 | ./index.md 2 | -------------------------------------------------------------------------------- /civet.dev/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "singleQuote": true 3 | } 4 | -------------------------------------------------------------------------------- /civet.dev/.vitepress/components/Contributors.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 20 | 21 | 54 | -------------------------------------------------------------------------------- /civet.dev/.vitepress/components/Hero.vue: -------------------------------------------------------------------------------- 1 | 22 | 23 | 36 | 37 | 49 | -------------------------------------------------------------------------------- /civet.dev/.vitepress/components/Sponsors.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 42 | 43 | 76 | -------------------------------------------------------------------------------- /civet.dev/.vitepress/head.mjs: -------------------------------------------------------------------------------- 1 | export const head = [ 2 | [ 3 | 'meta', 4 | { 5 | name: 'og:title', 6 | content: 'Civet - The Modern Way to Write TypeScript', 7 | }, 8 | ], 9 | [ 10 | 'meta', 11 | { 12 | name: 'og:site_name', 13 | content: 'Civet', 14 | }, 15 | ], 16 | [ 17 | 'meta', 18 | { 19 | name: 'og:url', 20 | content: 'https://civet.dev', 21 | }, 22 | ], 23 | [ 24 | 'meta', 25 | { 26 | name: 'og:type', 27 | content: 'website', 28 | }, 29 | ], 30 | [ 31 | 'meta', 32 | { 33 | name: 'og:image', 34 | content: 35 | 'https://user-images.githubusercontent.com/18894/184558519-b675a903-7490-43ba-883e-0d8addacd4b9.png', 36 | }, 37 | ], 38 | [ 39 | 'meta', 40 | { 41 | name: 'og:description', 42 | content: 43 | 'With Civet, you can enjoy a more concise and readable syntax while leveraging the power of TypeScript. Check out the documentation and resources on our website to learn more about Civet and how to use it effectively', 44 | }, 45 | ], 46 | [ 47 | 'link', 48 | { 49 | rel: 'apple-touch-icon', 50 | sizes: '180x180', 51 | href: '/favicon/apple-touch-icon.png', 52 | }, 53 | ], 54 | [ 55 | 'link', 56 | { 57 | rel: 'icon', 58 | sizes: '32x32', 59 | href: '/favicon/favicon-32x32.png', 60 | }, 61 | ], 62 | [ 63 | 'link', 64 | { 65 | rel: 'icon', 66 | sizes: '16x16', 67 | href: '/favicon/favicon-16x16.png', 68 | }, 69 | ], 70 | ]; 71 | -------------------------------------------------------------------------------- /civet.dev/.vitepress/store/ligatures.store.ts: -------------------------------------------------------------------------------- 1 | import { ref, watch } from 'vue'; 2 | 3 | // Read initial value from localStorage 4 | let init = false; 5 | try { 6 | init = JSON.parse(localStorage.getItem('ligatures') ?? 'false') 7 | } catch (e) {} 8 | 9 | // Shared state for ligatures toggle 10 | export const ligatures = ref(init); 11 | 12 | // Keep localStorage up-to-date 13 | watch(ligatures, () => { 14 | try { 15 | localStorage.setItem('ligatures', JSON.stringify(ligatures.value)); 16 | } catch (e) {} 17 | }) 18 | -------------------------------------------------------------------------------- /civet.dev/.vitepress/theme/index.js: -------------------------------------------------------------------------------- 1 | import { useRoute } from 'vitepress'; 2 | import DefaultTheme from 'vitepress/theme'; 3 | import { watch } from 'vue'; 4 | import Playground from '../components/Playground.vue'; 5 | import { compileCivetToHtml } from '../utils/compileCivetToHtml'; 6 | import './custom.css'; 7 | 8 | DefaultTheme.enhanceApp = async ({ app }) => { 9 | app.component('Playground', Playground); 10 | 11 | // Download compiler in the background 12 | if (typeof window !== 'undefined') { 13 | compileCivetToHtml(''); 14 | } 15 | 16 | // Make playground page 100% screen width 17 | const defaultSetup = app._component.setup; 18 | app._component.setup = (props) => { 19 | const route = useRoute(); 20 | 21 | watch( 22 | route, 23 | (route) => { 24 | if (typeof document === 'undefined') { 25 | return; 26 | } 27 | 28 | if (route.component.name === 'playground.md') { 29 | document.body.classList.add('playground'); 30 | } else { 31 | document.body.classList.remove('playground'); 32 | } 33 | }, 34 | { immediate: true } 35 | ); 36 | 37 | return defaultSetup(props); 38 | }; 39 | }; 40 | 41 | export default DefaultTheme; 42 | -------------------------------------------------------------------------------- /civet.dev/.vitepress/utils/b64.ts: -------------------------------------------------------------------------------- 1 | export const b64 = { 2 | encode(str: string) { 3 | const bytes = new TextEncoder().encode(str); 4 | str = String.fromCodePoint(...bytes); 5 | str = btoa(str); 6 | return str; 7 | }, 8 | decode(str: string) { 9 | str = atob(str); 10 | const bytes = Uint8Array.from(str, (c) => c.codePointAt(0)!); 11 | str = new TextDecoder().decode(bytes); 12 | return str; 13 | }, 14 | }; 15 | -------------------------------------------------------------------------------- /civet.dev/.vitepress/utils/compileCivet.ts: -------------------------------------------------------------------------------- 1 | // TODO: Fix "any" 2 | export function compileCivet( 3 | code: string, 4 | civetInstance: any, 5 | prettierInstance: any, 6 | parseOptions: any 7 | ) { 8 | // This SSR rendering code must be synchronous because of Markdown API 9 | let tsCode = civetInstance.compile(code, { parseOptions, sync: true }); 10 | const tsRawCode = tsCode; 11 | 12 | if (prettierInstance) { 13 | try { 14 | tsCode = prettierInstance.format(tsCode, { 15 | parser: 'typescript', 16 | printWidth: 50, 17 | }); 18 | } catch (err) { 19 | console.info('Prettier error. Fallback to raw civet output', { 20 | tsCode, 21 | err, 22 | }); 23 | } 24 | } 25 | 26 | return { tsCode, tsRawCode }; 27 | } 28 | -------------------------------------------------------------------------------- /civet.dev/.vitepress/utils/compileCivetToHtml.ts: -------------------------------------------------------------------------------- 1 | let playgroundWorker: Worker; 2 | 3 | interface WorkerResult { 4 | inputHtml: string; 5 | outputHtml?: string; 6 | error?: string; 7 | jsCode?: string; 8 | } 9 | 10 | const msgMap: Record void 12 | restart: boolean 13 | }> = {}; 14 | 15 | // @ts-ignore 16 | if (!import.meta.env.SSR) { 17 | function startWorker() { 18 | playgroundWorker = new Worker('/playground.worker.js') 19 | 20 | playgroundWorker.onmessage = ({ data }) => { 21 | const { resolve, restart } = msgMap[data.uid] 22 | resolve(data) 23 | delete msgMap[data.uid] 24 | if (restart) { 25 | playgroundWorker.terminate() 26 | startWorker() 27 | } 28 | }; 29 | } 30 | 31 | startWorker() 32 | } 33 | 34 | let uid = 0; 35 | 36 | export function compileCivetToHtml({ 37 | code = '', 38 | prettierOutput = true, 39 | jsOutput = false, 40 | tsOutput = true, 41 | parseOptions = {}, 42 | }): Promise { 43 | uid++; 44 | playgroundWorker.postMessage({ uid, code, prettierOutput, jsOutput, tsOutput, parseOptions }); 45 | return new Promise((resolve) => { 46 | msgMap[uid] = { 47 | resolve, 48 | // Restart the worker whenever we run it with comptime: true 49 | restart: Boolean((parseOptions as any).comptime), 50 | }; 51 | }); 52 | } 53 | -------------------------------------------------------------------------------- /civet.dev/.vitepress/utils/debounce.ts: -------------------------------------------------------------------------------- 1 | export function debounce any>( 2 | func: T, 3 | timeout = 300 4 | ) { 5 | let timer: NodeJS.Timer; 6 | return (...args: Parameters) => { 7 | clearTimeout(timer); 8 | timer = setTimeout(() => { 9 | func.apply(this, args); 10 | }, timeout); 11 | }; 12 | } 13 | -------------------------------------------------------------------------------- /civet.dev/.vitepress/utils/getContributors.mjs: -------------------------------------------------------------------------------- 1 | const token = process.env.API_TOKEN; 2 | 3 | export async function getContributors() { 4 | const headers = {}; 5 | 6 | if (token) { 7 | console.log('Using process.env.API_TOKEN'); 8 | headers['Authorization'] = `Bearer ${token}`; 9 | } 10 | 11 | const result = await fetch( 12 | 'https://api.github.com/repos/DanielXMoore/Civet/contributors', 13 | { headers } 14 | ) 15 | const json = await result.json() 16 | return json 17 | .filter((user) => user.type.toLowerCase() === 'user') 18 | .map((user) => { 19 | const { login, contributions, html_url, avatar_url } = user; 20 | return { 21 | href: html_url, 22 | avatar: avatar_url, 23 | login, 24 | contributions, 25 | }; 26 | }); 27 | } 28 | -------------------------------------------------------------------------------- /civet.dev/.vitepress/utils/getHighlighter.ts: -------------------------------------------------------------------------------- 1 | import * as shiki from 'shiki'; 2 | import type { Highlighter } from 'shiki'; 3 | 4 | let highlighter: Highlighter | null = null; 5 | 6 | export async function getHighlighter() { 7 | if (!highlighter) { 8 | highlighter = await shiki.getHighlighter({ 9 | theme: 'one-dark-pro', 10 | langs: ['coffee', 'tsx'], 11 | }); 12 | } 13 | 14 | return highlighter; 15 | } 16 | -------------------------------------------------------------------------------- /civet.dev/.vitepress/utils/getOpenCollectiveInfo.ts: -------------------------------------------------------------------------------- 1 | export type OpenCollectiveInfo = Awaited< 2 | ReturnType 3 | >; 4 | 5 | type Sponsor = { 6 | id: number; 7 | name?: string; 8 | image?: string; 9 | href: string; 10 | }; 11 | 12 | enum TierSlug { 13 | Backers = 'backers', 14 | Sponsors = 'sponsors', 15 | } 16 | 17 | /** 18 | * See: https://docs.opencollective.com/help/contributing/development/api/collectives#get-members-per-tier 19 | */ 20 | export async function getOpenCollectiveInfo() { 21 | const [backers, sponsors] = await Promise.all([ 22 | getTier(TierSlug.Backers), 23 | getTier(TierSlug.Sponsors), 24 | ]); 25 | 26 | return { sponsors, backers }; 27 | } 28 | 29 | async function getTier(tierSlug: TierSlug): Promise { 30 | const result = await fetch( 31 | `https://opencollective.com/civet/tiers/${tierSlug}/all.json` 32 | ) 33 | const json = await result.json() 34 | return json.map(parseSponsor); 35 | } 36 | 37 | function parseSponsor(sponsor: any): Sponsor { 38 | const { name, image, website, github, twitter, profile, MemberId } = sponsor; 39 | const href = website ?? github ?? twitter ?? profile ?? '#'; 40 | return { 41 | href, 42 | image, 43 | name: name ?? href, 44 | id: MemberId, 45 | }; 46 | } 47 | -------------------------------------------------------------------------------- /civet.dev/integrations.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Integrations 3 | --- 4 | 5 | # {{ $frontmatter.title }} 6 | 7 | ## VSCode 8 | 9 | - [Civet VSCode extension](https://marketplace.visualstudio.com/items?itemName=DanielX.civet) 10 | 11 | ## Build tools 12 | 13 | - [unplugin](https://github.com/DanielXMoore/Civet/blob/main/source/unplugin) integrates Civet into Vite, esbuild, Astro, Farm, Rolldown, Rollup, and Webpack, including `.d.ts` generation (see [basic instructions](https://civet.dev/getting-started#building-a-project)) 14 | - [Simpler esbuild plugin](https://github.com/DanielXMoore/Civet/blob/main/source/esbuild-plugin.civet) 15 | - [Older Vite plugin](https://github.com/edemaine/vite-plugin-civet) (no longer recommended) 16 | - [ESM/CJS loader](https://github.com/DanielXMoore/Civet/blob/main/register.js) for `import`/`require` to support `.civet` files 17 | - [Babel plugin](https://github.com/DanielXMoore/Civet/blob/main/source/babel-plugin.civet) 18 | - Including [React Native / Metro](https://github.com/DanielXMoore/Civet/tree/main/integration/metro) 19 | - [Jest plugin](https://github.com/DanielXMoore/Civet/tree/main/integration/jest) 20 | - [Gulp plugin](https://github.com/DanielXMoore/Civet/tree/main/integration/gulp) 21 | - [Bun plugin](https://github.com/DanielXMoore/Civet/blob/main/source/bun-civet.civet) 22 | - [` 14 | 15 |

16 | Playground Civet {{ data.civetVersion }} 17 |

18 |

Copy the URL to share your code!

19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /civet.dev/public/favicon/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DanielXMoore/Civet/19a8d4ba2724f3d22e63dffa3f9be3a99fae9b04/civet.dev/public/favicon/apple-touch-icon.png -------------------------------------------------------------------------------- /civet.dev/public/favicon/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DanielXMoore/Civet/19a8d4ba2724f3d22e63dffa3f9be3a99fae9b04/civet.dev/public/favicon/favicon-16x16.png -------------------------------------------------------------------------------- /civet.dev/public/favicon/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DanielXMoore/Civet/19a8d4ba2724f3d22e63dffa3f9be3a99fae9b04/civet.dev/public/favicon/favicon-32x32.png -------------------------------------------------------------------------------- /civet.dev/public/favicon/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DanielXMoore/Civet/19a8d4ba2724f3d22e63dffa3f9be3a99fae9b04/civet.dev/public/favicon/favicon.ico -------------------------------------------------------------------------------- /civet.dev/public/fonts/Breamcatcher.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DanielXMoore/Civet/19a8d4ba2724f3d22e63dffa3f9be3a99fae9b04/civet.dev/public/fonts/Breamcatcher.woff2 -------------------------------------------------------------------------------- /civet.dev/public/fonts/FiraCode-Regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DanielXMoore/Civet/19a8d4ba2724f3d22e63dffa3f9be3a99fae9b04/civet.dev/public/fonts/FiraCode-Regular.woff -------------------------------------------------------------------------------- /civet.dev/public/fonts/FiraCode-Regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DanielXMoore/Civet/19a8d4ba2724f3d22e63dffa3f9be3a99fae9b04/civet.dev/public/fonts/FiraCode-Regular.woff2 -------------------------------------------------------------------------------- /civet.dev/public/images/bg.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 7 | 8 | 10 | 11 | 13 | 14 | 15 | 16 | 18 | 19 | 21 | 22 | 24 | 25 | 27 | 28 | 30 | 31 | 33 | 34 | 36 | 37 | 39 | 40 | 42 | 43 | 45 | 46 | 48 | 49 | 51 | 52 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /civet.dev/public/shiki/onig.wasm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DanielXMoore/Civet/19a8d4ba2724f3d22e63dffa3f9be3a99fae9b04/civet.dev/public/shiki/onig.wasm -------------------------------------------------------------------------------- /integration/eslint/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Civet eslint plugin changelog 2 | 3 | ## v0.0.5 (2024-08-26) 4 | * [[#1378](https://github.com/DanielXMoore/Civet/pull/1378)]: 5 | * Support Node 22+ (switch to `import...with`) 6 | * Fix `typescipt-eslint` dependency to be truly optional 7 | * Upgrade build process to latest Civet and other deps 8 | 9 | ## v0.0.4 (2024-05-05) 10 | * Set engines requirement for `import...assert` 11 | * Use `comptime` for plugin version, resulting in smaller build 12 | 13 | ## v0.0.3 (2024-05-04) 14 | * Loosen eslint dependencies 15 | 16 | ## v0.0.2 (2024-05-03) 17 | * Add prepublish script to eslint 18 | 19 | ## v0.0.1 (2024-05-03) 20 | * Enable JSX in eslint, as Civet can output it 21 | 22 | ## v0.0.0 (2024-05-03) 23 | * Initial working version 24 | -------------------------------------------------------------------------------- /integration/eslint/esbuild.civet: -------------------------------------------------------------------------------- 1 | esbuild from "esbuild" 2 | civetPlugin from "@danielx/civet/esbuild" 3 | 4 | watch := process.argv.includes '--watch' 5 | build := 6 | if watch 7 | (opts) => esbuild.context(opts).then .watch() 8 | else 9 | esbuild.build 10 | minify := false 11 | sourcemap := false 12 | 13 | for format of ["esm", "cjs"] 14 | build({ 15 | entryPoints: 16 | index: "source/index.civet" 17 | ts: "source/ts.civet" 18 | bundle: true 19 | splitting: format is "esm" 20 | chunkNames: 'plugin-shared' 21 | external: [ 22 | "@danielx/civet" 23 | "@eslint/js" 24 | "eslint" 25 | "typescript-eslint" 26 | "./package.json" 27 | ] 28 | sourcemap 29 | minify 30 | platform: 'node' 31 | format 32 | target: "esNext" 33 | outdir: 'dist' 34 | outExtension: { ".js": if format == "esm" then ".js" else ".cjs" } 35 | plugins: [ 36 | civetPlugin 37 | parseOptions: 38 | comptime: true 39 | //emitDeclaration: true 40 | ts: "civet" 41 | ] 42 | }).catch -> process.exit 1 43 | -------------------------------------------------------------------------------- /integration/eslint/example/eslint.config.mjs: -------------------------------------------------------------------------------- 1 | //import civetPlugin from "eslint-plugin-civet" 2 | import tsCivetPlugin from "eslint-plugin-civet/ts" 3 | //import js from "@eslint/js" 4 | 5 | export default [ 6 | //--- Simple version, TypeScript: 7 | ...tsCivetPlugin.configs.jsRecommended, 8 | ...tsCivetPlugin.configs.recommended, 9 | ...tsCivetPlugin.configs.stylistic, 10 | //--- Simple version, JavaScript: 11 | //...civetPlugin.configs.recommended, 12 | //--- Longer version (for customization, JavaScript only): 13 | //js.configs.recommended, 14 | //{ 15 | // files: ["**/*.civet"], 16 | // plugins: { 17 | // civet: civetPlugin 18 | // //civet: civetPlugin.civet(options) 19 | // }, 20 | // processor: "civet/civet", 21 | // ...civetPlugin.configs.overrides 22 | //} 23 | ] 24 | -------------------------------------------------------------------------------- /integration/eslint/example/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "civet-eslint-example", 3 | "version": "0.0.0", 4 | "scripts": { 5 | "lint": "eslint" 6 | }, 7 | "devDependencies": { 8 | "@danielx/civet": "^0.9.4", 9 | "eslint": "^9.17.0", 10 | "eslint-plugin-civet": "^0.0.5", 11 | "typescript": "^5.7.2", 12 | "typescript-eslint": "^8.19.0" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /integration/eslint/example/test.civet: -------------------------------------------------------------------------------- 1 | console.log 'hello world' 2 | var foo: number, bar: any 3 | if foo = bar 4 | var bar = foo 5 | var foo 6 | loop 7 | try 8 | throw new Error 'caught' 9 | break 10 | -------------------------------------------------------------------------------- /integration/eslint/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "eslint-plugin-civet", 3 | "type": "module", 4 | "version": "0.0.6", 5 | "description": "ESLint plugin for Civet code", 6 | "engines": { 7 | "node": ">=18.0.0" 8 | }, 9 | "exports": { 10 | ".": { 11 | "import": "./dist/index.js", 12 | "require": "./dist/index.cjs" 13 | }, 14 | "./ts": { 15 | "import": "./dist/ts.js", 16 | "require": "./dist/ts.cjs" 17 | } 18 | }, 19 | "files": [ 20 | "dist/" 21 | ], 22 | "scripts": { 23 | "build": "civet --no-config esbuild.civet", 24 | "prepublishOnly": "yarn build", 25 | "test": "mocha" 26 | }, 27 | "homepage": "https://github.com/DanielXMoore/Civet#readme", 28 | "repository": { 29 | "type": "git", 30 | "url": "git+https://github.com/DanielXMoore/Civet.git", 31 | "directory": "integration/eslint" 32 | }, 33 | "keywords": [ 34 | "eslint" 35 | ], 36 | "author": "Civet Team", 37 | "license": "MIT", 38 | "bugs": { 39 | "url": "https://github.com/DanielXMoore/Civet/issues" 40 | }, 41 | "peerDependencies": { 42 | "@danielx/civet": ">=0.6.0", 43 | "@eslint/js": ">=8.57.0", 44 | "eslint": ">=8.57.0", 45 | "typescript-eslint": ">=7.0.0" 46 | }, 47 | "peerDependenciesMeta": { 48 | "typescript-eslint": { 49 | "optional": true 50 | } 51 | }, 52 | "devDependencies": { 53 | "@danielx/civet": "^0.9.4", 54 | "@eslint/js": "^9.17.0", 55 | "@types/eslint": "^9.6.1", 56 | "eslint": "^9.17.0", 57 | "mocha": "^10.7.3", 58 | "typescript-eslint": "^8.19.0" 59 | }, 60 | "mocha": { 61 | "extension": [ 62 | "civet" 63 | ], 64 | "require": "@danielx/civet/register.js" 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /integration/eslint/source/ts.civet: -------------------------------------------------------------------------------- 1 | type { Linter } from 'eslint' 2 | ts from "typescript-eslint" 3 | { civet: civetJS, type Options } from './index.civet' 4 | 5 | export function civet(options: Options = {js: false}) 6 | options.outputExtension ??= '.tsx' 7 | plugin := civetJS(options) 8 | 9 | function makeConfig(config: T): T 10 | if Array.isArray config 11 | for each c of config 12 | makeConfig c 13 | else 14 | config = {...config as Linter.FlatConfig} 15 | if config.rules? 16 | rules := { ...config.rules } 17 | for rule in plugin.configs.overrides.rules 18 | if rule in rules 19 | rules[rule] = plugin.configs.overrides.rules[rule] 20 | config.rules = { ...config.rules, ...plugin.configs!.overrides.rules } 21 | if config.files? 22 | config.files = [ ...config.files, "**/*.civet" ] 23 | config 24 | 25 | // Rename eslint recommended and all configs to jsRecommended and jsAll 26 | for config in plugin.configs 27 | continue if config is "base" 28 | plugin.configs[`js${config[0].toUpperCase()}${config[1..]}`] = 29 | plugin.configs[config] 30 | 31 | for config in ts.configs 32 | continue if config is "base" 33 | modified := makeConfig ts.configs[config as keyof typeof ts.configs] 34 | if Array.isArray modified 35 | plugin.configs![config] = [ 36 | plugin.configs.base 37 | ...modified 38 | ] 39 | else 40 | plugin.configs![config] = [ 41 | plugin.configs.base 42 | modified 43 | ] 44 | plugin.configs!.base = [ 45 | plugin.configs.base 46 | makeConfig ts.configs.base 47 | ] 48 | plugin 49 | 50 | export default civet() 51 | -------------------------------------------------------------------------------- /integration/example/basic.coffee: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DanielXMoore/Civet/19a8d4ba2724f3d22e63dffa3f9be3a99fae9b04/integration/example/basic.coffee -------------------------------------------------------------------------------- /integration/example/build.civet: -------------------------------------------------------------------------------- 1 | // This file is used in test/integration.civet to test the esbuild plugin 2 | esbuild from esbuild 3 | 4 | civetPlugin from ../../dist/unplugin/esbuild.mjs 5 | 6 | esbuild.build { 7 | +sourcemap 8 | entryPoints: ['source/main.civet'], 9 | outdir: 'dist', 10 | plugins: [ 11 | civetPlugin({}) 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /integration/example/bunfig.toml: -------------------------------------------------------------------------------- 1 | preload = [ "../../dist/bun-civet.mjs" ] 2 | -------------------------------------------------------------------------------- /integration/example/error-cjs.civet: -------------------------------------------------------------------------------- 1 | "civet" 2 | "civet" 3 | "civet" 4 | "civet" 5 | "civet" 6 | throw new Error "intentional" 7 | -------------------------------------------------------------------------------- /integration/example/error-esm.civet: -------------------------------------------------------------------------------- 1 | "civet" 2 | "civet" 3 | "civet" 4 | "civet" 5 | "civet" 6 | throw new Error "intentional" 7 | export irrelevant = 1 8 | -------------------------------------------------------------------------------- /integration/example/generate.coffee: -------------------------------------------------------------------------------- 1 | ###* 2 | Hi 3 | ### 4 | 5 | gen = (node) -> 6 | if node is null or node is undefined 7 | return "" 8 | 9 | if typeof node is "string" 10 | return node 11 | 12 | if Array.isArray(node) 13 | return node.map(gen).join('') 14 | 15 | if typeof node is "object" 16 | ; # TODO 17 | # heyy 18 | 19 | throw new Error("Unknown node", JSON.stringify(node)) 20 | 21 | module.exports = gen 22 | -------------------------------------------------------------------------------- /integration/example/simple.json: -------------------------------------------------------------------------------- 1 | {"hello": ["world"]} 2 | -------------------------------------------------------------------------------- /integration/example/source/main.civet: -------------------------------------------------------------------------------- 1 | // This file is used in test/integration.civet to test the esbuild plugin 2 | console.log "hello from main" 3 | 4 | export default "hi" 5 | -------------------------------------------------------------------------------- /integration/example/test.civet: -------------------------------------------------------------------------------- 1 | // For example, this file can be run in Bun via `bun run test.civet` 2 | // (thanks to `bunfig.toml` in this directory). 3 | 4 | function greet(src: string) 5 | console.log `Hello from ${src}!` 6 | 7 | greet 'Civet' 8 | -------------------------------------------------------------------------------- /integration/example/util.coffee: -------------------------------------------------------------------------------- 1 | assert = require "assert" 2 | let {decompile} = require "../source/util" 3 | hera = require "../source/main" 4 | rules = require "../source/rules" 5 | 6 | describe "util", -> 7 | it "should parse decompiled rules", -> 8 | grammar = decompile(rules) 9 | 10 | # console.log grammar 11 | parsedRules = hera.parse grammar 12 | # console.log parsedRules, rules 13 | 14 | Object.keys(parsedRules).forEach (key) -> 15 | assert.deepEqual(parsedRules[key], rules[key], "#{key} rule doesn't match") 16 | 17 | # strip trailing whitespace before compare 18 | grammar = grammar.replace(/[ ]+\n/g, '\n') 19 | assert.equal grammar, readFile("samples/hera.hera") 20 | 21 | it "should decompile nested choices", -> 22 | rules = hera.parse """ 23 | Rule 24 | ("A" / "C") ("B" / "D") 25 | "Z" -> "z" 26 | "N" -> 0 27 | """ 28 | 29 | decompiled = decompile rules 30 | assert.deepEqual hera.parse(decompiled), rules 31 | 32 | it "should decompile literal undefined", -> 33 | grammar = """ 34 | Rule 35 | "X" -> undefined 36 | 37 | """ 38 | rules = hera.parse grammar 39 | assert.equal decompile(rules), grammar 40 | 41 | it "decompiles to an object format", -> 42 | grammar = """ 43 | Rule 44 | "X" -> {a: 1, b: null} 45 | 46 | """ 47 | rules = hera.parse grammar 48 | 49 | assert.equal decompile(rules), grammar 50 | 51 | it "should throw an error when decompiling an unknown format", -> 52 | rules = hera.parse """ 53 | Rule 54 | "X" -> 0 55 | """ 56 | 57 | rules.Rule[2] = { 58 | yo: "wat" 59 | } 60 | 61 | assert.throws -> 62 | decompile rules 63 | , /Unknown/ 64 | -------------------------------------------------------------------------------- /integration/gulp/.gitignore: -------------------------------------------------------------------------------- 1 | index.js 2 | -------------------------------------------------------------------------------- /integration/gulp/README.md: -------------------------------------------------------------------------------- 1 | # gulp-civet 2 | 3 | `gulp-civet` compiles your [Civet](https://civet.dev) code 4 | in a [Gulp](https://gulpjs.com/) workflow 5 | 6 | The code is based on [gulp-coffee](https://github.com/gulp-community/gulp-coffee). 7 | 8 | ## Usage 9 | 10 | ```js 11 | const civet = require('gulp-civet'); 12 | 13 | gulp.task('civet', () => { 14 | gulp.src('./src/*.civet') 15 | .pipe(civet({ 16 | extension: '.js', 17 | js: true, 18 | }) 19 | .pipe(gulp.dest('./dist')); 20 | }); 21 | ``` 22 | 23 | ## Options 24 | 25 | * `extension` (optional): Output filename extension to use. 26 | Default: `.civet.tsx`, or `.civet.jsx` if `js` is true. 27 | * Other Civet compiler options (e.g. `js: true`). 28 | -------------------------------------------------------------------------------- /integration/gulp/index.civet: -------------------------------------------------------------------------------- 1 | through = require 'through2' 2 | replaceExt = require 'replace-ext' 3 | PluginError = require 'plugin-error' 4 | 5 | interface Options 6 | extension?: string 7 | inlineMap?: boolean 8 | js?: boolean 9 | // or any other Civet options 10 | 11 | module.exports = (options?: Options) -> 12 | function transform(file, encoding: string, callback) 13 | if file.isNull() 14 | return callback null, file 15 | if file.isStream() 16 | return callback new PluginError 'gulp-civet', 'Streaming not supported' 17 | 18 | compileOptions := { 19 | inlineMap: Boolean file.sourceMap 20 | filename: file.path 21 | ...options 22 | } 23 | extension := 24 | if compileOptions.extension? 25 | compileOptions.extension 26 | else if compileOptions.js 27 | ".civet.jsx" 28 | else 29 | ".civet.tsx" 30 | dest := replaceExt file.path, extension 31 | input := file.contents.toString encoding 32 | 33 | let compiled: string 34 | try 35 | compiled = await require('@danielx/civet').compile input, options 36 | catch err 37 | return callback new PluginError 'gulp-civet', err 38 | 39 | file.contents = Buffer.from compiled 40 | file.path = dest; 41 | callback null, file 42 | 43 | through.obj transform 44 | -------------------------------------------------------------------------------- /integration/gulp/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "gulp-civet", 3 | "version": "0.0.1", 4 | "description": "Compile Civet files with Gulp", 5 | "main": "index.js", 6 | "type": "commonjs", 7 | "scripts": { 8 | "prepare": "civet --js -c index.civet -o index.js", 9 | "test": "mocha" 10 | }, 11 | "homepage": "https://github.com/DanielXMoore/Civet#readme", 12 | "repository": { 13 | "type": "git", 14 | "url": "git+https://github.com/DanielXMoore/Civet.git" 15 | }, 16 | "keywords": [ 17 | "gulpplugin" 18 | ], 19 | "author": "Civet Team", 20 | "license": "MIT", 21 | "bugs": { 22 | "url": "https://github.com/DanielXMoore/Civet/issues" 23 | }, 24 | "peerDependencies": { 25 | "@danielx/civet": ">=0.5.35" 26 | }, 27 | "devDependencies": { 28 | "@danielx/civet": "^0.7.4", 29 | "mocha": "^10.7.3", 30 | "vinyl": "^3.0.0" 31 | }, 32 | "dependencies": { 33 | "plugin-error": "^2.0.1", 34 | "replace-ext": "^2.0.0", 35 | "through2": "^4.0.2" 36 | }, 37 | "mocha": { 38 | "extension": ["civet"], 39 | "require": "@danielx/civet/register" 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /integration/gulp/test/test.civet: -------------------------------------------------------------------------------- 1 | civet from '../index.js' 2 | assert from 'node:assert' 3 | {basename, dirname, normalize} from 'node:path' 4 | File from 'vinyl' 5 | 6 | function createFile(path: string, contents: string) 7 | base := dirname path 8 | new File { 9 | path 10 | base 11 | cwd: dirname base 12 | contents: Buffer.from contents 13 | } 14 | 15 | function testOutput(newPath: string, expected: string, done) 16 | newPath = normalize newPath 17 | return (newFile) => 18 | assert.equal newFile.path, newPath 19 | assert.equal String(newFile.contents), expected 20 | assert.equal newFile.relative, basename newPath 21 | done() 22 | 23 | describe 'gulp-civet', => 24 | it 'compiles a simple file', (done) => 25 | civet() 26 | .on 'error', done 27 | .on 'data', (testOutput '/home/civet/test/file.civet.tsx', ''' 28 | const hello = 'world' 29 | ''', done) 30 | .write createFile '/home/civet/test/file.civet', ''' 31 | hello := 'world' 32 | ''' 33 | 34 | it 'extension option changes output filename', (done) => 35 | civet {extension: '.js', js: true} 36 | .on 'error', done 37 | .on 'data', (testOutput '/home/civet/test/file.js', ''' 38 | const hello = 'world' 39 | ''', done) 40 | .write createFile '/home/civet/test/file.civet', ''' 41 | hello := 'world' 42 | ''' 43 | 44 | it 'emits errors correctly', (done) => 45 | civet() 46 | .on 'error', ((err) => done()) 47 | .on 'data', => 48 | throw new Error 'no file should have been emitted!' 49 | .write createFile '/home/civet/test/file.civet', ''' 50 | hello :::= 'world' 51 | ''' 52 | -------------------------------------------------------------------------------- /integration/jest/.gitignore: -------------------------------------------------------------------------------- 1 | index.js 2 | -------------------------------------------------------------------------------- /integration/jest/README.md: -------------------------------------------------------------------------------- 1 | # civet-jest 2 | 3 | `civet-jest` is a [Jest transformer](https://jestjs.io/docs/code-transformation) 4 | for automatically transpiling [Civet](https://civet.dev/) code into JavaScript 5 | when testing via [Jest](https://jestjs.io/). 6 | 7 | It does not yet support chaining with 8 | [babel-jest](https://github.com/jestjs/jest/tree/main/packages/babel-jest), 9 | so JSX is not supported. 10 | 11 | ## Usage 12 | 13 | ### Installation 14 | 15 | 1. Install Civet if you haven't already: `npm install -D @danielx/civet` 16 | 2. Install this plugin: `npm install -D civet-jest` 17 | 18 | ### Configuration 19 | 20 | Edit your `jest.config.*` file to define the transform and allow the `.civet` 21 | file extension. Here is an complete example `jest.config.mjs`: 22 | 23 | ```js 24 | import {defaults} from 'jest-config' 25 | 26 | export default { 27 | extensionsToTreatAsEsm: [ '.civet' ], 28 | moduleFileExtensions: [ ...defaults.moduleFileExtensions, 'civet' ], 29 | testMatch: [ '/test/**/*.civet' ], 30 | transform: { 31 | '\\.civet': 'civet-jest', 32 | }, 33 | verbose: true, 34 | } 35 | ``` 36 | 37 | This directory has a similar [`jest.config.mjs`](jest.config.mjs) 38 | that enables local testing via `yarn test`. 39 | 40 | ### package.json script 41 | 42 | In CommonJS mode, you should be able to just use: 43 | 44 | ```json 45 | { 46 | "scripts": { 47 | "test": "jest" 48 | } 49 | } 50 | ``` 51 | 52 | In [ESM mode](https://jestjs.io/docs/ecmascript-modules), 53 | you need something like this: 54 | 55 | ```json 56 | { 57 | "scripts": { 58 | "test": "cross-env NODE_OPTIONS=--experimental-vm-modules jest" 59 | } 60 | } 61 | ``` 62 | 63 | This directory has a similar [`package.json`](package.json) 64 | that enables local testing via `yarn test`. 65 | -------------------------------------------------------------------------------- /integration/jest/index.civet: -------------------------------------------------------------------------------- 1 | createCacheKeyFunction := require('@jest/create-cache-key-function').default; 2 | { compile } := require '@danielx/civet' 3 | 4 | module.exports = { 5 | 6 | // sync compilation API (when `require`ing .civet files) 7 | process(sourceText: string, filename: string) 8 | { code, sourceMap } := compile sourceText, { 9 | filename 10 | js: true 11 | sync: true 12 | sourceMap: true 13 | } 14 | { code, map: sourceMap.json() } 15 | 16 | // async compilation API (when `import`ing .civet files) 17 | async processAsync(sourceText: string, filename: string) 18 | { code, sourceMap } := await compile sourceText, { 19 | filename 20 | js: true 21 | sourceMap: true 22 | } 23 | { code, map: sourceMap.json() } 24 | 25 | getCacheKey: createCacheKeyFunction [ 26 | __filename 27 | require.resolve '@danielx/civet' 28 | ] 29 | 30 | } 31 | -------------------------------------------------------------------------------- /integration/jest/jest.config.mjs: -------------------------------------------------------------------------------- 1 | // NODE_OPTIONS="$NODE_OPTIONS --experimental-vm-modules" npx jest 2 | 3 | import {defaults} from 'jest-config' 4 | 5 | export default { 6 | extensionsToTreatAsEsm: [ '.civet' ], 7 | moduleFileExtensions: [ ...defaults.moduleFileExtensions, 'civet' ], 8 | testMatch: [ '/test/**/*.civet' ], 9 | transform: { 10 | // You should use the transform like this: 11 | //'\\.civet': 'civet-jest', 12 | // For local testing, we use the following: 13 | '\\.civet': './', // 'civet-jest', 14 | }, 15 | verbose: true, 16 | } 17 | -------------------------------------------------------------------------------- /integration/jest/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "civet-jest", 3 | "version": "0.0.0", 4 | "description": "Test Civet files with Jest", 5 | "main": "index.js", 6 | "type": "commonjs", 7 | "scripts": { 8 | "prepare": "civet --js -c index.civet -o index.js", 9 | "test": "yarn prepare && cross-env NODE_OPTIONS=--experimental-vm-modules jest" 10 | }, 11 | "homepage": "https://github.com/DanielXMoore/Civet#readme", 12 | "repository": { 13 | "type": "git", 14 | "url": "git+https://github.com/DanielXMoore/Civet.git" 15 | }, 16 | "keywords": [ 17 | "jest", 18 | "civet" 19 | ], 20 | "author": "Civet Team", 21 | "license": "MIT", 22 | "bugs": { 23 | "url": "https://github.com/DanielXMoore/Civet/issues" 24 | }, 25 | "peerDependencies": { 26 | "@danielx/civet": ">=0.7.0" 27 | }, 28 | "devDependencies": { 29 | "@danielx/civet": "0.7.17", 30 | "cross-env": "7.0.3", 31 | "jest": "29.7.0" 32 | }, 33 | "dependencies": { 34 | "@jest/create-cache-key-function": "29.7.0" 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /integration/jest/test/example.civet: -------------------------------------------------------------------------------- 1 | assert from assert 2 | 3 | describe 'tests', => 4 | it 'equal', => 5 | assert.equal 1+1, 2 6 | it 'not equal', => 7 | assert.throws => 8 | assert.equal 1+1, 3 9 | -------------------------------------------------------------------------------- /integration/metro/README.md: -------------------------------------------------------------------------------- 1 | # Civet in React Native / Metro 2 | 3 | To use Civet with [React Native](https://reactnative.dev/), 4 | you need to configure the [Metro bundler](https://reactnative.dev/docs/metro) to: 5 | 6 | 1. [Allow the `.civet` extension](https://metrobundler.dev/docs/configuration/#sourceexts) 7 | 2. Add the [Civet Babel plugin](https://github.com/DanielXMoore/Civet/blob/main/source/babel-plugin.civet) 8 | 9 | Here is an example diff for the configuration: 10 | 11 | ```diff 12 | // include .civet files to module resolution in metro.config.js 13 | -const config = {}; 14 | +const config = { 15 | + resolver: { 16 | + sourceExts: ['js', 'jsx', 'json', 'ts', 'tsx', 'civet'], 17 | + }, 18 | +}; 19 | 20 | // add plugin in babel.config.js 21 | module.exports = { 22 | presets: ['module:@react-native/babel-preset'], 23 | + plugins: [['@danielx/civet/babel-plugin']], 24 | + sourceMaps: 'inline', 25 | }; 26 | ``` 27 | -------------------------------------------------------------------------------- /integration/script/README.md: -------------------------------------------------------------------------------- 1 | # Civet in ` 9 | ``` 10 | 11 | Then you can run inline Civet scripts like so: 12 | 13 | ```html 14 | 17 | ``` 18 | 19 | You can also run Civet code from files, like so: 20 | 21 | ```html 22 | 23 | ``` 24 | 25 | In the latter case, the HTML needs to be served by a web server 26 | (not via `file:` URL) to pass CORS. 27 | 28 | If you dynamically add ` 49 | ``` 50 | 51 | You can turn off automatic execution of dynamically added scripts 52 | (but keep initial loading of scripts) by adding a `no-auto-scripts` 53 | attribute: 54 | 55 | ```html 56 | 57 | ``` 58 | 59 | You can turn off just the initial loading of scripts (but keep automatic 60 | execution of dynamically added scripts) by adding a `no-start-scripts` 61 | attribute: 62 | 63 | ```html 64 | 65 | ``` 66 | 67 | If you want to manually trigger running all ` 5 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /integration/unplugin-examples/astro/.gitignore: -------------------------------------------------------------------------------- 1 | # build output 2 | dist/ 3 | # generated types 4 | .astro/ 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 | -------------------------------------------------------------------------------- /integration/unplugin-examples/astro/.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": ["astro-build.astro-vscode"], 3 | "unwantedRecommendations": [] 4 | } 5 | -------------------------------------------------------------------------------- /integration/unplugin-examples/astro/.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.2.0", 3 | "configurations": [ 4 | { 5 | "command": "./node_modules/.bin/astro dev", 6 | "name": "Development server", 7 | "request": "launch", 8 | "type": "node-terminal" 9 | } 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /integration/unplugin-examples/astro/README.md: -------------------------------------------------------------------------------- 1 | # Astro Starter Kit: Minimal 2 | 3 | ``` 4 | npm create astro@latest -- --template minimal 5 | ``` 6 | 7 | [![Open in StackBlitz](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/github/withastro/astro/tree/latest/examples/minimal) 8 | [![Open with CodeSandbox](https://assets.codesandbox.io/github/button-edit-lime.svg)](https://codesandbox.io/p/sandbox/github/withastro/astro/tree/latest/examples/minimal) 9 | [![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/withastro/astro?devcontainer_path=.devcontainer/minimal/devcontainer.json) 10 | 11 | > 🧑‍🚀 **Seasoned astronaut?** Delete this file. Have fun! 12 | 13 | ## 🚀 Project Structure 14 | 15 | Inside of your Astro project, you'll see the following folders and files: 16 | 17 | ``` 18 | / 19 | ├── public/ 20 | ├── src/ 21 | │ └── pages/ 22 | │ └── index.astro 23 | └── package.json 24 | ``` 25 | 26 | Astro looks for `.astro` or `.md` files in the `src/pages/` directory. Each page is exposed as a route based on its file name. 27 | 28 | There's nothing special about `src/components/`, but that's where we like to put any Astro/React/Vue/Svelte/Preact components. 29 | 30 | Any static assets, like images, can be placed in the `public/` directory. 31 | 32 | ## 🧞 Commands 33 | 34 | All commands are run from the root of the project, from a terminal: 35 | 36 | | Command | Action | 37 | | :------------------------ | :----------------------------------------------- | 38 | | `npm install` | Installs dependencies | 39 | | `npm run dev` | Starts local dev server at `localhost:3000` | 40 | | `npm run build` | Build your production site to `./dist/` | 41 | | `npm run preview` | Preview your build locally, before deploying | 42 | | `npm run astro ...` | Run CLI commands like `astro add`, `astro check` | 43 | | `npm run astro -- --help` | Get help using the Astro CLI | 44 | 45 | ## 👀 Want to learn more? 46 | 47 | Feel free to check [our documentation](https://docs.astro.build) or jump into our [Discord server](https://astro.build/chat). 48 | -------------------------------------------------------------------------------- /integration/unplugin-examples/astro/astro.config.mjs: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'astro/config'; 2 | import civet from '@danielx/civet/astro'; 3 | 4 | import solidJs from '@astrojs/solid-js'; 5 | 6 | // https://astro.build/config 7 | export default defineConfig({ 8 | integrations: [ 9 | civet({ 10 | ts: 'preserve', 11 | }), 12 | solidJs(), 13 | ], 14 | }); 15 | -------------------------------------------------------------------------------- /integration/unplugin-examples/astro/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "astro-example", 3 | "type": "module", 4 | "version": "0.0.1", 5 | "scripts": { 6 | "dev": "astro dev", 7 | "start": "astro dev", 8 | "build": "astro build", 9 | "preview": "astro preview", 10 | "astro": "astro" 11 | }, 12 | "dependencies": { 13 | "@astrojs/solid-js": "^5.0.1", 14 | "astro": "^5.1.2", 15 | "solid-js": "^1.7.11" 16 | }, 17 | "devDependencies": { 18 | "@danielx/civet": "latest" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /integration/unplugin-examples/astro/public/favicon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 9 | 10 | -------------------------------------------------------------------------------- /integration/unplugin-examples/astro/src/component.civet: -------------------------------------------------------------------------------- 1 | {createSignal} from 'solid-js' 2 | 3 | 4 | export default function Counter() 5 | [count, setCount] := createSignal 0 6 | 7 | console.log "rendering" 8 | 9 |