phos 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (116) hide show
  1. package/.eslintignore +3 -0
  2. package/AGENTS.md +172 -0
  3. package/CHANGELOG.md +184 -0
  4. package/LICENSE +21 -0
  5. package/README.md +279 -0
  6. package/bun.lock +125 -0
  7. package/dist/cli.d.ts +3 -0
  8. package/dist/cli.d.ts.map +1 -0
  9. package/dist/cli.js +255 -0
  10. package/dist/cli.js.map +1 -0
  11. package/dist/generators/backends/elysia.d.ts +3 -0
  12. package/dist/generators/backends/elysia.d.ts.map +1 -0
  13. package/dist/generators/backends/elysia.js +135 -0
  14. package/dist/generators/backends/elysia.js.map +1 -0
  15. package/dist/generators/backends/fastapi.d.ts +3 -0
  16. package/dist/generators/backends/fastapi.d.ts.map +1 -0
  17. package/dist/generators/backends/fastapi.js +158 -0
  18. package/dist/generators/backends/fastapi.js.map +1 -0
  19. package/dist/generators/frontends/astro.d.ts +3 -0
  20. package/dist/generators/frontends/astro.d.ts.map +1 -0
  21. package/dist/generators/frontends/astro.js +303 -0
  22. package/dist/generators/frontends/astro.js.map +1 -0
  23. package/dist/generators/frontends/nextjs.d.ts +3 -0
  24. package/dist/generators/frontends/nextjs.d.ts.map +1 -0
  25. package/dist/generators/frontends/nextjs.js +274 -0
  26. package/dist/generators/frontends/nextjs.js.map +1 -0
  27. package/dist/generators/frontends/svelte.d.ts +3 -0
  28. package/dist/generators/frontends/svelte.d.ts.map +1 -0
  29. package/dist/generators/frontends/svelte.js +324 -0
  30. package/dist/generators/frontends/svelte.js.map +1 -0
  31. package/dist/generators/monorepo.d.ts +3 -0
  32. package/dist/generators/monorepo.d.ts.map +1 -0
  33. package/dist/generators/monorepo.js +320 -0
  34. package/dist/generators/monorepo.js.map +1 -0
  35. package/dist/generators/single.d.ts +3 -0
  36. package/dist/generators/single.d.ts.map +1 -0
  37. package/dist/generators/single.js +229 -0
  38. package/dist/generators/single.js.map +1 -0
  39. package/dist/utils/helpers.d.ts +38 -0
  40. package/dist/utils/helpers.d.ts.map +1 -0
  41. package/dist/utils/helpers.js +109 -0
  42. package/dist/utils/helpers.js.map +1 -0
  43. package/package.json +46 -0
  44. package/src/cli.ts +500 -0
  45. package/src/generators/backends/elysia.ts +45 -0
  46. package/src/generators/backends/fastapi.ts +71 -0
  47. package/src/generators/frontends/astro.ts +37 -0
  48. package/src/generators/frontends/nextjs.ts +37 -0
  49. package/src/generators/frontends/svelte.ts +38 -0
  50. package/src/generators/monorepo.ts +529 -0
  51. package/src/generators/single.ts +465 -0
  52. package/src/templates/backend/elysia/README.md +15 -0
  53. package/src/templates/backend/elysia/package.json +26 -0
  54. package/src/templates/backend/elysia/src/api/user_api.ts +0 -0
  55. package/src/templates/backend/elysia/src/db.ts +17 -0
  56. package/src/templates/backend/elysia/src/index.ts +68 -0
  57. package/src/templates/backend/elysia/src/service/user_service.ts +0 -0
  58. package/src/templates/backend/elysia/src/sql/user_sql.ts +0 -0
  59. package/src/templates/backend/elysia/src/types/user_type.ts +0 -0
  60. package/src/templates/backend/elysia/tsconfig.json +103 -0
  61. package/src/templates/backend/fastapi/.pylintrc +2 -0
  62. package/src/templates/backend/fastapi/README.md +33 -0
  63. package/src/templates/backend/fastapi/pyproject.toml +9 -0
  64. package/src/templates/backend/fastapi/pyproject_prettier.toml +20 -0
  65. package/src/templates/backend/fastapi/requirements.txt +15 -0
  66. package/src/templates/backend/fastapi/setup.sh +23 -0
  67. package/src/templates/backend/fastapi/src/api/user_api.py +0 -0
  68. package/src/templates/backend/fastapi/src/db.py +31 -0
  69. package/src/templates/backend/fastapi/src/main.py +53 -0
  70. package/src/templates/backend/fastapi/src/service/user_service.py +0 -0
  71. package/src/templates/backend/fastapi/src/sql/user_sql.py +0 -0
  72. package/src/templates/backend/fastapi/src/types/user_type.py +0 -0
  73. package/src/templates/frontend/astro/README.md +46 -0
  74. package/src/templates/frontend/astro/astro.config.mjs +5 -0
  75. package/src/templates/frontend/astro/package.json +28 -0
  76. package/src/templates/frontend/astro/public/favicon.ico +0 -0
  77. package/src/templates/frontend/astro/public/favicon.svg +9 -0
  78. package/src/templates/frontend/astro/src/assets/astro.svg +1 -0
  79. package/src/templates/frontend/astro/src/assets/background.svg +1 -0
  80. package/src/templates/frontend/astro/src/components/Welcome.astro +5 -0
  81. package/src/templates/frontend/astro/src/layouts/Layout.astro +23 -0
  82. package/src/templates/frontend/astro/src/pages/index.astro +8 -0
  83. package/src/templates/frontend/astro/tsconfig.json +5 -0
  84. package/src/templates/frontend/nextjs/README.md +36 -0
  85. package/src/templates/frontend/nextjs/app/favicon.ico +0 -0
  86. package/src/templates/frontend/nextjs/app/globals.css +26 -0
  87. package/src/templates/frontend/nextjs/app/layout.tsx +34 -0
  88. package/src/templates/frontend/nextjs/app/page.tsx +16 -0
  89. package/src/templates/frontend/nextjs/eslint.config.mjs +18 -0
  90. package/src/templates/frontend/nextjs/next.config.ts +7 -0
  91. package/src/templates/frontend/nextjs/package.json +28 -0
  92. package/src/templates/frontend/nextjs/postcss.config.mjs +7 -0
  93. package/src/templates/frontend/nextjs/public/file.svg +1 -0
  94. package/src/templates/frontend/nextjs/public/globe.svg +1 -0
  95. package/src/templates/frontend/nextjs/public/next.svg +1 -0
  96. package/src/templates/frontend/nextjs/public/vercel.svg +1 -0
  97. package/src/templates/frontend/nextjs/public/window.svg +1 -0
  98. package/src/templates/frontend/nextjs/tsconfig.json +34 -0
  99. package/src/templates/frontend/svelte/.prettierignore +9 -0
  100. package/src/templates/frontend/svelte/.prettierrc +19 -0
  101. package/src/templates/frontend/svelte/README.md +42 -0
  102. package/src/templates/frontend/svelte/eslint.config.js +39 -0
  103. package/src/templates/frontend/svelte/package.json +39 -0
  104. package/src/templates/frontend/svelte/src/app.d.ts +13 -0
  105. package/src/templates/frontend/svelte/src/app.html +11 -0
  106. package/src/templates/frontend/svelte/src/lib/assets/favicon.svg +1 -0
  107. package/src/templates/frontend/svelte/src/lib/index.ts +1 -0
  108. package/src/templates/frontend/svelte/src/routes/+layout.svelte +9 -0
  109. package/src/templates/frontend/svelte/src/routes/+page.svelte +2 -0
  110. package/src/templates/frontend/svelte/src/routes/layout.css +2 -0
  111. package/src/templates/frontend/svelte/static/robots.txt +3 -0
  112. package/src/templates/frontend/svelte/svelte.config.js +13 -0
  113. package/src/templates/frontend/svelte/tsconfig.json +20 -0
  114. package/src/templates/frontend/svelte/vite.config.ts +5 -0
  115. package/src/utils/helpers.ts +198 -0
  116. package/tsconfig.json +24 -0
