create-trokky 0.1.1
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/LICENSE +21 -0
- package/README.md +138 -0
- package/dist/cli.d.ts +8 -0
- package/dist/cli.js +95 -0
- package/dist/config.d.ts +24 -0
- package/dist/config.js +29 -0
- package/dist/emit.d.ts +21 -0
- package/dist/emit.js +489 -0
- package/dist/files-node.d.ts +8 -0
- package/dist/files-node.js +37 -0
- package/dist/files.d.ts +25 -0
- package/dist/files.js +48 -0
- package/dist/generate.d.ts +9 -0
- package/dist/generate.js +131 -0
- package/dist/generated/files-binary.d.ts +7 -0
- package/dist/generated/files-binary.js +7 -0
- package/dist/generated/files-text.d.ts +6 -0
- package/dist/generated/files-text.js +6 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +6 -0
- package/dist/manifest.d.ts +89 -0
- package/dist/manifest.js +24 -0
- package/dist/node.d.ts +6 -0
- package/dist/node.js +6 -0
- package/dist/validate.d.ts +51 -0
- package/dist/validate.js +97 -0
- package/dist/write.d.ts +5 -0
- package/dist/write.js +15 -0
- package/files/base/gitignore +7 -0
- package/files/content/magazine/public/seed/README.txt +4 -0
- package/files/content/magazine/public/seed/annual-report-2026.pdf +0 -0
- package/files/content/magazine/public/seed/avatar-1.jpg +0 -0
- package/files/content/magazine/public/seed/avatar-2.jpg +0 -0
- package/files/content/magazine/public/seed/avatar-3.jpg +0 -0
- package/files/content/magazine/public/seed/cover-1.jpg +0 -0
- package/files/content/magazine/public/seed/cover-2.jpg +0 -0
- package/files/content/magazine/public/seed/cover-3.jpg +0 -0
- package/files/content/magazine/public/seed/cover-4.jpg +0 -0
- package/files/content/magazine/public/seed/cover-5.jpg +0 -0
- package/files/content/magazine/public/seed/cover-6.jpg +0 -0
- package/files/content/magazine/public/seed/editorial-guidelines.pdf +0 -0
- package/files/content/magazine/src/trokky/schemas.ts +116 -0
- package/files/content/magazine/src/trokky/seed.ts +143 -0
- package/files/content/magazine/src/trokky/structure.ts +19 -0
- package/files/site/magazine/src/layouts/Base.astro +55 -0
- package/files/site/magazine/src/pages/[slug].astro +11 -0
- package/files/site/magazine/src/pages/articles/[slug].astro +30 -0
- package/files/site/magazine/src/pages/articles/index.astro +21 -0
- package/files/site/magazine/src/pages/authors/[slug].astro +19 -0
- package/files/site/magazine/src/pages/categories/[slug].astro +19 -0
- package/files/site/magazine/src/pages/documents.astro +19 -0
- package/files/site/magazine/src/pages/index.astro +35 -0
- package/files/site/magazine/src/trokky/site.ts +81 -0
- package/files/workers/scripts/copy-studio.mjs +28 -0
- package/manifest.json +330 -0
- package/package.json +62 -0
package/manifest.json
ADDED
|
@@ -0,0 +1,330 @@
|
|
|
1
|
+
{
|
|
2
|
+
"manifestVersion": 2,
|
|
3
|
+
"groups": [
|
|
4
|
+
{
|
|
5
|
+
"id": "runtime",
|
|
6
|
+
"title": "Runtime",
|
|
7
|
+
"hint": "Where the thing runs. This one decides most of the rest."
|
|
8
|
+
},
|
|
9
|
+
{
|
|
10
|
+
"id": "storage",
|
|
11
|
+
"title": "Storage",
|
|
12
|
+
"hint": "Where content, uploads and thumbnails live."
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
"id": "stack",
|
|
16
|
+
"title": "Stack",
|
|
17
|
+
"hint": "How much of Trokky you want, and what is in it on day one."
|
|
18
|
+
}
|
|
19
|
+
],
|
|
20
|
+
"axes": [
|
|
21
|
+
{
|
|
22
|
+
"id": "target",
|
|
23
|
+
"group": "runtime",
|
|
24
|
+
"title": "Where will it run?",
|
|
25
|
+
"options": [
|
|
26
|
+
{
|
|
27
|
+
"id": "workers",
|
|
28
|
+
"title": "Cloudflare Workers",
|
|
29
|
+
"hint": "No server, no disk. D1 + R2."
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
"id": "node",
|
|
33
|
+
"title": "Node / Express",
|
|
34
|
+
"hint": "A server you run: VPS, Docker, Railway."
|
|
35
|
+
}
|
|
36
|
+
]
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
"id": "data",
|
|
40
|
+
"group": "storage",
|
|
41
|
+
"title": "Where does content live?",
|
|
42
|
+
"options": [
|
|
43
|
+
{
|
|
44
|
+
"id": "filesystem-data",
|
|
45
|
+
"title": "JSON files on disk",
|
|
46
|
+
"hint": "Readable, diffable, committable."
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
"id": "postgres-data",
|
|
50
|
+
"title": "PostgreSQL",
|
|
51
|
+
"hint": "For more than one editor."
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
"id": "cloudflare-d1",
|
|
55
|
+
"title": "Cloudflare D1",
|
|
56
|
+
"hint": "SQLite at the edge."
|
|
57
|
+
}
|
|
58
|
+
]
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
"id": "media",
|
|
62
|
+
"group": "storage",
|
|
63
|
+
"title": "Where do uploads live?",
|
|
64
|
+
"options": [
|
|
65
|
+
{
|
|
66
|
+
"id": "filesystem-media",
|
|
67
|
+
"title": "Files on disk",
|
|
68
|
+
"hint": "Needs a path that survives a restart."
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
"id": "cloudflare-r2",
|
|
72
|
+
"title": "Cloudflare R2",
|
|
73
|
+
"hint": "Object storage, no disk."
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
"id": "s3-media",
|
|
77
|
+
"title": "S3-compatible storage",
|
|
78
|
+
"hint": "R2, MinIO, S3, Backblaze. Credentials, not a binding."
|
|
79
|
+
}
|
|
80
|
+
]
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
"id": "images",
|
|
84
|
+
"group": "storage",
|
|
85
|
+
"title": "How are thumbnails made?",
|
|
86
|
+
"options": [
|
|
87
|
+
{
|
|
88
|
+
"id": "sharp",
|
|
89
|
+
"title": "sharp",
|
|
90
|
+
"hint": "Local processing. Node only."
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
"id": "cloudflare-images",
|
|
94
|
+
"title": "Cloudflare Images",
|
|
95
|
+
"hint": "At upload, through the binding."
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
"id": "none",
|
|
99
|
+
"title": "None",
|
|
100
|
+
"hint": "Store originals only."
|
|
101
|
+
}
|
|
102
|
+
]
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
"id": "parts",
|
|
106
|
+
"group": "stack",
|
|
107
|
+
"title": "What do you want?",
|
|
108
|
+
"options": [
|
|
109
|
+
{
|
|
110
|
+
"id": "api",
|
|
111
|
+
"title": "API only",
|
|
112
|
+
"hint": "Headless. Bring your own frontend."
|
|
113
|
+
},
|
|
114
|
+
{
|
|
115
|
+
"id": "studio",
|
|
116
|
+
"title": "API + Studio",
|
|
117
|
+
"hint": "The admin UI, for editors."
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
"id": "full-site",
|
|
121
|
+
"title": "API + Studio + a site",
|
|
122
|
+
"hint": "An Astro frontend as well."
|
|
123
|
+
}
|
|
124
|
+
]
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
"id": "content",
|
|
128
|
+
"group": "stack",
|
|
129
|
+
"title": "Start with content?",
|
|
130
|
+
"options": [
|
|
131
|
+
{
|
|
132
|
+
"id": "blank",
|
|
133
|
+
"title": "Blank",
|
|
134
|
+
"hint": "No schemas. Write your own."
|
|
135
|
+
},
|
|
136
|
+
{
|
|
137
|
+
"id": "magazine",
|
|
138
|
+
"title": "Magazine",
|
|
139
|
+
"hint": "Articles, authors, categories, documents, pages."
|
|
140
|
+
}
|
|
141
|
+
]
|
|
142
|
+
}
|
|
143
|
+
],
|
|
144
|
+
"constraints": [
|
|
145
|
+
{
|
|
146
|
+
"id": "workers-data",
|
|
147
|
+
"when": {
|
|
148
|
+
"target": "workers"
|
|
149
|
+
},
|
|
150
|
+
"allow": {
|
|
151
|
+
"data": [
|
|
152
|
+
"cloudflare-d1"
|
|
153
|
+
]
|
|
154
|
+
},
|
|
155
|
+
"because": "A Worker has no disk, and the Postgres adapter needs a TCP client. D1 is the data store at the edge."
|
|
156
|
+
},
|
|
157
|
+
{
|
|
158
|
+
"id": "workers-media",
|
|
159
|
+
"when": {
|
|
160
|
+
"target": "workers"
|
|
161
|
+
},
|
|
162
|
+
"allow": {
|
|
163
|
+
"media": [
|
|
164
|
+
"cloudflare-r2"
|
|
165
|
+
]
|
|
166
|
+
},
|
|
167
|
+
"because": "A Worker has no disk. R2 is the media adapter that needs none, and inside a Worker its binding beats the S3 API: no credentials to hold."
|
|
168
|
+
},
|
|
169
|
+
{
|
|
170
|
+
"id": "workers-images",
|
|
171
|
+
"when": {
|
|
172
|
+
"target": "workers"
|
|
173
|
+
},
|
|
174
|
+
"allow": {
|
|
175
|
+
"images": [
|
|
176
|
+
"cloudflare-images",
|
|
177
|
+
"none"
|
|
178
|
+
]
|
|
179
|
+
},
|
|
180
|
+
"because": "sharp is a native libvips binding and Workers runs no native code."
|
|
181
|
+
},
|
|
182
|
+
{
|
|
183
|
+
"id": "node-data",
|
|
184
|
+
"when": {
|
|
185
|
+
"target": "node"
|
|
186
|
+
},
|
|
187
|
+
"allow": {
|
|
188
|
+
"data": [
|
|
189
|
+
"filesystem-data",
|
|
190
|
+
"postgres-data"
|
|
191
|
+
]
|
|
192
|
+
},
|
|
193
|
+
"because": "D1 arrives as a Worker binding; there is nothing for a Node process to connect to."
|
|
194
|
+
},
|
|
195
|
+
{
|
|
196
|
+
"id": "node-media",
|
|
197
|
+
"when": {
|
|
198
|
+
"target": "node"
|
|
199
|
+
},
|
|
200
|
+
"allow": {
|
|
201
|
+
"media": [
|
|
202
|
+
"filesystem-media",
|
|
203
|
+
"s3-media"
|
|
204
|
+
]
|
|
205
|
+
},
|
|
206
|
+
"because": "R2 arrives as a Worker binding, so a Node process reaches it over the S3 API instead \u2014 which also reaches MinIO, Backblaze and S3."
|
|
207
|
+
},
|
|
208
|
+
{
|
|
209
|
+
"id": "node-images",
|
|
210
|
+
"when": {
|
|
211
|
+
"target": "node"
|
|
212
|
+
},
|
|
213
|
+
"allow": {
|
|
214
|
+
"images": [
|
|
215
|
+
"sharp",
|
|
216
|
+
"none"
|
|
217
|
+
]
|
|
218
|
+
},
|
|
219
|
+
"because": "The Cloudflare Images binding only exists inside a Worker."
|
|
220
|
+
},
|
|
221
|
+
{
|
|
222
|
+
"id": "content-needs-schemas",
|
|
223
|
+
"when": {
|
|
224
|
+
"parts": "full-site"
|
|
225
|
+
},
|
|
226
|
+
"allow": {
|
|
227
|
+
"content": [
|
|
228
|
+
"magazine"
|
|
229
|
+
]
|
|
230
|
+
},
|
|
231
|
+
"because": "A site needs something to render. Choose the magazine content model, or drop the frontend."
|
|
232
|
+
}
|
|
233
|
+
],
|
|
234
|
+
"defaults": {
|
|
235
|
+
"workers": {
|
|
236
|
+
"data": "cloudflare-d1",
|
|
237
|
+
"media": "cloudflare-r2",
|
|
238
|
+
"images": "cloudflare-images",
|
|
239
|
+
"parts": "full-site",
|
|
240
|
+
"content": "magazine"
|
|
241
|
+
},
|
|
242
|
+
"node": {
|
|
243
|
+
"data": "filesystem-data",
|
|
244
|
+
"media": "filesystem-media",
|
|
245
|
+
"images": "sharp",
|
|
246
|
+
"parts": "studio",
|
|
247
|
+
"content": "magazine"
|
|
248
|
+
}
|
|
249
|
+
},
|
|
250
|
+
"secrets": [
|
|
251
|
+
{
|
|
252
|
+
"when": {
|
|
253
|
+
"target": "workers"
|
|
254
|
+
},
|
|
255
|
+
"secrets": [
|
|
256
|
+
{
|
|
257
|
+
"name": "TROKKY_JWT_SECRET",
|
|
258
|
+
"generate": "hex32",
|
|
259
|
+
"why": "Signs sessions and tokens. Must stay the same across deploys, or every login is invalidated."
|
|
260
|
+
},
|
|
261
|
+
{
|
|
262
|
+
"name": "TROKKY_CLAIM_SECRET",
|
|
263
|
+
"generate": "hex24",
|
|
264
|
+
"why": "Lets the first person to open Studio claim the instance as its administrator. A one-time token you type once, not a password to remember. Without it the claim is open to whoever reaches the URL first."
|
|
265
|
+
}
|
|
266
|
+
]
|
|
267
|
+
},
|
|
268
|
+
{
|
|
269
|
+
"when": {
|
|
270
|
+
"target": "node"
|
|
271
|
+
},
|
|
272
|
+
"secrets": [
|
|
273
|
+
{
|
|
274
|
+
"name": "TROKKY_JWT_SECRET",
|
|
275
|
+
"generate": "hex32",
|
|
276
|
+
"why": "Signs sessions and tokens. Must stay the same across restarts, or every login is invalidated."
|
|
277
|
+
},
|
|
278
|
+
{
|
|
279
|
+
"name": "TROKKY_CLAIM_SECRET",
|
|
280
|
+
"generate": "hex24",
|
|
281
|
+
"why": "Lets the first person to open Studio claim the instance as its administrator. A one-time token you type once, not a password to remember. Without it the claim is open to whoever reaches the URL first."
|
|
282
|
+
}
|
|
283
|
+
]
|
|
284
|
+
},
|
|
285
|
+
{
|
|
286
|
+
"when": {
|
|
287
|
+
"media": "s3-media"
|
|
288
|
+
},
|
|
289
|
+
"secrets": [
|
|
290
|
+
{
|
|
291
|
+
"name": "S3_ENDPOINT",
|
|
292
|
+
"why": "The bucket service endpoint, e.g. https://<account>.r2.cloudflarestorage.com"
|
|
293
|
+
},
|
|
294
|
+
{
|
|
295
|
+
"name": "S3_BUCKET",
|
|
296
|
+
"why": "The bucket name. Create it before the first upload."
|
|
297
|
+
},
|
|
298
|
+
{
|
|
299
|
+
"name": "S3_ACCESS_KEY_ID",
|
|
300
|
+
"why": "An access key with read and write on that bucket."
|
|
301
|
+
},
|
|
302
|
+
{
|
|
303
|
+
"name": "S3_SECRET_ACCESS_KEY",
|
|
304
|
+
"why": "Its secret. Never commit this."
|
|
305
|
+
},
|
|
306
|
+
{
|
|
307
|
+
"name": "S3_REGION",
|
|
308
|
+
"why": "Optional. SigV4 signs over a region whether or not the backend has one; defaults to 'auto', which is what R2 wants.",
|
|
309
|
+
"optional": true
|
|
310
|
+
}
|
|
311
|
+
]
|
|
312
|
+
}
|
|
313
|
+
],
|
|
314
|
+
"templates": [
|
|
315
|
+
{
|
|
316
|
+
"id": "magazine",
|
|
317
|
+
"title": "The magazine template",
|
|
318
|
+
"repo": "https://github.com/Trokky/trokky-template",
|
|
319
|
+
"deployButton": "https://deploy.workers.cloudflare.com/?url=https://github.com/Trokky/trokky-template",
|
|
320
|
+
"composition": {
|
|
321
|
+
"target": "workers",
|
|
322
|
+
"data": "cloudflare-d1",
|
|
323
|
+
"media": "cloudflare-r2",
|
|
324
|
+
"images": "cloudflare-images",
|
|
325
|
+
"parts": "full-site",
|
|
326
|
+
"content": "magazine"
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
]
|
|
330
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "create-trokky",
|
|
3
|
+
"version": "0.1.1",
|
|
4
|
+
"description": "Compose a Trokky project: pick the target, adapters and parts you want.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "git+https://github.com/Trokky/generator.git"
|
|
10
|
+
},
|
|
11
|
+
"bin": {
|
|
12
|
+
"create-trokky": "./dist/cli.js"
|
|
13
|
+
},
|
|
14
|
+
"exports": {
|
|
15
|
+
".": {
|
|
16
|
+
"types": "./dist/index.d.ts",
|
|
17
|
+
"import": "./dist/index.js"
|
|
18
|
+
},
|
|
19
|
+
"./manifest.json": "./manifest.json",
|
|
20
|
+
"./node": {
|
|
21
|
+
"types": "./dist/node.d.ts",
|
|
22
|
+
"import": "./dist/node.js"
|
|
23
|
+
},
|
|
24
|
+
"./generated/files-text": {
|
|
25
|
+
"types": "./dist/generated/files-text.d.ts",
|
|
26
|
+
"import": "./dist/generated/files-text.js"
|
|
27
|
+
},
|
|
28
|
+
"./generated/files-binary": {
|
|
29
|
+
"types": "./dist/generated/files-binary.d.ts",
|
|
30
|
+
"import": "./dist/generated/files-binary.js"
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
"files": [
|
|
34
|
+
"dist",
|
|
35
|
+
"files",
|
|
36
|
+
"manifest.json"
|
|
37
|
+
],
|
|
38
|
+
"engines": {
|
|
39
|
+
"node": ">=20"
|
|
40
|
+
},
|
|
41
|
+
"scripts": {
|
|
42
|
+
"prepare": "npm run build",
|
|
43
|
+
"build": "node scripts/inline-files.mjs && tsc -p tsconfig.json",
|
|
44
|
+
"test": "vitest run",
|
|
45
|
+
"check": "tsc -p tsconfig.json --noEmit",
|
|
46
|
+
"smoke": "node scripts/smoke.mjs",
|
|
47
|
+
"inline": "node scripts/inline-files.mjs"
|
|
48
|
+
},
|
|
49
|
+
"devDependencies": {
|
|
50
|
+
"@types/node": "^22.0.0",
|
|
51
|
+
"aws4fetch": "^1.0.20",
|
|
52
|
+
"typescript": "^5.6.0",
|
|
53
|
+
"vitest": "^3.2.4"
|
|
54
|
+
},
|
|
55
|
+
"keywords": [
|
|
56
|
+
"trokky",
|
|
57
|
+
"cms",
|
|
58
|
+
"scaffold",
|
|
59
|
+
"generator",
|
|
60
|
+
"cloudflare-workers"
|
|
61
|
+
]
|
|
62
|
+
}
|