create-kontrolia-auth 2.1.0 → 2.2.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/README.md +6 -4
- package/dist/index.js +28 -0
- package/dist/steps/application.d.ts.map +1 -1
- package/dist/steps/application.js +1 -8
- package/dist/steps/database.d.ts.map +1 -1
- package/dist/steps/database.js +1 -8
- package/dist/steps/deployment.d.ts.map +1 -1
- package/dist/steps/deployment.js +60 -22
- package/dist/utils/prompts.d.ts +3 -0
- package/dist/utils/prompts.d.ts.map +1 -0
- package/dist/utils/prompts.js +10 -0
- package/dist/utils/vercel-api.d.ts +21 -0
- package/dist/utils/vercel-api.d.ts.map +1 -1
- package/dist/utils/vercel-api.js +45 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -22,10 +22,11 @@ Eso hace, en orden:
|
|
|
22
22
|
4. **Primera aplicación** (opcional): registra tu app y su catálogo de permisos.
|
|
23
23
|
5. **Despliegue**: genera los `.env.local` de `auth-server` y `admin-panel`. Si
|
|
24
24
|
eliges Vercel y el repo ya está en GitHub, puede **crear los dos proyectos
|
|
25
|
-
por ti** vía la API de Vercel (carpeta y variables de
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
25
|
+
y desplegarlos por ti** vía la API de Vercel (carpeta y variables de
|
|
26
|
+
entorno correctas, y el primer build disparado automáticamente — sin
|
|
27
|
+
tocar el dashboard ni la CLI de Vercel) — solo pide un API token de
|
|
28
|
+
vercel.com/account/tokens (el instalador explica cómo generarlo). Para
|
|
29
|
+
Docker, Railway, Render o Coolify te da los pasos exactos.
|
|
29
30
|
|
|
30
31
|
Si ya estás **dentro del repo** (desarrollo), el instalador lo detecta y se
|
|
31
32
|
salta la descarga:
|
|
@@ -40,6 +41,7 @@ pnpm --filter create-kontrolia-auth dev
|
|
|
40
41
|
| ------------------------------------- | ----------------------------------------------------------------------------- |
|
|
41
42
|
| `npx create-kontrolia-auth [carpeta]` | Instalación completa (el flujo de arriba). |
|
|
42
43
|
| `npx create-kontrolia-auth update` | Descarga el código nuevo (`git pull`) sobre una copia ya instalada, instala dependencias, y aplica las migraciones nuevas. |
|
|
44
|
+
| `npx create-kontrolia-auth deploy` | Va directo al paso de despliegue (URLs, cliente OAuth, `.env.local`, creación automática en Vercel) sin repetir las preguntas de base de datos ni de aplicación — para cuando ya tienes todo corriendo y solo quieres (re)conectar auth-server o admin-panel a un nuevo destino. |
|
|
43
45
|
| `npx create-kontrolia-auth migrate` | Aplica/re-aplica las migraciones contra una base existente. |
|
|
44
46
|
| `npx create-kontrolia-auth doctor` | Solo revisa que tengas Node, pnpm, git y Docker. |
|
|
45
47
|
|
package/dist/index.js
CHANGED
|
@@ -6,6 +6,7 @@ import { askDatabaseStep } from "./steps/database.js";
|
|
|
6
6
|
import { askDeploymentStep } from "./steps/deployment.js";
|
|
7
7
|
import { bringUpAndMigrate } from "./utils/docker.js";
|
|
8
8
|
import { runPreflight } from "./utils/preflight.js";
|
|
9
|
+
import { textOrExit } from "./utils/prompts.js";
|
|
9
10
|
import { ensureRepo, isInsideRepo } from "./utils/scaffold.js";
|
|
10
11
|
import { pullLatest } from "./utils/update.js";
|
|
11
12
|
/** Applies the schema against an already-reachable database, with a spinner. */
|
|
@@ -86,6 +87,31 @@ async function runUpdateCommand() {
|
|
|
86
87
|
? "Listo. Si despliegas con Docker: `docker compose -f docker/docker-compose.yml up -d --build`. Si usas Vercel/Railway/Render/Coolify, vuelve a desplegar (push a tu rama, o su CLI) para que tomen el código nuevo."
|
|
87
88
|
: "El código ya está actualizado, pero revisa el error de las migraciones antes de redesplegar.");
|
|
88
89
|
}
|
|
90
|
+
/**
|
|
91
|
+
* `create-kontrolia-auth deploy` — jumps straight to the deployment step
|
|
92
|
+
* (URLs, OAuth client, .env.local generation, and the Vercel auto-create
|
|
93
|
+
* offer) without repeating the database/application questions. For anyone
|
|
94
|
+
* who already has everything running and just wants to (re)connect a
|
|
95
|
+
* deploy target — e.g. adding admin-panel after auth-server was already
|
|
96
|
+
* deployed. Doesn't persist Supabase credentials anywhere between runs, so
|
|
97
|
+
* it still has to ask for them once here.
|
|
98
|
+
*/
|
|
99
|
+
async function runDeployCommand() {
|
|
100
|
+
console.clear();
|
|
101
|
+
p.intro("KontrolIA Auth — desplegar auth-server / admin-panel");
|
|
102
|
+
if (!isInsideRepo(process.cwd())) {
|
|
103
|
+
p.log.error("Corre esto dentro de la carpeta donde instalaste KontrolIA Auth (la que tiene docker/docker-compose.yml).");
|
|
104
|
+
p.outro("Nada que hacer aquí.");
|
|
105
|
+
process.exitCode = 1;
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
const supabaseUrl = await textOrExit("URL de tu proyecto Supabase", "https://tu-proyecto.supabase.co");
|
|
109
|
+
const anonKey = await textOrExit("Anon/public key");
|
|
110
|
+
const serviceRoleKey = await textOrExit("Service role key (server-only, nunca la expongas al navegador)");
|
|
111
|
+
const db = { mode: "existing", databaseUrl: "", supabaseUrl, anonKey, serviceRoleKey };
|
|
112
|
+
await askDeploymentStep(process.cwd(), db);
|
|
113
|
+
p.outro("Listo.");
|
|
114
|
+
}
|
|
89
115
|
/** Default flow: preflight → (scaffold if outside repo) → DB → migrate → app → deploy. */
|
|
90
116
|
async function runInstall(targetDirArg) {
|
|
91
117
|
console.clear();
|
|
@@ -145,6 +171,8 @@ async function main() {
|
|
|
145
171
|
return runDoctor();
|
|
146
172
|
if (first === "update")
|
|
147
173
|
return runUpdateCommand();
|
|
174
|
+
if (first === "deploy")
|
|
175
|
+
return runDeployCommand();
|
|
148
176
|
// `create <dir>` / `install <dir>` / `<dir>` / (nothing) all reach install.
|
|
149
177
|
const dir = first === "create" || first === "install" ? args[1] : first;
|
|
150
178
|
return runInstall(dir);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"application.d.ts","sourceRoot":"","sources":["../../src/steps/application.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"application.d.ts","sourceRoot":"","sources":["../../src/steps/application.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAYpD;;;;;;GAMG;AACH,wBAAsB,kBAAkB,CAAC,EAAE,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAgG1E"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import * as p from "@clack/prompts";
|
|
2
2
|
import { registerApplication } from "@kontrolia/db";
|
|
3
|
+
import { textOrExit } from "../utils/prompts.js";
|
|
3
4
|
function slugify(name) {
|
|
4
5
|
return name
|
|
5
6
|
.trim()
|
|
@@ -95,11 +96,3 @@ export async function askApplicationStep(db) {
|
|
|
95
96
|
}
|
|
96
97
|
p.note("Para habilitarla en una organización, entra a admin-panel → \"Aplicaciones\" — cualquier owner/admin puede activarla ahí con un clic.", "Siguiente paso");
|
|
97
98
|
}
|
|
98
|
-
async function textOrExit(message, placeholder) {
|
|
99
|
-
const value = await p.text({ message, placeholder });
|
|
100
|
-
if (p.isCancel(value)) {
|
|
101
|
-
p.cancel("Instalación cancelada.");
|
|
102
|
-
process.exit(0);
|
|
103
|
-
}
|
|
104
|
-
return value;
|
|
105
|
-
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"database.d.ts","sourceRoot":"","sources":["../../src/steps/database.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"database.d.ts","sourceRoot":"","sources":["../../src/steps/database.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,UAAU,GAAG,iBAAiB,CAAC;IACrC,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,EAAE,MAAM,CAAC;CACxB;AAED;;;GAGG;AACH,wBAAsB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC,CAmE/E"}
|
package/dist/steps/database.js
CHANGED
|
@@ -2,6 +2,7 @@ import * as p from "@clack/prompts";
|
|
|
2
2
|
import { generateJwtSecret } from "../utils/secrets.js";
|
|
3
3
|
import { generateSupabaseKeys } from "../utils/supabase-keys.js";
|
|
4
4
|
import { writeEnvFile } from "../utils/files.js";
|
|
5
|
+
import { textOrExit } from "../utils/prompts.js";
|
|
5
6
|
/**
|
|
6
7
|
* Question A from the architecture plan: where does Postgres + GoTrue come
|
|
7
8
|
* from? Two fully independent paths — neither assumes Docker.
|
|
@@ -60,11 +61,3 @@ export async function askDatabaseStep(repoRoot) {
|
|
|
60
61
|
serviceRoleKey,
|
|
61
62
|
};
|
|
62
63
|
}
|
|
63
|
-
async function textOrExit(message, placeholder) {
|
|
64
|
-
const value = await p.text({ message, placeholder });
|
|
65
|
-
if (p.isCancel(value)) {
|
|
66
|
-
p.cancel("Instalación cancelada.");
|
|
67
|
-
process.exit(0);
|
|
68
|
-
}
|
|
69
|
-
return value;
|
|
70
|
-
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"deployment.d.ts","sourceRoot":"","sources":["../../src/steps/deployment.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"deployment.d.ts","sourceRoot":"","sources":["../../src/steps/deployment.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AA8JpD;;;;GAIG;AACH,wBAAsB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAwI3F"}
|
package/dist/steps/deployment.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as p from "@clack/prompts";
|
|
2
2
|
import { updateEnvValue, writeEnvFile } from "../utils/files.js";
|
|
3
3
|
import { registerOAuthClient } from "../utils/oauth-client.js";
|
|
4
|
-
import { createVercelProject, detectGitHubRepo } from "../utils/vercel-api.js";
|
|
4
|
+
import { createVercelProject, detectCurrentBranch, detectGitHubRepo, triggerVercelDeployment } from "../utils/vercel-api.js";
|
|
5
5
|
const NEXT_STEPS = {
|
|
6
6
|
docker: "Ya está: los servicios auth-server y admin-panel viven en el mismo docker/docker-compose.yml. Corre `docker compose -f docker/docker-compose.yml up -d` para tenerlos arriba.",
|
|
7
7
|
vercel: "Lo más confiable con un monorepo pnpm es conectar el repo desde el dashboard (no desplegar carpetas sueltas por CLI):\n" +
|
|
@@ -28,12 +28,48 @@ const NEXT_STEPS = {
|
|
|
28
28
|
manual: "Corre `pnpm build && pnpm start` en apps/auth-server y apps/admin-panel en el servidor/K8s de tu elección, usando los .env.local generados.",
|
|
29
29
|
};
|
|
30
30
|
/**
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
31
|
+
* Creates one Vercel project and immediately triggers its first deployment
|
|
32
|
+
* — creating the project alone only connects the GitHub repo, it doesn't
|
|
33
|
+
* build or deploy anything by itself, so skipping this step would leave the
|
|
34
|
+
* user with a project that just sits there until something else (a push, or
|
|
35
|
+
* clicking "Deploy" by hand) triggers a build. Reports both outcomes
|
|
36
|
+
* separately since either can fail independently of the other.
|
|
37
|
+
*/
|
|
38
|
+
async function createAndDeployVercelProject(options) {
|
|
39
|
+
const createSpinner = p.spinner();
|
|
40
|
+
createSpinner.start(`Creando proyecto de Vercel para ${options.appLabel}`);
|
|
41
|
+
const created = await createVercelProject({
|
|
42
|
+
token: options.token,
|
|
43
|
+
repo: options.repo,
|
|
44
|
+
name: options.projectName,
|
|
45
|
+
rootDirectory: options.rootDirectory,
|
|
46
|
+
env: options.env,
|
|
47
|
+
});
|
|
48
|
+
createSpinner.stop(created.ok ? `Proyecto ${options.appLabel} creado` : `Falló creando ${options.appLabel}: ${created.error}`);
|
|
49
|
+
if (!created.ok)
|
|
50
|
+
return false;
|
|
51
|
+
const deploySpinner = p.spinner();
|
|
52
|
+
deploySpinner.start(`Desplegando ${options.appLabel} (primer build)`);
|
|
53
|
+
const deployed = await triggerVercelDeployment({
|
|
54
|
+
token: options.token,
|
|
55
|
+
repo: options.repo,
|
|
56
|
+
branch: options.branch,
|
|
57
|
+
projectName: options.projectName,
|
|
58
|
+
});
|
|
59
|
+
deploySpinner.stop(deployed.ok
|
|
60
|
+
? `${options.appLabel} desplegándose — sigue el progreso en vercel.com/dashboard`
|
|
61
|
+
: `Proyecto creado, pero no se pudo disparar el despliegue: ${deployed.error} — dale "Deploy" a mano en el dashboard.`);
|
|
62
|
+
return true;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Offers to create both Vercel projects (and deploy them) via the REST API
|
|
66
|
+
* instead of walking the user through the dashboard/CLI by hand — the same
|
|
67
|
+
* fields that are easy to get wrong doing this manually (gitRepository,
|
|
68
|
+
* rootDirectory, environmentVariables) are just fields in two request
|
|
69
|
+
* bodies here. Returns true if both projects were at least created, so the
|
|
70
|
+
* caller knows whether to still show the manual fallback instructions (a
|
|
71
|
+
* project that was created but failed to deploy still doesn't need those —
|
|
72
|
+
* the user just clicks "Deploy" once in the dashboard).
|
|
37
73
|
*/
|
|
38
74
|
async function tryAutoCreateVercelProjects(repoRoot, authServerEnv, adminPanelEnv) {
|
|
39
75
|
const repo = await detectGitHubRepo(repoRoot);
|
|
@@ -44,41 +80,43 @@ async function tryAutoCreateVercelProjects(repoRoot, authServerEnv, adminPanelEn
|
|
|
44
80
|
return false;
|
|
45
81
|
}
|
|
46
82
|
const auto = await p.confirm({
|
|
47
|
-
message: `¿Quieres que cree los dos proyectos de Vercel automáticamente (conectados a ${repo}, con sus variables ya puestas)? Solo necesito un API token de Vercel.`,
|
|
83
|
+
message: `¿Quieres que cree y despliegue los dos proyectos de Vercel automáticamente (conectados a ${repo}, con sus variables ya puestas)? Solo necesito un API token de Vercel.`,
|
|
48
84
|
initialValue: true,
|
|
49
85
|
});
|
|
50
86
|
if (p.isCancel(auto) || !auto)
|
|
51
87
|
return false;
|
|
88
|
+
p.note("1. Entra a vercel.com/account/tokens (inicia sesión con tu cuenta de Vercel si te lo pide)\n" +
|
|
89
|
+
'2. Dale click a "Create Token"\n' +
|
|
90
|
+
'3. Ponle un nombre (por ejemplo "kontrolia-auth"), deja lo demás por defecto y confirma\n' +
|
|
91
|
+
"4. Copia el token que te muestra (solo se ve una vez) y pégalo aquí abajo", "Cómo conseguir el API token de Vercel");
|
|
52
92
|
const token = await p.password({
|
|
53
|
-
message: "API token de Vercel (
|
|
93
|
+
message: "API token de Vercel (no se guarda, solo se usa ahora)",
|
|
54
94
|
validate: (value) => (value.trim() ? undefined : "Requerido"),
|
|
55
95
|
});
|
|
56
96
|
if (p.isCancel(token))
|
|
57
97
|
return false;
|
|
98
|
+
const branch = await detectCurrentBranch(repoRoot);
|
|
58
99
|
const namePrefix = repo.split("/")[1] ?? "kontrolia-auth";
|
|
59
|
-
const
|
|
60
|
-
authSpinner.start("Creando proyecto de Vercel para auth-server");
|
|
61
|
-
const authResult = await createVercelProject({
|
|
100
|
+
const authOk = await createAndDeployVercelProject({
|
|
62
101
|
token,
|
|
63
102
|
repo,
|
|
64
|
-
|
|
103
|
+
branch,
|
|
104
|
+
appLabel: "auth-server",
|
|
105
|
+
projectName: `${namePrefix}-auth-server`,
|
|
65
106
|
rootDirectory: "apps/auth-server",
|
|
66
107
|
env: authServerEnv,
|
|
67
108
|
});
|
|
68
|
-
|
|
69
|
-
const adminSpinner = p.spinner();
|
|
70
|
-
adminSpinner.start("Creando proyecto de Vercel para admin-panel");
|
|
71
|
-
const adminResult = await createVercelProject({
|
|
109
|
+
const adminOk = await createAndDeployVercelProject({
|
|
72
110
|
token,
|
|
73
111
|
repo,
|
|
74
|
-
|
|
112
|
+
branch,
|
|
113
|
+
appLabel: "admin-panel",
|
|
114
|
+
projectName: `${namePrefix}-admin-panel`,
|
|
75
115
|
rootDirectory: "apps/admin-panel",
|
|
76
116
|
env: adminPanelEnv,
|
|
77
117
|
});
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
p.note("Los dos proyectos ya están conectados a tu repo, con la carpeta y las variables correctas. Entra a " +
|
|
81
|
-
"vercel.com/dashboard y dale \"Deploy\" a cada uno (o empuja un commit a tu rama principal) para el primer despliegue.", "Listo");
|
|
118
|
+
if (authOk && adminOk) {
|
|
119
|
+
p.note("Revisa el progreso del build en vercel.com/dashboard — cada uno toma un par de minutos.", "Listo");
|
|
82
120
|
return true;
|
|
83
121
|
}
|
|
84
122
|
p.note("Algo falló creando los proyectos — usa los pasos manuales de abajo para lo que no se haya creado.", "Revisa el error de arriba");
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompts.d.ts","sourceRoot":"","sources":["../../src/utils/prompts.ts"],"names":[],"mappings":"AAEA,gHAAgH;AAChH,wBAAsB,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAOvF"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import * as p from "@clack/prompts";
|
|
2
|
+
/** A required text prompt — exits cleanly on Ctrl+C instead of returning a cancel symbol to every call site. */
|
|
3
|
+
export async function textOrExit(message, placeholder) {
|
|
4
|
+
const value = await p.text({ message, placeholder });
|
|
5
|
+
if (p.isCancel(value)) {
|
|
6
|
+
p.cancel("Instalación cancelada.");
|
|
7
|
+
process.exit(0);
|
|
8
|
+
}
|
|
9
|
+
return value;
|
|
10
|
+
}
|
|
@@ -7,6 +7,8 @@ import type { EnvValues } from "./files.js";
|
|
|
7
7
|
* but this product's docs and CLI only ever assume GitHub.
|
|
8
8
|
*/
|
|
9
9
|
export declare function detectGitHubRepo(repoRoot: string): Promise<string | null>;
|
|
10
|
+
/** The branch actually checked out — what should get deployed, not an assumed "main". */
|
|
11
|
+
export declare function detectCurrentBranch(repoRoot: string): Promise<string>;
|
|
10
12
|
export interface CreateVercelProjectOptions {
|
|
11
13
|
token: string;
|
|
12
14
|
/** "owner/repo" on GitHub. */
|
|
@@ -32,4 +34,23 @@ export interface CreateVercelProjectResult {
|
|
|
32
34
|
* https://vercel.com/docs/rest-api/reference/endpoints/projects/create-a-new-project
|
|
33
35
|
*/
|
|
34
36
|
export declare function createVercelProject(options: CreateVercelProjectOptions): Promise<CreateVercelProjectResult>;
|
|
37
|
+
export interface TriggerDeploymentOptions {
|
|
38
|
+
token: string;
|
|
39
|
+
/** "owner/repo" on GitHub. */
|
|
40
|
+
repo: string;
|
|
41
|
+
branch: string;
|
|
42
|
+
/** Must match the `name` used in createVercelProject — that's how this targets the right project. */
|
|
43
|
+
projectName: string;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Creating a project via the API (createVercelProject above) connects the
|
|
47
|
+
* GitHub repo but does NOT build or deploy anything by itself — that's a
|
|
48
|
+
* separate resource. Without this, a freshly created project just sits
|
|
49
|
+
* there until something else (a push, or clicking "Deploy" in the
|
|
50
|
+
* dashboard) triggers its first build, which defeats the point of
|
|
51
|
+
* automating this in the first place.
|
|
52
|
+
*
|
|
53
|
+
* https://vercel.com/docs/rest-api/reference/endpoints/deployments/create-a-new-deployment
|
|
54
|
+
*/
|
|
55
|
+
export declare function triggerVercelDeployment(options: TriggerDeploymentOptions): Promise<CreateVercelProjectResult>;
|
|
35
56
|
//# sourceMappingURL=vercel-api.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vercel-api.d.ts","sourceRoot":"","sources":["../../src/utils/vercel-api.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAE5C;;;;;;GAMG;AACH,wBAAsB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAQ/E;AAED,MAAM,WAAW,0BAA0B;IACzC,KAAK,EAAE,MAAM,CAAC;IACd,8BAA8B;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,EAAE,MAAM,CAAC;IACtB,GAAG,EAAE,SAAS,CAAC;CAChB;AAED,MAAM,WAAW,yBAAyB;IACxC,EAAE,EAAE,OAAO,CAAC;IACZ,qCAAqC;IACrC,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,mBAAmB,CAAC,OAAO,EAAE,0BAA0B,GAAG,OAAO,CAAC,yBAAyB,CAAC,CAgCjH"}
|
|
1
|
+
{"version":3,"file":"vercel-api.d.ts","sourceRoot":"","sources":["../../src/utils/vercel-api.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAE5C;;;;;;GAMG;AACH,wBAAsB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAQ/E;AAED,yFAAyF;AACzF,wBAAsB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAO3E;AAED,MAAM,WAAW,0BAA0B;IACzC,KAAK,EAAE,MAAM,CAAC;IACd,8BAA8B;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,EAAE,MAAM,CAAC;IACtB,GAAG,EAAE,SAAS,CAAC;CAChB;AAED,MAAM,WAAW,yBAAyB;IACxC,EAAE,EAAE,OAAO,CAAC;IACZ,qCAAqC;IACrC,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,mBAAmB,CAAC,OAAO,EAAE,0BAA0B,GAAG,OAAO,CAAC,yBAAyB,CAAC,CAgCjH;AAED,MAAM,WAAW,wBAAwB;IACvC,KAAK,EAAE,MAAM,CAAC;IACd,8BAA8B;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,qGAAqG;IACrG,WAAW,EAAE,MAAM,CAAC;CACrB;AAED;;;;;;;;;GASG;AACH,wBAAsB,uBAAuB,CAAC,OAAO,EAAE,wBAAwB,GAAG,OAAO,CAAC,yBAAyB,CAAC,CAyBnH"}
|
package/dist/utils/vercel-api.js
CHANGED
|
@@ -16,6 +16,16 @@ export async function detectGitHubRepo(repoRoot) {
|
|
|
16
16
|
return null;
|
|
17
17
|
}
|
|
18
18
|
}
|
|
19
|
+
/** The branch actually checked out — what should get deployed, not an assumed "main". */
|
|
20
|
+
export async function detectCurrentBranch(repoRoot) {
|
|
21
|
+
try {
|
|
22
|
+
const branch = (await run("git", ["branch", "--show-current"], { cwd: repoRoot })).trim();
|
|
23
|
+
return branch || "main";
|
|
24
|
+
}
|
|
25
|
+
catch {
|
|
26
|
+
return "main";
|
|
27
|
+
}
|
|
28
|
+
}
|
|
19
29
|
/**
|
|
20
30
|
* Creates a Vercel project via the REST API — connected to the GitHub repo,
|
|
21
31
|
* scoped to one app's folder in this monorepo, with its environment
|
|
@@ -59,3 +69,38 @@ export async function createVercelProject(options) {
|
|
|
59
69
|
const body = (await response.json().catch(() => null));
|
|
60
70
|
return { ok: false, error: body?.error?.message ?? `HTTP ${response.status}` };
|
|
61
71
|
}
|
|
72
|
+
/**
|
|
73
|
+
* Creating a project via the API (createVercelProject above) connects the
|
|
74
|
+
* GitHub repo but does NOT build or deploy anything by itself — that's a
|
|
75
|
+
* separate resource. Without this, a freshly created project just sits
|
|
76
|
+
* there until something else (a push, or clicking "Deploy" in the
|
|
77
|
+
* dashboard) triggers its first build, which defeats the point of
|
|
78
|
+
* automating this in the first place.
|
|
79
|
+
*
|
|
80
|
+
* https://vercel.com/docs/rest-api/reference/endpoints/deployments/create-a-new-deployment
|
|
81
|
+
*/
|
|
82
|
+
export async function triggerVercelDeployment(options) {
|
|
83
|
+
const [org, repo] = options.repo.split("/");
|
|
84
|
+
let response;
|
|
85
|
+
try {
|
|
86
|
+
response = await fetch("https://api.vercel.com/v13/deployments", {
|
|
87
|
+
method: "POST",
|
|
88
|
+
headers: {
|
|
89
|
+
Authorization: `Bearer ${options.token}`,
|
|
90
|
+
"Content-Type": "application/json",
|
|
91
|
+
},
|
|
92
|
+
body: JSON.stringify({
|
|
93
|
+
name: options.projectName,
|
|
94
|
+
target: "production",
|
|
95
|
+
gitSource: { type: "github", ref: options.branch, org, repo },
|
|
96
|
+
}),
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
catch (error) {
|
|
100
|
+
return { ok: false, error: error.message };
|
|
101
|
+
}
|
|
102
|
+
if (response.ok)
|
|
103
|
+
return { ok: true };
|
|
104
|
+
const body = (await response.json().catch(() => null));
|
|
105
|
+
return { ok: false, error: body?.error?.message ?? `HTTP ${response.status}` };
|
|
106
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-kontrolia-auth",
|
|
3
|
-
"version": "2.1
|
|
3
|
+
"version": "2.2.1",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "Turnkey installer for KontrolIA Auth. `npx create-kontrolia-auth mi-app` checks requirements, downloads the repo, installs deps, and runs a wizard: (1) connect to an existing Supabase project or create a new self-hosted one via Docker; (2) where to deploy auth-server/admin-panel (Docker, Vercel, Railway, Render, Coolify). Also exposes `update`, `migrate` and `doctor` subcommands.",
|
|
6
6
|
"keywords": [
|