@geekmidas/cli 10.0.0-alpha.116 → 10.0.0-alpha.118
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 +7 -2
- package/dist/{GoDaddyProvider-BDvIMTO-.cjs → GoDaddyProvider-B6SPHBCU.cjs} +2 -2
- package/dist/{GoDaddyProvider-BDvIMTO-.cjs.map → GoDaddyProvider-B6SPHBCU.cjs.map} +1 -1
- package/dist/{GoDaddyProvider-eW1mre1g.mjs → GoDaddyProvider-CcjbFkLt.mjs} +2 -2
- package/dist/{GoDaddyProvider-eW1mre1g.mjs.map → GoDaddyProvider-CcjbFkLt.mjs.map} +1 -1
- package/dist/{LegacyStateStore-DFeykTd8.cjs → LegacyStateStore-2l5jw_VI.cjs} +3 -3
- package/dist/{LegacyStateStore-DFeykTd8.cjs.map → LegacyStateStore-2l5jw_VI.cjs.map} +1 -1
- package/dist/{LegacyStateStore-Ba1_x0cr.mjs → LegacyStateStore-D-D6r_JT.mjs} +3 -3
- package/dist/{LegacyStateStore-Ba1_x0cr.mjs.map → LegacyStateStore-D-D6r_JT.mjs.map} +1 -1
- package/dist/{LocalStateStore-C1rUUvBr.mjs → LocalStateStore-DIAY7j1O.mjs} +2 -2
- package/dist/{LocalStateStore-C1rUUvBr.mjs.map → LocalStateStore-DIAY7j1O.mjs.map} +1 -1
- package/dist/{LocalStateStore-CV-04jpI.cjs → LocalStateStore-Dg3rvwwe.cjs} +2 -2
- package/dist/{LocalStateStore-CV-04jpI.cjs.map → LocalStateStore-Dg3rvwwe.cjs.map} +1 -1
- package/dist/{S3StateStore-Dszt4fN5.mjs → S3StateStore-BKi1eamw.mjs} +2 -2
- package/dist/{S3StateStore-Dszt4fN5.mjs.map → S3StateStore-BKi1eamw.mjs.map} +1 -1
- package/dist/{S3StateStore-CqYi-1sb.cjs → S3StateStore-BdcgQNhO.cjs} +2 -2
- package/dist/{S3StateStore-CqYi-1sb.cjs.map → S3StateStore-BdcgQNhO.cjs.map} +1 -1
- package/dist/{SSMStateStore-zpHjDCAW.cjs → SSMStateStore-CS-pAKT9.cjs} +2 -2
- package/dist/{SSMStateStore-zpHjDCAW.cjs.map → SSMStateStore-CS-pAKT9.cjs.map} +1 -1
- package/dist/{SSMStateStore-BYRUyMkE.mjs → SSMStateStore-DHgaNW75.mjs} +2 -2
- package/dist/{SSMStateStore-BYRUyMkE.mjs.map → SSMStateStore-DHgaNW75.mjs.map} +1 -1
- package/dist/{add-0XI8_HOf.cjs → add-6VPdRbRT.cjs} +3 -3
- package/dist/{add-0XI8_HOf.cjs.map → add-6VPdRbRT.cjs.map} +1 -1
- package/dist/{add-DXdJjp0b.mjs → add-BcZXHa3Z.mjs} +3 -3
- package/dist/{add-DXdJjp0b.mjs.map → add-BcZXHa3Z.mjs.map} +1 -1
- package/dist/{bundler-CgcwaVI0.mjs → bundler-Ciim6amq.mjs} +7 -59
- package/dist/bundler-Ciim6amq.mjs.map +1 -0
- package/dist/{bundler-B2_2-Dum.cjs → bundler-jjWtQ882.cjs} +6 -58
- package/dist/bundler-jjWtQ882.cjs.map +1 -0
- package/dist/{cli-H0uB_znq.mjs → cli-BkxlWYfI.mjs} +2 -2
- package/dist/{cli-H0uB_znq.mjs.map → cli-BkxlWYfI.mjs.map} +1 -1
- package/dist/{cli-5k6kV_i4.cjs → cli-CQ2ij0Mi.cjs} +2 -2
- package/dist/{cli-5k6kV_i4.cjs.map → cli-CQ2ij0Mi.cjs.map} +1 -1
- package/dist/{compose-CYeMW2_o.cjs → compose-JOasAHcd.cjs} +4 -4
- package/dist/{compose-CYeMW2_o.cjs.map → compose-JOasAHcd.cjs.map} +1 -1
- package/dist/{compose-BEiJWrB7.mjs → compose-qLTNYJAY.mjs} +4 -4
- package/dist/{compose-BEiJWrB7.mjs.map → compose-qLTNYJAY.mjs.map} +1 -1
- package/dist/deploy/public.cjs +6 -6
- package/dist/deploy/public.d.cts.map +1 -1
- package/dist/deploy/public.d.mts.map +1 -1
- package/dist/deploy/public.mjs +6 -6
- package/dist/{deploy-Q5qo1OP-.cjs → deploy-D-liNXfx.cjs} +5 -5
- package/dist/{deploy-Q5qo1OP-.cjs.map → deploy-D-liNXfx.cjs.map} +1 -1
- package/dist/{deploy-Cyx5fSb7.mjs → deploy-_g-2dX38.mjs} +5 -5
- package/dist/{deploy-Cyx5fSb7.mjs.map → deploy-_g-2dX38.mjs.map} +1 -1
- package/dist/{dns-CsApfzLc.mjs → dns-DGq4xkJT.mjs} +2 -2
- package/dist/{dns-CsApfzLc.mjs.map → dns-DGq4xkJT.mjs.map} +1 -1
- package/dist/{dns-v9viladZ.cjs → dns-DfQKqAyt.cjs} +2 -2
- package/dist/{dns-v9viladZ.cjs.map → dns-DfQKqAyt.cjs.map} +1 -1
- package/dist/{dokploy-DfUo_QRw.mjs → dokploy-ClIPZaPH.mjs} +2 -2
- package/dist/{dokploy-DfUo_QRw.mjs.map → dokploy-ClIPZaPH.mjs.map} +1 -1
- package/dist/{dokploy-Di7rC2z0.cjs → dokploy-D17I2BCE.cjs} +2 -2
- package/dist/{dokploy-Di7rC2z0.cjs.map → dokploy-D17I2BCE.cjs.map} +1 -1
- package/dist/{drivers-D11JHxrD.mjs → drivers-3klmg9Sk.mjs} +22 -4
- package/dist/drivers-3klmg9Sk.mjs.map +1 -0
- package/dist/{drivers-GKaA6ITM.cjs → drivers-CoqD5zYP.cjs} +27 -3
- package/dist/drivers-CoqD5zYP.cjs.map +1 -0
- package/dist/{eas-CTfRmndW.mjs → eas-DJXhARYb.mjs} +2 -2
- package/dist/{eas-CTfRmndW.mjs.map → eas-DJXhARYb.mjs.map} +1 -1
- package/dist/{eas-CIvNT6qa.cjs → eas-b95MCG14.cjs} +2 -2
- package/dist/{eas-CIvNT6qa.cjs.map → eas-b95MCG14.cjs.map} +1 -1
- package/dist/{encryption--U4NsK7N.cjs → encryption-C_NRQ9cY.cjs} +2 -2
- package/dist/{encryption--U4NsK7N.cjs.map → encryption-C_NRQ9cY.cjs.map} +1 -1
- package/dist/{encryption-BpTPmd7h.mjs → encryption-CldvLtip.mjs} +2 -2
- package/dist/{encryption-BpTPmd7h.mjs.map → encryption-CldvLtip.mjs.map} +1 -1
- package/dist/{engine-BFmHfek1.mjs → engine-BBnTj8OD.mjs} +12 -6
- package/dist/engine-BBnTj8OD.mjs.map +1 -0
- package/dist/{engine-Ovl1PB6i.cjs → engine-CKfdvEVt.cjs} +11 -5
- package/dist/engine-CKfdvEVt.cjs.map +1 -0
- package/dist/{github-tWAGuR9i.mjs → github-BMPci2wg.mjs} +4 -4
- package/dist/{github-tWAGuR9i.mjs.map → github-BMPci2wg.mjs.map} +1 -1
- package/dist/{github-CTlPQ5Ra.cjs → github-D5Ck3srU.cjs} +4 -4
- package/dist/{github-CTlPQ5Ra.cjs.map → github-D5Ck3srU.cjs.map} +1 -1
- package/dist/{googlePlay-BNH729It.cjs → googlePlay-C-GBRDMp.cjs} +3 -3
- package/dist/{googlePlay-BNH729It.cjs.map → googlePlay-C-GBRDMp.cjs.map} +1 -1
- package/dist/{googlePlay-m1De-qIJ.mjs → googlePlay-fw0VWly7.mjs} +3 -3
- package/dist/{googlePlay-m1De-qIJ.mjs.map → googlePlay-fw0VWly7.mjs.map} +1 -1
- package/dist/index.cjs +245 -139
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +245 -139
- package/dist/index.mjs.map +1 -1
- package/dist/{migrate-4B4RgAjU.mjs → migrate-1bHqjfIe.mjs} +2 -2
- package/dist/{migrate-4B4RgAjU.mjs.map → migrate-1bHqjfIe.mjs.map} +1 -1
- package/dist/{migrate-DZ2--SaO.cjs → migrate-BndHuwqw.cjs} +2 -2
- package/dist/{migrate-DZ2--SaO.cjs.map → migrate-BndHuwqw.cjs.map} +1 -1
- package/dist/{migrate-X0Y7fz3N.mjs → migrate-WyWhSivN.mjs} +2 -2
- package/dist/{migrate-X0Y7fz3N.mjs.map → migrate-WyWhSivN.mjs.map} +1 -1
- package/dist/{migrate-BYEmpoIg.cjs → migrate-rke2Qvj2.cjs} +2 -2
- package/dist/{migrate-BYEmpoIg.cjs.map → migrate-rke2Qvj2.cjs.map} +1 -1
- package/dist/{publish-BUvYjiZH.cjs → publish-B22IhdS9.cjs} +2 -2
- package/dist/{publish-BUvYjiZH.cjs.map → publish-B22IhdS9.cjs.map} +1 -1
- package/dist/{publish-hhgraEhO.mjs → publish-BBG4zx8E.mjs} +2 -2
- package/dist/{publish-hhgraEhO.mjs.map → publish-BBG4zx8E.mjs.map} +1 -1
- package/dist/{ready-CIt5SOtg.mjs → ready-4hEoQ_cr.mjs} +2 -2
- package/dist/{ready-CIt5SOtg.mjs.map → ready-4hEoQ_cr.mjs.map} +1 -1
- package/dist/{ready-BMFjxBYA.cjs → ready-gc9IFByS.cjs} +2 -2
- package/dist/{ready-BMFjxBYA.cjs.map → ready-gc9IFByS.cjs.map} +1 -1
- package/dist/{resolve-DotGHvtX.mjs → resolve-CC6ndodR.mjs} +3 -3
- package/dist/{resolve-DotGHvtX.mjs.map → resolve-CC6ndodR.mjs.map} +1 -1
- package/dist/{resolve-DdFKTx8l.cjs → resolve-isFTuJp4.cjs} +3 -3
- package/dist/{resolve-DdFKTx8l.cjs.map → resolve-isFTuJp4.cjs.map} +1 -1
- package/dist/{rollback-9t9G3c_u.mjs → rollback-DaEmEC2Y.mjs} +4 -4
- package/dist/{rollback-9t9G3c_u.mjs.map → rollback-DaEmEC2Y.mjs.map} +1 -1
- package/dist/{rollback-D4xeUQvG.cjs → rollback-Lj9bQvHq.cjs} +4 -4
- package/dist/{rollback-D4xeUQvG.cjs.map → rollback-Lj9bQvHq.cjs.map} +1 -1
- package/dist/{seeds-DbKNcs3o.cjs → seeds-CF9Nx6_g.cjs} +33 -6
- package/dist/seeds-CF9Nx6_g.cjs.map +1 -0
- package/dist/{seeds-CRkKeyW0.mjs → seeds-CYzoBDg2.mjs} +33 -6
- package/dist/seeds-CYzoBDg2.mjs.map +1 -0
- package/dist/{serverSetup-DlRKRfTi.mjs → serverSetup-0h1Vh5un.mjs} +5 -5
- package/dist/{serverSetup-DlRKRfTi.mjs.map → serverSetup-0h1Vh5un.mjs.map} +1 -1
- package/dist/{serverSetup-CcWgNtiC.cjs → serverSetup-CbuJK4zg.cjs} +5 -5
- package/dist/{serverSetup-CcWgNtiC.cjs.map → serverSetup-CbuJK4zg.cjs.map} +1 -1
- package/dist/{sniffer-CakkKKqQ.mjs → sniffer-CRJHtBaK.mjs} +6 -6
- package/dist/{sniffer-CakkKKqQ.mjs.map → sniffer-CRJHtBaK.mjs.map} +1 -1
- package/dist/{sniffer-B6T6za4n.cjs → sniffer-Dz3Va1Jo.cjs} +6 -6
- package/dist/{sniffer-B6T6za4n.cjs.map → sniffer-Dz3Va1Jo.cjs.map} +1 -1
- package/dist/{stage-Mp6qQIoD.mjs → stage-CIo8s2WT.mjs} +4 -4
- package/dist/{stage-Mp6qQIoD.mjs.map → stage-CIo8s2WT.mjs.map} +1 -1
- package/dist/{stage-W3PUt7ar.cjs → stage-y9qFelxT.cjs} +4 -4
- package/dist/{stage-W3PUt7ar.cjs.map → stage-y9qFelxT.cjs.map} +1 -1
- package/dist/target/public.cjs +1 -1
- package/dist/target/public.mjs +1 -1
- package/dist/vitest.cjs +1 -1
- package/dist/vitest.mjs +1 -1
- package/package.json +15 -15
- package/dist/bundler-B2_2-Dum.cjs.map +0 -1
- package/dist/bundler-CgcwaVI0.mjs.map +0 -1
- package/dist/drivers-D11JHxrD.mjs.map +0 -1
- package/dist/drivers-GKaA6ITM.cjs.map +0 -1
- package/dist/engine-BFmHfek1.mjs.map +0 -1
- package/dist/engine-Ovl1PB6i.cjs.map +0 -1
- package/dist/seeds-CRkKeyW0.mjs.map +0 -1
- package/dist/seeds-DbKNcs3o.cjs.map +0 -1
package/dist/index.mjs
CHANGED
|
@@ -3,27 +3,28 @@ import { n as __require, t as __exportAll } from "./rolldown-runtime-BhDjJH2R.mj
|
|
|
3
3
|
import { n as isGkmError, t as GkmError } from "./errors-D8Gwp5kU.mjs";
|
|
4
4
|
import { r as DEFAULT_TIMEOUT_MS, t as CommandFailed } from "./run-BJLIerMM.mjs";
|
|
5
5
|
import { a as getDokployCredentials, d as removeGoDaddyCredentials, f as storeDokployCredentials, i as getCredentialsPath, l as readCredentials, m as storeHostingerToken, o as getDokployRegistryId, p as storeGoDaddyToken, s as getDokployToken, u as removeDokployCredentials } from "./credentials-B5N5yKk6.mjs";
|
|
6
|
-
import { C as dockerCompose, S as sshTarget, _ as parseDigests, b as dockerHost, c as edgeRef, f as derivedCredentials, h as EDGE_PROJECT, i as ComposePushNeedsBuild, l as removeEdgeRoutes, m as stackPlan, o as stackOverrideFile, p as stackDir, r as ComposePinNeedsPull, t as composeTarget, u as composeProject, v as pinnedRef, w as projectNetwork, y as composeServer } from "./compose-
|
|
6
|
+
import { C as dockerCompose, S as sshTarget, _ as parseDigests, b as dockerHost, c as edgeRef, f as derivedCredentials, h as EDGE_PROJECT, i as ComposePushNeedsBuild, l as removeEdgeRoutes, m as stackPlan, o as stackOverrideFile, p as stackDir, r as ComposePinNeedsPull, t as composeTarget, u as composeProject, v as pinnedRef, w as projectNetwork, y as composeServer } from "./compose-qLTNYJAY.mjs";
|
|
7
7
|
import { A as InvalidStages, F as stageProblems, P as deployedProblems, R as stageSampleRate, a as allConstructGlobs, d as getAppGkmConfig, j as TEST_STAGE, u as getAppBuildOrder } from "./workspace-D1QbNd55.mjs";
|
|
8
|
-
import { b as runTime, d as BACKUPS_URL_KEY, f as RUNNER_PATH, g as backupDatabases, u as BACKUPS_SERVICE, v as backupFile, x as stageBackups, y as backupsPrefix } from "./dns-
|
|
9
|
-
import {
|
|
8
|
+
import { b as runTime, d as BACKUPS_URL_KEY, f as RUNNER_PATH, g as backupDatabases, u as BACKUPS_SERVICE, v as backupFile, x as stageBackups, y as backupsPrefix } from "./dns-DGq4xkJT.mjs";
|
|
9
|
+
import { o as email } from "./schemas-BCwKKA42.mjs";
|
|
10
|
+
import { $t as isUnder, An as appTelemetry, At as isPortAvailable, Bn as fakeKey, Bt as maskPassword, Ct as cacheBackendFor, Dn as TELEMETRY_CONTAINER, Dt as createCredentialsPreload, G as CronGenerator, Gn as LOCAL_LOGS_EMAIL, H as workerBundleName, Hn as portsOf, Ht as toEmbeddableSecrets, It as secretsStoreFor, L as dockerCommand, Mn as scopeTelemetryEnv, Mt as loadPortState, Nn as surfaceClientTraced, Nt as loadSecretsForApp, Ot as createEntryWrapper, Pn as telemetryOf, Pt as prepareEntryCredentials, Q as assertDevServicesFlag, Tt as providerOf, U as workerEntryDir, Ut as withCustomSecret, V as WorkerGenerator, W as QueueGenerator, Wn as primaryPortKey, Xt as imageBuildCredentials, Zt as isImageBuild, a as dnsResources, an as postgresDatabaseNames, bt as pgClient, c as describeActor, dt as constructGlobs, en as workerUnits, fn as readLocalCredentials, ft as derivedContainers, gn as projectKey, gt as forgetState, ht as LOCAL_CA_PATH, jt as loadEnvFiles, kt as findAvailablePort, lt as FAKE_ENV, mn as getKeyPath, pn as FileSecretsStore, pt as reconcileWorkspace, sn as quoteIdentifier, ut as backendsOf$1, wt as eventsBackendFor, xt as CLUSTER_DATABASE, zn as describeServices } from "./seeds-CYzoBDg2.mjs";
|
|
10
11
|
import { t as appKey } from "./derive-B4vDpzgP.mjs";
|
|
11
12
|
import { l as isCacheBackend, n as assertTestCredentials, t as SubscriberGenerator } from "./SubscriberGenerator-DHnIYwUU.mjs";
|
|
12
13
|
import { n as deployIdentity } from "./identity-CBXr4wNi.mjs";
|
|
13
14
|
import { a as startTelemetryCode, c as parseTelemetryFlag, i as routeTelemetry, n as runtimeFor, o as telemetryFor, r as mountRequestSpansCode, s as writeTelemetryModule, t as EndpointGenerator } from "./EndpointGenerator-CvLX8bpx.mjs";
|
|
14
15
|
import { d as ConstructGenerator, i as discover, r as consumedBy, u as withOwningTsconfigJsx } from "./discover-Ca8U75dl.mjs";
|
|
15
16
|
import { ConfigNotFound, NotABackendApp, NotInAnApp, loadAppConfig, loadConfig, loadWorkspaceConfig, loadWorkspaceSettings, parseModuleConfig } from "./config.mjs";
|
|
16
|
-
import { d as awsEndpoint, f as awsProvisioningCredentials, t as deploy$1, u as awsClientConfig } from "./deploy-
|
|
17
|
+
import { d as awsEndpoint, f as awsProvisioningCredentials, t as deploy$1, u as awsClientConfig } from "./deploy-_g-2dX38.mjs";
|
|
17
18
|
import { generateOpenApi, openapiCommand, resolveOpenApiConfig } from "./openapi.mjs";
|
|
18
19
|
import { a as describeHolder, c as withAppPorts, i as assignAppPorts, o as describeMove, r as appTag, s as holderOf, t as APP_TAG_ENV } from "./appPorts-BoXMwolc.mjs";
|
|
19
|
-
import { n as driversFor, r as eventsBackendsIn, t as cacheBackendsIn } from "./drivers-
|
|
20
|
+
import { a as opensKmsKeys, n as driversFor, r as eventsBackendsIn, t as cacheBackendsIn } from "./drivers-3klmg9Sk.mjs";
|
|
20
21
|
import { n as withCompute, r as withRoutes, t as manifestModule } from "./emit-C1e8qD08.mjs";
|
|
21
22
|
import { t as LocalSandbox } from "./local-BwC2v2Y8.mjs";
|
|
22
|
-
import { S as createStateStore, k as keyFingerprint, n as sniffAppEnvironment, o as DokployApi } from "./sniffer-
|
|
23
|
+
import { S as createStateStore, k as keyFingerprint, n as sniffAppEnvironment, o as DokployApi } from "./sniffer-CRJHtBaK.mjs";
|
|
23
24
|
import { o as loadCredentialSchemas, t as CredentialsInvalid } from "./credentialSchemas-Cf5Pf8VE.mjs";
|
|
24
|
-
import { t as LocalStateStore } from "./LocalStateStore-
|
|
25
|
+
import { t as LocalStateStore } from "./LocalStateStore-DIAY7j1O.mjs";
|
|
25
26
|
import { a as getExecCommand, c as validateProjectName, i as findWorkspaceRoot, n as detectPackageManager$1, o as getInstallCommand, r as findWorkspacePackages, s as getRunCommand, t as checkDirectoryExists } from "./utils-D_fxUqvU.mjs";
|
|
26
|
-
import { a as writeTestHarness, i as TEST_MANIFEST_ENV, n as TEST_READY_FILE, t as TEST_READY_ENV } from "./ready-
|
|
27
|
+
import { a as writeTestHarness, i as TEST_MANIFEST_ENV, n as TEST_READY_FILE, t as TEST_READY_ENV } from "./ready-4hEoQ_cr.mjs";
|
|
27
28
|
import { createRequire } from "node:module";
|
|
28
29
|
import { basename, dirname, isAbsolute, join, relative, resolve } from "node:path";
|
|
29
30
|
import { Command, Option } from "commander";
|
|
@@ -51,7 +52,7 @@ import crypto from "crypto";
|
|
|
51
52
|
import { Function } from "@geekmidas/constructs/functions";
|
|
52
53
|
import { Topic } from "@geekmidas/constructs/topic";
|
|
53
54
|
//#region package.json
|
|
54
|
-
var version = "10.0.0-alpha.
|
|
55
|
+
var version = "10.0.0-alpha.118";
|
|
55
56
|
//#endregion
|
|
56
57
|
//#region src/prompt.ts
|
|
57
58
|
/**
|
|
@@ -134,7 +135,7 @@ const logger$8 = console;
|
|
|
134
135
|
* Validate Dokploy token by making a test API call
|
|
135
136
|
*/
|
|
136
137
|
async function validateDokployToken(endpoint, token) {
|
|
137
|
-
const { DokployApi } = await import("./sniffer-
|
|
138
|
+
const { DokployApi } = await import("./sniffer-CRJHtBaK.mjs").then((n) => n.c);
|
|
138
139
|
return new DokployApi({
|
|
139
140
|
baseUrl: endpoint,
|
|
140
141
|
token
|
|
@@ -2174,7 +2175,7 @@ async function execCommand(commandArgs, options = {}, stageDeps) {
|
|
|
2174
2175
|
const cwd = options.cwd ?? process.cwd();
|
|
2175
2176
|
if (!commandArgs[0]) throw new NoCommandSpecified();
|
|
2176
2177
|
if (options.stage && !isImageBuild()) {
|
|
2177
|
-
const { execOnStage } = await import("./stage-
|
|
2178
|
+
const { execOnStage } = await import("./stage-CIo8s2WT.mjs").then((n) => n.n);
|
|
2178
2179
|
const { loadWorkspaceConfig } = await import("./config.mjs");
|
|
2179
2180
|
const { workspace } = await loadWorkspaceConfig(cwd);
|
|
2180
2181
|
if (options.stage !== workspace.stages.local) {
|
|
@@ -2747,9 +2748,9 @@ async function workspaceDevCommand(configured, options) {
|
|
|
2747
2748
|
for (const { id, port } of fakes) logger$5.log(`🎭 ${id} fake: http://localhost:${port}`);
|
|
2748
2749
|
logger$5.log(options.migrate || options.seed ? "🗄️ Migrating the databases" : "🗄️ Checking for pending migrations");
|
|
2749
2750
|
if (options.migrate || options.seed) {
|
|
2750
|
-
const { prepareDevDatabases } = await import("./migrate-
|
|
2751
|
+
const { prepareDevDatabases } = await import("./migrate-WyWhSivN.mjs");
|
|
2751
2752
|
await prepareDevDatabases(workspace, reconciled.env, { seed: !!options.seed });
|
|
2752
|
-
} else await import("./migrate-
|
|
2753
|
+
} else await import("./migrate-WyWhSivN.mjs").then(({ reportPendingMigrations }) => reportPendingMigrations(workspace, reconciled.env)).catch((error) => {
|
|
2753
2754
|
logger$5.log(`⚠️ Could not check for pending migrations: ${error instanceof Error ? error.message : String(error)}`);
|
|
2754
2755
|
});
|
|
2755
2756
|
const appUrls = {};
|
|
@@ -3825,7 +3826,7 @@ async function buildApp(input) {
|
|
|
3825
3826
|
...production,
|
|
3826
3827
|
...telemetry ? { telemetry } : {}
|
|
3827
3828
|
});
|
|
3828
|
-
const { bundleServer } = await import("./bundler-
|
|
3829
|
+
const { bundleServer } = await import("./bundler-Ciim6amq.mjs");
|
|
3829
3830
|
await bundleServer({
|
|
3830
3831
|
entryPoint,
|
|
3831
3832
|
outputDir: join(outputDir, "dist"),
|
|
@@ -3900,7 +3901,8 @@ async function buildApp(input) {
|
|
|
3900
3901
|
appRoot,
|
|
3901
3902
|
reach,
|
|
3902
3903
|
cacheBackend,
|
|
3903
|
-
eventsBackend
|
|
3904
|
+
eventsBackend,
|
|
3905
|
+
target
|
|
3904
3906
|
}));
|
|
3905
3907
|
if (target === "server") buildContext.telemetry = telemetryFor({
|
|
3906
3908
|
node: processTelemetry(declared, derived.surface?.id, servesOnly ? [] : hosted.map((unit) => unit.id)),
|
|
@@ -3933,7 +3935,8 @@ async function buildApp(input) {
|
|
|
3933
3935
|
appRoot,
|
|
3934
3936
|
reach: reachedBy(declared, [workerId], work),
|
|
3935
3937
|
cacheBackend,
|
|
3936
|
-
eventsBackend
|
|
3938
|
+
eventsBackend,
|
|
3939
|
+
target
|
|
3937
3940
|
})
|
|
3938
3941
|
}),
|
|
3939
3942
|
telemetry: (workerId) => telemetryFor({
|
|
@@ -3983,7 +3986,8 @@ function processTelemetry(declared, surfaceId, workers) {
|
|
|
3983
3986
|
* The drivers a process's entry registers, from the declarations it reaches:
|
|
3984
3987
|
* the cache's — the declaration for one that named its database, the deploy
|
|
3985
3988
|
* target's default for one that named nowhere — and the broker's, only when
|
|
3986
|
-
* it reaches a topic or a queue (see `eventsBackendsIn`)
|
|
3989
|
+
* it reaches a topic or a queue (see `eventsBackendsIn`) — and the KMS
|
|
3990
|
+
* cipher, only built for AWS and only when it reaches an `Encryption`.
|
|
3987
3991
|
*/
|
|
3988
3992
|
function runtimeDrivers(options) {
|
|
3989
3993
|
const eventsBackends = eventsBackendsIn(options.reach, options.eventsBackend);
|
|
@@ -3991,7 +3995,8 @@ function runtimeDrivers(options) {
|
|
|
3991
3995
|
storageDrivers: driversFor({
|
|
3992
3996
|
appRoot: options.appRoot,
|
|
3993
3997
|
cache: cacheBackendsIn(options.reach, options.cacheBackend),
|
|
3994
|
-
events: eventsBackends
|
|
3998
|
+
events: eventsBackends,
|
|
3999
|
+
kms: opensKmsKeys(options.reach, options.target)
|
|
3995
4000
|
}),
|
|
3996
4001
|
eventsBackends
|
|
3997
4002
|
};
|
|
@@ -4024,7 +4029,7 @@ async function buildWorkers(input) {
|
|
|
4024
4029
|
});
|
|
4025
4030
|
logger$4.log(`Generated worker ${worker.id}: ${crons.length} crons, ${queues.length} queues, ${subscribers.length} subscribers`);
|
|
4026
4031
|
if (!input.bundle) continue;
|
|
4027
|
-
const { bundleServer } = await import("./bundler-
|
|
4032
|
+
const { bundleServer } = await import("./bundler-Ciim6amq.mjs");
|
|
4028
4033
|
const outfile = workerBundleName(worker.id);
|
|
4029
4034
|
await bundleServer({
|
|
4030
4035
|
entryPoint,
|
|
@@ -4110,7 +4115,7 @@ async function buildForTarget(target, context, appRoot, workspaceRoot, endpointG
|
|
|
4110
4115
|
let masterKey;
|
|
4111
4116
|
if (context.production?.bundle && !skipBundle) {
|
|
4112
4117
|
logger$4.log(`\n📦 Bundling production server...`);
|
|
4113
|
-
const { bundleServer } = await import("./bundler-
|
|
4118
|
+
const { bundleServer } = await import("./bundler-Ciim6amq.mjs");
|
|
4114
4119
|
const allConstructs = [
|
|
4115
4120
|
...endpoints.map((e) => e.construct),
|
|
4116
4121
|
...functions.map((f) => f.construct),
|
|
@@ -5944,25 +5949,25 @@ function loadPackageJson() {
|
|
|
5944
5949
|
* Run: pnpm --filter @geekmidas/cli sync-versions
|
|
5945
5950
|
*/
|
|
5946
5951
|
const GEEKMIDAS_VERSIONS = {
|
|
5947
|
-
"@geekmidas/audit": "~10.0.0-alpha.
|
|
5948
|
-
"@geekmidas/auth": "~10.0.0-alpha.
|
|
5949
|
-
"@geekmidas/cache": "~10.0.0-alpha.
|
|
5950
|
-
"@geekmidas/client": "~10.0.0-alpha.
|
|
5951
|
-
"@geekmidas/cloud": "~10.0.0-alpha.
|
|
5952
|
-
"@geekmidas/constructs": "~10.0.0-alpha.
|
|
5953
|
-
"@geekmidas/db": "~10.0.0-alpha.
|
|
5954
|
-
"@geekmidas/emailkit": "~10.0.0-alpha.
|
|
5955
|
-
"@geekmidas/envkit": "~10.0.0-alpha.
|
|
5956
|
-
"@geekmidas/errors": "~10.0.0-alpha.
|
|
5957
|
-
"@geekmidas/events": "~10.0.0-alpha.
|
|
5958
|
-
"@geekmidas/logger": "~10.0.0-alpha.
|
|
5959
|
-
"@geekmidas/manifest": "~10.0.0-alpha.
|
|
5960
|
-
"@geekmidas/rate-limit": "~10.0.0-alpha.
|
|
5961
|
-
"@geekmidas/schema": "~10.0.0-alpha.
|
|
5962
|
-
"@geekmidas/services": "~10.0.0-alpha.
|
|
5963
|
-
"@geekmidas/storage": "~10.0.0-alpha.
|
|
5964
|
-
"@geekmidas/telescope": "~10.0.0-alpha.
|
|
5965
|
-
"@geekmidas/testkit": "~10.0.0-alpha.
|
|
5952
|
+
"@geekmidas/audit": "~10.0.0-alpha.118",
|
|
5953
|
+
"@geekmidas/auth": "~10.0.0-alpha.118",
|
|
5954
|
+
"@geekmidas/cache": "~10.0.0-alpha.118",
|
|
5955
|
+
"@geekmidas/client": "~10.0.0-alpha.118",
|
|
5956
|
+
"@geekmidas/cloud": "~10.0.0-alpha.118",
|
|
5957
|
+
"@geekmidas/constructs": "~10.0.0-alpha.118",
|
|
5958
|
+
"@geekmidas/db": "~10.0.0-alpha.118",
|
|
5959
|
+
"@geekmidas/emailkit": "~10.0.0-alpha.118",
|
|
5960
|
+
"@geekmidas/envkit": "~10.0.0-alpha.118",
|
|
5961
|
+
"@geekmidas/errors": "~10.0.0-alpha.118",
|
|
5962
|
+
"@geekmidas/events": "~10.0.0-alpha.118",
|
|
5963
|
+
"@geekmidas/logger": "~10.0.0-alpha.118",
|
|
5964
|
+
"@geekmidas/manifest": "~10.0.0-alpha.118",
|
|
5965
|
+
"@geekmidas/rate-limit": "~10.0.0-alpha.118",
|
|
5966
|
+
"@geekmidas/schema": "~10.0.0-alpha.118",
|
|
5967
|
+
"@geekmidas/services": "~10.0.0-alpha.118",
|
|
5968
|
+
"@geekmidas/storage": "~10.0.0-alpha.118",
|
|
5969
|
+
"@geekmidas/telescope": "~10.0.0-alpha.118",
|
|
5970
|
+
"@geekmidas/testkit": "~10.0.0-alpha.118",
|
|
5966
5971
|
"@geekmidas/cli": `~${loadPackageJson().version}`
|
|
5967
5972
|
};
|
|
5968
5973
|
//#endregion
|
|
@@ -7155,7 +7160,7 @@ const COMMIT = /^[0-9a-f]{40}$/;
|
|
|
7155
7160
|
* The `uses:` value for the stages action, with a comment saying which CLI
|
|
7156
7161
|
* release the pinned commit is.
|
|
7157
7162
|
*/
|
|
7158
|
-
function stagesActionUses(commit = "
|
|
7163
|
+
function stagesActionUses(commit = "01a325bb2dfb75faf9c255cb3f1d9288c6c42c1e", version = cliVersion()) {
|
|
7159
7164
|
return commit && COMMIT.test(commit) ? `${STAGES_ACTION}@${commit} # @geekmidas/cli ${version}` : `${STAGES_ACTION}@main # pin to a commit SHA: see the action's README`;
|
|
7160
7165
|
}
|
|
7161
7166
|
//#endregion
|
|
@@ -9066,6 +9071,10 @@ interface SignedIn {
|
|
|
9066
9071
|
* The \`users\` row for whoever signed in, made the first time they call the
|
|
9067
9072
|
* API and given the Member role. The auth server owns who someone is; this
|
|
9068
9073
|
* row is what the application's own tables refer to.
|
|
9074
|
+
*
|
|
9075
|
+
* Someone the seeds named before they signed in — an admin, in
|
|
9076
|
+
* \`03_admins.ts\` — already has a row with their email and no auth user: their
|
|
9077
|
+
* first sign-in claims it, roles and all.
|
|
9069
9078
|
*/
|
|
9070
9079
|
export async function memberFor(db: Kysely<Database>, user: SignedIn) {
|
|
9071
9080
|
const found = await db
|
|
@@ -9075,13 +9084,23 @@ export async function memberFor(db: Kysely<Database>, user: SignedIn) {
|
|
|
9075
9084
|
.executeTakeFirst();
|
|
9076
9085
|
if (found) return found;
|
|
9077
9086
|
|
|
9078
|
-
const member =
|
|
9079
|
-
|
|
9080
|
-
|
|
9081
|
-
|
|
9082
|
-
|
|
9083
|
-
|
|
9084
|
-
|
|
9087
|
+
const member =
|
|
9088
|
+
(await db
|
|
9089
|
+
.updateTable('users')
|
|
9090
|
+
.set({ authUserId: user.id, ...(user.name ? { name: user.name } : {}) })
|
|
9091
|
+
.where('email', '=', user.email)
|
|
9092
|
+
.where('authUserId', 'is', null)
|
|
9093
|
+
.returningAll()
|
|
9094
|
+
.executeTakeFirst()) ??
|
|
9095
|
+
(await db
|
|
9096
|
+
.insertInto('users')
|
|
9097
|
+
.values({ authUserId: user.id, email: user.email, name: user.name })
|
|
9098
|
+
// Two first requests at once: the second finds the first's row.
|
|
9099
|
+
.onConflict((oc) =>
|
|
9100
|
+
oc.column('authUserId').doUpdateSet({ email: user.email }),
|
|
9101
|
+
)
|
|
9102
|
+
.returningAll()
|
|
9103
|
+
.executeTakeFirstOrThrow());
|
|
9085
9104
|
|
|
9086
9105
|
const memberRole = await db
|
|
9087
9106
|
.selectFrom('roles')
|
|
@@ -9244,65 +9263,6 @@ export const AdminUsersSchema = z
|
|
|
9244
9263
|
}];
|
|
9245
9264
|
}
|
|
9246
9265
|
/**
|
|
9247
|
-
* `scripts/grant-admin.ts`: the first Super admin. Nobody can grant a role
|
|
9248
|
-
* before someone has one, so the first is granted from a terminal.
|
|
9249
|
-
*/
|
|
9250
|
-
function grantAdminScript(options) {
|
|
9251
|
-
return {
|
|
9252
|
-
path: "scripts/grant-admin.ts",
|
|
9253
|
-
content: `/**
|
|
9254
|
-
* Make someone a Super admin — the first one, before the admin panel can.
|
|
9255
|
-
*
|
|
9256
|
-
* gkm exec -- tsx scripts/grant-admin.ts you@example.com
|
|
9257
|
-
*
|
|
9258
|
-
* They need to have signed in once (the web site, the admin panel or the app),
|
|
9259
|
-
* which is what makes their \`users\` row.
|
|
9260
|
-
*/
|
|
9261
|
-
import { database } from '@${options.name}/constructs/database.ts';
|
|
9262
|
-
import { SYSTEM_ROLES } from '@${options.name}/models/access';
|
|
9263
|
-
import { EnvironmentParser } from '@geekmidas/envkit';
|
|
9264
|
-
|
|
9265
|
-
const email = process.argv[2]?.trim().toLowerCase();
|
|
9266
|
-
if (!email) {
|
|
9267
|
-
console.error('Usage: gkm exec -- tsx scripts/grant-admin.ts <email>');
|
|
9268
|
-
process.exit(1);
|
|
9269
|
-
}
|
|
9270
|
-
|
|
9271
|
-
const db = await database.service.register({
|
|
9272
|
-
envParser: new EnvironmentParser({ ...process.env }),
|
|
9273
|
-
} as never);
|
|
9274
|
-
|
|
9275
|
-
try {
|
|
9276
|
-
const user = await db
|
|
9277
|
-
.selectFrom('users')
|
|
9278
|
-
.select('id')
|
|
9279
|
-
.where('email', '=', email)
|
|
9280
|
-
.executeTakeFirst();
|
|
9281
|
-
if (!user) {
|
|
9282
|
-
console.error(\`No one has signed in as \${email} yet. Sign in once, then run this again.\`);
|
|
9283
|
-
process.exit(1);
|
|
9284
|
-
}
|
|
9285
|
-
|
|
9286
|
-
const role = await db
|
|
9287
|
-
.selectFrom('roles')
|
|
9288
|
-
.select('id')
|
|
9289
|
-
.where('name', '=', SYSTEM_ROLES.SuperAdmin.name)
|
|
9290
|
-
.executeTakeFirstOrThrow();
|
|
9291
|
-
|
|
9292
|
-
await db
|
|
9293
|
-
.insertInto('userRoles')
|
|
9294
|
-
.values({ userId: user.id, roleId: role.id })
|
|
9295
|
-
.onConflict((oc) => oc.columns(['userId', 'roleId']).doNothing())
|
|
9296
|
-
.execute();
|
|
9297
|
-
|
|
9298
|
-
console.log(\`\${email} is a \${SYSTEM_ROLES.SuperAdmin.name}.\`);
|
|
9299
|
-
} finally {
|
|
9300
|
-
await db.destroy();
|
|
9301
|
-
}
|
|
9302
|
-
`
|
|
9303
|
-
};
|
|
9304
|
-
}
|
|
9305
|
-
/**
|
|
9306
9266
|
* The API's feature tests: signing in by email end to end, and the admin
|
|
9307
9267
|
* panel's gate. Each runs in a transaction, against the real auth server and
|
|
9308
9268
|
* the real mail catcher.
|
|
@@ -9365,6 +9325,39 @@ describe('the admin panel', () => {
|
|
|
9365
9325
|
|
|
9366
9326
|
expect(users).toContainEqual(expect.objectContaining({ id: me.id }));
|
|
9367
9327
|
});
|
|
9328
|
+
|
|
9329
|
+
it('lets in an admin the seeds named, on their first sign-in', async ({
|
|
9330
|
+
browser,
|
|
9331
|
+
db,
|
|
9332
|
+
faker,
|
|
9333
|
+
}) => {
|
|
9334
|
+
// What \`03_admins.ts\` writes: a row with no auth user yet, and the role.
|
|
9335
|
+
const email = faker.internet.email();
|
|
9336
|
+
const app = await db.get('database');
|
|
9337
|
+
const admin = await app
|
|
9338
|
+
.insertInto('users')
|
|
9339
|
+
.values({ email, name: 'Admin' })
|
|
9340
|
+
.returning('id')
|
|
9341
|
+
.executeTakeFirstOrThrow();
|
|
9342
|
+
const superAdmin = await app
|
|
9343
|
+
.selectFrom('roles')
|
|
9344
|
+
.select('id')
|
|
9345
|
+
.where('name', '=', SYSTEM_ROLES.SuperAdmin.name)
|
|
9346
|
+
.executeTakeFirstOrThrow();
|
|
9347
|
+
await app
|
|
9348
|
+
.insertInto('userRoles')
|
|
9349
|
+
.values({ userId: admin.id, roleId: superAdmin.id })
|
|
9350
|
+
.execute();
|
|
9351
|
+
|
|
9352
|
+
await browser.signIn(email);
|
|
9353
|
+
|
|
9354
|
+
expect(await browser.api.get('/profiles/me')).toMatchObject({
|
|
9355
|
+
id: admin.id,
|
|
9356
|
+
email,
|
|
9357
|
+
});
|
|
9358
|
+
const { users } = await browser.api.get('/admin/users');
|
|
9359
|
+
expect(users).toContainEqual(expect.objectContaining({ id: admin.id }));
|
|
9360
|
+
});
|
|
9368
9361
|
});
|
|
9369
9362
|
`;
|
|
9370
9363
|
}
|
|
@@ -9663,9 +9656,11 @@ export interface Database {
|
|
|
9663
9656
|
id: Generated<string>;
|
|
9664
9657
|
/**
|
|
9665
9658
|
* The Better Auth user this person signs in as. The auth schema is its
|
|
9666
|
-
* own, so this is a plain column, not a foreign key into it.
|
|
9659
|
+
* own, so this is a plain column, not a foreign key into it. Null for
|
|
9660
|
+
* someone the seeds named who has not signed in yet: their first sign-in
|
|
9661
|
+
* claims the row by email.
|
|
9667
9662
|
*/
|
|
9668
|
-
authUserId: string;
|
|
9663
|
+
authUserId: string | null;
|
|
9669
9664
|
name: string;
|
|
9670
9665
|
email: string;
|
|
9671
9666
|
createdAt: Generated<Date>;
|
|
@@ -9952,8 +9947,9 @@ export async function up(db: Kysely<unknown>): Promise<void> {
|
|
|
9952
9947
|
col.primaryKey().defaultTo(db.fn('gen_random_uuid')),
|
|
9953
9948
|
)
|
|
9954
9949
|
// The Better Auth user this person signs in as. A plain column: the auth
|
|
9955
|
-
// schema is its own, and the id's format is Better Auth's to choose.
|
|
9956
|
-
|
|
9950
|
+
// schema is its own, and the id's format is Better Auth's to choose. Null
|
|
9951
|
+
// until someone the seeds named (an admin) first signs in.
|
|
9952
|
+
.addColumn('auth_user_id', 'text', (col) => col.unique())
|
|
9957
9953
|
.addColumn('name', 'varchar(255)', (col) => col.notNull())
|
|
9958
9954
|
.addColumn('email', 'varchar(255)', (col) => col.notNull().unique())
|
|
9959
9955
|
.addColumn('created_at', 'timestamptz', (col) =>
|
|
@@ -10058,11 +10054,13 @@ export async function down(db: Kysely<unknown>): Promise<void> {
|
|
|
10058
10054
|
* upserts, run after every migration, so a changed list is applied by running
|
|
10059
10055
|
* them again.
|
|
10060
10056
|
*/
|
|
10061
|
-
function accessControlSeeds(
|
|
10057
|
+
function accessControlSeeds(options) {
|
|
10058
|
+
const { name } = options;
|
|
10062
10059
|
const folder = seedFolder(databaseFor().id);
|
|
10063
|
-
return [
|
|
10064
|
-
|
|
10065
|
-
|
|
10060
|
+
return [
|
|
10061
|
+
{
|
|
10062
|
+
path: `${folder}/01_permissions.ts`,
|
|
10063
|
+
content: `import { PERMISSION_KEYS, PERMISSIONS } from '@${name}/models/access';
|
|
10066
10064
|
import type { Kysely } from 'kysely';
|
|
10067
10065
|
|
|
10068
10066
|
type Tables = { permissions: { key: string; description: string } };
|
|
@@ -10093,9 +10091,10 @@ export async function seed(db: Kysely<unknown>): Promise<void> {
|
|
|
10093
10091
|
.execute();
|
|
10094
10092
|
}
|
|
10095
10093
|
`
|
|
10096
|
-
|
|
10097
|
-
|
|
10098
|
-
|
|
10094
|
+
},
|
|
10095
|
+
{
|
|
10096
|
+
path: `${folder}/02_system_roles.ts`,
|
|
10097
|
+
content: `import { SYSTEM_ROLES } from '@${name}/models/access';
|
|
10099
10098
|
import type { Kysely } from 'kysely';
|
|
10100
10099
|
|
|
10101
10100
|
type Tables = {
|
|
@@ -10142,7 +10141,76 @@ export async function seed(db: Kysely<unknown>): Promise<void> {
|
|
|
10142
10141
|
}
|
|
10143
10142
|
}
|
|
10144
10143
|
`
|
|
10145
|
-
|
|
10144
|
+
},
|
|
10145
|
+
adminsSeed(folder, options)
|
|
10146
|
+
];
|
|
10147
|
+
}
|
|
10148
|
+
/**
|
|
10149
|
+
* The Super admins, by email — the first one asked for by `gkm init`. Each
|
|
10150
|
+
* gets a `users` row before they have signed in, which their first sign-in
|
|
10151
|
+
* claims (`memberFor`), so the admin panel lets them in straight away.
|
|
10152
|
+
*/
|
|
10153
|
+
function adminsSeed(folder, options) {
|
|
10154
|
+
const admins = options.adminEmail ? `[\n '${options.adminEmail}',\n]` : "[\n // 'you@example.com',\n]";
|
|
10155
|
+
return {
|
|
10156
|
+
path: `${folder}/03_admins.ts`,
|
|
10157
|
+
content: `import { SYSTEM_ROLES } from '@${options.name}/models/access';
|
|
10158
|
+
import type { Kysely } from 'kysely';
|
|
10159
|
+
|
|
10160
|
+
/**
|
|
10161
|
+
* Who is a Super admin, by the address they sign in with. Add someone here and
|
|
10162
|
+
* run the seeds (\`gkm dev --seed\`, or the next deploy); taking them off the
|
|
10163
|
+
* list does not take the role away — the admin panel does that.
|
|
10164
|
+
*/
|
|
10165
|
+
const ADMINS: string[] = ${admins};
|
|
10166
|
+
|
|
10167
|
+
type Tables = {
|
|
10168
|
+
users: { id?: string; email: string; name: string };
|
|
10169
|
+
roles: { id: string; name: string; is_system: boolean };
|
|
10170
|
+
user_roles: { user_id: string; role_id: string };
|
|
10171
|
+
};
|
|
10172
|
+
|
|
10173
|
+
/**
|
|
10174
|
+
* A \`users\` row for each admin who has none — their first sign-in claims it —
|
|
10175
|
+
* and the Member and Super admin roles. Runs after the system roles seed.
|
|
10176
|
+
*/
|
|
10177
|
+
export async function seed(db: Kysely<unknown>): Promise<void> {
|
|
10178
|
+
// Better Auth stores addresses lowercased; so does every \`users\` row.
|
|
10179
|
+
const emails = ADMINS.map((email) => email.trim().toLowerCase());
|
|
10180
|
+
if (emails.length === 0) return;
|
|
10181
|
+
|
|
10182
|
+
const tables = db.withTables<Tables>();
|
|
10183
|
+
|
|
10184
|
+
await tables
|
|
10185
|
+
.insertInto('users')
|
|
10186
|
+
.values(emails.map((email) => ({ email, name: email.split('@')[0]! })))
|
|
10187
|
+
.onConflict((oc) => oc.column('email').doNothing())
|
|
10188
|
+
.execute();
|
|
10189
|
+
|
|
10190
|
+
const users = await tables
|
|
10191
|
+
.selectFrom('users')
|
|
10192
|
+
.select('id')
|
|
10193
|
+
.where('email', 'in', emails)
|
|
10194
|
+
.execute();
|
|
10195
|
+
const roles = await tables
|
|
10196
|
+
.selectFrom('roles')
|
|
10197
|
+
.select('id')
|
|
10198
|
+
.where('is_system', '=', true)
|
|
10199
|
+
.where('name', 'in', [SYSTEM_ROLES.Member.name, SYSTEM_ROLES.SuperAdmin.name])
|
|
10200
|
+
.execute();
|
|
10201
|
+
|
|
10202
|
+
await tables
|
|
10203
|
+
.insertInto('user_roles')
|
|
10204
|
+
.values(
|
|
10205
|
+
users.flatMap((user) =>
|
|
10206
|
+
roles.map((role) => ({ user_id: user.id!, role_id: role.id })),
|
|
10207
|
+
),
|
|
10208
|
+
)
|
|
10209
|
+
.onConflict((oc) => oc.columns(['user_id', 'role_id']).doNothing())
|
|
10210
|
+
.execute();
|
|
10211
|
+
}
|
|
10212
|
+
`
|
|
10213
|
+
};
|
|
10146
10214
|
}
|
|
10147
10215
|
//#endregion
|
|
10148
10216
|
//#region src/init/generators/monorepo.ts
|
|
@@ -10659,8 +10727,7 @@ export const logger = createLogger();
|
|
|
10659
10727
|
},
|
|
10660
10728
|
workspaceUsersMigration(),
|
|
10661
10729
|
accessControlMigration(),
|
|
10662
|
-
...accessControlSeeds(options
|
|
10663
|
-
grantAdminScript(options)
|
|
10730
|
+
...accessControlSeeds(options)
|
|
10664
10731
|
];
|
|
10665
10732
|
if (uploads) {
|
|
10666
10733
|
const bucket = storageFor();
|
|
@@ -14870,6 +14937,27 @@ function isFullstackTemplate(name) {
|
|
|
14870
14937
|
//#region src/init/index.ts
|
|
14871
14938
|
/** `' staging, prod '` → `['staging', 'prod']`. */
|
|
14872
14939
|
const stageList = (value) => value.split(",").map((name) => name.trim()).filter(Boolean);
|
|
14940
|
+
/** Whether `value` is an email address, as the API's models check one. */
|
|
14941
|
+
const isEmail = (value) => email().safeParse(value.trim()).success;
|
|
14942
|
+
/**
|
|
14943
|
+
* Who `git` says you are, offered as the first admin: the address you most
|
|
14944
|
+
* likely sign in with. Nothing when git has none.
|
|
14945
|
+
*/
|
|
14946
|
+
function gitEmail() {
|
|
14947
|
+
try {
|
|
14948
|
+
const email = execSync("git config user.email", {
|
|
14949
|
+
encoding: "utf-8",
|
|
14950
|
+
stdio: [
|
|
14951
|
+
"ignore",
|
|
14952
|
+
"pipe",
|
|
14953
|
+
"ignore"
|
|
14954
|
+
]
|
|
14955
|
+
}).trim();
|
|
14956
|
+
return isEmail(email) ? email.toLowerCase() : void 0;
|
|
14957
|
+
} catch {
|
|
14958
|
+
return;
|
|
14959
|
+
}
|
|
14960
|
+
}
|
|
14873
14961
|
/** `eu-west-1`, `us-gov-west-1`, `ap-southeast-2`. */
|
|
14874
14962
|
const AWS_REGION = /^[a-z]{2}(-gov)?-[a-z]+-\d$/;
|
|
14875
14963
|
/**
|
|
@@ -14881,6 +14969,7 @@ async function initCommand(projectName, options = {}) {
|
|
|
14881
14969
|
if (options.deploy && !deployTargetChoices.some((choice) => choice.value === options.deploy)) throw new UnknownDeployTarget(options.deploy, deployTargetChoices.map((c) => c.value));
|
|
14882
14970
|
if (options.web && !frontendFrameworkChoices.some((choice) => choice.value === options.web)) throw new UnknownWebFramework(options.web, frontendFrameworkChoices.map((c) => c.value));
|
|
14883
14971
|
if (options.region && !AWS_REGION.test(options.region)) throw new NotAnAwsRegion(options.region);
|
|
14972
|
+
if (options.adminEmail && !isEmail(options.adminEmail)) throw new NotAnEmail(options.adminEmail);
|
|
14884
14973
|
if (options.stages || options.localStage || options.protectedStage) {
|
|
14885
14974
|
const deployed = stageList(options.stages ?? "");
|
|
14886
14975
|
const problems = [
|
|
@@ -15019,6 +15108,13 @@ async function initCommand(projectName, options = {}) {
|
|
|
15019
15108
|
name: "mobileApp",
|
|
15020
15109
|
message: "Include a mobile app? (Expo, with its sign-in and a site for App Store and Play Store reviewers)",
|
|
15021
15110
|
initial: true
|
|
15111
|
+
},
|
|
15112
|
+
{
|
|
15113
|
+
type: (_prev, values) => !options.yes && !options.adminEmail && (options.template === "fullstack" || values.template === "fullstack") ? "text" : null,
|
|
15114
|
+
name: "adminEmail",
|
|
15115
|
+
message: "Admin email (the first Super admin of the admin panel):",
|
|
15116
|
+
initial: gitEmail() ?? "",
|
|
15117
|
+
validate: (value) => isEmail(value) || "An email address, like you@example.com"
|
|
15022
15118
|
}
|
|
15023
15119
|
], { onCancel });
|
|
15024
15120
|
const name = projectName || options.name || answers.name;
|
|
@@ -15053,6 +15149,7 @@ async function initCommand(projectName, options = {}) {
|
|
|
15053
15149
|
const deployTarget = options.deploy ?? (options.yes ? "none" : answers.deployTarget ?? "none");
|
|
15054
15150
|
const frontendFramework = isFullstack ? options.web ?? (options.yes ? "nextjs" : answers.frontendFramework ?? "nextjs") : void 0;
|
|
15055
15151
|
const mobileApp = isFullstack ? options.mobileApp ?? (options.yes ? true : answers.mobileApp ?? true) : void 0;
|
|
15152
|
+
const adminEmail = isFullstack ? (options.adminEmail ?? (options.yes ? gitEmail() : answers.adminEmail))?.trim().toLowerCase() : void 0;
|
|
15056
15153
|
const templateOptions = {
|
|
15057
15154
|
name,
|
|
15058
15155
|
template,
|
|
@@ -15068,7 +15165,8 @@ async function initCommand(projectName, options = {}) {
|
|
|
15068
15165
|
...deployTarget === "sst" ? { region: options.region ?? (options.yes ? "eu-west-1" : answers.region?.trim()) } : {},
|
|
15069
15166
|
constructs,
|
|
15070
15167
|
frontendFramework,
|
|
15071
|
-
...mobileApp !== void 0 ? { mobileApp } : {}
|
|
15168
|
+
...mobileApp !== void 0 ? { mobileApp } : {},
|
|
15169
|
+
...adminEmail ? { adminEmail } : {}
|
|
15072
15170
|
};
|
|
15073
15171
|
const targetDir = join(cwd, name);
|
|
15074
15172
|
const baseTemplate = getTemplate(templateOptions.template);
|
|
@@ -15307,6 +15405,14 @@ function defaultRegistry(name) {
|
|
|
15307
15405
|
return `ghcr.io/${(name ?? "my-org").toLowerCase()}`;
|
|
15308
15406
|
}
|
|
15309
15407
|
/** `--region` that is not shaped like one, e.g. `europe` for `eu-west-1`. */
|
|
15408
|
+
var NotAnEmail = class extends GkmError {
|
|
15409
|
+
value;
|
|
15410
|
+
constructor(value) {
|
|
15411
|
+
super(`"${value}" is not an email address. Give --admin-email the address the first admin signs in with.`);
|
|
15412
|
+
this.value = value;
|
|
15413
|
+
this.name = "NotAnEmail";
|
|
15414
|
+
}
|
|
15415
|
+
};
|
|
15310
15416
|
var NotAnAwsRegion = class extends GkmError {
|
|
15311
15417
|
region;
|
|
15312
15418
|
constructor(region) {
|
|
@@ -16026,7 +16132,7 @@ function testDatabases(reconciled) {
|
|
|
16026
16132
|
* starts without the reference data the app needs.
|
|
16027
16133
|
*/
|
|
16028
16134
|
async function migrateTestStage(workspace, env) {
|
|
16029
|
-
const { migrateAndSeed } = await import("./migrate-
|
|
16135
|
+
const { migrateAndSeed } = await import("./migrate-WyWhSivN.mjs");
|
|
16030
16136
|
const { discover } = await import("./discover-Ca8U75dl.mjs").then((n) => n.a);
|
|
16031
16137
|
const sources = {};
|
|
16032
16138
|
const manifest = await discover({
|
|
@@ -16362,7 +16468,7 @@ const program = new Command();
|
|
|
16362
16468
|
program.name("gkm").description("GeekMidas backend framework CLI").version(version).option("--cwd <path>", "Change working directory").option("--debug", "Enable debug mode (verbose errors with stack traces)").hook("preAction", () => {
|
|
16363
16469
|
if (program.opts().debug) enableDebug();
|
|
16364
16470
|
});
|
|
16365
|
-
program.command("init").description("Scaffold a new project").argument("[name]", "Project name").option("--template <template>", "Project template (minimal, api, fullstack, serverless, worker)").option("--skip-install", "Skip dependency installation", false).option("-y, --yes", "Skip prompts, use defaults", false).option("--monorepo", "Setup as monorepo with packages/models", false).option("--api-path <path>", "API app path in monorepo (default: apps/api)").option("--pm <manager>", "Package manager (pnpm, npm, yarn, bun)").option("--deploy <target>", "Where it deploys (dokploy, compose, sst, none)").option("--region <region>", "AWS region for an SST deploy (e.g. eu-west-1)").option("--registry <registry>", "Container registry for a compose deploy (e.g. ghcr.io/acme)").option("--stages <names>", "Deployed stages, comma-separated (e.g. staging,prod)").option("--protected-stage <name>", "Which deployed stage is production").option("--local-stage <name>", "What gkm dev runs as (e.g. dev)").option("--web <framework>", "Fullstack: what the web site and admin panel use (nextjs, tanstack-start)").option("--mobile-app", "Fullstack: include the Expo app and its store-reviewer site").option("--no-mobile-app", "Fullstack: no mobile app").action(async (name, options) => {
|
|
16471
|
+
program.command("init").description("Scaffold a new project").argument("[name]", "Project name").option("--template <template>", "Project template (minimal, api, fullstack, serverless, worker)").option("--skip-install", "Skip dependency installation", false).option("-y, --yes", "Skip prompts, use defaults", false).option("--monorepo", "Setup as monorepo with packages/models", false).option("--api-path <path>", "API app path in monorepo (default: apps/api)").option("--pm <manager>", "Package manager (pnpm, npm, yarn, bun)").option("--deploy <target>", "Where it deploys (dokploy, compose, sst, none)").option("--region <region>", "AWS region for an SST deploy (e.g. eu-west-1)").option("--registry <registry>", "Container registry for a compose deploy (e.g. ghcr.io/acme)").option("--stages <names>", "Deployed stages, comma-separated (e.g. staging,prod)").option("--protected-stage <name>", "Which deployed stage is production").option("--local-stage <name>", "What gkm dev runs as (e.g. dev)").option("--web <framework>", "Fullstack: what the web site and admin panel use (nextjs, tanstack-start)").option("--mobile-app", "Fullstack: include the Expo app and its store-reviewer site").option("--no-mobile-app", "Fullstack: no mobile app").option("--admin-email <email>", "Fullstack: who the seeds make the first Super admin").action(async (name, options) => {
|
|
16366
16472
|
try {
|
|
16367
16473
|
const globalOptions = program.opts();
|
|
16368
16474
|
if (globalOptions.cwd) process.chdir(globalOptions.cwd);
|
|
@@ -16450,7 +16556,7 @@ program.command("eas:sync").description("Set up a mobile app's EAS project for a
|
|
|
16450
16556
|
try {
|
|
16451
16557
|
const globalOptions = program.opts();
|
|
16452
16558
|
if (globalOptions.cwd) process.chdir(globalOptions.cwd);
|
|
16453
|
-
const { easSync } = await import("./eas-
|
|
16559
|
+
const { easSync } = await import("./eas-DJXhARYb.mjs");
|
|
16454
16560
|
await easSync(options);
|
|
16455
16561
|
} catch (error) {
|
|
16456
16562
|
exitWithError(error);
|
|
@@ -16460,7 +16566,7 @@ program.command("publish").description("Ship a mobile app for a deployed stage:
|
|
|
16460
16566
|
try {
|
|
16461
16567
|
const globalOptions = program.opts();
|
|
16462
16568
|
if (globalOptions.cwd) process.chdir(globalOptions.cwd);
|
|
16463
|
-
const { publish, PublishModeConflict } = await import("./publish-
|
|
16569
|
+
const { publish, PublishModeConflict } = await import("./publish-BBG4zx8E.mjs");
|
|
16464
16570
|
if (options.build && options.update) throw new PublishModeConflict();
|
|
16465
16571
|
const { build, update, ...rest } = options;
|
|
16466
16572
|
await publish({
|
|
@@ -16476,7 +16582,7 @@ program.command("deploy:google-play").description("Let EAS Submit publish a mobi
|
|
|
16476
16582
|
try {
|
|
16477
16583
|
const globalOptions = program.opts();
|
|
16478
16584
|
if (globalOptions.cwd) process.chdir(globalOptions.cwd);
|
|
16479
|
-
const { deployGooglePlay } = await import("./googlePlay-
|
|
16585
|
+
const { deployGooglePlay } = await import("./googlePlay-fw0VWly7.mjs");
|
|
16480
16586
|
await deployGooglePlay(options);
|
|
16481
16587
|
} catch (error) {
|
|
16482
16588
|
exitWithError(error);
|
|
@@ -16498,7 +16604,7 @@ program.command("migrate").description("Apply each database construct's migratio
|
|
|
16498
16604
|
try {
|
|
16499
16605
|
const globalOptions = program.opts();
|
|
16500
16606
|
if (globalOptions.cwd) process.chdir(globalOptions.cwd);
|
|
16501
|
-
const { migrateCommand } = await import("./migrate-
|
|
16607
|
+
const { migrateCommand } = await import("./migrate-WyWhSivN.mjs");
|
|
16502
16608
|
await migrateCommand({
|
|
16503
16609
|
...options,
|
|
16504
16610
|
...construct ? { construct } : {}
|
|
@@ -16511,7 +16617,7 @@ program.command("seed").description("Migrate, then run each database construct's
|
|
|
16511
16617
|
try {
|
|
16512
16618
|
const globalOptions = program.opts();
|
|
16513
16619
|
if (globalOptions.cwd) process.chdir(globalOptions.cwd);
|
|
16514
|
-
const { seedCommand } = await import("./migrate-
|
|
16620
|
+
const { seedCommand } = await import("./migrate-WyWhSivN.mjs");
|
|
16515
16621
|
await seedCommand({
|
|
16516
16622
|
...options,
|
|
16517
16623
|
...construct ? { construct } : {}
|
|
@@ -16524,7 +16630,7 @@ program.command("migration").description("Write a construct's next migration: an
|
|
|
16524
16630
|
try {
|
|
16525
16631
|
const globalOptions = program.opts();
|
|
16526
16632
|
if (globalOptions.cwd) process.chdir(globalOptions.cwd);
|
|
16527
|
-
const { migrationCommand } = await import("./migrate-
|
|
16633
|
+
const { migrationCommand } = await import("./migrate-WyWhSivN.mjs");
|
|
16528
16634
|
await migrationCommand({
|
|
16529
16635
|
construct,
|
|
16530
16636
|
...name ? { name } : {}
|
|
@@ -16624,7 +16730,7 @@ program.command("secrets:add").description("Build the keys a stage must be given
|
|
|
16624
16730
|
try {
|
|
16625
16731
|
const globalOptions = program.opts();
|
|
16626
16732
|
if (globalOptions.cwd) process.chdir(globalOptions.cwd);
|
|
16627
|
-
const { secretsAddCommand } = await import("./add-
|
|
16733
|
+
const { secretsAddCommand } = await import("./add-BcZXHa3Z.mjs");
|
|
16628
16734
|
await secretsAddCommand(options);
|
|
16629
16735
|
} catch (error) {
|
|
16630
16736
|
exitWithError(error);
|
|
@@ -16634,7 +16740,7 @@ program.command("encryption:rotate").description("Add a new current key to an En
|
|
|
16634
16740
|
try {
|
|
16635
16741
|
const globalOptions = program.opts();
|
|
16636
16742
|
if (globalOptions.cwd) process.chdir(globalOptions.cwd);
|
|
16637
|
-
const { encryptionRotateCommand } = await import("./encryption-
|
|
16743
|
+
const { encryptionRotateCommand } = await import("./encryption-CldvLtip.mjs");
|
|
16638
16744
|
await encryptionRotateCommand(construct, options);
|
|
16639
16745
|
} catch (error) {
|
|
16640
16746
|
exitWithError(error);
|
|
@@ -16644,7 +16750,7 @@ program.command("encryption:retire").description("Remove an old key from an Encr
|
|
|
16644
16750
|
try {
|
|
16645
16751
|
const globalOptions = program.opts();
|
|
16646
16752
|
if (globalOptions.cwd) process.chdir(globalOptions.cwd);
|
|
16647
|
-
const { encryptionRetireCommand } = await import("./encryption-
|
|
16753
|
+
const { encryptionRetireCommand } = await import("./encryption-CldvLtip.mjs");
|
|
16648
16754
|
await encryptionRetireCommand(construct, key, options);
|
|
16649
16755
|
} catch (error) {
|
|
16650
16756
|
exitWithError(error);
|
|
@@ -16683,7 +16789,7 @@ program.command("secrets:reconcile").description("Backfill missing custom secret
|
|
|
16683
16789
|
if (globalOptions.cwd) process.chdir(globalOptions.cwd);
|
|
16684
16790
|
const { loadWorkspaceConfig } = await import("./config.mjs");
|
|
16685
16791
|
const { reconcileMissingSecrets } = await import("./reconcile--I7V4Klj.mjs");
|
|
16686
|
-
const { secretsStoreFor } = await import("./seeds-
|
|
16792
|
+
const { secretsStoreFor } = await import("./seeds-CYzoBDg2.mjs").then((n) => n.Rt);
|
|
16687
16793
|
const { workspace } = await loadWorkspaceConfig();
|
|
16688
16794
|
const stage = options.stage ?? workspace.stages.local;
|
|
16689
16795
|
const store = await secretsStoreFor(workspace, stage);
|
|
@@ -16692,7 +16798,7 @@ program.command("secrets:reconcile").description("Backfill missing custom secret
|
|
|
16692
16798
|
console.error(`No secrets found for stage "${stage}". Run "gkm secrets:init --stage ${stage}" first.`);
|
|
16693
16799
|
process.exit(1);
|
|
16694
16800
|
}
|
|
16695
|
-
const { derivedContainers } = await import("./seeds-
|
|
16801
|
+
const { derivedContainers } = await import("./seeds-CYzoBDg2.mjs").then((n) => n.mt);
|
|
16696
16802
|
const result = reconcileMissingSecrets(secrets, workspace, await derivedContainers(workspace, stage));
|
|
16697
16803
|
if (!result) {
|
|
16698
16804
|
console.log(`\n✓ Secrets for stage "${stage}" are up-to-date`);
|
|
@@ -16709,14 +16815,14 @@ program.command("secrets:migrate").description("Copy a deployed stage's secrets
|
|
|
16709
16815
|
try {
|
|
16710
16816
|
const globalOptions = program.opts();
|
|
16711
16817
|
if (globalOptions.cwd) process.chdir(globalOptions.cwd);
|
|
16712
|
-
const { secretsMigrateCommand } = await import("./migrate-
|
|
16818
|
+
const { secretsMigrateCommand } = await import("./migrate-1bHqjfIe.mjs");
|
|
16713
16819
|
await secretsMigrateCommand(options);
|
|
16714
16820
|
} catch (error) {
|
|
16715
16821
|
exitWithError(error);
|
|
16716
16822
|
}
|
|
16717
16823
|
});
|
|
16718
16824
|
program.command("deploy").description("Deploy a stage through its target").option("--target <name>", "Deploy target: dokploy, compose, sst, or one named in deploy.targets (default: deploy.default)").option("--provider <provider>", "[DEPRECATED] Use --target instead").requiredOption("--stage <stage>", "Deployment stage (e.g., production, staging)").option("--tag <tag>", "Image tag (default: stage-timestamp; compose: the commit). Compose pulls a given tag").option("--skip-push", "Skip pushing image to registry").option("--skip-build", "Skip build step (use existing build)").option("--json", "Write events as JSON lines instead of progress; never prompts").option("--dry-run", "Show what would be created or reused; change, build and push nothing").option("--atomic", "If the release fails, roll back every app it released, not only the failed ones").option("--allow-dev-services", "Server targets: run the dev service (MinIO, Mailpit) for every bucket and mail the stage doesn't account for. Not production-grade").option("--skip-dns", "Compose: neither write the public hosts' DNS records nor check they point at GKM_SERVER_IPV4 (a CDN or proxy in front, or records written elsewhere)").option("--rotate-keys", "Deployed stage: each provider issues its runtime keys a successor (the old one is deleted by the next deploy)").option("--retire-old-keys", "Deployed stage: delete a rotated-out key now instead of on the next deploy").action(async (options) => {
|
|
16719
|
-
const { deployCli } = await import("./cli-
|
|
16825
|
+
const { deployCli } = await import("./cli-BkxlWYfI.mjs");
|
|
16720
16826
|
const globalOptions = program.opts();
|
|
16721
16827
|
const code = await deployCli({
|
|
16722
16828
|
cwd: resolve(globalOptions.cwd ?? process.cwd()),
|
|
@@ -16736,7 +16842,7 @@ program.command("deploy").description("Deploy a stage through its target").optio
|
|
|
16736
16842
|
});
|
|
16737
16843
|
program.command("deploy:rollback").description("Put a stage's app back on its previous release (Dokploy): one app with --app, every app with --atomic").requiredOption("--stage <stage>", "A deployed stage").option("--app <app>", "The app to roll back").option("--atomic", "Roll back every app that has an earlier release").action(async (options) => {
|
|
16738
16844
|
try {
|
|
16739
|
-
const { rollbackStage } = await import("./rollback-
|
|
16845
|
+
const { rollbackStage } = await import("./rollback-DaEmEC2Y.mjs").then((n) => n.a);
|
|
16740
16846
|
const { terminalCredentials } = await import("./terminal-CybB-cjk.mjs");
|
|
16741
16847
|
const globalOptions = program.opts();
|
|
16742
16848
|
await rollbackStage({
|
|
@@ -16755,7 +16861,7 @@ program.command("compose:server").description("Set up a stage's server for compo
|
|
|
16755
16861
|
try {
|
|
16756
16862
|
const globalOptions = program.opts();
|
|
16757
16863
|
if (globalOptions.cwd) process.chdir(globalOptions.cwd);
|
|
16758
|
-
const { composeServerCommand } = await import("./serverSetup-
|
|
16864
|
+
const { composeServerCommand } = await import("./serverSetup-0h1Vh5un.mjs");
|
|
16759
16865
|
await composeServerCommand(options);
|
|
16760
16866
|
} catch (error) {
|
|
16761
16867
|
exitWithError(error);
|
|
@@ -16780,7 +16886,7 @@ program.command("deploy:github").description("Let GitHub Actions deploy a stage:
|
|
|
16780
16886
|
try {
|
|
16781
16887
|
const globalOptions = program.opts();
|
|
16782
16888
|
if (globalOptions.cwd) process.chdir(globalOptions.cwd);
|
|
16783
|
-
const { deployGithubCommand } = await import("./github-
|
|
16889
|
+
const { deployGithubCommand } = await import("./github-BMPci2wg.mjs");
|
|
16784
16890
|
await deployGithubCommand(options);
|
|
16785
16891
|
} catch (error) {
|
|
16786
16892
|
exitWithError(error);
|