create-disposabl-app 0.1.3 → 0.2.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.
- package/dist/index.js +43 -9
- package/dist/templates/default/.github/workflows/pipeline.yml +100 -0
- package/dist/templates/default/bun.lock +767 -38
- package/dist/templates/default/packages/backend/package.json +1 -0
- package/dist/templates/default/packages/disposabl-kit/server/dev-setup.mjs +39 -0
- package/dist/templates/default/turbo.json +9 -1
- package/package.json +51 -3
package/dist/index.js
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
// index.ts
|
|
4
|
-
import { spawn, spawnSync } from "node:child_process";
|
|
5
|
-
import {
|
|
4
|
+
import { execFileSync, spawn, spawnSync } from "node:child_process";
|
|
5
|
+
import { lstatSync } from "node:fs";
|
|
6
6
|
import { resolve } from "node:path";
|
|
7
7
|
import { fileURLToPath } from "node:url";
|
|
8
8
|
import { Command, CommanderError } from "commander";
|
|
9
9
|
import * as p2 from "@clack/prompts";
|
|
10
10
|
// package.json
|
|
11
|
-
var version = "0.
|
|
11
|
+
var version = "0.2.0";
|
|
12
12
|
|
|
13
13
|
// options.ts
|
|
14
14
|
var platforms = [
|
|
@@ -302,7 +302,7 @@ import {
|
|
|
302
302
|
} from "node:fs/promises";
|
|
303
303
|
import { existsSync } from "node:fs";
|
|
304
304
|
import { join } from "node:path";
|
|
305
|
-
async function
|
|
305
|
+
async function createApp(template, destination, name, config, overwrite = false) {
|
|
306
306
|
config = {
|
|
307
307
|
...config,
|
|
308
308
|
features: selectFeatures(config.features.join(",") || "none")
|
|
@@ -313,6 +313,8 @@ async function createProject(template, destination, name, config) {
|
|
|
313
313
|
throw new Error("The bundled starter is missing " + folder + "/package.json. Rebuild the CLI.");
|
|
314
314
|
}
|
|
315
315
|
}
|
|
316
|
+
if (overwrite)
|
|
317
|
+
await rm(destination, { recursive: true, force: true });
|
|
316
318
|
await mkdir(destination);
|
|
317
319
|
try {
|
|
318
320
|
for (const entry of await readdir(template)) {
|
|
@@ -373,6 +375,7 @@ The starter includes web and backend authentication code. No appId or Convex dep
|
|
|
373
375
|
|
|
374
376
|
class Cancelled extends Error {
|
|
375
377
|
}
|
|
378
|
+
var pathExists = (path) => lstatSync(path, { throwIfNoEntry: false }) !== undefined;
|
|
376
379
|
function answer(value) {
|
|
377
380
|
if (p2.isCancel(value))
|
|
378
381
|
throw new Cancelled("Cancelled. No files were created.");
|
|
@@ -450,7 +453,7 @@ async function main() {
|
|
|
450
453
|
message: "App name",
|
|
451
454
|
placeholder: "my-app",
|
|
452
455
|
defaultValue: "my-app",
|
|
453
|
-
validate: (value) => validateName(value ?? "")
|
|
456
|
+
validate: (value) => validateName(value ?? "")
|
|
454
457
|
}));
|
|
455
458
|
}
|
|
456
459
|
if (!name)
|
|
@@ -458,9 +461,25 @@ async function main() {
|
|
|
458
461
|
const invalidName = validateName(name);
|
|
459
462
|
if (invalidName)
|
|
460
463
|
throw new Error(invalidName);
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
+
let directory = resolve(name);
|
|
465
|
+
let overwrite = false;
|
|
466
|
+
if (pathExists(directory)) {
|
|
467
|
+
overwrite = interactive && answer(await p2.confirm({
|
|
468
|
+
message: `"${name}" already exists. Delete its contents and replace it?`,
|
|
469
|
+
initialValue: false
|
|
470
|
+
}));
|
|
471
|
+
if (!overwrite) {
|
|
472
|
+
const requestedName = name;
|
|
473
|
+
let suffix = 2;
|
|
474
|
+
do {
|
|
475
|
+
const ending = `-${suffix++}`;
|
|
476
|
+
name = requestedName.slice(0, 214 - ending.length) + ending;
|
|
477
|
+
directory = resolve(name);
|
|
478
|
+
} while (pathExists(directory));
|
|
479
|
+
if (!options.json)
|
|
480
|
+
p2.log.info(`Using "${name}" instead.`);
|
|
481
|
+
}
|
|
482
|
+
}
|
|
464
483
|
if (interactive && options.platforms === undefined) {
|
|
465
484
|
const selected = answer(await createPlatformPrompt().prompt() ?? []);
|
|
466
485
|
chosenPlatforms = selectPlatforms(selected.length ? selected.join(",") : "web");
|
|
@@ -485,10 +504,12 @@ async function main() {
|
|
|
485
504
|
const setup = options.json ? undefined : projectSetup(name, config);
|
|
486
505
|
let installationStarted = false;
|
|
487
506
|
try {
|
|
507
|
+
if (spawnSync("git", ["--version"], { stdio: "ignore" }).status !== 0)
|
|
508
|
+
throw new Error("Install Git first to create the app's initial commit.");
|
|
488
509
|
if (!options.skipInstall && spawnSync("bun", ["--version"], { stdio: "ignore" }).status !== 0)
|
|
489
510
|
throw new Error("Install Bun first, or pass --skip-install to create the files only.");
|
|
490
511
|
const template = fileURLToPath(new URL("./templates/default", import.meta.url));
|
|
491
|
-
await
|
|
512
|
+
await createApp(template, directory, name, config, overwrite);
|
|
492
513
|
if (!options.skipInstall) {
|
|
493
514
|
installationStarted = true;
|
|
494
515
|
setup?.installing();
|
|
@@ -503,6 +524,19 @@ async function main() {
|
|
|
503
524
|
});
|
|
504
525
|
throw error;
|
|
505
526
|
}
|
|
527
|
+
const git = (...args) => execFileSync("git", args, { cwd: directory, stdio: "pipe" });
|
|
528
|
+
git("init", "--initial-branch=main");
|
|
529
|
+
git("add", "--all");
|
|
530
|
+
const hasIdentity = spawnSync("git", ["var", "GIT_AUTHOR_IDENT"], {
|
|
531
|
+
cwd: directory,
|
|
532
|
+
stdio: "ignore"
|
|
533
|
+
}).status === 0;
|
|
534
|
+
git(...hasIdentity ? [] : [
|
|
535
|
+
"-c",
|
|
536
|
+
"user.name=create-disposabl-app",
|
|
537
|
+
"-c",
|
|
538
|
+
"user.email=create-disposabl-app@users.noreply.github.com"
|
|
539
|
+
], "-c", "commit.gpgsign=false", "commit", "-m", "Initial commit");
|
|
506
540
|
const folders = selectedFolders(config);
|
|
507
541
|
if (options.json) {
|
|
508
542
|
console.log(JSON.stringify({
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
name: CI and deploy
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
pull_request:
|
|
5
|
+
branches: [main]
|
|
6
|
+
types: [opened, synchronize, reopened]
|
|
7
|
+
push:
|
|
8
|
+
branches: [main]
|
|
9
|
+
|
|
10
|
+
permissions:
|
|
11
|
+
contents: read
|
|
12
|
+
|
|
13
|
+
concurrency:
|
|
14
|
+
group: ${{ github.workflow }}-${{ github.head_ref || github.ref_name }}
|
|
15
|
+
cancel-in-progress: false
|
|
16
|
+
|
|
17
|
+
jobs:
|
|
18
|
+
pipeline:
|
|
19
|
+
if: github.event.deleted != true && github.repository != 'disposabl-dev/create-disposabl-app'
|
|
20
|
+
runs-on: ubuntu-latest
|
|
21
|
+
timeout-minutes: 30
|
|
22
|
+
steps:
|
|
23
|
+
- name: Check out repository
|
|
24
|
+
uses: actions/checkout@v6
|
|
25
|
+
with:
|
|
26
|
+
persist-credentials: false
|
|
27
|
+
|
|
28
|
+
- name: Install Node.js
|
|
29
|
+
uses: actions/setup-node@v6
|
|
30
|
+
with:
|
|
31
|
+
node-version: "24"
|
|
32
|
+
package-manager-cache: false
|
|
33
|
+
|
|
34
|
+
- name: Install Bun
|
|
35
|
+
uses: oven-sh/setup-bun@v2
|
|
36
|
+
with:
|
|
37
|
+
bun-version: "1.4.4"
|
|
38
|
+
|
|
39
|
+
- name: Install dependencies
|
|
40
|
+
run: bun install --frozen-lockfile
|
|
41
|
+
|
|
42
|
+
- name: Typecheck
|
|
43
|
+
run: bun run typecheck
|
|
44
|
+
|
|
45
|
+
- name: Lint
|
|
46
|
+
run: bun run lint
|
|
47
|
+
|
|
48
|
+
- name: Check formatting
|
|
49
|
+
run: bun fmt --check
|
|
50
|
+
|
|
51
|
+
- name: Test
|
|
52
|
+
# The starter currently has no tests. Run any tests added later.
|
|
53
|
+
run: bun test --pass-with-no-tests
|
|
54
|
+
|
|
55
|
+
- name: Build
|
|
56
|
+
env:
|
|
57
|
+
VITE_CONVEX_URL: https://ci.invalid
|
|
58
|
+
VITE_CONVEX_SITE_URL: https://ci.invalid
|
|
59
|
+
run: bun run build
|
|
60
|
+
|
|
61
|
+
- name: Deploy production
|
|
62
|
+
id: production
|
|
63
|
+
if: github.event_name == 'push'
|
|
64
|
+
working-directory: packages/backend
|
|
65
|
+
env:
|
|
66
|
+
CONVEX_DEPLOY_KEY: ${{ secrets.CONVEX_DEPLOY_KEY }}
|
|
67
|
+
run: |
|
|
68
|
+
bun x --no-install convex deploy --yes \
|
|
69
|
+
--cmd-url-env-var-name VITE_CONVEX_URL \
|
|
70
|
+
--cmd '
|
|
71
|
+
bun x --no-install --package @convex-dev/auth auth --keys-only --prod &&
|
|
72
|
+
VITE_CONVEX_SITE_URL="$CONVEX_SITE_URL" bun run --cwd ../.. build &&
|
|
73
|
+
echo "url=$CONVEX_SITE_URL" >> "$GITHUB_OUTPUT"
|
|
74
|
+
'
|
|
75
|
+
bun x --no-install static-hosting upload --prod --no-spa --dist ../../apps/web/dist/client
|
|
76
|
+
|
|
77
|
+
- name: Deploy preview
|
|
78
|
+
id: preview
|
|
79
|
+
if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository
|
|
80
|
+
working-directory: packages/backend
|
|
81
|
+
env:
|
|
82
|
+
CONVEX_DEPLOY_KEY: ${{ secrets.CONVEX_DEPLOY_KEY_PREVIEW }}
|
|
83
|
+
PREVIEW_NAME: ${{ github.head_ref }}
|
|
84
|
+
run: |
|
|
85
|
+
bun x --no-install convex deploy --yes --preview-name "$PREVIEW_NAME" \
|
|
86
|
+
--cmd-url-env-var-name VITE_CONVEX_URL \
|
|
87
|
+
--cmd '
|
|
88
|
+
bun x --no-install --package @convex-dev/auth auth --keys-only --preview-name "$PREVIEW_NAME" &&
|
|
89
|
+
VITE_CONVEX_SITE_URL="$CONVEX_SITE_URL" bun run --cwd ../.. build &&
|
|
90
|
+
echo "url=$CONVEX_SITE_URL" >> "$GITHUB_OUTPUT"
|
|
91
|
+
'
|
|
92
|
+
bun x --no-install static-hosting upload --preview-name "$PREVIEW_NAME" --no-spa --dist ../../apps/web/dist/client
|
|
93
|
+
|
|
94
|
+
- name: Show deployment URL
|
|
95
|
+
if: steps.production.outcome == 'success' || steps.preview.outcome == 'success'
|
|
96
|
+
env:
|
|
97
|
+
DEPLOYMENT_URL: ${{ steps.production.outputs.url || steps.preview.outputs.url }}
|
|
98
|
+
run: |
|
|
99
|
+
printf 'Deployed app: %s\n' "$DEPLOYMENT_URL"
|
|
100
|
+
printf '### Deployment\n\n[Open app](%s)\n' "$DEPLOYMENT_URL" >> "$GITHUB_STEP_SUMMARY"
|