├── .node-version ├── packages ├── melon │ ├── log │ │ └── .keep │ ├── src │ │ ├── assets │ │ │ ├── robots.txt │ │ │ ├── favicon.ico │ │ │ ├── icons │ │ │ │ ├── icon-72x72.png │ │ │ │ ├── icon-96x96.png │ │ │ │ ├── icon-128x128.png │ │ │ │ ├── icon-144x144.png │ │ │ │ ├── icon-152x152.png │ │ │ │ ├── icon-192x192.png │ │ │ │ ├── icon-384x384.png │ │ │ │ └── icon-512x512.png │ │ │ ├── register.js │ │ │ ├── images │ │ │ │ ├── states-of-js-2020.png │ │ │ │ ├── ogp-pipeline-operator.png │ │ │ │ └── loading.svg │ │ │ ├── css │ │ │ │ ├── theme.css │ │ │ │ ├── reset.css │ │ │ │ └── markdown.css │ │ │ ├── manifest.json │ │ │ └── sw.js │ │ ├── pages │ │ │ ├── index.tsx │ │ │ └── blog │ │ │ │ ├── 20201221 │ │ │ │ └── index.tsx │ │ │ │ ├── 20211204 │ │ │ │ └── index.tsx │ │ │ │ ├── index.tsx │ │ │ │ └── articles.tsx │ │ ├── components │ │ │ ├── organisms │ │ │ │ └── nav │ │ │ │ │ └── index.tsx │ │ │ └── templates │ │ │ │ ├── html.tsx │ │ │ │ └── page.tsx │ │ └── index.tsx │ ├── .gitignore │ ├── README.md │ ├── tsconfig.json │ ├── package.json │ └── for-local │ │ └── nginx.templ.conf ├── ichigo │ ├── src │ │ ├── html │ │ │ ├── index.ts │ │ │ ├── classnames.ts │ │ │ └── __tests__ │ │ │ │ └── classnames.spec.ts │ │ ├── http │ │ │ ├── index.ts │ │ │ ├── content-type.ts │ │ │ └── __tests__ │ │ │ │ └── content-type.spec.ts │ │ ├── index.ts │ │ ├── __tests__ │ │ │ └── pipe.spec.ts │ │ └── pipe.ts │ ├── README.md │ ├── tsconfig.esm.json │ ├── tsconfig.json │ ├── jest.config.js │ └── package.json ├── zakuro │ ├── src │ │ ├── index.tsx │ │ ├── atoms │ │ │ ├── index.tsx │ │ │ ├── bold │ │ │ │ ├── index.tsx │ │ │ │ └── story.tsx │ │ │ └── time │ │ │ │ ├── story.tsx │ │ │ │ └── index.tsx │ │ └── explorer │ │ │ ├── assets │ │ │ ├── index.js │ │ │ └── index.css │ │ │ ├── import.tsx │ │ │ ├── root.tsx │ │ │ └── index.tsx │ ├── README.md │ ├── tsconfig.esm.json │ ├── jest.config.js │ ├── tsconfig.json │ └── package.json ├── naruto │ ├── src │ │ ├── index.ts │ │ ├── res.ts │ │ └── req.ts │ ├── README.md │ ├── tsconfig.json │ ├── tsconfig.esm.json │ └── package.json ├── suica │ ├── src │ │ ├── middleware │ │ │ ├── body-parser │ │ │ │ ├── index.ts │ │ │ │ ├── json.ts │ │ │ │ └── utils.ts │ │ │ └── index.ts │ │ ├── __tests__ │ │ │ └── index.spec.ts │ │ └── index.ts │ ├── README.md │ ├── tsconfig.esm.json │ ├── jest.config.js │ ├── tsconfig.json │ └── package.json ├── lemon │ ├── README.md │ ├── tsconfig.esm.json │ ├── jest.config.js │ ├── tsconfig.json │ ├── src │ │ ├── index.ts │ │ ├── __tests__ │ │ │ ├── css.spec.ts │ │ │ ├── index.spec.ts │ │ │ ├── jsx.spec.tsx │ │ │ └── renderToString.spec.tsx │ │ ├── autocomplete.ts │ │ ├── createElement.ts │ │ ├── renderToString.ts │ │ ├── role.ts │ │ ├── wai-aria.ts │ │ ├── css.ts │ │ ├── rfc2978.ts │ │ └── jsx.ts │ └── package.json └── knife │ ├── README.md │ ├── yarn.lock │ ├── package-lock.json │ ├── tsconfig.esm.json │ ├── jest.config.js │ ├── tsconfig.json │ ├── package.json │ └── src │ ├── __tests__ │ └── tokenizer.spec.ts │ └── tokenizer.ts ├── .gitignore ├── renovate.json ├── .vim-lsp-settings └── settings.json ├── .editorconfig ├── .prettierrc.json ├── README.md ├── docker ├── nginx │ └── Dockerfile └── app │ └── Dockerfile ├── docker-compose.yml ├── tsconfig.node.json ├── tsconfig.json ├── package.json ├── .github └── workflows │ ├── main.yml │ └── codeql-analysis.yml ├── LICENSE └── nginx └── nginx.conf /.node-version: -------------------------------------------------------------------------------- 1 | 16.15.0 2 | -------------------------------------------------------------------------------- /packages/melon/log/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /packages/ichigo/src/html/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./classnames"; 2 | -------------------------------------------------------------------------------- /packages/melon/src/assets/robots.txt: -------------------------------------------------------------------------------- 1 | User-agent: * 2 | Allow: / 3 | -------------------------------------------------------------------------------- /packages/zakuro/src/index.tsx: -------------------------------------------------------------------------------- 1 | export * as atoms from "./atoms"; 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | build 2 | esm 3 | node_modules 4 | *.tsbuildinfo 5 | *.log 6 | -------------------------------------------------------------------------------- /packages/ichigo/src/http/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./content-type"; 2 | -------------------------------------------------------------------------------- /renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": [ 3 | "config:base" 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /packages/melon/.gitignore: -------------------------------------------------------------------------------- 1 | *.0x 2 | *.pem 3 | /for-local/nginx.conf 4 | *.log 5 | -------------------------------------------------------------------------------- /packages/naruto/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./req"; 2 | export * from "./res"; 3 | -------------------------------------------------------------------------------- /packages/suica/src/middleware/body-parser/index.ts: -------------------------------------------------------------------------------- 1 | export { json } from "./json"; 2 | -------------------------------------------------------------------------------- /packages/suica/src/middleware/index.ts: -------------------------------------------------------------------------------- 1 | export * as bodyParser from "./body-parser"; 2 | -------------------------------------------------------------------------------- /packages/zakuro/src/atoms/index.tsx: -------------------------------------------------------------------------------- 1 | export * from "./bold"; 2 | export * from "./time"; 3 | -------------------------------------------------------------------------------- /packages/lemon/README.md: -------------------------------------------------------------------------------- 1 | # :lemon: kajitsu:lemon - 果実:れもん 2 | > jsx 3 | 4 | ## LICENSE 5 | 6 | MIT 7 | -------------------------------------------------------------------------------- /packages/melon/README.md: -------------------------------------------------------------------------------- 1 | # :melon: kajitsu:melon - 果実:めろん 2 | > めろんのブログ 3 | 4 | ## LICENSE 5 | 6 | MIT 7 | -------------------------------------------------------------------------------- /.vim-lsp-settings/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "efm-langserver": { 3 | "disabled": false 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /packages/knife/README.md: -------------------------------------------------------------------------------- 1 | # :hocho: kajitsu:knife - 果実:ナイフ 2 | > 果物ナイフでマークダウン 3 | 4 | ## LICENSE 5 | 6 | MIT 7 | -------------------------------------------------------------------------------- /packages/naruto/README.md: -------------------------------------------------------------------------------- 1 | # :fish_cake: kajitsu:naruto - 果実:鳴門 2 | > テスト用モック集 3 | 4 | ## LICENSE 5 | 6 | MIT 7 | -------------------------------------------------------------------------------- /packages/ichigo/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./pipe"; 2 | export * from "./html"; 3 | export * as http from "./http"; 4 | -------------------------------------------------------------------------------- /packages/ichigo/README.md: -------------------------------------------------------------------------------- 1 | # :strawberry: kajitsu:ichigo - 果実:いちご 2 | > つぶつぶイチゴの関数ユーティリティ 3 | 4 | ## LICENSE 5 | 6 | MIT 7 | -------------------------------------------------------------------------------- /packages/knife/yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | -------------------------------------------------------------------------------- /packages/melon/src/assets/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MaxMEllon/kajitsu/HEAD/packages/melon/src/assets/favicon.ico -------------------------------------------------------------------------------- /packages/suica/README.md: -------------------------------------------------------------------------------- 1 | # :watermelon: kajitsu:suica - 果実:すいか 2 | > ウェブフレームワーク・フォー・ノード 3 | 4 | ## LICENSE 5 | 6 | MIT 7 | -------------------------------------------------------------------------------- /packages/zakuro/README.md: -------------------------------------------------------------------------------- 1 | # :red_circle: kajitsu:zakuro - 果実:ざくろ 2 | > component utility 3 | 4 | ## LICENSE 5 | 6 | MIT 7 | -------------------------------------------------------------------------------- /packages/knife/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@kajitsu/knife", 3 | "version": "1.0.0", 4 | "lockfileVersion": 1 5 | } 6 | -------------------------------------------------------------------------------- /packages/melon/src/assets/icons/icon-72x72.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MaxMEllon/kajitsu/HEAD/packages/melon/src/assets/icons/icon-72x72.png -------------------------------------------------------------------------------- /packages/melon/src/assets/icons/icon-96x96.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MaxMEllon/kajitsu/HEAD/packages/melon/src/assets/icons/icon-96x96.png -------------------------------------------------------------------------------- /packages/melon/src/assets/icons/icon-128x128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MaxMEllon/kajitsu/HEAD/packages/melon/src/assets/icons/icon-128x128.png -------------------------------------------------------------------------------- /packages/melon/src/assets/icons/icon-144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MaxMEllon/kajitsu/HEAD/packages/melon/src/assets/icons/icon-144x144.png -------------------------------------------------------------------------------- /packages/melon/src/assets/icons/icon-152x152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MaxMEllon/kajitsu/HEAD/packages/melon/src/assets/icons/icon-152x152.png -------------------------------------------------------------------------------- /packages/melon/src/assets/icons/icon-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MaxMEllon/kajitsu/HEAD/packages/melon/src/assets/icons/icon-192x192.png -------------------------------------------------------------------------------- /packages/melon/src/assets/icons/icon-384x384.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MaxMEllon/kajitsu/HEAD/packages/melon/src/assets/icons/icon-384x384.png -------------------------------------------------------------------------------- /packages/melon/src/assets/icons/icon-512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MaxMEllon/kajitsu/HEAD/packages/melon/src/assets/icons/icon-512x512.png -------------------------------------------------------------------------------- /packages/melon/src/assets/register.js: -------------------------------------------------------------------------------- 1 | if ("serviceWorker" in navigator) { 2 | navigator.serviceWorker.register("/sw.h6u4siOcagcPl8vd.js"); 3 | } 4 | -------------------------------------------------------------------------------- /packages/zakuro/src/atoms/bold/index.tsx: -------------------------------------------------------------------------------- 1 | import { styled } from "@kajitsu/lemon"; 2 | 3 | export const Bold = styled("b")` 4 | font-weight: 700; 5 | `; 6 | -------------------------------------------------------------------------------- /packages/melon/src/assets/images/states-of-js-2020.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MaxMEllon/kajitsu/HEAD/packages/melon/src/assets/images/states-of-js-2020.png -------------------------------------------------------------------------------- /packages/zakuro/src/atoms/bold/story.tsx: -------------------------------------------------------------------------------- 1 | import { h } from "@kajitsu/lemon"; 2 | import { Bold } from "."; 3 | 4 | export const basic = () => example; 5 | -------------------------------------------------------------------------------- /packages/melon/src/assets/images/ogp-pipeline-operator.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MaxMEllon/kajitsu/HEAD/packages/melon/src/assets/images/ogp-pipeline-operator.png -------------------------------------------------------------------------------- /packages/naruto/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.node.json", 3 | "compilerOptions": { 4 | "rootDir": "./src", 5 | "outDir": "./build" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /packages/ichigo/src/html/classnames.ts: -------------------------------------------------------------------------------- 1 | export const classnames = ( 2 | ...names: Array 3 | ): string => { 4 | return names.filter((x) => x).join(" "); 5 | }; 6 | -------------------------------------------------------------------------------- /packages/ichigo/tsconfig.esm.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "module": "ESNext", 5 | "rootDir": "./src", 6 | "outDir": "./esm" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /packages/knife/tsconfig.esm.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "module": "ESNext", 5 | "rootDir": "./src", 6 | "outDir": "./esm" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /packages/lemon/tsconfig.esm.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "module": "ESNext", 5 | "rootDir": "./src", 6 | "outDir": "./esm" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /packages/naruto/tsconfig.esm.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "module": "ESNext", 5 | "rootDir": "./src", 6 | "outDir": "./esm" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /packages/suica/tsconfig.esm.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "module": "ESNext", 5 | "rootDir": "./src", 6 | "outDir": "./esm" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /packages/zakuro/src/atoms/time/story.tsx: -------------------------------------------------------------------------------- 1 | import { h } from "@kajitsu/lemon"; 2 | import { Time } from "."; 3 | 4 | export const basic = () => ; 5 | -------------------------------------------------------------------------------- /packages/zakuro/tsconfig.esm.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "module": "ESNext", 5 | "rootDir": "./src", 6 | "outDir": "./esm" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | indent_size = 2 5 | trim_trailing_whitespace = true 6 | insert_final_newline = true 7 | 8 | [{*.json,*.yml,*.ts,*.tsx,*.js}] 9 | indent_style = space 10 | -------------------------------------------------------------------------------- /.prettierrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "printWidth": 120, 3 | "tabWidth": 2, 4 | "singleQuote": false, 5 | "trailingComma": "all", 6 | "semi": true, 7 | "arrowParens": "always", 8 | "parser": "typescript" 9 | } 10 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # :tropical_drink: kajitsu - 果実 2 | 3 | [![Actions Status: CI](https://github.com/MaxMEllon/kajitsu/workflows/CI/badge.svg)](https://github.com/MaxMEllon/kajitsu/actions?query=workflow%3A"CI") 4 | 5 | ## LICENSE 6 | 7 | MIT 8 | -------------------------------------------------------------------------------- /packages/ichigo/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "compilerOptions": { 4 | "module": "CommonJS", 5 | "rootDir": "./src", 6 | "outDir": "./build", 7 | "esModuleInterop": true 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /packages/ichigo/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | roots: ["."], 3 | transform: { 4 | "^.+\\.tsx?$": "ts-jest", 5 | }, 6 | testRegex: "/__tests__/.*\\.spec\\.tsx?$", 7 | moduleFileExtensions: ["ts", "tsx", "js", "jsx", "json", "node"], 8 | }; 9 | -------------------------------------------------------------------------------- /packages/knife/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | roots: ["."], 3 | transform: { 4 | "^.+\\.tsx?$": "ts-jest", 5 | }, 6 | testRegex: "/__tests__/.*\\.spec\\.tsx?$", 7 | moduleFileExtensions: ["ts", "tsx", "js", "jsx", "json", "node"], 8 | }; 9 | -------------------------------------------------------------------------------- /packages/knife/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "compilerOptions": { 4 | "module": "CommonJS", 5 | "rootDir": "./src", 6 | "outDir": "./build", 7 | "jsx": "react", 8 | "jsxFactory": "h" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /packages/lemon/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | roots: ["."], 3 | transform: { 4 | "^.+\\.tsx?$": "ts-jest", 5 | }, 6 | testRegex: "/__tests__/.*\\.spec\\.tsx?$", 7 | moduleFileExtensions: ["ts", "tsx", "js", "jsx", "json", "node"], 8 | }; 9 | -------------------------------------------------------------------------------- /packages/zakuro/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | roots: ["."], 3 | transform: { 4 | "^.+\\.tsx?$": "ts-jest", 5 | }, 6 | testRegex: "/__tests__/.*\\.spec\\.tsx?$", 7 | moduleFileExtensions: ["ts", "tsx", "js", "jsx", "json", "node"], 8 | }; 9 | -------------------------------------------------------------------------------- /packages/melon/src/pages/index.tsx: -------------------------------------------------------------------------------- 1 | import { h, FC, styled } from "@kajitsu/lemon"; 2 | import { PageTemplate } from "../components/templates/page"; 3 | 4 | export const Index: FC = () => ; 5 | -------------------------------------------------------------------------------- /packages/zakuro/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "compilerOptions": { 4 | "module": "CommonJS", 5 | "rootDir": "./src", 6 | "outDir": "./build", 7 | "jsx": "react", 8 | "jsxFactory": "h" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /packages/zakuro/src/atoms/time/index.tsx: -------------------------------------------------------------------------------- 1 | import { h, FC } from "@kajitsu/lemon"; 2 | 3 | export const Time: FC<{ datetime?: string }> = ({ datetime, children }) => { 4 | if (datetime) return ; 5 | return ; 6 | }; 7 | -------------------------------------------------------------------------------- /packages/zakuro/src/explorer/assets/index.js: -------------------------------------------------------------------------------- 1 | const iframe = document.querySelector("iframe#story"); 2 | const buttons = document.querySelectorAll("button"); 3 | 4 | for (const b of buttons) { 5 | b.addEventListener("click", () => { 6 | iframe.src = "/" + b.innerText; 7 | }); 8 | } 9 | -------------------------------------------------------------------------------- /docker/nginx/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM nginx:1.23.0-alpine 2 | 3 | RUN apk --no-cache add tzdata && \ 4 | cp /usr/share/zoneinfo/Asia/Tokyo /etc/localtime && \ 5 | apk del tzdata 6 | 7 | COPY ./nginx/nginx.conf /etc/nginx/nginx.conf 8 | 9 | CMD sh -c "exec nginx -g 'daemon off;'" 10 | 11 | 12 | -------------------------------------------------------------------------------- /packages/lemon/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "compilerOptions": { 4 | "module": "CommonJS", 5 | "rootDir": "./src", 6 | "outDir": "./build", 7 | "jsx": "react", 8 | "jsxFactory": "h", 9 | "jsxFragmentFactory": "Fragment" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /packages/melon/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.node.json", 3 | "compilerOptions": { 4 | "rootDir": "./src", 5 | "outDir": "./build", 6 | "module": "commonjs", 7 | "jsx": "react", 8 | "jsxFactory": "h", 9 | "jsxFragmentFactory": "Fragment" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /packages/suica/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | roots: ["."], 3 | transform: { 4 | "^.+\\.tsx?$": "ts-jest", 5 | }, 6 | moduleDirectories: ["../../node_modules"], 7 | testRegex: "/__tests__/.*\\.spec\\.tsx?$", 8 | moduleFileExtensions: ["ts", "tsx", "js", "jsx", "json", "node"], 9 | }; 10 | -------------------------------------------------------------------------------- /packages/suica/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.node.json", 3 | "compilerOptions": { 4 | "rootDir": "./src", 5 | "outDir": "./build", 6 | "typeRoots": [ 7 | "../../node_modules/@types", 8 | "./node_modules/@types", 9 | "./src/@types" 10 | ] 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: "3" 2 | 3 | services: 4 | app: 5 | build: 6 | context: . 7 | dockerfile: ./docker/app/Dockerfile 8 | ports: 9 | - "3000:3000" 10 | 11 | nginx: 12 | build: 13 | context: . 14 | dockerfile: ./docker/nginx/Dockerfile 15 | depends_on: 16 | - app 17 | ports: 18 | - "8080:80" 19 | -------------------------------------------------------------------------------- /tsconfig.node.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2018", 4 | "module": "commonjs", 5 | "lib": [ 6 | "ES2019", 7 | "ESNext" 8 | ], 9 | "strict": true, 10 | "moduleResolution": "node", 11 | "esModuleInterop": true, 12 | "skipLibCheck": true, 13 | "forceConsistentCasingInFileNames": true, 14 | "sourceMap": true, 15 | "incremental": true 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /packages/lemon/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./jsx"; 2 | export * from "./renderToString"; 3 | export * from "./createElement"; 4 | 5 | import * as css from "./css"; 6 | 7 | export const styled = css.css; 8 | export const renderToStyleString = css.renderToStyleString; 9 | export const createStyleContext = css.createStyleContext; 10 | export const refreshContext = css.refreshContext; 11 | export type StyleContext = css.Context; 12 | -------------------------------------------------------------------------------- /packages/naruto/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@kajitsu/naruto", 3 | "version": "1.0.0", 4 | "main": "build/index.js", 5 | "module": "esm/index.js", 6 | "types": "esm/index.d.ts", 7 | "scripts": { 8 | "build:cjs": "tsc -d -p ./tsconfig.json", 9 | "build:esm": "tsc -d -p ./tsconfig.esm.json", 10 | "build": "npm run build:cjs && npm run build:esm", 11 | "test": "echo TODO" 12 | }, 13 | "license": "MIT" 14 | } 15 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es6", 4 | "module": "CommonJS", 5 | "lib": [ 6 | "ES2015", 7 | "ES2016", 8 | "ES2017", 9 | "ES2018", 10 | "ES2019", 11 | "ESNext" 12 | ], 13 | "strict": true, 14 | "moduleResolution": "node", 15 | "esModuleInterop": true, 16 | "forceConsistentCasingInFileNames": true, 17 | "sourceMap": true, 18 | "incremental": true 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /packages/ichigo/src/html/__tests__/classnames.spec.ts: -------------------------------------------------------------------------------- 1 | import { classnames } from "../classnames"; 2 | 3 | describe("classnames", () => { 4 | it.each` 5 | args | expected 6 | ${["a", "b", false && "c"]} | ${"a b"} 7 | ${[true ? "a" : "b", "c", "b"]} | ${"a c b"} 8 | `(`returns $expected when got $args`, ({ args, expected }) => { 9 | const actual = classnames(...args); 10 | expect(actual).toBe(expected); 11 | }); 12 | }); 13 | -------------------------------------------------------------------------------- /packages/knife/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@kajitsu/knife", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "build/index.js", 6 | "module": "esm/index.js", 7 | "types": "esm/index.d.ts", 8 | "scripts": { 9 | "build:cjs": "tsc -d -p ./tsconfig.json", 10 | "build:esm": "tsc -d -p ./tsconfig.esm.json", 11 | "build": "npm run build:cjs && npm run build:esm", 12 | "test": "jest" 13 | }, 14 | "dependencies": {}, 15 | "author": "", 16 | "license": "MIT" 17 | } 18 | -------------------------------------------------------------------------------- /packages/ichigo/src/__tests__/pipe.spec.ts: -------------------------------------------------------------------------------- 1 | import assert from "assert"; 2 | import { pipe } from "../pipe"; 3 | 4 | describe("pipe", () => { 5 | it("1op", () => { 6 | const op1 = (val: number) => val + 1; 7 | const actual = pipe(1, op1); 8 | assert.strictEqual(actual, 2); 9 | }); 10 | 11 | it("2op", () => { 12 | const op1 = (val: number) => val + 1; 13 | const op2 = (val: number): string => String(val); 14 | const actual = pipe(1, op1, op2); 15 | assert.strictEqual(actual, "2"); 16 | }); 17 | }); 18 | -------------------------------------------------------------------------------- /packages/ichigo/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@kajitsu/ichigo", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "build/index.js", 6 | "module": "esm/index.js", 7 | "types": "esm/index.d.ts", 8 | "scripts": { 9 | "build:cjs": "tsc -d -p ./tsconfig.json", 10 | "build:esm": "tsc -d -p ./tsconfig.esm.json", 11 | "build": "npm run build:cjs && npm run build:esm", 12 | "test": "jest" 13 | }, 14 | "dependencies": { 15 | "@kajitsu/naruto": "1.0.0" 16 | }, 17 | "author": "", 18 | "license": "MIT" 19 | } 20 | -------------------------------------------------------------------------------- /packages/zakuro/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@kajitsu/zakuro", 3 | "version": "1.0.0", 4 | "main": "index.js", 5 | "license": "MIT", 6 | "scripts": { 7 | "build:cjs": "tsc -d -p ./tsconfig.json", 8 | "build:esm": "tsc -d -p ./tsconfig.esm.json", 9 | "build": "npm run build:cjs && npm run build:esm", 10 | "start": "npx ts-node ./src/explorer/index.tsx", 11 | "test": "echo TODO" 12 | }, 13 | "author": "", 14 | "dependencies": { 15 | "@kajitsu/lemon": "1.0.0", 16 | "@kajitsu/suica": "1.0.0" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /packages/lemon/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@kajitsu/lemon", 3 | "version": "1.0.0", 4 | "main": "build/index.js", 5 | "module": "esm/index.js", 6 | "types": "esm/index.d.ts", 7 | "scripts": { 8 | "build:cjs": "tsc -d -p ./tsconfig.json", 9 | "build:esm": "tsc -d -p ./tsconfig.esm.json", 10 | "prebuild": "rm -rf esm build *.tsbuildinfo", 11 | "build": "npm run build:esm && npm run build:cjs", 12 | "test": "jest" 13 | }, 14 | "dependencies": { 15 | "@kajitsu/ichigo": "1.0.0" 16 | }, 17 | "author": "", 18 | "license": "MIT" 19 | } 20 | -------------------------------------------------------------------------------- /packages/melon/src/assets/css/theme.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --header-bg-color: #b0dab0; 3 | --header-color: #111; 4 | --main-bg-color: #fff; 5 | --main-color: #111; 6 | } 7 | 8 | a:visited { 9 | color: darkviolet; 10 | } 11 | 12 | a { 13 | color: darkblue; 14 | } 15 | 16 | @media (prefers-color-scheme: dark) { 17 | :root { 18 | --header-bg-color: #353; 19 | --header-color: #e3ffe5; 20 | --main-bg-color: #222; 21 | --main-color: #fff; 22 | } 23 | 24 | a:visited { 25 | color: coral; 26 | } 27 | 28 | a { 29 | color: cyan; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /packages/suica/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@kajitsu/suica", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "build/index.js", 6 | "module": "esm/index.js", 7 | "types": "esm/index.d.ts", 8 | "scripts": { 9 | "build:cjs": "tsc -d -p ./tsconfig.json", 10 | "build:esm": "tsc -d -p ./tsconfig.esm.json", 11 | "build": "npm run build:cjs && npm run build:esm", 12 | "test": "jest" 13 | }, 14 | "dependencies": { 15 | "@kajitsu/ichigo": "1.0.0", 16 | "@kajitsu/naruto": "1.0.0" 17 | }, 18 | "author": "", 19 | "license": "MIT" 20 | } 21 | -------------------------------------------------------------------------------- /packages/melon/src/assets/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "me1on's blog", 3 | "name": "maxmellon's blog", 4 | "icons": [ 5 | { 6 | "src": "/icon-192x192.png", 7 | "type": "image/png", 8 | "sizes": "192x192", 9 | "purpose": "any maskable" 10 | }, 11 | { 12 | "src": "/icon-512x512.png", 13 | "type": "image/png", 14 | "sizes": "512x512" 15 | } 16 | ], 17 | "start_url": "/", 18 | "background_color": "#222", 19 | "display": "minimal-ui", 20 | "prefer_related_applications": true, 21 | "scope": "/", 22 | "theme_color": "#353" 23 | } 24 | -------------------------------------------------------------------------------- /packages/suica/src/middleware/body-parser/json.ts: -------------------------------------------------------------------------------- 1 | import { http } from "@kajitsu/ichigo"; 2 | import { RequestHandler } from "../.."; 3 | import { concatStream } from "./utils"; 4 | 5 | declare global { 6 | namespace Suica { 7 | export interface Context { 8 | body?: string; 9 | } 10 | } 11 | } 12 | 13 | export const json: RequestHandler = async (ctx, req, _res, next) => { 14 | try { 15 | if (http.contentType(req).subtype !== "json") return next(); 16 | const string = await concatStream(req); 17 | ctx.body = JSON.parse(string); 18 | } catch { 19 | await next(); 20 | } 21 | }; 22 | -------------------------------------------------------------------------------- /packages/suica/src/middleware/body-parser/utils.ts: -------------------------------------------------------------------------------- 1 | import { Readable } from "stream"; 2 | import { pipe } from "@kajitsu/ichigo"; 3 | 4 | export const concatStream = (stream: Readable): Promise => { 5 | return new Promise((resolve, reject) => { 6 | const data: Array = []; 7 | const append = (chunk: Buffer) => data.push(chunk); 8 | const handleError = (err: Error) => reject(err); 9 | const concatString = () => pipe(data.concat().toString(), resolve); 10 | stream.on("data", append); 11 | stream.on("error", handleError); 12 | stream.on("end", concatString); 13 | }); 14 | }; 15 | -------------------------------------------------------------------------------- /packages/lemon/src/__tests__/css.spec.ts: -------------------------------------------------------------------------------- 1 | import { createStyleContext, renderToString } from ".."; 2 | import { css, renderToStyleString } from "../css"; 3 | 4 | describe("css", () => { 5 | it("works", () => { 6 | const Component = css("div")` 7 | color: black; 8 | font-weight: 800; 9 | `; 10 | const ctx = createStyleContext().set(); 11 | const string = renderToString(Component({})); 12 | const act = renderToStyleString(ctx); 13 | const classNames = ctx.getClassNames(); 14 | expect(string).toEqual(`
`); 15 | expect(act).toEqual(`.${classNames[0]} { color: black; font-weight: 800; }`); 16 | }); 17 | }); 18 | -------------------------------------------------------------------------------- /packages/zakuro/src/explorer/import.tsx: -------------------------------------------------------------------------------- 1 | import { VNode } from "@kajitsu/lemon"; 2 | import fs from "fs"; 3 | import path from "path"; 4 | 5 | const atoms = fs 6 | .readdirSync(path.resolve(__dirname, "..", "atoms"), { 7 | withFileTypes: true, 8 | }) 9 | .filter((file) => file.isDirectory()); 10 | 11 | type Story = { 12 | [k: string]: () => VNode; 13 | }; 14 | 15 | export const atomsStories = atoms 16 | .map((f) => { 17 | const stories = require(`${__dirname}/../atoms/${f.name}/story.tsx`) as Story; 18 | return Object.entries(stories).map(([key, story]) => ({ 19 | key: `atoms/${f.name}/${key}`, 20 | story, 21 | })); 22 | }) 23 | .flat() as { key: string; story: () => VNode }[]; 24 | -------------------------------------------------------------------------------- /packages/melon/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@kajitsu/melon", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "prebuild": "rm -rf build tsconfig.tsbuildinfo && cp -r src build", 8 | "build": "tsc -d -p ./tsconfig.json", 9 | "test": "echo TODO", 10 | "run": "npx nodemon -e js,ts,tsx,css --watch ./src --exec \"npx ts-node ./src/index.tsx\"", 11 | "production": "NODE_ENV=production node ./build/index.js", 12 | "nginx": "envsubst '\\$GHQ_ROOT' < ./for-local/nginx.templ.conf > ./for-local/nginx.conf && nginx -c $(pwd)/for-local/nginx.conf -g 'daemon off;'" 13 | }, 14 | "author": "", 15 | "license": "MIT", 16 | "dependencies": { 17 | "@kajitsu/ichigo": "1.0.0", 18 | "@kajitsu/suica": "1.0.0" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /packages/melon/src/assets/sw.js: -------------------------------------------------------------------------------- 1 | const CACHE_NAME = "@kajitsu/melon@1.1.1"; 2 | 3 | const urlsToCache = ["/", "/blog/20201221", "/main.css", "/markdown.css"]; 4 | 5 | self.addEventListener("install", (event) => { 6 | event.waitUntil( 7 | caches.open(CACHE_NAME).then((cache) => { 8 | cache.addAll(urlsToCache); 9 | }), 10 | ); 11 | }); 12 | 13 | self.addEventListener("fetch", (event) => { 14 | if (!(event.request.url.indexOf("http") === 0)) { 15 | return event.respondWith(fetch(event.request)); 16 | } 17 | event.respondWith( 18 | fetch(event.request) 19 | .then((res) => 20 | caches.open(CACHE_NAME).then((cache) => { 21 | cache.put(event.request.url, res.clone()); 22 | return res; 23 | }), 24 | ) 25 | .catch(() => caches.match(event.request)), 26 | ); 27 | }); 28 | -------------------------------------------------------------------------------- /packages/melon/src/components/organisms/nav/index.tsx: -------------------------------------------------------------------------------- 1 | import { h, FC, styled } from "@kajitsu/lemon"; 2 | 3 | export const Nav: FC = () => ( 4 | 5 | maxmellon's blog 6 | 7 | 8 | Blog 9 | 10 | 11 | 12 | ); 13 | 14 | const NavTitle = styled("h1")` 15 | font-size: 1.5rem; 16 | line-height: 1.7; 17 | display: inline-flex; 18 | `; 19 | 20 | const HtmlNav = styled("nav")` 21 | width: min(1000px, 95%); 22 | margin: 0 auto; 23 | height: 100%; 24 | `; 25 | const NavList = styled("ol")` 26 | display: inline-flex; 27 | vertical-align: top; 28 | height: 100%; 29 | line-height: 1.8; 30 | `; 31 | 32 | const NavListItem = styled("li")` 33 | padding-left: 3rem; 34 | line-height: 2.6; 35 | `; 36 | -------------------------------------------------------------------------------- /packages/knife/src/__tests__/tokenizer.spec.ts: -------------------------------------------------------------------------------- 1 | import assert from 'assert' 2 | import { Tokenizer, Token } from '../tokenizer' 3 | 4 | describe("tokenizer", () => { 5 | it.skip("works", () => { 6 | const text = `# hoge` 7 | const tokenizer = new Tokenizer(text) 8 | const iterator = tokenizer.tokenize() 9 | let result: Array = [] 10 | let itr: IteratorResult = iterator.next() 11 | while (!itr.done) { 12 | console.log(itr.value) 13 | result.push(itr.value) 14 | itr = iterator.next() 15 | } 16 | assert.deepStrictEqual(result, [ 17 | { 18 | type: 'SHARP', 19 | literal: '#', 20 | }, 21 | { 22 | type: 'PLAIN', 23 | literal: 'hoge', 24 | }, 25 | { 26 | type: 'EOS', 27 | literal: 'EOS' 28 | } 29 | ]) 30 | }) 31 | }) 32 | -------------------------------------------------------------------------------- /packages/naruto/src/res.ts: -------------------------------------------------------------------------------- 1 | import { ServerResponse } from "http"; 2 | import { Transform } from "stream"; 3 | 4 | export const createMockServerResponse = ( 5 | finish?: () => void 6 | ): ServerResponse => { 7 | const MockServerResponse = class extends Transform { 8 | public statusCode: number; 9 | public finished: boolean; 10 | public _header: Record; 11 | public _headers: Record; 12 | public _responseData: Array; 13 | 14 | constructor() { 15 | super(); 16 | this.statusCode = 200; 17 | this._header = this._headers = {}; 18 | if (typeof finish === "function") this.on("finish", finish); 19 | this._responseData = []; 20 | 21 | this.finished = false; 22 | } 23 | 24 | _transform(_data: string) {} 25 | }; 26 | // @ts-ignore 27 | return new MockServerResponse() as ServerResponse; 28 | }; 29 | -------------------------------------------------------------------------------- /packages/ichigo/src/pipe.ts: -------------------------------------------------------------------------------- 1 | export function pipe(value: A, op1: (input: A) => B): B; 2 | export function pipe( 3 | value: A, 4 | op1: (input: A) => B, 5 | op2: (input: B) => C 6 | ): C; 7 | 8 | export function pipe( 9 | value: A, 10 | op1: (input: A) => B, 11 | op2: (input: B) => C, 12 | op3: (input: C) => D 13 | ): D; 14 | 15 | export function pipe( 16 | value: A, 17 | op1: (input: A) => B, 18 | op2: (input: B) => C, 19 | op3: (input: C) => D, 20 | op4: (input: D) => E 21 | ): E; 22 | 23 | export function pipe( 24 | value: A, 25 | op1: (input: A) => B, 26 | op2: (input: B) => C, 27 | op3: (input: C) => D, 28 | op4: (input: D) => E, 29 | op5: (input: E) => F 30 | ): F; 31 | 32 | export function pipe( 33 | value: any, 34 | ...operations: Array<(value: any) => any> 35 | ): any { 36 | return operations.reduce((acc, cur) => { 37 | return cur(acc); 38 | }, value); 39 | } 40 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "kajitsu", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "build": "yarn workspaces run build", 8 | "test": "yarn workspaces run test" 9 | }, 10 | "repository": { 11 | "type": "git", 12 | "url": "git+ssh://git@github.com/MaxMEllon/kajitsu.git" 13 | }, 14 | "author": "", 15 | "license": "ISC", 16 | "bugs": { 17 | "url": "https://github.com/MaxMEllon/kajitsu/issues" 18 | }, 19 | "homepage": "https://github.com/MaxMEllon/kajitsu#readme", 20 | "private": true, 21 | "workspaces": [ 22 | "packages/naruto", 23 | "packages/ichigo", 24 | "packages/knife", 25 | "packages/lemon", 26 | "packages/suica", 27 | "packages/zakuro", 28 | "packages/melon" 29 | ], 30 | "devDependencies": { 31 | "@types/jest": "26.0.24", 32 | "@types/node": "16.11.35", 33 | "jest": "26.6.3", 34 | "ts-jest": "26.5.6", 35 | "typescript": "4.6.3" 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /docker/app/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:18-slim as node 2 | 3 | RUN apt-get update \ 4 | && apt-get install -y locales tzdata busybox \ 5 | && apt-get clean && rm -rf /var/lib/apt/lists/* \ 6 | && echo "# Install Busybox" \ 7 | && mkdir /usr/local/busybox \ 8 | && busybox --install /usr/local/busybox \ 9 | && echo "# Generate locale" \ 10 | && echo "en_US.UTF-8 UTF-8" >> /etc/locale.gen \ 11 | && echo "ja_JP.UTF-8 UTF-8" >> /etc/locale.gen \ 12 | && locale-gen 13 | ENV PATH "$PATH:/usr/local/busybox" 14 | ENV TZ "Asia/Tokyo" 15 | ENV LANG "ja_JP.UTF-8" 16 | ENV LC_ALL "ja_JP.UTF-8" 17 | 18 | 19 | FROM node AS build 20 | WORKDIR /sources 21 | COPY yarn.lock package.json tsconfig.json tsconfig.node.json ./ 22 | COPY . ./ 23 | RUN yarn && yarn build 24 | 25 | FROM node AS app 26 | 27 | WORKDIR /app 28 | COPY --from=build /sources/node_modules/ /app/node_modules 29 | COPY --from=build /sources/packages/ /app/packages 30 | 31 | WORKDIR /app/packages/melon 32 | CMD yarn run -s production 33 | -------------------------------------------------------------------------------- /packages/lemon/src/__tests__/index.spec.ts: -------------------------------------------------------------------------------- 1 | import assert from "assert"; 2 | import { h } from ".."; 3 | 4 | describe("createElement", () => { 5 | it("expected to get type as string VNode when give 1st args string", () => { 6 | const actual = h("p", { id: "hoge" }); 7 | assert.deepStrictEqual(actual, { 8 | props: { 9 | children: [], 10 | id: "hoge", 11 | }, 12 | type: "p", 13 | }); 14 | }); 15 | 16 | it("expected to get nested VNode when nested call", () => { 17 | const actual = h("div", {}, h("div", {}), h("div", {})); 18 | assert.deepStrictEqual(actual, { 19 | props: { 20 | children: [ 21 | { 22 | props: { 23 | children: [], 24 | }, 25 | type: "div", 26 | }, 27 | { 28 | props: { 29 | children: [], 30 | }, 31 | type: "div", 32 | }, 33 | ], 34 | }, 35 | type: "div", 36 | }); 37 | }); 38 | }); 39 | -------------------------------------------------------------------------------- /packages/naruto/src/req.ts: -------------------------------------------------------------------------------- 1 | import { IncomingMessage } from "http"; 2 | import { Transform } from "stream"; 3 | 4 | export const createMockIncomingMessage = (opt?: { 5 | method?: string; 6 | url?: string; 7 | headers?: Record; 8 | }): IncomingMessage => { 9 | const MockIncomingMessage = class extends Transform { 10 | public method: string; 11 | public url: string; 12 | public headers: Record; 13 | public rawHeaders: Array; 14 | 15 | constructor() { 16 | super(); 17 | this.method = opt?.method || "GET"; 18 | this.url = opt?.url || ""; 19 | this.headers = opt?.headers || {}; 20 | // TODO: opt.headers convert rawHeaders object 21 | this.rawHeaders = []; 22 | if ( 23 | this.method === "GET" || 24 | this.method === "HEAD" || 25 | this.method === "DELETE" 26 | ) 27 | this.end(); 28 | } 29 | }; 30 | // @ts-ignore 31 | return new MockIncomingMessage() as IncomingMessage; 32 | }; 33 | -------------------------------------------------------------------------------- /packages/melon/src/assets/images/loading.svg: -------------------------------------------------------------------------------- 1 | 3 | 6 | 8 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: [ push, pull_request ] 4 | 5 | jobs: 6 | build: 7 | runs-on: ubuntu-latest 8 | 9 | strategy: 10 | matrix: 11 | node-version: [ 14, 16, 18 ] 12 | 13 | steps: 14 | - uses: actions/checkout@v2 15 | 16 | - name: Use Node.js ${{ matrix.node-version }} 17 | uses: actions/setup-node@v2 18 | with: 19 | node-version: ${{ matrix.node-version }} 20 | 21 | - name: Cache node modules 22 | uses: actions/cache@v3 23 | with: 24 | # npm cache files are stored in `~/.npm` on Linux/macOS 25 | path: '**/node_modules' 26 | key: ${{ runner.os }}-modules--${{ hashFiles('**/yarn.lock') }}--${{ hashFiles('**/package.json') }} 27 | 28 | - run: npm config set scripts-prepend-node-path true 29 | 30 | - run: npm install -g yarn 31 | 32 | - run: yarn install 33 | 34 | - run: yarn build 35 | env: 36 | NODE_ENV: production 37 | 38 | - run: yarn test 39 | env: 40 | NODE_ENV: test 41 | -------------------------------------------------------------------------------- /packages/melon/src/components/templates/html.tsx: -------------------------------------------------------------------------------- 1 | import { h, FC } from "@kajitsu/lemon"; 2 | 3 | type Props = { 4 | style?: string; 5 | title?: string; 6 | nonce?: string; 7 | extendsHead?: h.JSX.Element; 8 | }; 9 | 10 | export const Html: FC = ({ extendsHead, nonce, title, style, children }) => ( 11 | 12 | 13 | 14 | 15 | 16 | 17 | {title && `${title} | `}maxmellon's blog 18 | 19 | 20 | 21 | {extendsHead} 22 | {nonce ? : } 23 | 24 | {children} 25 | {process.env.NODE_ENV === "production" && `); 37 | const actual2 = renderToString(`); 39 | }); 40 | 41 | it("Fragment works", () => { 42 | const X: FC = () =>
x
43 | const actual = renderToString(<>

a

b

); 44 | expect(actual).toEqual('

a

x

b

'); 45 | }) 46 | }); 47 | -------------------------------------------------------------------------------- /packages/melon/src/pages/blog/index.tsx: -------------------------------------------------------------------------------- 1 | import { h, FC, styled } from "@kajitsu/lemon"; 2 | import { PageTemplate } from "../../components/templates/page"; 3 | import { Nav } from "../../components/organisms/nav"; 4 | import { articles } from "./articles"; 5 | 6 | export const Blog: FC = () => { 7 | const header =