create-bcp-app 0.1.3 → 0.1.4
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/README.md +16 -3
- package/package.json +3 -3
- package/src/project-options.mjs +237 -27
package/README.md
CHANGED
|
@@ -27,9 +27,22 @@ Select a database:
|
|
|
27
27
|
When Tailwind is enabled, the project includes:
|
|
28
28
|
|
|
29
29
|
- `tailwindcss`
|
|
30
|
-
- `@tailwindcss/
|
|
31
|
-
- `
|
|
30
|
+
- `@tailwindcss/cli`
|
|
31
|
+
- `concurrently`
|
|
32
32
|
- `app/globals.css`
|
|
33
|
+
- `app/api/bcp-styles/route.ts`
|
|
34
|
+
- a stylesheet link in `app/layout.tsx`
|
|
35
|
+
- starter Tailwind utility classes in `app/page.tsx`
|
|
36
|
+
|
|
37
|
+
The generated npm scripts compile Tailwind before starting BCP and keep Tailwind running in watch mode during development:
|
|
38
|
+
|
|
39
|
+
```text
|
|
40
|
+
npm run css:build
|
|
41
|
+
npm run css:watch
|
|
42
|
+
npm run css:build:prod
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
`npm run dev` performs an initial CSS build, then runs the Tailwind watcher and `bcp dev` together. `npm run build` creates a minified stylesheet before the BCP production build.
|
|
33
46
|
|
|
34
47
|
### Database
|
|
35
48
|
|
|
@@ -66,5 +79,5 @@ npx create-bcp-app my-app --yes
|
|
|
66
79
|
The `--bcp` option is primarily useful for prerelease and local package testing, for example:
|
|
67
80
|
|
|
68
81
|
```bash
|
|
69
|
-
npx create-bcp-app my-app --bcp file:../bcp-0.1.
|
|
82
|
+
npx create-bcp-app my-app --bcp file:../bcp-0.1.4.tgz
|
|
70
83
|
```
|
package/package.json
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-bcp-app",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.4",
|
|
4
4
|
"description": "Create a new BCP Framework application.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
7
|
+
"bcpFrameworkPackage": "@chidchanun/bcp",
|
|
7
8
|
"bin": {
|
|
8
9
|
"create-bcp-app": "bin/create-bcp-app.mjs"
|
|
9
10
|
},
|
|
@@ -24,6 +25,5 @@
|
|
|
24
25
|
},
|
|
25
26
|
"publishConfig": {
|
|
26
27
|
"access": "public"
|
|
27
|
-
}
|
|
28
|
-
"bcpFrameworkPackage": "@chidchanun/bcp"
|
|
28
|
+
}
|
|
29
29
|
}
|
package/src/project-options.mjs
CHANGED
|
@@ -176,34 +176,9 @@ export function applyProjectOptions({
|
|
|
176
176
|
);
|
|
177
177
|
|
|
178
178
|
if (tailwind) {
|
|
179
|
-
|
|
180
|
-
...packageJson.devDependencies,
|
|
181
|
-
tailwindcss:
|
|
182
|
-
"^4.3.3",
|
|
183
|
-
"@tailwindcss/postcss":
|
|
184
|
-
"^4.3.3",
|
|
185
|
-
};
|
|
186
|
-
|
|
187
|
-
writeFile(
|
|
179
|
+
configureTailwind(
|
|
188
180
|
targetDirectory,
|
|
189
|
-
|
|
190
|
-
`export default {
|
|
191
|
-
plugins: {
|
|
192
|
-
"@tailwindcss/postcss": {},
|
|
193
|
-
},
|
|
194
|
-
};
|
|
195
|
-
`
|
|
196
|
-
);
|
|
197
|
-
|
|
198
|
-
writeFile(
|
|
199
|
-
targetDirectory,
|
|
200
|
-
"app/globals.css",
|
|
201
|
-
`@import "tailwindcss";
|
|
202
|
-
|
|
203
|
-
@theme {
|
|
204
|
-
--font-sans: Inter, ui-sans-serif, system-ui, sans-serif;
|
|
205
|
-
}
|
|
206
|
-
`
|
|
181
|
+
packageJson
|
|
207
182
|
);
|
|
208
183
|
}
|
|
209
184
|
|
|
@@ -245,6 +220,241 @@ export function applyProjectOptions({
|
|
|
245
220
|
};
|
|
246
221
|
}
|
|
247
222
|
|
|
223
|
+
function configureTailwind(
|
|
224
|
+
targetDirectory,
|
|
225
|
+
packageJson
|
|
226
|
+
) {
|
|
227
|
+
packageJson.devDependencies = {
|
|
228
|
+
...packageJson.devDependencies,
|
|
229
|
+
tailwindcss:
|
|
230
|
+
"^4.3.3",
|
|
231
|
+
"@tailwindcss/cli":
|
|
232
|
+
"^4.3.3",
|
|
233
|
+
concurrently:
|
|
234
|
+
"^10.0.5",
|
|
235
|
+
};
|
|
236
|
+
|
|
237
|
+
packageJson.scripts = {
|
|
238
|
+
...packageJson.scripts,
|
|
239
|
+
dev:
|
|
240
|
+
"npm run css:build && concurrently -k -n tailwind,bcp \"npm run css:watch\" \"bcp dev\"",
|
|
241
|
+
build:
|
|
242
|
+
"npm run css:build:prod && bcp build",
|
|
243
|
+
"css:build":
|
|
244
|
+
"tailwindcss -i ./app/globals.css -o ./public/bcp.css",
|
|
245
|
+
"css:watch":
|
|
246
|
+
"tailwindcss -i ./app/globals.css -o ./public/bcp.css --watch",
|
|
247
|
+
"css:build:prod":
|
|
248
|
+
"tailwindcss -i ./app/globals.css -o ./public/bcp.css --minify",
|
|
249
|
+
};
|
|
250
|
+
|
|
251
|
+
writeFile(
|
|
252
|
+
targetDirectory,
|
|
253
|
+
"app/globals.css",
|
|
254
|
+
`@import "tailwindcss" source("../");
|
|
255
|
+
|
|
256
|
+
@theme {
|
|
257
|
+
--font-sans: Inter, ui-sans-serif, system-ui, sans-serif;
|
|
258
|
+
}
|
|
259
|
+
`
|
|
260
|
+
);
|
|
261
|
+
|
|
262
|
+
writeFile(
|
|
263
|
+
targetDirectory,
|
|
264
|
+
"app/api/bcp-styles/route.ts",
|
|
265
|
+
`import fs from "node:fs/promises";
|
|
266
|
+
import path from "node:path";
|
|
267
|
+
|
|
268
|
+
export async function GET() {
|
|
269
|
+
const stylesheet =
|
|
270
|
+
path.join(
|
|
271
|
+
process.cwd(),
|
|
272
|
+
"public",
|
|
273
|
+
"bcp.css"
|
|
274
|
+
);
|
|
275
|
+
|
|
276
|
+
try {
|
|
277
|
+
const css =
|
|
278
|
+
await fs.readFile(
|
|
279
|
+
stylesheet,
|
|
280
|
+
"utf8"
|
|
281
|
+
);
|
|
282
|
+
|
|
283
|
+
return new Response(
|
|
284
|
+
css,
|
|
285
|
+
{
|
|
286
|
+
headers: {
|
|
287
|
+
"Content-Type":
|
|
288
|
+
"text/css; charset=utf-8",
|
|
289
|
+
"Cache-Control":
|
|
290
|
+
"no-store, max-age=0",
|
|
291
|
+
},
|
|
292
|
+
}
|
|
293
|
+
);
|
|
294
|
+
} catch {
|
|
295
|
+
return new Response(
|
|
296
|
+
"/* BCP Tailwind stylesheet has not been built yet. */",
|
|
297
|
+
{
|
|
298
|
+
status: 503,
|
|
299
|
+
headers: {
|
|
300
|
+
"Content-Type":
|
|
301
|
+
"text/css; charset=utf-8",
|
|
302
|
+
"Cache-Control":
|
|
303
|
+
"no-store, max-age=0",
|
|
304
|
+
},
|
|
305
|
+
}
|
|
306
|
+
);
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
`
|
|
310
|
+
);
|
|
311
|
+
|
|
312
|
+
fs.mkdirSync(
|
|
313
|
+
path.join(
|
|
314
|
+
targetDirectory,
|
|
315
|
+
"public"
|
|
316
|
+
),
|
|
317
|
+
{
|
|
318
|
+
recursive: true,
|
|
319
|
+
}
|
|
320
|
+
);
|
|
321
|
+
|
|
322
|
+
injectTailwindStylesheet(
|
|
323
|
+
targetDirectory
|
|
324
|
+
);
|
|
325
|
+
applyTailwindStarterStyles(
|
|
326
|
+
targetDirectory
|
|
327
|
+
);
|
|
328
|
+
appendGitIgnore(
|
|
329
|
+
targetDirectory,
|
|
330
|
+
"public/bcp.css"
|
|
331
|
+
);
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
function injectTailwindStylesheet(
|
|
335
|
+
targetDirectory
|
|
336
|
+
) {
|
|
337
|
+
const layoutFile =
|
|
338
|
+
path.join(
|
|
339
|
+
targetDirectory,
|
|
340
|
+
"app",
|
|
341
|
+
"layout.tsx"
|
|
342
|
+
);
|
|
343
|
+
const source =
|
|
344
|
+
fs.readFileSync(
|
|
345
|
+
layoutFile,
|
|
346
|
+
"utf8"
|
|
347
|
+
);
|
|
348
|
+
const rootPattern =
|
|
349
|
+
/^([ \t]*)<div>[ \t]*(\r?\n)/m;
|
|
350
|
+
const match =
|
|
351
|
+
rootPattern.exec(
|
|
352
|
+
source
|
|
353
|
+
);
|
|
354
|
+
|
|
355
|
+
if (!match) {
|
|
356
|
+
throw new Error(
|
|
357
|
+
"BCP create-app could not attach the Tailwind stylesheet to app/layout.tsx."
|
|
358
|
+
);
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
const indent =
|
|
362
|
+
match[1];
|
|
363
|
+
const newline =
|
|
364
|
+
match[2];
|
|
365
|
+
const childIndent =
|
|
366
|
+
`${indent} `;
|
|
367
|
+
const propertyIndent =
|
|
368
|
+
`${childIndent} `;
|
|
369
|
+
const replacement =
|
|
370
|
+
`${indent}<div>${newline}` +
|
|
371
|
+
`${childIndent}<link${newline}` +
|
|
372
|
+
`${propertyIndent}rel="stylesheet"${newline}` +
|
|
373
|
+
`${propertyIndent}href="/api/bcp-styles"${newline}` +
|
|
374
|
+
`${childIndent}/>${newline}`;
|
|
375
|
+
|
|
376
|
+
fs.writeFileSync(
|
|
377
|
+
layoutFile,
|
|
378
|
+
source.replace(
|
|
379
|
+
rootPattern,
|
|
380
|
+
replacement
|
|
381
|
+
),
|
|
382
|
+
"utf8"
|
|
383
|
+
);
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
function applyTailwindStarterStyles(
|
|
387
|
+
targetDirectory
|
|
388
|
+
) {
|
|
389
|
+
const pageFile =
|
|
390
|
+
path.join(
|
|
391
|
+
targetDirectory,
|
|
392
|
+
"app",
|
|
393
|
+
"page.tsx"
|
|
394
|
+
);
|
|
395
|
+
let source =
|
|
396
|
+
fs.readFileSync(
|
|
397
|
+
pageFile,
|
|
398
|
+
"utf8"
|
|
399
|
+
);
|
|
400
|
+
|
|
401
|
+
source =
|
|
402
|
+
source.replace(
|
|
403
|
+
" <section>",
|
|
404
|
+
" <section className=\"mx-auto max-w-3xl space-y-6 px-6 py-16\">"
|
|
405
|
+
);
|
|
406
|
+
source =
|
|
407
|
+
source.replace(
|
|
408
|
+
" <h1>",
|
|
409
|
+
" <h1 className=\"text-4xl font-bold tracking-tight text-slate-900\">"
|
|
410
|
+
);
|
|
411
|
+
source =
|
|
412
|
+
source.replace(
|
|
413
|
+
" <p>",
|
|
414
|
+
" <p className=\"text-lg text-slate-600\">"
|
|
415
|
+
);
|
|
416
|
+
|
|
417
|
+
fs.writeFileSync(
|
|
418
|
+
pageFile,
|
|
419
|
+
source,
|
|
420
|
+
"utf8"
|
|
421
|
+
);
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
function appendGitIgnore(
|
|
425
|
+
targetDirectory,
|
|
426
|
+
entry
|
|
427
|
+
) {
|
|
428
|
+
const filePath =
|
|
429
|
+
path.join(
|
|
430
|
+
targetDirectory,
|
|
431
|
+
".gitignore"
|
|
432
|
+
);
|
|
433
|
+
const current =
|
|
434
|
+
fs.existsSync(
|
|
435
|
+
filePath
|
|
436
|
+
)
|
|
437
|
+
? fs.readFileSync(
|
|
438
|
+
filePath,
|
|
439
|
+
"utf8"
|
|
440
|
+
).trimEnd()
|
|
441
|
+
: "";
|
|
442
|
+
const lines =
|
|
443
|
+
new Set(
|
|
444
|
+
current
|
|
445
|
+
.split(/\r?\n/)
|
|
446
|
+
.filter(Boolean)
|
|
447
|
+
);
|
|
448
|
+
|
|
449
|
+
lines.add(entry);
|
|
450
|
+
|
|
451
|
+
fs.writeFileSync(
|
|
452
|
+
filePath,
|
|
453
|
+
`${Array.from(lines).join("\n")}\n`,
|
|
454
|
+
"utf8"
|
|
455
|
+
);
|
|
456
|
+
}
|
|
457
|
+
|
|
248
458
|
function appendEnvExample(
|
|
249
459
|
targetDirectory,
|
|
250
460
|
lines
|