@@ -0,0 +1,28 @@
1
+ {
2
+ "name": "{{#if (eq projectType 'monorepo')}}frontend{{else}}{{projectName}}{{/if}}",
3
+ "version": "0.1.0",
4
+ "private": true,
5
+ "scripts": {
6
+ "dev": "next dev",
7
+ "build": "next build",
8
+ "start": "next start"{{#if frontend.eslint}},
9
+ "lint": "eslint"{{/if}}{{#if frontend.prettier}},
10
+ "format": "prettier --write ."{{/if}}
11
+ },
12
+ "dependencies": {
13
+ "next": "16.1.6",
14
+ "react": "19.2.3",
15
+ "react-dom": "19.2.3"
16
+ },
17
+ "devDependencies": {
18
+ "@tailwindcss/postcss": "^4",
19
+ "@types/node": "^20",
20
+ "@types/react": "^19",
21
+ "@types/react-dom": "^19"{{#if frontend.eslint}},
22
+ "eslint": "^9",
23
+ "eslint-config-next": "16.1.6"{{/if}}{{#if (eq frontend.cssFramework 'tailwind')}},
24
+ "tailwindcss": "^4"{{/if}},
25
+ "typescript": "^5"{{#if frontend.prettier}},
26
+ "prettier": "^3"{{/if}}
27
+ }
28
+ }
@@ -0,0 +1,7 @@
1
+ const config = {
2
+ plugins: {
3
+ "@tailwindcss/postcss": {},
4
+ },
5
+ };
6
+
7
+ export default config;
@@ -0,0 +1 @@
1
+ <svg fill="none" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><path d="M14.5 13.5V5.41a1 1 0 0 0-.3-.7L9.8.29A1 1 0 0 0 9.08 0H1.5v13.5A2.5 2.5 0 0 0 4 16h8a2.5 2.5 0 0 0 2.5-2.5m-1.5 0v-7H8v-5H3v12a1 1 0 0 0 1 1h8a1 1 0 0 0 1-1M9.5 5V2.12L12.38 5zM5.13 5h-.62v1.25h2.12V5zm-.62 3h7.12v1.25H4.5zm.62 3h-.62v1.25h7.12V11z" clip-rule="evenodd" fill="#666" fill-rule="evenodd"/></svg>
@@ -0,0 +1 @@
1
+ <svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><g clip-path="url(#a)"><path fill-rule="evenodd" clip-rule="evenodd" d="M10.27 14.1a6.5 6.5 0 0 0 3.67-3.45q-1.24.21-2.7.34-.31 1.83-.97 3.1M8 16A8 8 0 1 0 8 0a8 8 0 0 0 0 16m.48-1.52a7 7 0 0 1-.96 0H7.5a4 4 0 0 1-.84-1.32q-.38-.89-.63-2.08a40 40 0 0 0 3.92 0q-.25 1.2-.63 2.08a4 4 0 0 1-.84 1.31zm2.94-4.76q1.66-.15 2.95-.43a7 7 0 0 0 0-2.58q-1.3-.27-2.95-.43a18 18 0 0 1 0 3.44m-1.27-3.54a17 17 0 0 1 0 3.64 39 39 0 0 1-4.3 0 17 17 0 0 1 0-3.64 39 39 0 0 1 4.3 0m1.1-1.17q1.45.13 2.69.34a6.5 6.5 0 0 0-3.67-3.44q.65 1.26.98 3.1M8.48 1.5l.01.02q.41.37.84 1.31.38.89.63 2.08a40 40 0 0 0-3.92 0q.25-1.2.63-2.08a4 4 0 0 1 .85-1.32 7 7 0 0 1 .96 0m-2.75.4a6.5 6.5 0 0 0-3.67 3.44 29 29 0 0 1 2.7-.34q.31-1.83.97-3.1M4.58 6.28q-1.66.16-2.95.43a7 7 0 0 0 0 2.58q1.3.27 2.95.43a18 18 0 0 1 0-3.44m.17 4.71q-1.45-.12-2.69-.34a6.5 6.5 0 0 0 3.67 3.44q-.65-1.27-.98-3.1" fill="#666"/></g><defs><clipPath id="a"><path fill="#fff" d="M0 0h16v16H0z"/></clipPath></defs></svg>
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 394 80"><path fill="#000" d="M262 0h68.5v12.7h-27.2v66.6h-13.6V12.7H262V0ZM149 0v12.7H94v20.4h44.3v12.6H94v21h55v12.6H80.5V0h68.7zm34.3 0h-17.8l63.8 79.4h17.9l-32-39.7 32-39.6h-17.9l-23 28.6-23-28.6zm18.3 56.7-9-11-27.1 33.7h17.8l18.3-22.7z"/><path fill="#000" d="M81 79.3 17 0H0v79.3h13.6V17l50.2 62.3H81Zm252.6-.4c-1 0-1.8-.4-2.5-1s-1.1-1.6-1.1-2.6.3-1.8 1-2.5 1.6-1 2.6-1 1.8.3 2.5 1a3.4 3.4 0 0 1 .6 4.3 3.7 3.7 0 0 1-3 1.8zm23.2-33.5h6v23.3c0 2.1-.4 4-1.3 5.5a9.1 9.1 0 0 1-3.8 3.5c-1.6.8-3.5 1.3-5.7 1.3-2 0-3.7-.4-5.3-1s-2.8-1.8-3.7-3.2c-.9-1.3-1.4-3-1.4-5h6c.1.8.3 1.6.7 2.2s1 1.2 1.6 1.5c.7.4 1.5.5 2.4.5 1 0 1.8-.2 2.4-.6a4 4 0 0 0 1.6-1.8c.3-.8.5-1.8.5-3V45.5zm30.9 9.1a4.4 4.4 0 0 0-2-3.3 7.5 7.5 0 0 0-4.3-1.1c-1.3 0-2.4.2-3.3.5-.9.4-1.6 1-2 1.6a3.5 3.5 0 0 0-.3 4c.3.5.7.9 1.3 1.2l1.8 1 2 .5 3.2.8c1.3.3 2.5.7 3.7 1.2a13 13 0 0 1 3.2 1.8 8.1 8.1 0 0 1 3 6.5c0 2-.5 3.7-1.5 5.1a10 10 0 0 1-4.4 3.5c-1.8.8-4.1 1.2-6.8 1.2-2.6 0-4.9-.4-6.8-1.2-2-.8-3.4-2-4.5-3.5a10 10 0 0 1-1.7-5.6h6a5 5 0 0 0 3.5 4.6c1 .4 2.2.6 3.4.6 1.3 0 2.5-.2 3.5-.6 1-.4 1.8-1 2.4-1.7a4 4 0 0 0 .8-2.4c0-.9-.2-1.6-.7-2.2a11 11 0 0 0-2.1-1.4l-3.2-1-3.8-1c-2.8-.7-5-1.7-6.6-3.2a7.2 7.2 0 0 1-2.4-5.7 8 8 0 0 1 1.7-5 10 10 0 0 1 4.3-3.5c2-.8 4-1.2 6.4-1.2 2.3 0 4.4.4 6.2 1.2 1.8.8 3.2 2 4.3 3.4 1 1.4 1.5 3 1.5 5h-5.8z"/></svg>
@@ -0,0 +1 @@
1
+ <svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1155 1000"><path d="m577.3 0 577.4 1000H0z" fill="#fff"/></svg>
@@ -0,0 +1 @@
1
+ <svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><path fill-rule="evenodd" clip-rule="evenodd" d="M1.5 2.5h13v10a1 1 0 0 1-1 1h-11a1 1 0 0 1-1-1zM0 1h16v11.5a2.5 2.5 0 0 1-2.5 2.5h-11A2.5 2.5 0 0 1 0 12.5zm3.75 4.5a.75.75 0 1 0 0-1.5.75.75 0 0 0 0 1.5M7 4.75a.75.75 0 1 1-1.5 0 .75.75 0 0 1 1.5 0m1.75.75a.75.75 0 1 0 0-1.5.75.75 0 0 0 0 1.5" fill="#666"/></svg>
@@ -0,0 +1,34 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2017",
4
+ "lib": ["dom", "dom.iterable", "esnext"],
5
+ "allowJs": true,
6
+ "skipLibCheck": true,
7
+ "strict": true,
8
+ "noEmit": true,
9
+ "esModuleInterop": true,
10
+ "module": "esnext",
11
+ "moduleResolution": "bundler",
12
+ "resolveJsonModule": true,
13
+ "isolatedModules": true,
14
+ "jsx": "react-jsx",
15
+ "incremental": true,
16
+ "plugins": [
17
+ {
18
+ "name": "next"
19
+ }
20
+ ],
21
+ "paths": {
22
+ "@/*": ["./*"]
23
+ }
24
+ },
25
+ "include": [
26
+ "next-env.d.ts",
27
+ "**/*.ts",
28
+ "**/*.tsx",
29
+ ".next/types/**/*.ts",
30
+ ".next/dev/types/**/*.ts",
31
+ "**/*.mts"
32
+ ],
33
+ "exclude": ["node_modules"]
34
+ }
@@ -0,0 +1,9 @@
1
+ # Package Managers
2
+ package-lock.json
3
+ pnpm-lock.yaml
4
+ yarn.lock
5
+ bun.lock
6
+ bun.lockb
7
+
8
+ # Miscellaneous
9
+ /static/
@@ -0,0 +1,19 @@
1
+ {
2
+ "useTabs": true,
3
+ "singleQuote": true,
4
+ "trailingComma": "none",
5
+ "printWidth": 100,
6
+ "plugins": [
7
+ "prettier-plugin-svelte",
8
+ "prettier-plugin-tailwindcss"
9
+ ],
10
+ "overrides": [
11
+ {
12
+ "files": "*.svelte",
13
+ "options": {
14
+ "parser": "svelte"
15
+ }
16
+ }
17
+ ],
18
+ "tailwindStylesheet": "./src/routes/layout.css"
19
+ }
@@ -0,0 +1,42 @@
1
+ # sv
2
+
3
+ Everything you need to build a Svelte project, powered by [`sv`](https://github.com/sveltejs/cli).
4
+
5
+ ## Creating a project
6
+
7
+ If you're seeing this, you've probably already done this step. Congrats!
8
+
9
+ ```sh
10
+ # create a new project
11
+ npx sv create my-app
12
+ ```
13
+
14
+ To recreate this project with the same configuration:
15
+
16
+ ```sh
17
+ # recreate this project
18
+ npx sv create --template minimal --types ts --add prettier eslint tailwindcss="plugins:typography" --no-install svelte
19
+ ```
20
+
21
+ ## Developing
22
+
23
+ Once you've created a project and installed dependencies with `npm install` (or `pnpm install` or `yarn`), start a development server:
24
+
25
+ ```sh
26
+ npm run dev
27
+
28
+ # or start the server and open the app in a new browser tab
29
+ npm run dev -- --open
30
+ ```
31
+
32
+ ## Building
33
+
34
+ To create a production version of your app:
35
+
36
+ ```sh
37
+ npm run build
38
+ ```
39
+
40
+ You can preview the production build with `npm run preview`.
41
+
42
+ > To deploy your app, you may need to install an [adapter](https://svelte.dev/docs/kit/adapters) for your target environment.
@@ -0,0 +1,39 @@
1
+ import prettier from 'eslint-config-prettier';
2
+ import path from 'node:path';
3
+ import { includeIgnoreFile } from '@eslint/compat';
4
+ import js from '@eslint/js';
5
+ import svelte from 'eslint-plugin-svelte';
6
+ import { defineConfig } from 'eslint/config';
7
+ import globals from 'globals';
8
+ import ts from 'typescript-eslint';
9
+ import svelteConfig from './svelte.config.js';
10
+
11
+ const gitignorePath = path.resolve(import.meta.dirname, '.gitignore');
12
+
13
+ export default defineConfig(
14
+ includeIgnoreFile(gitignorePath),
15
+ js.configs.recommended,
16
+ ...ts.configs.recommended,
17
+ ...svelte.configs.recommended,
18
+ prettier,
19
+ ...svelte.configs.prettier,
20
+ {
21
+ languageOptions: { globals: { ...globals.browser, ...globals.node } },
22
+ rules: {
23
+ // typescript-eslint strongly recommend that you do not use the no-undef lint rule on TypeScript projects.
24
+ // see: https://typescript-eslint.io/troubleshooting/faqs/eslint/#i-get-errors-from-the-no-undef-rule-about-global-variables-not-being-defined-even-though-there-are-no-typescript-errors
25
+ "no-undef": 'off'
26
+ }
27
+ },
28
+ {
29
+ files: ['**/*.svelte', '**/*.svelte.ts', '**/*.svelte.js'],
30
+ languageOptions: {
31
+ parserOptions: {
32
+ projectService: true,
33
+ extraFileExtensions: ['.svelte'],
34
+ parser: ts.parser,
35
+ svelteConfig
36
+ }
37
+ }
38
+ }
39
+ );
@@ -0,0 +1,39 @@
1
+ {
2
+ "name": "{{#if (eq projectType 'monorepo')}}frontend{{else}}{{projectName}}{{/if}}",
3
+ "private": true,
4
+ "version": "0.1.0",
5
+ "type": "module",
6
+ "scripts": {
7
+ "dev": "vite dev",
8
+ "build": "vite build",
9
+ "preview": "vite preview"{{#if frontend.eslint}},
10
+ "lint": "prettier --check . && eslint ."{{/if}}{{#if frontend.prettier}},
11
+ "format": "prettier --write ."{{/if}}
12
+ },
13
+ "devDependencies": {
14
+ "eslint": "^9.39.2",
15
+ "@eslint/compat": "^2.0.2",
16
+ "eslint-config-prettier": "^10.1.8",
17
+ "@eslint/js": "^9.39.2",
18
+ "eslint-plugin-svelte": "^3.14.0",
19
+ "globals": "^17.3.0",
20
+ "prettier": "^3.8.1",
21
+ "prettier-plugin-svelte": "^3.4.1"{{#if (eq frontend.cssFramework 'tailwind')}},
22
+ "prettier-plugin-tailwindcss": "^0.7.2"{{/if}},
23
+ "svelte": "^5.49.2",
24
+ "svelte-check": "^4.3.6",
25
+ "@sveltejs/adapter-auto": "^7.0.0",
26
+ "@sveltejs/kit": "^2.50.2",
27
+ "@sveltejs/vite-plugin-svelte": "^6.2.4"{{#if (eq frontend.cssFramework 'tailwind')}},
28
+ "tailwindcss": "^4.1.18",
29
+ "@tailwindcss/typography": "^0.5.19",
30
+ "@tailwindcss/vite": "^4.1.18"{{/if}},
31
+ "typescript": "^5.9.3",
32
+ "typescript-eslint": "^8.54.0",
33
+ "@types/node": "^20"{{#if (eq frontend.testing 'vitest')}},
34
+ "vitest": "^2.0.0",
35
+ "@vitest/ui": "^2.0.0"{{/if}}{{#if (or (eq frontend.testing 'playwright') (eq frontend.testing 'both'))}},
36
+ "@playwright/test": "^1.40.0"{{/if}},
37
+ "vite": "^7.3.1"
38
+ }
39
+ }
@@ -0,0 +1,13 @@
1
+ // See https://svelte.dev/docs/kit/types#app.d.ts
2
+ // for information about these interfaces
3
+ declare global {
4
+ namespace App {
5
+ // interface Error {}
6
+ // interface Locals {}
7
+ // interface PageData {}
8
+ // interface PageState {}
9
+ // interface Platform {}
10
+ }
11
+ }
12
+
13
+ export {};
@@ -0,0 +1,11 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
6
+ %sveltekit.head%
7
+ </head>
8
+ <body data-sveltekit-preload-data="hover">
9
+ <div style="display: contents">%sveltekit.body%</div>
10
+ </body>
11
+ </html>
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="107" height="128" viewBox="0 0 107 128"><title>svelte-logo</title><path d="M94.157 22.819c-10.4-14.885-30.94-19.297-45.792-9.835L22.282 29.608A29.92 29.92 0 0 0 8.764 49.65a31.5 31.5 0 0 0 3.108 20.231 30 30 0 0 0-4.477 11.183 31.9 31.9 0 0 0 5.448 24.116c10.402 14.887 30.942 19.297 45.791 9.835l26.083-16.624A29.92 29.92 0 0 0 98.235 78.35a31.53 31.53 0 0 0-3.105-20.232 30 30 0 0 0 4.474-11.182 31.88 31.88 0 0 0-5.447-24.116" style="fill:#ff3e00"/><path d="M45.817 106.582a20.72 20.72 0 0 1-22.237-8.243 19.17 19.17 0 0 1-3.277-14.503 18 18 0 0 1 .624-2.435l.49-1.498 1.337.981a33.6 33.6 0 0 0 10.203 5.098l.97.294-.09.968a5.85 5.85 0 0 0 1.052 3.878 6.24 6.24 0 0 0 6.695 2.485 5.8 5.8 0 0 0 1.603-.704L69.27 76.28a5.43 5.43 0 0 0 2.45-3.631 5.8 5.8 0 0 0-.987-4.371 6.24 6.24 0 0 0-6.698-2.487 5.7 5.7 0 0 0-1.6.704l-9.953 6.345a19 19 0 0 1-5.296 2.326 20.72 20.72 0 0 1-22.237-8.243 19.17 19.17 0 0 1-3.277-14.502 17.99 17.99 0 0 1 8.13-12.052l26.081-16.623a19 19 0 0 1 5.3-2.329 20.72 20.72 0 0 1 22.237 8.243 19.17 19.17 0 0 1 3.277 14.503 18 18 0 0 1-.624 2.435l-.49 1.498-1.337-.98a33.6 33.6 0 0 0-10.203-5.1l-.97-.294.09-.968a5.86 5.86 0 0 0-1.052-3.878 6.24 6.24 0 0 0-6.696-2.485 5.8 5.8 0 0 0-1.602.704L37.73 51.72a5.42 5.42 0 0 0-2.449 3.63 5.79 5.79 0 0 0 .986 4.372 6.24 6.24 0 0 0 6.698 2.486 5.8 5.8 0 0 0 1.602-.704l9.952-6.342a19 19 0 0 1 5.295-2.328 20.72 20.72 0 0 1 22.237 8.242 19.17 19.17 0 0 1 3.277 14.503 18 18 0 0 1-8.13 12.053l-26.081 16.622a19 19 0 0 1-5.3 2.328" style="fill:#fff"/></svg>
@@ -0,0 +1 @@
1
+ // place files you want to import through the `$lib` alias in this folder.
@@ -0,0 +1,9 @@
1
+ <script lang="ts">
2
+ import './layout.css';
3
+ import favicon from '$lib/assets/favicon.svg';
4
+
5
+ let { children } = $props();
6
+ </script>
7
+
8
+ <svelte:head><link rel="icon" href={favicon} /></svelte:head>
9
+ {@render children()}
@@ -0,0 +1,2 @@
1
+ <h1>Welcome to {{projectName}}</h1>
2
+ <p>This project was generated by Phos 🚀</p>
@@ -0,0 +1,2 @@
1
+ @import 'tailwindcss';
2
+ @plugin '@tailwindcss/typography';
@@ -0,0 +1,3 @@
1
+ # allow crawling everything by default
2
+ User-agent: *
3
+ Disallow:
@@ -0,0 +1,13 @@
1
+ import adapter from '@sveltejs/adapter-auto';
2
+
3
+ /** @type {import('@sveltejs/kit').Config} */
4
+ const config = {
5
+ kit: {
6
+ // adapter-auto only supports some environments, see https://svelte.dev/docs/kit/adapter-auto for a list.
7
+ // If your environment is not supported, or you settled on a specific environment, switch out the adapter.
8
+ // See https://svelte.dev/docs/kit/adapters for more information about adapters.
9
+ adapter: adapter()
10
+ }
11
+ };
12
+
13
+ export default config;
@@ -0,0 +1,20 @@
1
+ {
2
+ "extends": "./.svelte-kit/tsconfig.json",
3
+ "compilerOptions": {
4
+ "rewriteRelativeImportExtensions": true,
5
+ "allowJs": true,
6
+ "checkJs": true,
7
+ "esModuleInterop": true,
8
+ "forceConsistentCasingInFileNames": true,
9
+ "resolveJsonModule": true,
10
+ "skipLibCheck": true,
11
+ "sourceMap": true,
12
+ "strict": true,
13
+ "moduleResolution": "bundler"
14
+ }
15
+ // Path aliases are handled by https://svelte.dev/docs/kit/configuration#alias
16
+ // except $lib which is handled by https://svelte.dev/docs/kit/configuration#files
17
+ //
18
+ // To make changes to top-level options such as include and exclude, we recommend extending
19
+ // the generated config; see https://svelte.dev/docs/kit/configuration#typescript
20
+ }
@@ -0,0 +1,5 @@
1
+ import tailwindcss from '@tailwindcss/vite';
2
+ import { sveltekit } from '@sveltejs/kit/vite';
3
+ import { defineConfig } from 'vite';
4
+
5
+ export default defineConfig({ plugins: [tailwindcss(), sveltekit()] });
@@ -0,0 +1,198 @@
1
+ import fs from "fs-extra";
2
+ import Handlebars from "handlebars";
3
+ import pc from "picocolors";
4
+ import { execSync } from "child_process";
5
+ import { resolve, join } from "path";
6
+
7
+ Handlebars.registerHelper("eq", function (a, b) {
8
+ return a === b;
9
+ });
10
+
11
+ Handlebars.registerHelper("or", function (...args) {
12
+ return args.slice(0, -1).some(Boolean);
13
+ });
14
+
15
+ export interface GeneratorConfig {
16
+ projectName: string;
17
+ projectType: "monorepo" | "single";
18
+ backend?: {
19
+ framework: "elysia" | "fastapi";
20
+ packageManager: "npm" | "yarn" | "pnpm" | "bun" | "venv" | "pip";
21
+ typescript: boolean;
22
+ eslint: boolean;
23
+ prettier: boolean;
24
+ };
25
+ frontend?: {
26
+ framework: "astro" | "svelte" | "nextjs";
27
+ packageManager: "npm" | "yarn" | "pnpm" | "bun";
28
+ typescript: boolean;
29
+ eslint: boolean;
30
+ prettier: boolean;
31
+ cssFramework: "none" | "tailwind" | "scss" | "css-modules";
32
+ uiComponents: "none" | "shadcn" | "radix";
33
+ testing: "none" | "vitest" | "playwright" | "both";
34
+ };
35
+ git: boolean;
36
+ install: boolean;
37
+ }
38
+
39
+ export async function createDirectory(dirPath: string): Promise<void> {
40
+ await fs.ensureDir(dirPath);
41
+ }
42
+
43
+ export async function writeFile(filePath: string, content: string): Promise<void> {
44
+ await fs.ensureFile(filePath);
45
+ await fs.writeFile(filePath, content, "utf-8");
46
+ }
47
+
48
+ export async function copyTemplate(
49
+ templatePath: string,
50
+ outputPath: string,
51
+ data: Record<string, unknown>
52
+ ): Promise<void> {
53
+ const files = await fs.readdir(templatePath, { withFileTypes: true });
54
+
55
+ const binaryExtensions = [
56
+ ".png",
57
+ ".jpg",
58
+ ".jpeg",
59
+ ".gif",
60
+ ".svg",
61
+ ".ico",
62
+ ".webp",
63
+ ".woff",
64
+ ".woff2",
65
+ ".ttf",
66
+ ".otf",
67
+ ".eot",
68
+ ".pdf",
69
+ ".zip",
70
+ ".tar",
71
+ ".gz",
72
+ ".7z",
73
+ ".bin",
74
+ ".exe",
75
+ ".dll",
76
+ ".so",
77
+ ".dylib",
78
+ ];
79
+
80
+ for (const file of files) {
81
+ const srcPath = join(templatePath, file.name);
82
+ const destPath = join(outputPath, file.name);
83
+
84
+ if (file.isDirectory()) {
85
+ await createDirectory(destPath);
86
+ await copyTemplate(srcPath, destPath, data);
87
+ } else {
88
+ const ext = file.name.toLowerCase();
89
+ const isBinary = binaryExtensions.some((binExt) => ext.endsWith(binExt));
90
+
91
+ if (isBinary) {
92
+ await fs.copy(srcPath, destPath);
93
+ } else {
94
+ let content = await fs.readFile(srcPath, "utf-8");
95
+ const template = Handlebars.compile(content);
96
+ const rendered = template(data);
97
+ await writeFile(destPath, rendered);
98
+ }
99
+ }
100
+ }
101
+ }
102
+
103
+ export function getPackageManagerInstallCmd(packageManager: string): string {
104
+ switch (packageManager) {
105
+ case "npm":
106
+ return "npm install";
107
+ case "yarn":
108
+ return "yarn";
109
+ case "pnpm":
110
+ return "pnpm install";
111
+ case "bun":
112
+ return "bun install";
113
+ case "venv":
114
+ return "source venv/bin/activate && pip install -r requirements.txt";
115
+ case "pip":
116
+ return "pip install -r requirements.txt";
117
+ default:
118
+ return "npm install";
119
+ }
120
+ }
121
+
122
+ export function getPackageManagerRunCmd(packageManager: string, script: string): string {
123
+ switch (packageManager) {
124
+ case "npm":
125
+ return `npm run ${script}`;
126
+ case "yarn":
127
+ return `yarn ${script}`;
128
+ case "pnpm":
129
+ return `pnpm run ${script}`;
130
+ case "bun":
131
+ return `bun run ${script}`;
132
+ case "venv":
133
+ return `source venv/bin/activate && python src/main.py`;
134
+ case "pip":
135
+ return `python src/main.py`;
136
+ default:
137
+ return `npm run ${script}`;
138
+ }
139
+ }
140
+
141
+ export function logStep(message: string): void {
142
+ console.log(pc.cyan(` ${message}`));
143
+ }
144
+
145
+ export function logSuccess(message: string): void {
146
+ console.log(pc.green(` ✅ ${message}`));
147
+ }
148
+
149
+ export function logInfo(message: string): void {
150
+ console.log(pc.blue(` ℹ️ ${message}`));
151
+ }
152
+
153
+ export async function installDependencies(
154
+ projectPath: string,
155
+ packageManager: string
156
+ ): Promise<void> {
157
+ try {
158
+ logStep(`Installing dependencies with ${packageManager}...`);
159
+ execSync(getPackageManagerInstallCmd(packageManager), {
160
+ cwd: projectPath,
161
+ stdio: "inherit",
162
+ });
163
+ logSuccess("Dependencies installed");
164
+ } catch (error) {
165
+ throw new Error(`Failed to install dependencies: ${error}`);
166
+ }
167
+ }
168
+
169
+ export async function initializeGit(projectPath: string): Promise<void> {
170
+ try {
171
+ logStep("Initializing Git repository...");
172
+ execSync("git init", { cwd: projectPath, stdio: "inherit" });
173
+ execSync("git add .", { cwd: projectPath, stdio: "inherit" });
174
+ execSync('git commit -m "Initial commit from Phos"', {
175
+ cwd: projectPath,
176
+ stdio: "inherit",
177
+ });
178
+ logSuccess("Git repository initialized");
179
+ } catch (error) {
180
+ throw new Error(`Failed to initialize Git: ${error}`);
181
+ }
182
+ }
183
+
184
+ export function getProjectPath(projectName: string): string {
185
+ return resolve(process.cwd(), projectName);
186
+ }
187
+
188
+ export function capitalize(str: string): string {
189
+ return str.charAt(0).toUpperCase() + str.slice(1);
190
+ }
191
+
192
+ export function toKebabCase(str: string): string {
193
+ return str.replace(/([a-z])([A-Z])/g, "$1-$2").toLowerCase();
194
+ }
195
+
196
+ export function toPascalCase(str: string): string {
197
+ return str.replace(/[-_](.)/g, (_, c) => c.toUpperCase()).replace(/^(.)/, (c) => c.toUpperCase());
198
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,24 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2022",
4
+ "module": "ES2022",
5
+ "lib": ["ES2022"],
6
+ "moduleResolution": "bundler",
7
+ "outDir": "./dist",
8
+ "rootDir": "./src",
9
+ "strict": true,
10
+ "esModuleInterop": true,
11
+ "skipLibCheck": true,
12
+ "forceConsistentCasingInFileNames": true,
13
+ "resolveJsonModule": true,
14
+ "declaration": true,
15
+ "declarationMap": true,
16
+ "sourceMap": true,
17
+ "baseUrl": ".",
18
+ "paths": {
19
+ "@/*": ["./src/*"]
20
+ }
21
+ },
22
+ "include": ["src/**/*"],
23
+ "exclude": ["node_modules", "dist"]
24
+ }