create-pylon 1.1.5-canary-20250812173555.281a13c7bdcad57f6a055166537c2e9a10703656 → 1.1.5-canary-20251001075248.01df717bb7203eb5e3940ffe3e9b55027ac35ebd
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.
- package/dist/index.js +11 -876
- package/dist/index.js.map +4 -4
- package/package.json +4 -5
- package/templates/bun/default/Dockerfile +47 -0
- package/templates/bun/default/package.json +23 -0
- package/templates/bun/default/src/index.ts +12 -0
- package/templates/bun/default/tsconfig.json +8 -0
- package/templates/cf-workers/default/package.json +25 -0
- package/templates/cf-workers/default/src/index.ts +12 -0
- package/templates/cf-workers/default/tsconfig.json +4 -0
- package/templates/cf-workers/default/worker-configuration.d.ts +3 -0
- package/templates/cf-workers/default/wrangler.toml +108 -0
- package/templates/deno/default/.vscode/extensions.json +5 -0
- package/templates/deno/default/.vscode/settings.json +6 -0
- package/templates/deno/default/Dockerfile +12 -0
- package/templates/deno/default/deno.json +15 -0
- package/templates/deno/default/src/index.ts +17 -0
- package/templates/node/default/Dockerfile +45 -0
- package/templates/node/default/package.json +23 -0
- package/templates/node/default/src/index.ts +15 -0
- package/templates/shared/.dockerignore +15 -0
- package/templates/shared/.github/workflows/publish.yaml +43 -0
- package/templates/shared/.gitignore.example +175 -0
- package/templates/shared/pylon.d.ts +7 -0
- package/templates/shared/tsconfig.json +4 -0
package/dist/index.js
CHANGED
|
@@ -1,881 +1,16 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import
|
|
2
|
+
import{Option as k,program as J}from"commander";import{consola as u}from"consola";import{input as E,select as W,confirm as N}from"@inquirer/prompts";import c from"path";import m from"chalk";import*as r from"fs";import*as L from"@getcronit/pylon-telemetry";import{fileURLToPath as ne}from"url";import{dirname as re}from"path";import{spawnSync as ce}from"child_process";import*as y from"node:fs";import*as h from"node:path";import M from"node:process";import{execSync as X}from"node:child_process";import{consola as I}from"consola";function x(e){try{return X(`${e} --version`,{stdio:"ignore"}),!0}catch(a){return console.error(a),!1}}function z(){return typeof Bun<"u"&&x("bun")}function G(){return M.env.npm_execpath?.includes("npm")??!1}function Q(){return M.env.npm_execpath?.includes("yarn")??!1}function Z(){return typeof Deno<"u"&&x("deno")}function ee(){return M.env.npm_execpath?.includes("pnpm")??!1}function te(e){return y.existsSync(h.join(e,"bun.lockb"))?"bun":y.existsSync(h.join(e,"package-lock.json"))?"npm":y.existsSync(h.join(e,"yarn.lock"))?"yarn":y.existsSync(h.join(e,"deno.json"))||y.existsSync(h.join(e,"deno.lock"))?"deno":y.existsSync(h.join(e,"pnpm-lock.yaml"))?"pnpm":null}function R({preferredPm:e,cwd:a=M.cwd()}){if(e&&x(e))return e;if(z())return"bun";if(G())return"npm";if(ee())return"pnpm";if(Z())return"deno";if(Q())return"yarn";let n=te(a);if(n){if(I.info(`Detected package manager by lock file: ${n}`),x(n))return n;I.warn(`Lock file detected, but ${n} is not installed.`)}return"unknown"}function T(e){switch(e){case"bun":return"bun";case"npm":return"npm run";case"yarn":return"yarn";case"pnpm":return"pnpm run";case"deno":return"deno task";default:throw new Error("Unknown package manager")}}var ae=ne(import.meta.url),A=re(ae),U=JSON.parse(r.readFileSync(c.join(A,"..","package.json"),"utf-8")).version;function ie(e){try{r.mkdirSync(e,{recursive:!0})}catch(a){if(a instanceof Error&&"code"in a&&a.code==="EEXIST")return;throw a}}var D=[{key:"bun",name:"Bun.js",website:"https://bunjs.dev",templates:["default"]},{key:"node",name:"Node.js",website:"https://nodejs.org",templates:["default"]},{key:"cf-workers",name:"Cloudflare Workers",website:"https://workers.cloudflare.com",templates:["default"]},{key:"deno",name:"Deno",website:"https://deno.land",templates:["default"]}],q=[{key:"default",name:"Default",description:"Default template"},{key:"database",name:"Database (Prisma)",description:"Template with Prisma ORM"}],se=(e,a)=>{let n=e;return Object.entries(a).forEach(([i,f])=>{n=n.replaceAll(i,f)}),n},B=e=>{let a=n=>{let i=[];return r.readdirSync(n).forEach(b=>{let l=c.join(n,b);r.statSync(l).isDirectory()&&i.push(...a(l)),r.statSync(l).isFile()&&i.push(l)}),i};return a(e).map(n=>n.replace(e,"."))},oe=async e=>{let{runtime:a,template:n,target:i}=e,f=D.find(({key:t})=>t===a)?.name,b=q.find(({key:t})=>t===n)?.name;if(!f)throw new Error(`Invalid runtime: ${a}`);if(!b)throw new Error(`Invalid template: ${n}`);let l=c.join(A,"..","templates","shared");if(!r.existsSync(l))throw new Error(`Shared templates not found: ${l}`);let w=c.join(A,"..","templates",a,n);if(!r.existsSync(w))throw new Error(`Template not found: ${w}`);let P=c.join(process.cwd(),i);u.start(`Creating pylon in ${P}`);let v=t=>se(t,{__PYLON_NAME__:e.name});B(l).forEach(t=>{let d=c.join(l,t),s=c.join(P,t),p=c.dirname(s);if(a==="cf-workers"&&d.includes(".github/workflows/publish.yaml"))return;r.existsSync(p)||r.mkdirSync(p,{recursive:!0}),s.endsWith(".example")&&(s=s.replace(".example",""));let g=v(r.readFileSync(d,"utf-8"));r.writeFileSync(s,g)}),B(w).forEach(t=>{let d=c.join(w,t),s=c.join(P,t),p=c.dirname(s);r.existsSync(p)||r.mkdirSync(p,{recursive:!0}),s.endsWith(".example")&&(s=s.replace(".example",""));let g=v(r.readFileSync(d,"utf-8"));r.writeFileSync(s,g)}),u.success("Pylon created")},le=async e=>{let a=c.resolve(e.target),n=e.packageManager,i="";switch(n){case"yarn":i="yarn";break;case"npm":i="npm install";break;case"pnpm":i="pnpm install";break;case"bun":i="bun install";break;case"deno":i="deno install";break;default:throw new Error(`Invalid package manager: ${n}`)}if(u.start(`Installing dependencies using ${n}`),ce(i,{cwd:a,shell:!0,stdio:"inherit"}).status!==0)throw new Error("Failed to install dependencies");u.success("Dependencies installed")};J.name("create-pylon").version(U).arguments("[target]").addOption(new k("-i, --install","Install dependencies")).addOption(new k("-r, --runtime <runtime>","Runtime").choices(D.map(({key:e})=>e))).addOption(new k("-t, --template <template>","Template")).addOption(new k("-pm, --package-manager <packageManager>","Package manager")).addOption(new k("--client","Enable client generation (https://pylon.cronit.io/docs/integrations/gqty)")).addOption(new k("--client-path <clientPath>","Client path")).addOption(new k("--client-port <clientPort>","Client port")).action(me);var pe=e=>{if(e==="bun")return"bun";if(e==="deno")return"deno"};async function me(e,a,n){try{u.log(`${n.name()} version ${n.version()}`);let{install:i,runtime:f,template:b,packageManager:l,client:w,clientPath:P,clientPort:v}=a,t="";e?(t=e,u.success(`Using target directory \u2026 ${t}`)):t=await E({message:"Target directory",default:"my-pylon"});let d="";t==="."?d=c.basename(process.cwd()):d=c.basename(t);let s=f||await W({message:"Which runtime would you like to use?",choices:D.map(o=>({name:`${o.name} (${o.website})`,value:o.key})),default:0});if(!s)throw new Error("No runtime selected");let p=D.find(({key:o})=>o===s);if(!p)throw new Error(`Invalid runtime selected: ${s}`);let g=b||await W({message:"Which template would you like to use?",choices:q.filter(o=>p.templates?.includes(o.key)).map(o=>({name:o.name,value:o.key})),default:0});if(!g)throw new Error("No template selected");r.existsSync(t)?r.readdirSync(t).length>0&&(await N({message:"Directory not empty. Continue?",default:!1})||process.exit(1)):ie(t);let V=i||await N({message:"Would you like to install dependencies?"});await oe({name:d,runtime:s,template:g,target:t});let F=R({preferredPm:pe(p.key),cwd:t});V&&await le({target:t,packageManager:F});let Y=w||await N({message:"Would you like to enable client generation? (https://pylon.cronit.io/docs/integrations/gqty)",default:!1}),j="",C="",O="";if(Y){P||(j=await E({message:"Path to the root where the client should be generated",default:"."}),C=await E({message:"Path to generate the client to",default:c.join(j,"gqty/index.ts"),validate:K=>K.startsWith(j==="."?"":j)?!0:"Path must start with the client root"})),O=v||await E({message:"Port of the pylon server to generate the client from",default:"3000"}),u.start("Updating pylon dev script to generate client");let o,S;p.key==="deno"?(o=c.join(t,"deno.json"),S="tasks"):(o=c.join(t,"package.json"),S="scripts");let $=JSON.parse(r.readFileSync(o,"utf-8"));$[S]={...$[S],dev:$[S].dev+` --client --client-port ${O} --client-path ${C}`},r.writeFileSync(o,JSON.stringify($,null,2)),u.success("Pylon dev script updated")}let _=T(F),H=`
|
|
3
|
+
\u{1F389} ${m.green.bold("Pylon created successfully.")}
|
|
3
4
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
yarn-error.log*
|
|
9
|
-
lerna-debug.log*
|
|
10
|
-
.pnpm-debug.log*
|
|
5
|
+
\u{1F4BB} ${m.cyan.bold("Continue Developing")}
|
|
6
|
+
${m.yellow("Change directories:")} cd ${m.blue(t)}
|
|
7
|
+
${m.yellow("Start dev server:")} ${_} dev
|
|
8
|
+
${m.yellow("Deploy:")} ${_} deploy
|
|
11
9
|
|
|
12
|
-
|
|
10
|
+
\u{1F4D6} ${m.cyan.bold("Explore Documentation")}
|
|
11
|
+
${m.underline.blue("https://pylon.cronit.io/docs")}
|
|
13
12
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
pids
|
|
19
|
-
_.pid
|
|
20
|
-
_.seed
|
|
21
|
-
*.pid.lock
|
|
22
|
-
|
|
23
|
-
# Directory for instrumented libs generated by jscoverage/JSCover
|
|
24
|
-
|
|
25
|
-
lib-cov
|
|
26
|
-
|
|
27
|
-
# Coverage directory used by tools like istanbul
|
|
28
|
-
|
|
29
|
-
coverage
|
|
30
|
-
*.lcov
|
|
31
|
-
|
|
32
|
-
# nyc test coverage
|
|
33
|
-
|
|
34
|
-
.nyc_output
|
|
35
|
-
|
|
36
|
-
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
|
|
37
|
-
|
|
38
|
-
.grunt
|
|
39
|
-
|
|
40
|
-
# Bower dependency directory (https://bower.io/)
|
|
41
|
-
|
|
42
|
-
bower_components
|
|
43
|
-
|
|
44
|
-
# node-waf configuration
|
|
45
|
-
|
|
46
|
-
.lock-wscript
|
|
47
|
-
|
|
48
|
-
# Compiled binary addons (https://nodejs.org/api/addons.html)
|
|
49
|
-
|
|
50
|
-
build/Release
|
|
51
|
-
|
|
52
|
-
# Dependency directories
|
|
53
|
-
|
|
54
|
-
node_modules/
|
|
55
|
-
jspm_packages/
|
|
56
|
-
|
|
57
|
-
# Snowpack dependency directory (https://snowpack.dev/)
|
|
58
|
-
|
|
59
|
-
web_modules/
|
|
60
|
-
|
|
61
|
-
# TypeScript cache
|
|
62
|
-
|
|
63
|
-
*.tsbuildinfo
|
|
64
|
-
|
|
65
|
-
# Optional npm cache directory
|
|
66
|
-
|
|
67
|
-
.npm
|
|
68
|
-
|
|
69
|
-
# Optional eslint cache
|
|
70
|
-
|
|
71
|
-
.eslintcache
|
|
72
|
-
|
|
73
|
-
# Optional stylelint cache
|
|
74
|
-
|
|
75
|
-
.stylelintcache
|
|
76
|
-
|
|
77
|
-
# Microbundle cache
|
|
78
|
-
|
|
79
|
-
.rpt2_cache/
|
|
80
|
-
.rts2_cache_cjs/
|
|
81
|
-
.rts2_cache_es/
|
|
82
|
-
.rts2_cache_umd/
|
|
83
|
-
|
|
84
|
-
# Optional REPL history
|
|
85
|
-
|
|
86
|
-
.node_repl_history
|
|
87
|
-
|
|
88
|
-
# Output of 'npm pack'
|
|
89
|
-
|
|
90
|
-
*.tgz
|
|
91
|
-
|
|
92
|
-
# Yarn Integrity file
|
|
93
|
-
|
|
94
|
-
.yarn-integrity
|
|
95
|
-
|
|
96
|
-
# dotenv environment variable files
|
|
97
|
-
|
|
98
|
-
.env
|
|
99
|
-
.env.development.local
|
|
100
|
-
.env.test.local
|
|
101
|
-
.env.production.local
|
|
102
|
-
.env.local
|
|
103
|
-
|
|
104
|
-
# parcel-bundler cache (https://parceljs.org/)
|
|
105
|
-
|
|
106
|
-
.cache
|
|
107
|
-
.parcel-cache
|
|
108
|
-
|
|
109
|
-
# Next.js build output
|
|
110
|
-
|
|
111
|
-
.next
|
|
112
|
-
out
|
|
113
|
-
|
|
114
|
-
# Nuxt.js build / generate output
|
|
115
|
-
|
|
116
|
-
.nuxt
|
|
117
|
-
dist
|
|
118
|
-
|
|
119
|
-
# Gatsby files
|
|
120
|
-
|
|
121
|
-
.cache/
|
|
122
|
-
|
|
123
|
-
# Comment in the public line in if your project uses Gatsby and not Next.js
|
|
124
|
-
|
|
125
|
-
# https://nextjs.org/blog/next-9-1#public-directory-support
|
|
126
|
-
|
|
127
|
-
# public
|
|
128
|
-
|
|
129
|
-
# vuepress build output
|
|
130
|
-
|
|
131
|
-
.vuepress/dist
|
|
132
|
-
|
|
133
|
-
# vuepress v2.x temp and cache directory
|
|
134
|
-
|
|
135
|
-
.temp
|
|
136
|
-
.cache
|
|
137
|
-
|
|
138
|
-
# Docusaurus cache and generated files
|
|
139
|
-
|
|
140
|
-
.docusaurus
|
|
141
|
-
|
|
142
|
-
# Serverless directories
|
|
143
|
-
|
|
144
|
-
.serverless/
|
|
145
|
-
|
|
146
|
-
# FuseBox cache
|
|
147
|
-
|
|
148
|
-
.fusebox/
|
|
149
|
-
|
|
150
|
-
# DynamoDB Local files
|
|
151
|
-
|
|
152
|
-
.dynamodb/
|
|
153
|
-
|
|
154
|
-
# TernJS port file
|
|
155
|
-
|
|
156
|
-
.tern-port
|
|
157
|
-
|
|
158
|
-
# Stores VSCode versions used for testing VSCode extensions
|
|
159
|
-
|
|
160
|
-
.vscode-test
|
|
161
|
-
|
|
162
|
-
# yarn v2
|
|
163
|
-
|
|
164
|
-
.yarn/cache
|
|
165
|
-
.yarn/unplugged
|
|
166
|
-
.yarn/build-state.yml
|
|
167
|
-
.yarn/install-state.gz
|
|
168
|
-
.pnp.*
|
|
169
|
-
|
|
170
|
-
# wrangler project
|
|
171
|
-
|
|
172
|
-
.dev.vars
|
|
173
|
-
.wrangler/
|
|
174
|
-
|
|
175
|
-
# Pylon project
|
|
176
|
-
.pylon
|
|
177
|
-
`},{path:".dockerignore",content:`node_modules
|
|
178
|
-
Dockerfile*
|
|
179
|
-
docker-compose*
|
|
180
|
-
.dockerignore
|
|
181
|
-
.git
|
|
182
|
-
.gitignore
|
|
183
|
-
README.md
|
|
184
|
-
LICENSE
|
|
185
|
-
.vscode
|
|
186
|
-
Makefile
|
|
187
|
-
helm-charts
|
|
188
|
-
.env
|
|
189
|
-
.editorconfig
|
|
190
|
-
.idea
|
|
191
|
-
coverage*
|
|
192
|
-
`,specificRuntimes:["node","bun"]},{path:".github/workflows/publish.yml",content:`name: publish
|
|
193
|
-
|
|
194
|
-
on: [push]
|
|
195
|
-
env:
|
|
196
|
-
IMAGE_NAME: __PYLON_NAME__
|
|
197
|
-
|
|
198
|
-
jobs:
|
|
199
|
-
# Push image to GitHub Packages.
|
|
200
|
-
# See also https://docs.docker.com/docker-hub/builds/
|
|
201
|
-
publish-container:
|
|
202
|
-
runs-on: ubuntu-latest
|
|
203
|
-
permissions:
|
|
204
|
-
packages: write
|
|
205
|
-
contents: read
|
|
206
|
-
|
|
207
|
-
steps:
|
|
208
|
-
- uses: actions/checkout@v4
|
|
209
|
-
|
|
210
|
-
- name: Build image
|
|
211
|
-
run: docker build . --file Dockerfile --tag $IMAGE_NAME
|
|
212
|
-
|
|
213
|
-
- name: Log into registry
|
|
214
|
-
run: echo "\${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u \${{ github.actor }} --password-stdin
|
|
215
|
-
|
|
216
|
-
- name: Push image
|
|
217
|
-
run: |
|
|
218
|
-
IMAGE_ID=ghcr.io/\${{ github.repository_owner }}/$IMAGE_NAME
|
|
219
|
-
|
|
220
|
-
# Change all uppercase to lowercase
|
|
221
|
-
IMAGE_ID=$(echo $IMAGE_ID | tr '[A-Z]' '[a-z]')
|
|
222
|
-
# Strip git ref prefix from version
|
|
223
|
-
VERSION=$(echo "\${{ github.ref }}" | sed -e 's,.*/\\(.*\\),\\1,')
|
|
224
|
-
# Strip "v" prefix from tag name
|
|
225
|
-
[[ "\${{ github.ref }}" == "refs/tags/"* ]] && VERSION=$(echo $VERSION | sed -e 's/^v//')
|
|
226
|
-
# Use Docker \`latest\` tag convention
|
|
227
|
-
[ "$VERSION" == "main" ] && VERSION=latest
|
|
228
|
-
echo IMAGE_ID=$IMAGE_ID
|
|
229
|
-
echo VERSION=$VERSION
|
|
230
|
-
docker tag $IMAGE_NAME $IMAGE_ID:$VERSION
|
|
231
|
-
docker push $IMAGE_ID:$VERSION
|
|
232
|
-
|
|
233
|
-
# SPDX-License-Identifier: (EUPL-1.2)
|
|
234
|
-
# Copyright \xA9 2024 cronit KG`,specificRuntimes:["node","bun"]}],bun:[{path:"package.json",content:`{
|
|
235
|
-
"name": "__PYLON_NAME__",
|
|
236
|
-
"private": true,
|
|
237
|
-
"version": "0.0.1",
|
|
238
|
-
"type": "module",
|
|
239
|
-
"description": "Generated with \`npm create pylon\`",
|
|
240
|
-
"scripts": {
|
|
241
|
-
"dev": "pylon dev -c \\"bun run .pylon/index.js\\"",
|
|
242
|
-
"build": "pylon build"
|
|
243
|
-
},
|
|
244
|
-
"dependencies": {
|
|
245
|
-
"@getcronit/pylon": "${u}",
|
|
246
|
-
},
|
|
247
|
-
"devDependencies": {
|
|
248
|
-
"@getcronit/pylon-dev": "${g}",
|
|
249
|
-
"@types/bun": "^1.0.0"
|
|
250
|
-
},
|
|
251
|
-
"repository": {
|
|
252
|
-
"type": "git",
|
|
253
|
-
"url": "https://github.com/getcronit/pylon.git"
|
|
254
|
-
},
|
|
255
|
-
"homepage": "https://pylon.cronit.io",
|
|
256
|
-
"packageManager": "bun"
|
|
257
|
-
}
|
|
258
|
-
`},{path:"Dockerfile",content:`# use the official Bun image
|
|
259
|
-
# see all versions at https://hub.docker.com/r/oven/bun/tags
|
|
260
|
-
FROM oven/bun:1 as base
|
|
261
|
-
|
|
262
|
-
LABEL description="Offical docker image for Pylon services (Bun)"
|
|
263
|
-
LABEL org.opencontainers.image.source="https://github.com/getcronit/pylon"
|
|
264
|
-
LABEL maintainer="office@cronit.io"
|
|
265
|
-
|
|
266
|
-
WORKDIR /usr/src/pylon
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
# install dependencies into temp directory
|
|
270
|
-
# this will cache them and speed up future builds
|
|
271
|
-
FROM base AS install
|
|
272
|
-
RUN mkdir -p /temp/dev
|
|
273
|
-
COPY package.json bun.lockb /temp/dev/
|
|
274
|
-
RUN cd /temp/dev && bun install --frozen-lockfile
|
|
275
|
-
|
|
276
|
-
# install with --production (exclude devDependencies)
|
|
277
|
-
RUN mkdir -p /temp/prod
|
|
278
|
-
COPY package.json bun.lockb /temp/prod/
|
|
279
|
-
RUN cd /temp/prod && bun install --frozen-lockfile --production
|
|
280
|
-
|
|
281
|
-
# copy node_modules from temp directory
|
|
282
|
-
# then copy all (non-ignored) project files into the image
|
|
283
|
-
FROM install AS prerelease
|
|
284
|
-
COPY --from=install /temp/dev/node_modules node_modules
|
|
285
|
-
COPY . .
|
|
286
|
-
|
|
287
|
-
# [optional] tests & build
|
|
288
|
-
ENV NODE_ENV=production
|
|
289
|
-
|
|
290
|
-
# Create .pylon folder (mkdir)
|
|
291
|
-
RUN mkdir -p .pylon
|
|
292
|
-
# RUN bun test
|
|
293
|
-
RUN bun run pylon build
|
|
294
|
-
|
|
295
|
-
# copy production dependencies and source code into final image
|
|
296
|
-
FROM base AS release
|
|
297
|
-
COPY --from=install /temp/prod/node_modules node_modules
|
|
298
|
-
COPY --from=prerelease /usr/src/pylon/.pylon .pylon
|
|
299
|
-
COPY --from=prerelease /usr/src/pylon/package.json .
|
|
300
|
-
|
|
301
|
-
# run the app
|
|
302
|
-
USER bun
|
|
303
|
-
EXPOSE 3000/tcp
|
|
304
|
-
ENTRYPOINT [ "bun", "run", "/usr/src/pylon/.pylon/index.js" ]
|
|
305
|
-
`}],node:[{path:"package.json",content:`{
|
|
306
|
-
"name": "__PYLON_NAME__",
|
|
307
|
-
"private": true,
|
|
308
|
-
"version": "0.0.1",
|
|
309
|
-
"type": "module",
|
|
310
|
-
"description": "Generated with \`npm create pylon\`",
|
|
311
|
-
"scripts": {
|
|
312
|
-
"dev": "pylon dev -c \\"node --enable-source-maps .pylon/index.js\\"",
|
|
313
|
-
"build": "pylon build"
|
|
314
|
-
},
|
|
315
|
-
"dependencies": {
|
|
316
|
-
"@getcronit/pylon": "${u}",
|
|
317
|
-
"@hono/node-server": "^1.12.2"
|
|
318
|
-
},
|
|
319
|
-
"devDependencies": {
|
|
320
|
-
"@getcronit/pylon-dev": "${g}"
|
|
321
|
-
},
|
|
322
|
-
"repository": {
|
|
323
|
-
"type": "git",
|
|
324
|
-
"url": "https://github.com/getcronit/pylon.git"
|
|
325
|
-
},
|
|
326
|
-
"homepage": "https://pylon.cronit.io"
|
|
327
|
-
}
|
|
328
|
-
`},{path:"Dockerfile",content:`# Use the official Node.js 20 image as the base
|
|
329
|
-
FROM node:20-alpine as base
|
|
330
|
-
|
|
331
|
-
LABEL description="Offical docker image for Pylon services (Node.js)"
|
|
332
|
-
LABEL org.opencontainers.image.source="https://github.com/getcronit/pylon"
|
|
333
|
-
LABEL maintainer="office@cronit.io"
|
|
334
|
-
|
|
335
|
-
WORKDIR /usr/src/pylon
|
|
336
|
-
|
|
337
|
-
# install dependencies into a temp directory
|
|
338
|
-
# this will cache them and speed up future builds
|
|
339
|
-
FROM base AS install
|
|
340
|
-
RUN mkdir -p /temp/dev
|
|
341
|
-
COPY package.json package-lock.json /temp/dev/
|
|
342
|
-
RUN cd /temp/dev && npm ci
|
|
343
|
-
|
|
344
|
-
# install with --production (exclude devDependencies)
|
|
345
|
-
RUN mkdir -p /temp/prod
|
|
346
|
-
COPY package.json package-lock.json /temp/prod/
|
|
347
|
-
RUN cd /temp/prod && npm ci --only=production
|
|
348
|
-
|
|
349
|
-
# copy node_modules from temp directory
|
|
350
|
-
# then copy all (non-ignored) project files into the image
|
|
351
|
-
FROM install AS prerelease
|
|
352
|
-
COPY --from=install /temp/dev/node_modules node_modules
|
|
353
|
-
COPY . .
|
|
354
|
-
|
|
355
|
-
# [optional] tests & build
|
|
356
|
-
ENV NODE_ENV=production
|
|
357
|
-
|
|
358
|
-
# Create .pylon folder (mkdir)
|
|
359
|
-
RUN mkdir -p .pylon
|
|
360
|
-
# RUN npm test
|
|
361
|
-
RUN npm run pylon build
|
|
362
|
-
|
|
363
|
-
# copy production dependencies and source code into final image
|
|
364
|
-
FROM base AS release
|
|
365
|
-
COPY --from=install /temp/prod/node_modules node_modules
|
|
366
|
-
COPY --from=prerelease /usr/src/pylon/.pylon .pylon
|
|
367
|
-
COPY --from=prerelease /usr/src/pylon/package.json .
|
|
368
|
-
|
|
369
|
-
# run the app
|
|
370
|
-
USER node
|
|
371
|
-
EXPOSE 3000/tcp
|
|
372
|
-
ENTRYPOINT [ "node", "/usr/src/pylon/.pylon/index.js" ]
|
|
373
|
-
`}],"cf-workers":[{path:"package.json",content:`{
|
|
374
|
-
"name": "__PYLON_NAME__",
|
|
375
|
-
"type": "module",
|
|
376
|
-
"description": "Generated with \`npm create pylon\`",
|
|
377
|
-
"version": "0.0.1",
|
|
378
|
-
"private": true,
|
|
379
|
-
"scripts": {
|
|
380
|
-
"deploy": "pylon build && wrangler deploy",
|
|
381
|
-
"dev": "pylon dev -c \\"wrangler dev\\"",
|
|
382
|
-
"cf-typegen": "wrangler types"
|
|
383
|
-
},
|
|
384
|
-
"dependencies": {
|
|
385
|
-
"@getcronit/pylon": "${u}",
|
|
386
|
-
},
|
|
387
|
-
"devDependencies": {
|
|
388
|
-
"@getcronit/pylon-dev": "${g}",
|
|
389
|
-
"@cloudflare/vitest-pool-workers": "^0.4.5",
|
|
390
|
-
"@cloudflare/workers-types": "^4.20240903.0",
|
|
391
|
-
"typescript": "^5.5.2",
|
|
392
|
-
"wrangler": "^3.60.3"
|
|
393
|
-
},
|
|
394
|
-
"repository": {
|
|
395
|
-
"type": "git",
|
|
396
|
-
"url": "https://github.com/getcronit/pylon.git"
|
|
397
|
-
},
|
|
398
|
-
"homepage": "https://pylon.cronit.io"
|
|
399
|
-
}
|
|
400
|
-
`},{path:"wrangler.toml",content:`#:schema node_modules/wrangler/config-schema.json
|
|
401
|
-
name = "__PYLON_NAME__"
|
|
402
|
-
main = ".pylon/index.js"
|
|
403
|
-
compatibility_date = "2024-09-03"
|
|
404
|
-
compatibility_flags = ["nodejs_compat_v2"]
|
|
405
|
-
|
|
406
|
-
# Automatically place your workloads in an optimal location to minimize latency.
|
|
407
|
-
# If you are running back-end logic in a Worker, running it closer to your back-end infrastructure
|
|
408
|
-
# rather than the end user may result in better performance.
|
|
409
|
-
# Docs: https://developers.cloudflare.com/workers/configuration/smart-placement/#smart-placement
|
|
410
|
-
# [placement]
|
|
411
|
-
# mode = "smart"
|
|
412
|
-
|
|
413
|
-
# Variable bindings. These are arbitrary, plaintext strings (similar to environment variables)
|
|
414
|
-
# Docs:
|
|
415
|
-
# - https://developers.cloudflare.com/workers/wrangler/configuration/#environment-variables
|
|
416
|
-
# Note: Use secrets to store sensitive data.
|
|
417
|
-
# - https://developers.cloudflare.com/workers/configuration/secrets/
|
|
418
|
-
# [vars]
|
|
419
|
-
# MY_VARIABLE = "production_value"
|
|
420
|
-
|
|
421
|
-
# Bind the Workers AI model catalog. Run machine learning models, powered by serverless GPUs, on Cloudflare\u2019s global network
|
|
422
|
-
# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#workers-ai
|
|
423
|
-
# [ai]
|
|
424
|
-
# binding = "AI"
|
|
425
|
-
|
|
426
|
-
# Bind an Analytics Engine dataset. Use Analytics Engine to write analytics within your Pages Function.
|
|
427
|
-
# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#analytics-engine-datasets
|
|
428
|
-
# [[analytics_engine_datasets]]
|
|
429
|
-
# binding = "MY_DATASET"
|
|
430
|
-
|
|
431
|
-
# Bind a headless browser instance running on Cloudflare's global network.
|
|
432
|
-
# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#browser-rendering
|
|
433
|
-
# [browser]
|
|
434
|
-
# binding = "MY_BROWSER"
|
|
435
|
-
|
|
436
|
-
# Bind a D1 database. D1 is Cloudflare\u2019s native serverless SQL database.
|
|
437
|
-
# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#d1-databases
|
|
438
|
-
# [[d1_databases]]
|
|
439
|
-
# binding = "MY_DB"
|
|
440
|
-
# database_name = "my-database"
|
|
441
|
-
# database_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
|
|
442
|
-
|
|
443
|
-
# Bind a dispatch namespace. Use Workers for Platforms to deploy serverless functions programmatically on behalf of your customers.
|
|
444
|
-
# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#dispatch-namespace-bindings-workers-for-platforms
|
|
445
|
-
# [[dispatch_namespaces]]
|
|
446
|
-
# binding = "MY_DISPATCHER"
|
|
447
|
-
# namespace = "my-namespace"
|
|
448
|
-
|
|
449
|
-
# Bind a Durable Object. Durable objects are a scale-to-zero compute primitive based on the actor model.
|
|
450
|
-
# Durable Objects can live for as long as needed. Use these when you need a long-running "server", such as in realtime apps.
|
|
451
|
-
# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#durable-objects
|
|
452
|
-
# [[durable_objects.bindings]]
|
|
453
|
-
# name = "MY_DURABLE_OBJECT"
|
|
454
|
-
# class_name = "MyDurableObject"
|
|
455
|
-
|
|
456
|
-
# Durable Object migrations.
|
|
457
|
-
# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#migrations
|
|
458
|
-
# [[migrations]]
|
|
459
|
-
# tag = "v1"
|
|
460
|
-
# new_classes = ["MyDurableObject"]
|
|
461
|
-
|
|
462
|
-
# Bind a Hyperdrive configuration. Use to accelerate access to your existing databases from Cloudflare Workers.
|
|
463
|
-
# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#hyperdrive
|
|
464
|
-
# [[hyperdrive]]
|
|
465
|
-
# binding = "MY_HYPERDRIVE"
|
|
466
|
-
# id = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
|
467
|
-
|
|
468
|
-
# Bind a KV Namespace. Use KV as persistent storage for small key-value pairs.
|
|
469
|
-
# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#kv-namespaces
|
|
470
|
-
# [[kv_namespaces]]
|
|
471
|
-
# binding = "MY_KV_NAMESPACE"
|
|
472
|
-
# id = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
|
473
|
-
|
|
474
|
-
# Bind an mTLS certificate. Use to present a client certificate when communicating with another service.
|
|
475
|
-
# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#mtls-certificates
|
|
476
|
-
# [[mtls_certificates]]
|
|
477
|
-
# binding = "MY_CERTIFICATE"
|
|
478
|
-
# certificate_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
|
|
479
|
-
|
|
480
|
-
# Bind a Queue producer. Use this binding to schedule an arbitrary task that may be processed later by a Queue consumer.
|
|
481
|
-
# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#queues
|
|
482
|
-
# [[queues.producers]]
|
|
483
|
-
# binding = "MY_QUEUE"
|
|
484
|
-
# queue = "my-queue"
|
|
485
|
-
|
|
486
|
-
# Bind a Queue consumer. Queue Consumers can retrieve tasks scheduled by Producers to act on them.
|
|
487
|
-
# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#queues
|
|
488
|
-
# [[queues.consumers]]
|
|
489
|
-
# queue = "my-queue"
|
|
490
|
-
|
|
491
|
-
# Bind an R2 Bucket. Use R2 to store arbitrarily large blobs of data, such as files.
|
|
492
|
-
# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#r2-buckets
|
|
493
|
-
# [[r2_buckets]]
|
|
494
|
-
# binding = "MY_BUCKET"
|
|
495
|
-
# bucket_name = "my-bucket"
|
|
496
|
-
|
|
497
|
-
# Bind another Worker service. Use this binding to call another Worker without network overhead.
|
|
498
|
-
# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#service-bindings
|
|
499
|
-
# [[services]]
|
|
500
|
-
# binding = "MY_SERVICE"
|
|
501
|
-
# service = "my-service"
|
|
502
|
-
|
|
503
|
-
# Bind a Vectorize index. Use to store and query vector embeddings for semantic search, classification and other vector search use-cases.
|
|
504
|
-
# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#vectorize-indexes
|
|
505
|
-
# [[vectorize]]
|
|
506
|
-
# binding = "MY_INDEX"
|
|
507
|
-
# index_name = "my-index"
|
|
508
|
-
`}],deno:[{path:".vscode/settings.json",content:`{
|
|
509
|
-
"deno.enablePaths": [
|
|
510
|
-
"./"
|
|
511
|
-
],
|
|
512
|
-
"editor.inlayHints.enabled": "off"
|
|
513
|
-
}`},{path:".vscode/extensions.json",content:`{
|
|
514
|
-
"recommendations": [
|
|
515
|
-
"denoland.vscode-deno"
|
|
516
|
-
]
|
|
517
|
-
}`},{path:"deno.json",content:`{
|
|
518
|
-
"imports": {
|
|
519
|
-
"@getcronit/pylon-dev": "npm:@getcronit/pylon-dev@${g}",
|
|
520
|
-
"@getcronit/pylon": "npm:@getcronit/pylon@${u}"
|
|
521
|
-
},
|
|
522
|
-
"tasks": {
|
|
523
|
-
"dev": "pylon dev -c \\"deno run -A .pylon/index.js --config tsconfig.json\\"",
|
|
524
|
-
"build": "pylon build"
|
|
525
|
-
},
|
|
526
|
-
"compilerOptions": {
|
|
527
|
-
"jsx": "precompile",
|
|
528
|
-
"jsxImportSource": "hono/jsx"
|
|
529
|
-
},
|
|
530
|
-
"nodeModulesDir": "auto",
|
|
531
|
-
"packageManager": "deno"
|
|
532
|
-
}
|
|
533
|
-
`}]};var m=[{key:"bun",name:"Bun.js",website:"https://bunjs.dev",supportedFeatures:["auth","pages"]},{key:"node",name:"Node.js",website:"https://nodejs.org",supportedFeatures:["auth","pages"]},{key:"cf-workers",name:"Cloudflare Workers",website:"https://workers.cloudflare.com",supportedFeatures:["auth"]},{key:"deno",name:"Deno",website:"https://deno.land"}],v=[{key:"auth",name:"Authentication",website:"https://pylon.cronit.io/docs/authentication"},{key:"pages",name:"Pages",website:"https://pylon.cronit.io/docs/pages"}],A=(e,r)=>{let o=["app","PylonConfig"],t=[];r.includes("auth")&&(o.push("useAuth"),t.push("useAuth({issuer: 'https://test-0o6zvq.zitadel.cloud'})")),r.includes("pages")&&(o.push("usePages"),t.push("usePages()"));let n="";return n+=`import {${o.join(", ")}} from '@getcronit/pylon'
|
|
534
|
-
|
|
535
|
-
`,e==="node"&&(n+=`import {serve} from '@hono/node-server'
|
|
536
|
-
`),n+=`
|
|
537
|
-
|
|
538
|
-
`,n+=`export const graphql = {
|
|
539
|
-
Query: {
|
|
540
|
-
hello: () => {
|
|
541
|
-
return 'Hello, world!'
|
|
542
|
-
}
|
|
543
|
-
},
|
|
544
|
-
Mutation: {}
|
|
545
|
-
}`,n+=`
|
|
546
|
-
|
|
547
|
-
`,e==="bun"||e==="cf-workers"?n+="export default app":e==="node"?n+="serve(app, info => {\n console.log(`Server running at ${info.port}`)\n})":e==="deno"&&(n+=`Deno.serve({port: 3000}, app.fetch)
|
|
548
|
-
`),n+=`
|
|
549
|
-
|
|
550
|
-
`,n+=`export const config: PylonConfig = {
|
|
551
|
-
plugins: [${t.join(", ")}]
|
|
552
|
-
}`,n},M=async(e,r)=>{let o=`import '@getcronit/pylon'
|
|
553
|
-
|
|
554
|
-
declare module '@getcronit/pylon' {
|
|
555
|
-
interface Bindings {}
|
|
556
|
-
|
|
557
|
-
interface Variables {}
|
|
558
|
-
}
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
`;return r.includes("pages")&&(o+=`import {useQuery} from './.pylon/client'
|
|
562
|
-
|
|
563
|
-
declare module '@getcronit/pylon/pages' {
|
|
564
|
-
interface PageData extends ReturnType<typeof useQuery> {}
|
|
565
|
-
}`),o},I=async(e,r)=>{let o={extends:"@getcronit/pylon/tsconfig.pylon.json",include:["pylon.d.ts","src/**/*.ts"]};return e==="cf-workers"&&o.include.push("worker-configuration.d.ts"),r.includes("pages")&&(o.compilerOptions={baseUrl:".",paths:{"@/*":["./*"]},jsx:"react-jsx"},o.include.push("pages","components",".pylon")),JSON.stringify(o,null,2)},S=async e=>{let r=[{path:"pages/layout.tsx",content:`import '../globals.css'
|
|
566
|
-
|
|
567
|
-
export default function RootLayout({children}: {children: React.ReactNode}) {
|
|
568
|
-
return (
|
|
569
|
-
<html lang="en">
|
|
570
|
-
<body>{children}</body>
|
|
571
|
-
</html>
|
|
572
|
-
)
|
|
573
|
-
}
|
|
574
|
-
`},{path:"pages/page.tsx",content:`import { Button } from '@/components/ui/button'
|
|
575
|
-
import { PageProps } from '@getcronit/pylon/pages'
|
|
576
|
-
|
|
577
|
-
const Page: React.FC<PageProps> = props => {
|
|
578
|
-
return (
|
|
579
|
-
<div className="container">
|
|
580
|
-
<title>{props.data.hello}</title>
|
|
581
|
-
<Button>Hello {props.data.hello}</Button>
|
|
582
|
-
</div>
|
|
583
|
-
)
|
|
584
|
-
}
|
|
585
|
-
|
|
586
|
-
export default Page
|
|
587
|
-
`},{path:"globals.css",content:`@import 'tailwindcss';
|
|
588
|
-
|
|
589
|
-
@plugin 'tailwindcss-animate';
|
|
590
|
-
|
|
591
|
-
@custom-variant dark (&:is(.dark *));
|
|
592
|
-
|
|
593
|
-
@theme {
|
|
594
|
-
--color-background: hsl(var(--background));
|
|
595
|
-
--color-foreground: hsl(var(--foreground));
|
|
596
|
-
|
|
597
|
-
--color-card: hsl(var(--card));
|
|
598
|
-
--color-card-foreground: hsl(var(--card-foreground));
|
|
599
|
-
|
|
600
|
-
--color-popover: hsl(var(--popover));
|
|
601
|
-
--color-popover-foreground: hsl(var(--popover-foreground));
|
|
602
|
-
|
|
603
|
-
--color-primary: hsl(var(--primary));
|
|
604
|
-
--color-primary-foreground: hsl(var(--primary-foreground));
|
|
605
|
-
|
|
606
|
-
--color-secondary: hsl(var(--secondary));
|
|
607
|
-
--color-secondary-foreground: hsl(var(--secondary-foreground));
|
|
608
|
-
|
|
609
|
-
--color-muted: hsl(var(--muted));
|
|
610
|
-
--color-muted-foreground: hsl(var(--muted-foreground));
|
|
611
|
-
|
|
612
|
-
--color-accent: hsl(var(--accent));
|
|
613
|
-
--color-accent-foreground: hsl(var(--accent-foreground));
|
|
614
|
-
|
|
615
|
-
--color-destructive: hsl(var(--destructive));
|
|
616
|
-
--color-destructive-foreground: hsl(var(--destructive-foreground));
|
|
617
|
-
|
|
618
|
-
--color-border: hsl(var(--border));
|
|
619
|
-
--color-input: hsl(var(--input));
|
|
620
|
-
--color-ring: hsl(var(--ring));
|
|
621
|
-
|
|
622
|
-
--color-chart-1: hsl(var(--chart-1));
|
|
623
|
-
--color-chart-2: hsl(var(--chart-2));
|
|
624
|
-
--color-chart-3: hsl(var(--chart-3));
|
|
625
|
-
--color-chart-4: hsl(var(--chart-4));
|
|
626
|
-
--color-chart-5: hsl(var(--chart-5));
|
|
627
|
-
|
|
628
|
-
--color-sidebar: hsl(var(--sidebar-background));
|
|
629
|
-
--color-sidebar-foreground: hsl(var(--sidebar-foreground));
|
|
630
|
-
--color-sidebar-primary: hsl(var(--sidebar-primary));
|
|
631
|
-
--color-sidebar-primary-foreground: hsl(var(--sidebar-primary-foreground));
|
|
632
|
-
--color-sidebar-accent: hsl(var(--sidebar-accent));
|
|
633
|
-
--color-sidebar-accent-foreground: hsl(var(--sidebar-accent-foreground));
|
|
634
|
-
--color-sidebar-border: hsl(var(--sidebar-border));
|
|
635
|
-
--color-sidebar-ring: hsl(var(--sidebar-ring));
|
|
636
|
-
|
|
637
|
-
--radius-lg: var(--radius);
|
|
638
|
-
--radius-md: calc(var(--radius) - 2px);
|
|
639
|
-
--radius-sm: calc(var(--radius) - 4px);
|
|
640
|
-
|
|
641
|
-
--animate-accordion-down: accordion-down 0.2s ease-out;
|
|
642
|
-
--animate-accordion-up: accordion-up 0.2s ease-out;
|
|
643
|
-
|
|
644
|
-
@keyframes accordion-down {
|
|
645
|
-
from {
|
|
646
|
-
height: 0;
|
|
647
|
-
}
|
|
648
|
-
to {
|
|
649
|
-
height: var(--radix-accordion-content-height);
|
|
650
|
-
}
|
|
651
|
-
}
|
|
652
|
-
@keyframes accordion-up {
|
|
653
|
-
from {
|
|
654
|
-
height: var(--radix-accordion-content-height);
|
|
655
|
-
}
|
|
656
|
-
to {
|
|
657
|
-
height: 0;
|
|
658
|
-
}
|
|
659
|
-
}
|
|
660
|
-
}
|
|
661
|
-
|
|
662
|
-
/*
|
|
663
|
-
The default border color has changed to \`currentColor\` in Tailwind CSS v4,
|
|
664
|
-
so we've added these compatibility styles to make sure everything still
|
|
665
|
-
looks the same as it did with Tailwind CSS v3.
|
|
666
|
-
|
|
667
|
-
If we ever want to remove these styles, we need to add an explicit border
|
|
668
|
-
color utility to any element that depends on these defaults.
|
|
669
|
-
*/
|
|
670
|
-
@layer base {
|
|
671
|
-
*,
|
|
672
|
-
::after,
|
|
673
|
-
::before,
|
|
674
|
-
::backdrop,
|
|
675
|
-
::file-selector-button {
|
|
676
|
-
border-color: var(--color-gray-200, currentColor);
|
|
677
|
-
}
|
|
678
|
-
}
|
|
679
|
-
|
|
680
|
-
@layer utilities {
|
|
681
|
-
body {
|
|
682
|
-
font-family: Arial, Helvetica, sans-serif;
|
|
683
|
-
}
|
|
684
|
-
}
|
|
685
|
-
|
|
686
|
-
@layer base {
|
|
687
|
-
:root {
|
|
688
|
-
--background: 0 0% 100%;
|
|
689
|
-
--foreground: 0 0% 3.9%;
|
|
690
|
-
--card: 0 0% 100%;
|
|
691
|
-
--card-foreground: 0 0% 3.9%;
|
|
692
|
-
--popover: 0 0% 100%;
|
|
693
|
-
--popover-foreground: 0 0% 3.9%;
|
|
694
|
-
--primary: 0 0% 9%;
|
|
695
|
-
--primary-foreground: 0 0% 98%;
|
|
696
|
-
--secondary: 0 0% 96.1%;
|
|
697
|
-
--secondary-foreground: 0 0% 9%;
|
|
698
|
-
--muted: 0 0% 96.1%;
|
|
699
|
-
--muted-foreground: 0 0% 45.1%;
|
|
700
|
-
--accent: 0 0% 96.1%;
|
|
701
|
-
--accent-foreground: 0 0% 9%;
|
|
702
|
-
--destructive: 0 84.2% 60.2%;
|
|
703
|
-
--destructive-foreground: 0 0% 98%;
|
|
704
|
-
--border: 0 0% 89.8%;
|
|
705
|
-
--input: 0 0% 89.8%;
|
|
706
|
-
--ring: 0 0% 3.9%;
|
|
707
|
-
--chart-1: 12 76% 61%;
|
|
708
|
-
--chart-2: 173 58% 39%;
|
|
709
|
-
--chart-3: 197 37% 24%;
|
|
710
|
-
--chart-4: 43 74% 66%;
|
|
711
|
-
--chart-5: 27 87% 67%;
|
|
712
|
-
--radius: 0.5rem;
|
|
713
|
-
--sidebar-background: 0 0% 98%;
|
|
714
|
-
--sidebar-foreground: 240 5.3% 26.1%;
|
|
715
|
-
--sidebar-primary: 240 5.9% 10%;
|
|
716
|
-
--sidebar-primary-foreground: 0 0% 98%;
|
|
717
|
-
--sidebar-accent: 240 4.8% 95.9%;
|
|
718
|
-
--sidebar-accent-foreground: 240 5.9% 10%;
|
|
719
|
-
--sidebar-border: 220 13% 91%;
|
|
720
|
-
--sidebar-ring: 217.2 91.2% 59.8%;
|
|
721
|
-
}
|
|
722
|
-
.dark {
|
|
723
|
-
--background: 0 0% 3.9%;
|
|
724
|
-
--foreground: 0 0% 98%;
|
|
725
|
-
--card: 0 0% 3.9%;
|
|
726
|
-
--card-foreground: 0 0% 98%;
|
|
727
|
-
--popover: 0 0% 3.9%;
|
|
728
|
-
--popover-foreground: 0 0% 98%;
|
|
729
|
-
--primary: 0 0% 98%;
|
|
730
|
-
--primary-foreground: 0 0% 9%;
|
|
731
|
-
--secondary: 0 0% 14.9%;
|
|
732
|
-
--secondary-foreground: 0 0% 98%;
|
|
733
|
-
--muted: 0 0% 14.9%;
|
|
734
|
-
--muted-foreground: 0 0% 63.9%;
|
|
735
|
-
--accent: 0 0% 14.9%;
|
|
736
|
-
--accent-foreground: 0 0% 98%;
|
|
737
|
-
--destructive: 0 62.8% 30.6%;
|
|
738
|
-
--destructive-foreground: 0 0% 98%;
|
|
739
|
-
--border: 0 0% 14.9%;
|
|
740
|
-
--input: 0 0% 14.9%;
|
|
741
|
-
--ring: 0 0% 83.1%;
|
|
742
|
-
--chart-1: 220 70% 50%;
|
|
743
|
-
--chart-2: 160 60% 45%;
|
|
744
|
-
--chart-3: 30 80% 55%;
|
|
745
|
-
--chart-4: 280 65% 60%;
|
|
746
|
-
--chart-5: 340 75% 55%;
|
|
747
|
-
--sidebar-background: 240 5.9% 10%;
|
|
748
|
-
--sidebar-foreground: 240 4.8% 95.9%;
|
|
749
|
-
--sidebar-primary: 224.3 76.3% 48%;
|
|
750
|
-
--sidebar-primary-foreground: 0 0% 100%;
|
|
751
|
-
--sidebar-accent: 240 3.7% 15.9%;
|
|
752
|
-
--sidebar-accent-foreground: 240 4.8% 95.9%;
|
|
753
|
-
--sidebar-border: 240 3.7% 15.9%;
|
|
754
|
-
--sidebar-ring: 217.2 91.2% 59.8%;
|
|
755
|
-
}
|
|
756
|
-
}
|
|
757
|
-
|
|
758
|
-
@layer base {
|
|
759
|
-
* {
|
|
760
|
-
@apply border-border;
|
|
761
|
-
}
|
|
762
|
-
body {
|
|
763
|
-
@apply bg-background text-foreground;
|
|
764
|
-
}
|
|
765
|
-
}
|
|
766
|
-
|
|
767
|
-
/*
|
|
768
|
-
---break---
|
|
769
|
-
*/
|
|
770
|
-
|
|
771
|
-
@layer base {
|
|
772
|
-
* {
|
|
773
|
-
@apply border-border outline-ring/50;
|
|
774
|
-
}
|
|
775
|
-
body {
|
|
776
|
-
@apply bg-background text-foreground;
|
|
777
|
-
}
|
|
778
|
-
}
|
|
779
|
-
`},{path:"postcss.config.js",content:`import tailwindPostCss from '@tailwindcss/postcss'
|
|
780
|
-
|
|
781
|
-
export default {
|
|
782
|
-
plugins: [tailwindPostCss]
|
|
783
|
-
}
|
|
784
|
-
`},{path:"components.json",content:`{
|
|
785
|
-
"$schema": "https://ui.shadcn.com/schema.json",
|
|
786
|
-
"style": "new-york",
|
|
787
|
-
"rsc": false,
|
|
788
|
-
"tsx": true,
|
|
789
|
-
"tailwind": {
|
|
790
|
-
"config": "tailwind.config.js",
|
|
791
|
-
"css": "globals.css",
|
|
792
|
-
"baseColor": "zinc",
|
|
793
|
-
"cssVariables": true,
|
|
794
|
-
"prefix": ""
|
|
795
|
-
},
|
|
796
|
-
"aliases": {
|
|
797
|
-
"components": "@/components",
|
|
798
|
-
"utils": "@/lib/utils",
|
|
799
|
-
"ui": "@/components/ui",
|
|
800
|
-
"lib": "@/lib",
|
|
801
|
-
"hooks": "@/hooks"
|
|
802
|
-
},
|
|
803
|
-
"iconLibrary": "lucide"
|
|
804
|
-
}`},{path:"lib/utils.ts",content:`import {clsx, type ClassValue} from 'clsx'
|
|
805
|
-
import {twMerge} from 'tailwind-merge'
|
|
806
|
-
|
|
807
|
-
export function cn(...inputs: ClassValue[]) {
|
|
808
|
-
return twMerge(clsx(inputs))
|
|
809
|
-
}`},{path:"components/ui/button.tsx",content:`import * as React from 'react'
|
|
810
|
-
import {Slot} from '@radix-ui/react-slot'
|
|
811
|
-
import {cva, type VariantProps} from 'class-variance-authority'
|
|
812
|
-
|
|
813
|
-
import {cn} from '@/lib/utils'
|
|
814
|
-
|
|
815
|
-
const buttonVariants = cva(
|
|
816
|
-
"inline-flexxx items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-[color,box-shadow] disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 [&_svg]:shrink-0 ring-ring/10 dark:ring-ring/20 dark:outline-ring/40 outline-ring/50 focus-visible:ring-4 focus-visible:outline-1 aria-invalid:focus-visible:ring-0",
|
|
817
|
-
{
|
|
818
|
-
variants: {
|
|
819
|
-
variant: {
|
|
820
|
-
default:
|
|
821
|
-
'bg-primary text-primary-foreground shadow-sm hover:bg-primary/90',
|
|
822
|
-
destructive:
|
|
823
|
-
'bg-destructive text-destructive-foreground shadow-xs hover:bg-destructive/90',
|
|
824
|
-
outline:
|
|
825
|
-
'border border-input bg-background shadow-xs hover:bg-accent hover:text-accent-foreground',
|
|
826
|
-
secondary:
|
|
827
|
-
'bg-secondary text-secondary-foreground shadow-xs hover:bg-secondary/80',
|
|
828
|
-
ghost: 'hover:bg-accent hover:text-accent-foreground',
|
|
829
|
-
link: 'text-primary underline-offset-4 hover:underline'
|
|
830
|
-
},
|
|
831
|
-
size: {
|
|
832
|
-
default: 'h-9 px-4 py-2 has-[>svg]:px-3',
|
|
833
|
-
sm: 'h-8 rounded-md px-3 has-[>svg]:px-2.5',
|
|
834
|
-
lg: 'h-10 rounded-md px-6 has-[>svg]:px-4',
|
|
835
|
-
icon: 'size-9'
|
|
836
|
-
}
|
|
837
|
-
},
|
|
838
|
-
defaultVariants: {
|
|
839
|
-
variant: 'default',
|
|
840
|
-
size: 'default'
|
|
841
|
-
}
|
|
842
|
-
}
|
|
843
|
-
)
|
|
844
|
-
|
|
845
|
-
function Button({
|
|
846
|
-
className,
|
|
847
|
-
variant,
|
|
848
|
-
size,
|
|
849
|
-
asChild = false,
|
|
850
|
-
...props
|
|
851
|
-
}: React.ComponentProps<'button'> &
|
|
852
|
-
VariantProps<typeof buttonVariants> & {
|
|
853
|
-
asChild?: boolean
|
|
854
|
-
}) {
|
|
855
|
-
const Comp = asChild ? Slot : 'button'
|
|
856
|
-
|
|
857
|
-
return (
|
|
858
|
-
<Comp
|
|
859
|
-
data-slot="button"
|
|
860
|
-
className={cn(buttonVariants({variant, size, className}))}
|
|
861
|
-
{...props}
|
|
862
|
-
/>
|
|
863
|
-
)
|
|
864
|
-
}
|
|
865
|
-
|
|
866
|
-
export {Button, buttonVariants}
|
|
867
|
-
`}];e.push(...r);let o=e.find(t=>t.path==="package.json");if(o){let t=JSON.parse(o.content);t.dependencies={...t.dependencies,"@gqty/react":"^3.1.0",gqty:"^3.4.0","@radix-ui/react-slot":"^1.1.2","class-variance-authority":"^0.7.1",clsx:"^2.1.1","lucide-react":"^0.474.0",react:"^19.0.0","react-dom":"^19.0.0","tailwind-merge":"^3.0.1",tailwindcss:"^4.0.4","tailwindcss-animate":"^1.0.7"},t.devDependencies={...t.devDependencies,"@tailwindcss/postcss":"^4.0.6","@types/react":"^19.0.8"},o.content=JSON.stringify(t,null,2)}return e},$=(e,r)=>{let o=e;return Object.entries(r).forEach(([t,n])=>{o=o.replaceAll(t,n)}),o},j=async e=>{let{destination:r,runtime:o,features:t}=e,n=b.ALL.concat(b[o]||[]).filter(l=>l.specificRuntimes?l.specificRuntimes.includes(o):!0),k=A(o,t),d=await I(o,t),p=await M(o,t);n.push({path:"tsconfig.json",content:d},{path:"pylon.d.ts",content:p},{path:"src/index.ts",content:k}),t.includes("pages")&&(n=await S(n));for(let l of n){let a=_.join(r,l.path);await w.mkdir(_.dirname(a),{recursive:!0}),await w.writeFile(a,$(l.content,e.variables))}};import B from"node:process";import{detect as L}from"package-manager-detector/detect";import U from"consola";async function f(e=B.cwd()){return(await L({cwd:e,onUnknown(o){U.warn("Unknown packageManager:",o)}}))?.agent||null}function E(e){if(e===null)return null;let[r]=e.split("@");switch(r){case"bun":return"bun";case"npm":return"npm run";case"yarn":return"yarn";case"pnpm":return"pnpm run";case"deno":return"deno task";default:return null}}import{existsSync as Y}from"node:fs";import{resolve as V}from"node:path";import F from"node:process";import{x as T}from"tinyexec";async function P(e,r={}){let o=r.packageManager||await f(r.cwd)||"npm",[t]=o.split("@");Array.isArray(e)||(e=[e]);let n=(typeof r.additionalArgs=="function"?r.additionalArgs(t,o):r.additionalArgs)||[];return r.preferOffline&&(o==="yarn@berry"?n.unshift("--cached"):n.unshift("--prefer-offline")),t==="pnpm"&&Y(V(r.cwd??F.cwd(),"pnpm-workspace.yaml"))&&n.unshift("-w","--prod=false"),T(t,[t==="yarn"?"add":"install",r.dev?"-D":"",...n,...e].filter(Boolean),{nodeOptions:{stdio:r.silent?"ignore":"inherit",cwd:r.cwd},throwOnError:!0})}import{PostHog as G}from"posthog-node";import z from"conf";import{readFileSync as q}from"fs";import{randomUUID as O}from"crypto";var J={distinctId:{type:"string",default:O()}},W=new z({projectName:"pylon",schema:J}),R=W.get("distinctId"),xe=O(),x=new G("phc_KN4qCOcCdkXp6sHLIuMWGRfzZWuNht69oqv5Kw5rGxj",{host:"https://eu.i.posthog.com",disabled:process.env.PYLON_DISABLE_TELEMETRY==="true"}),H=()=>{let e;try{e=JSON.parse(q("./package.json","utf8"))}catch{e={}}let r=e.dependencies||{},o=e.devDependencies||{},t=e.peerDependencies||{};return{dependencies:r,devDependencies:o,peerDependencies:t}},ke=H();var C="1.1.5-canary-20250812173555.281a13c7bdcad57f6a055166537c2e9a10703656";D.name("create-pylon").version(C).arguments("[target]").addOption(new h("-i, --install","Install dependencies")).addOption(new h("-r, --runtime <runtime>","Runtime").choices(m.map(({key:e})=>e))).addOption(new h("--features [features...]","Features").choices(v.map(({key:e})=>e))).addOption(new h("-pm, --package-manager <packageManager>","Package manager")).action(Q);async function Q(e,r,o){c.log(`${o.name()} version ${o.version()}`);try{e||(e=await c.prompt("Where should the project be created?",{default:"./my-pylon",placeholder:"./my-pylon",cancel:"reject"}));let t="";if(e==="."?t=N.basename(process.cwd()):t=N.basename(e),!r.runtime){let a=await c.prompt("Select a runtime environment:",{type:"select",options:m.map(s=>({label:s.name,value:s.key,hint:s.website})),cancel:"reject"});r.runtime=a}let n=m.find(a=>a.key===r.runtime);if(!n)throw new Error(`Invalid runtime selected: ${r.runtime}`);if(!r.features){let a=await c.prompt("Configure features:",{type:"multiselect",options:v.filter(s=>n.supportedFeatures?.includes(s.key)).map(s=>({label:s.name,value:s.key,hint:s.website})),required:!1,cancel:"reject"});r.features=a}for(let a of r.features)if(!n.supportedFeatures?.includes(a))throw new Error(`Invalid feature selected: ${a}`);if(!await c.prompt(`Ready to create the project in ${i.blue(e)}?`,{type:"confirm",initial:!0,cancel:"reject"})){let a=new Error("Prompt cancelled.");throw a.name="ConsolaPromptCancelledError",a}if(y.existsSync(e)&&y.readdirSync(e).length>0&&!await c.prompt("Directory not empty. Continue?",{type:"confirm",cancel:"reject"})){let s=new Error("Prompt cancelled.");throw s.name="ConsolaPromptCancelledError",s}await j({variables:{__PYLON_NAME__:t},runtime:n.key,features:r.features,destination:e});let d=r.packageManager||await f(e)||"npm";r.install===void 0&&(r.install=await c.prompt(`Installed dependencies with ${d} now? You can also do this later.`,{type:"confirm",initial:!0,cancel:"reject"})),r.install&&await P([]),x.capture({distinctId:R,event:"create-pylon",properties:{runtime:n.key,features:r.features,packageManager:d,install:r.install}});let p=E(d),l=`
|
|
868
|
-
\u{1F389} ${i.green.bold("Pylon created successfully.")}
|
|
869
|
-
|
|
870
|
-
\u{1F4BB} ${i.cyan.bold("Continue Developing")}
|
|
871
|
-
${i.yellow("Change directories:")} cd ${i.blue(e)}
|
|
872
|
-
${i.yellow("Start dev server:")} ${p} dev
|
|
873
|
-
${n.key==="cf-workers"?`${i.yellow("Deploy:")} ${p} deploy`:""}
|
|
874
|
-
|
|
875
|
-
\u{1F4D6} ${i.cyan.bold("Explore Documentation")}
|
|
876
|
-
${i.underline.blue("https://pylon.cronit.io/docs")}
|
|
877
|
-
|
|
878
|
-
\u{1F4AC} ${i.cyan.bold("Join our Community")}
|
|
879
|
-
${i.underline.blue("https://discord.gg/cbJjkVrnHe")}
|
|
880
|
-
`;c.box(l)}catch(t){c.error(t)}finally{await x.shutdown()}}D.parse();
|
|
13
|
+
\u{1F4AC} ${m.cyan.bold("Join our Community")}
|
|
14
|
+
${m.underline.blue("https://discord.gg/cbJjkVrnHe")}
|
|
15
|
+
`;await L.sendCreateEvent({name:d,pylonCreateVersion:U,runtime:s,template:g,clientPath:C||void 0,clientPort:parseInt(O)||void 0}),u.box(H)}catch(i){u.error(i)}}J.parse();
|
|
881
16
|
//# sourceMappingURL=index.js.map
|