@korajs/cli 0.3.2 → 0.4.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/bin.cjs +385 -288
- package/dist/bin.cjs.map +1 -1
- package/dist/bin.js +25 -11
- package/dist/bin.js.map +1 -1
- package/dist/{chunk-KTSRAPSE.js → chunk-CMSX76KM.js} +108 -65
- package/dist/chunk-CMSX76KM.js.map +1 -0
- package/dist/{chunk-ZGYRDYXS.js → chunk-MVP5PDT4.js} +22 -4
- package/dist/chunk-MVP5PDT4.js.map +1 -0
- package/dist/{chunk-E7OCVRYL.js → chunk-YGVO4POI.js} +242 -215
- package/dist/chunk-YGVO4POI.js.map +1 -0
- package/dist/create.cjs +122 -66
- package/dist/create.cjs.map +1 -1
- package/dist/create.js +2 -2
- package/dist/index.cjs +348 -278
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +31 -26
- package/dist/index.d.ts +31 -26
- package/dist/index.js +2 -2
- package/package.json +2 -2
- package/templates/tauri-react/.env.example +7 -0
- package/templates/tauri-react/.github/workflows/release-desktop.yml +107 -0
- package/templates/tauri-react/README.md.hbs +148 -0
- package/templates/tauri-react/dev.ts +37 -0
- package/templates/tauri-react/index.html.hbs +16 -0
- package/templates/tauri-react/kora.config.ts +17 -0
- package/templates/tauri-react/package.json.hbs +44 -0
- package/templates/tauri-react/server.ts +23 -0
- package/templates/tauri-react/src/App.tsx +578 -0
- package/templates/tauri-react/src/AppShell.tsx +116 -0
- package/templates/tauri-react/src/SetupScreen.tsx +239 -0
- package/templates/tauri-react/src/main.tsx +9 -0
- package/templates/tauri-react/src/schema.ts +15 -0
- package/templates/tauri-react/src/sync-config.ts +103 -0
- package/templates/tauri-react/src/updater.ts +38 -0
- package/templates/tauri-react/src-tauri/Cargo.toml +19 -0
- package/templates/tauri-react/src-tauri/build.rs +3 -0
- package/templates/tauri-react/src-tauri/capabilities/default.json +12 -0
- package/templates/tauri-react/src-tauri/icons/128x128.png +0 -0
- package/templates/tauri-react/src-tauri/icons/128x128@2x.png +0 -0
- package/templates/tauri-react/src-tauri/icons/32x32.png +0 -0
- package/templates/tauri-react/src-tauri/icons/icon.icns +0 -0
- package/templates/tauri-react/src-tauri/icons/icon.ico +0 -0
- package/templates/tauri-react/src-tauri/src/lib.rs +8 -0
- package/templates/tauri-react/src-tauri/src/main.rs +6 -0
- package/templates/tauri-react/src-tauri/tauri.conf.json +44 -0
- package/templates/tauri-react/tsconfig.json +15 -0
- package/templates/tauri-react/vite.config.ts +15 -0
- package/dist/chunk-E7OCVRYL.js.map +0 -1
- package/dist/chunk-KTSRAPSE.js.map +0 -1
- package/dist/chunk-ZGYRDYXS.js.map +0 -1
package/dist/bin.cjs
CHANGED
|
@@ -88,6 +88,7 @@ var DevServerError = class extends import_core.KoraError {
|
|
|
88
88
|
// src/prompts/preferences.ts
|
|
89
89
|
var import_conf = __toESM(require("conf"), 1);
|
|
90
90
|
var DEFAULT_PREFERENCES = {
|
|
91
|
+
platform: "web",
|
|
91
92
|
framework: "react",
|
|
92
93
|
tailwind: true,
|
|
93
94
|
sync: true,
|
|
@@ -189,6 +190,7 @@ function promptConfirm(message, defaultValue = false, options) {
|
|
|
189
190
|
resolve9(false);
|
|
190
191
|
return;
|
|
191
192
|
}
|
|
193
|
+
;
|
|
192
194
|
(options?.output ?? process.stdout).write(" Please answer with y or n\n");
|
|
193
195
|
ask();
|
|
194
196
|
});
|
|
@@ -294,7 +296,8 @@ var TEMPLATES = [
|
|
|
294
296
|
"react-tailwind-sync",
|
|
295
297
|
"react-tailwind",
|
|
296
298
|
"react-sync",
|
|
297
|
-
"react-basic"
|
|
299
|
+
"react-basic",
|
|
300
|
+
"tauri-react"
|
|
298
301
|
];
|
|
299
302
|
|
|
300
303
|
// src/utils/fs-helpers.ts
|
|
@@ -562,12 +565,16 @@ async function findNearestAncestorWithEntry(startDir, entryName) {
|
|
|
562
565
|
|
|
563
566
|
// src/commands/create/options.ts
|
|
564
567
|
function determineTemplateFromSelections(input) {
|
|
568
|
+
if (input.platform === "desktop-tauri") return "tauri-react";
|
|
565
569
|
const shouldSync = input.sync && input.db !== "none";
|
|
566
570
|
if (input.tailwind && shouldSync) return "react-tailwind-sync";
|
|
567
571
|
if (input.tailwind && !shouldSync) return "react-tailwind";
|
|
568
572
|
if (!input.tailwind && shouldSync) return "react-sync";
|
|
569
573
|
return "react-basic";
|
|
570
574
|
}
|
|
575
|
+
function isPlatformValue(value) {
|
|
576
|
+
return value === "web" || value === "desktop-tauri";
|
|
577
|
+
}
|
|
571
578
|
function isFrameworkValue(value) {
|
|
572
579
|
return value === "react" || value === "vue" || value === "svelte" || value === "solid";
|
|
573
580
|
}
|
|
@@ -602,83 +609,110 @@ async function resolveCreatePreferencesFlow(params) {
|
|
|
602
609
|
usedStoredPreferences = true;
|
|
603
610
|
}
|
|
604
611
|
}
|
|
605
|
-
if (flags.
|
|
606
|
-
if (!
|
|
607
|
-
throw new Error(
|
|
608
|
-
`Invalid --framework value "${flags.framework}". Expected one of: react, vue, svelte, solid.`
|
|
609
|
-
);
|
|
610
|
-
}
|
|
611
|
-
effective.framework = flags.framework;
|
|
612
|
-
} else if (!flags.useDefaults && !usedStoredPreferences) {
|
|
613
|
-
effective.framework = await prompts.select("UI framework:", [
|
|
614
|
-
{ label: "React", value: "react" },
|
|
615
|
-
{ label: "Vue (coming soon)", value: "vue", disabled: true },
|
|
616
|
-
{ label: "Svelte (coming soon)", value: "svelte", disabled: true },
|
|
617
|
-
{ label: "Solid (coming soon)", value: "solid", disabled: true }
|
|
618
|
-
]);
|
|
619
|
-
}
|
|
620
|
-
if (flags.auth !== void 0) {
|
|
621
|
-
if (!isAuthValue(flags.auth)) {
|
|
612
|
+
if (flags.platform !== void 0) {
|
|
613
|
+
if (!isPlatformValue(flags.platform)) {
|
|
622
614
|
throw new Error(
|
|
623
|
-
`Invalid --
|
|
615
|
+
`Invalid --platform value "${flags.platform}". Expected one of: web, desktop-tauri.`
|
|
624
616
|
);
|
|
625
617
|
}
|
|
626
|
-
effective.
|
|
627
|
-
} else if (!flags.useDefaults && !usedStoredPreferences) {
|
|
628
|
-
effective.auth = await prompts.select("Authentication:", [
|
|
629
|
-
{ label: "None", value: "none" },
|
|
630
|
-
{ label: "Email + Password (coming soon)", value: "email-password", disabled: true },
|
|
631
|
-
{ label: "OAuth (coming soon)", value: "oauth", disabled: true }
|
|
632
|
-
]);
|
|
633
|
-
}
|
|
634
|
-
if (flags.tailwind !== void 0) {
|
|
635
|
-
effective.tailwind = flags.tailwind;
|
|
636
|
-
} else if (!flags.useDefaults && !usedStoredPreferences) {
|
|
637
|
-
effective.tailwind = await prompts.confirm("Use Tailwind CSS?", true);
|
|
638
|
-
}
|
|
639
|
-
if (flags.sync !== void 0) {
|
|
640
|
-
effective.sync = flags.sync;
|
|
641
|
-
} else if (!flags.useDefaults && !usedStoredPreferences) {
|
|
642
|
-
effective.sync = await prompts.confirm("Enable multi-device sync?", true);
|
|
643
|
-
}
|
|
644
|
-
if (flags.db !== void 0) {
|
|
645
|
-
if (!isDatabaseValue(flags.db)) {
|
|
646
|
-
throw new Error(`Invalid --db value "${flags.db}". Expected one of: none, sqlite, postgres.`);
|
|
647
|
-
}
|
|
648
|
-
effective.db = flags.db;
|
|
649
|
-
} else if (!effective.sync) {
|
|
650
|
-
effective.db = "none";
|
|
618
|
+
effective.platform = flags.platform;
|
|
651
619
|
} else if (!flags.useDefaults && !usedStoredPreferences) {
|
|
652
|
-
effective.
|
|
653
|
-
{ label: "
|
|
654
|
-
{ label: "
|
|
620
|
+
effective.platform = await prompts.select("Platform:", [
|
|
621
|
+
{ label: "Web (browser)", value: "web" },
|
|
622
|
+
{ label: "Desktop (Tauri \u2014 native SQLite)", value: "desktop-tauri" }
|
|
655
623
|
]);
|
|
656
624
|
}
|
|
657
|
-
|
|
625
|
+
const isTauri = effective.platform === "desktop-tauri";
|
|
626
|
+
if (isTauri) {
|
|
627
|
+
effective.framework = "react";
|
|
628
|
+
effective.tailwind = false;
|
|
629
|
+
effective.sync = true;
|
|
630
|
+
effective.db = "sqlite";
|
|
658
631
|
effective.dbProvider = "none";
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
632
|
+
effective.auth = "none";
|
|
633
|
+
} else {
|
|
634
|
+
if (flags.framework !== void 0) {
|
|
635
|
+
if (!isFrameworkValue(flags.framework)) {
|
|
636
|
+
throw new Error(
|
|
637
|
+
`Invalid --framework value "${flags.framework}". Expected one of: react, vue, svelte, solid.`
|
|
638
|
+
);
|
|
639
|
+
}
|
|
640
|
+
effective.framework = flags.framework;
|
|
641
|
+
} else if (!flags.useDefaults && !usedStoredPreferences) {
|
|
642
|
+
effective.framework = await prompts.select("UI framework:", [
|
|
643
|
+
{ label: "React", value: "react" },
|
|
644
|
+
{ label: "Vue (coming soon)", value: "vue", disabled: true },
|
|
645
|
+
{ label: "Svelte (coming soon)", value: "svelte", disabled: true },
|
|
646
|
+
{ label: "Solid (coming soon)", value: "solid", disabled: true }
|
|
647
|
+
]);
|
|
648
|
+
}
|
|
649
|
+
if (flags.auth !== void 0) {
|
|
650
|
+
if (!isAuthValue(flags.auth)) {
|
|
651
|
+
throw new Error(
|
|
652
|
+
`Invalid --auth value "${flags.auth}". Expected one of: none, email-password, oauth.`
|
|
653
|
+
);
|
|
654
|
+
}
|
|
655
|
+
effective.auth = flags.auth;
|
|
656
|
+
} else if (!flags.useDefaults && !usedStoredPreferences) {
|
|
657
|
+
effective.auth = await prompts.select("Authentication:", [
|
|
658
|
+
{ label: "None", value: "none" },
|
|
659
|
+
{ label: "Email + Password (coming soon)", value: "email-password", disabled: true },
|
|
660
|
+
{ label: "OAuth (coming soon)", value: "oauth", disabled: true }
|
|
661
|
+
]);
|
|
662
|
+
}
|
|
663
|
+
if (flags.tailwind !== void 0) {
|
|
664
|
+
effective.tailwind = flags.tailwind;
|
|
665
|
+
} else if (!flags.useDefaults && !usedStoredPreferences) {
|
|
666
|
+
effective.tailwind = await prompts.confirm("Use Tailwind CSS?", true);
|
|
667
|
+
}
|
|
668
|
+
if (flags.sync !== void 0) {
|
|
669
|
+
effective.sync = flags.sync;
|
|
670
|
+
} else if (!flags.useDefaults && !usedStoredPreferences) {
|
|
671
|
+
effective.sync = await prompts.confirm("Enable multi-device sync?", true);
|
|
672
|
+
}
|
|
673
|
+
if (flags.db !== void 0) {
|
|
674
|
+
if (!isDatabaseValue(flags.db)) {
|
|
675
|
+
throw new Error(
|
|
676
|
+
`Invalid --db value "${flags.db}". Expected one of: none, sqlite, postgres.`
|
|
677
|
+
);
|
|
678
|
+
}
|
|
679
|
+
effective.db = flags.db;
|
|
680
|
+
} else if (!effective.sync) {
|
|
681
|
+
effective.db = "none";
|
|
682
|
+
} else if (!flags.useDefaults && !usedStoredPreferences) {
|
|
683
|
+
effective.db = await prompts.select("Server-side database:", [
|
|
684
|
+
{ label: "SQLite (zero-config)", value: "sqlite" },
|
|
685
|
+
{ label: "PostgreSQL (production-scale)", value: "postgres" }
|
|
686
|
+
]);
|
|
687
|
+
}
|
|
688
|
+
if (effective.db !== "postgres") {
|
|
689
|
+
effective.dbProvider = "none";
|
|
690
|
+
} else if (flags.dbProvider !== void 0) {
|
|
691
|
+
if (!isDatabaseProviderValue(flags.dbProvider)) {
|
|
692
|
+
throw new Error(
|
|
693
|
+
`Invalid --db-provider value "${flags.dbProvider}". Expected one of: none, local, supabase, neon, railway, vercel-postgres, custom.`
|
|
694
|
+
);
|
|
695
|
+
}
|
|
696
|
+
effective.dbProvider = flags.dbProvider;
|
|
697
|
+
} else if (!flags.useDefaults && !usedStoredPreferences) {
|
|
698
|
+
effective.dbProvider = await prompts.select("Database provider:", [
|
|
699
|
+
{ label: "Local Postgres", value: "local" },
|
|
700
|
+
{ label: "Supabase", value: "supabase" },
|
|
701
|
+
{ label: "Neon", value: "neon" },
|
|
702
|
+
{ label: "Railway", value: "railway" },
|
|
703
|
+
{ label: "Vercel Postgres", value: "vercel-postgres" },
|
|
704
|
+
{ label: "Custom connection string", value: "custom" }
|
|
705
|
+
]);
|
|
664
706
|
}
|
|
665
|
-
effective.dbProvider = flags.dbProvider;
|
|
666
|
-
} else if (!flags.useDefaults && !usedStoredPreferences) {
|
|
667
|
-
effective.dbProvider = await prompts.select("Database provider:", [
|
|
668
|
-
{ label: "Local Postgres", value: "local" },
|
|
669
|
-
{ label: "Supabase", value: "supabase" },
|
|
670
|
-
{ label: "Neon", value: "neon" },
|
|
671
|
-
{ label: "Railway", value: "railway" },
|
|
672
|
-
{ label: "Vercel Postgres", value: "vercel-postgres" },
|
|
673
|
-
{ label: "Custom connection string", value: "custom" }
|
|
674
|
-
]);
|
|
675
707
|
}
|
|
676
708
|
const template = determineTemplateFromSelections({
|
|
709
|
+
platform: effective.platform,
|
|
677
710
|
tailwind: effective.tailwind,
|
|
678
711
|
sync: effective.sync,
|
|
679
712
|
db: effective.db
|
|
680
713
|
});
|
|
681
714
|
return {
|
|
715
|
+
platform: effective.platform,
|
|
682
716
|
framework: effective.framework,
|
|
683
717
|
auth: effective.auth,
|
|
684
718
|
db: effective.db,
|
|
@@ -694,6 +728,7 @@ function shouldSavePreferences(flags) {
|
|
|
694
728
|
}
|
|
695
729
|
function saveResolvedPreferences(store, resolution) {
|
|
696
730
|
store.saveCreatePreferences({
|
|
731
|
+
platform: resolution.platform,
|
|
697
732
|
framework: resolution.framework,
|
|
698
733
|
tailwind: resolution.tailwind,
|
|
699
734
|
sync: resolution.sync,
|
|
@@ -704,12 +739,15 @@ function saveResolvedPreferences(store, resolution) {
|
|
|
704
739
|
});
|
|
705
740
|
}
|
|
706
741
|
function hasExplicitPreferenceFlags(flags) {
|
|
707
|
-
return flags.framework !== void 0 || flags.auth !== void 0 || flags.db !== void 0 || flags.dbProvider !== void 0 || flags.tailwind !== void 0 || flags.sync !== void 0;
|
|
742
|
+
return flags.platform !== void 0 || flags.framework !== void 0 || flags.auth !== void 0 || flags.db !== void 0 || flags.dbProvider !== void 0 || flags.tailwind !== void 0 || flags.sync !== void 0;
|
|
708
743
|
}
|
|
709
744
|
function promptSupportsRichOptions() {
|
|
710
745
|
return typeof process !== "undefined" && process.stdin.isTTY && process.stdout.isTTY;
|
|
711
746
|
}
|
|
712
747
|
function formatStoredPreferenceLabel(preferences) {
|
|
748
|
+
if (preferences.platform === "desktop-tauri") {
|
|
749
|
+
return `Use previous settings (tauri-desktop + ${preferences.packageManager})`;
|
|
750
|
+
}
|
|
713
751
|
const syncLabel = preferences.sync ? `sync/${preferences.db}` : "local-only";
|
|
714
752
|
const styleLabel = preferences.tailwind ? "tailwind" : "css";
|
|
715
753
|
return `Use previous settings (${preferences.framework} + ${styleLabel} + ${syncLabel} + ${preferences.packageManager})`;
|
|
@@ -811,7 +849,7 @@ async function applySyncProviderPreset(options) {
|
|
|
811
849
|
await (0, import_promises3.writeFile)(readmePath, readmeTemplate, "utf-8");
|
|
812
850
|
}
|
|
813
851
|
function isSyncTemplate(template) {
|
|
814
|
-
return template === "react-sync" || template === "react-tailwind-sync";
|
|
852
|
+
return template === "react-sync" || template === "react-tailwind-sync" || template === "tauri-react";
|
|
815
853
|
}
|
|
816
854
|
function getProviderDisplayName(provider) {
|
|
817
855
|
switch (provider) {
|
|
@@ -927,6 +965,18 @@ function createCompatibilityLayerPlan(templateName) {
|
|
|
927
965
|
authLayer
|
|
928
966
|
]
|
|
929
967
|
};
|
|
968
|
+
case "tauri-react":
|
|
969
|
+
return {
|
|
970
|
+
compatibilityTarget: templateName,
|
|
971
|
+
layers: [
|
|
972
|
+
{ category: "base", name: "tauri", sourceTemplate: "tauri-react" },
|
|
973
|
+
uiLayer,
|
|
974
|
+
{ category: "style", name: "plain", sourceTemplate: null },
|
|
975
|
+
{ category: "sync", name: "enabled", sourceTemplate: null },
|
|
976
|
+
{ category: "db", name: "tauri-sqlite", sourceTemplate: null },
|
|
977
|
+
authLayer
|
|
978
|
+
]
|
|
979
|
+
};
|
|
930
980
|
}
|
|
931
981
|
}
|
|
932
982
|
async function composeTemplateLayers(plan, targetDir, context) {
|
|
@@ -983,9 +1033,13 @@ var createCommand = (0, import_citty.defineCommand)({
|
|
|
983
1033
|
description: "Project directory name",
|
|
984
1034
|
required: false
|
|
985
1035
|
},
|
|
1036
|
+
platform: {
|
|
1037
|
+
type: "string",
|
|
1038
|
+
description: "Target platform (web, desktop-tauri)"
|
|
1039
|
+
},
|
|
986
1040
|
template: {
|
|
987
1041
|
type: "string",
|
|
988
|
-
description: "Project template (react-tailwind-sync, react-tailwind, react-sync, react-basic)"
|
|
1042
|
+
description: "Project template (react-tailwind-sync, react-tailwind, react-sync, react-basic, tauri-react)"
|
|
989
1043
|
},
|
|
990
1044
|
pm: {
|
|
991
1045
|
type: "string",
|
|
@@ -1056,6 +1110,7 @@ var createCommand = (0, import_citty.defineCommand)({
|
|
|
1056
1110
|
return;
|
|
1057
1111
|
}
|
|
1058
1112
|
const preferenceFlags = {
|
|
1113
|
+
platform: typeof args.platform === "string" ? args.platform : void 0,
|
|
1059
1114
|
framework: typeof args.framework === "string" ? args.framework : void 0,
|
|
1060
1115
|
auth: typeof args.auth === "string" ? args.auth : void 0,
|
|
1061
1116
|
db: typeof args.db === "string" ? args.db : void 0,
|
|
@@ -1163,6 +1218,7 @@ var createCommand = (0, import_citty.defineCommand)({
|
|
|
1163
1218
|
logger.success("Project scaffolded");
|
|
1164
1219
|
if (shouldSavePreferences(preferenceFlags)) {
|
|
1165
1220
|
saveResolvedPreferences(preferenceStore, {
|
|
1221
|
+
platform: selection.platform,
|
|
1166
1222
|
framework: selection.framework,
|
|
1167
1223
|
auth: selection.auth,
|
|
1168
1224
|
db: selection.db,
|
|
@@ -1214,7 +1270,7 @@ function isValidPackageManager(value) {
|
|
|
1214
1270
|
return PACKAGE_MANAGERS.includes(value);
|
|
1215
1271
|
}
|
|
1216
1272
|
function isSyncTemplate2(template) {
|
|
1217
|
-
return template === "react-sync" || template === "react-tailwind-sync";
|
|
1273
|
+
return template === "react-sync" || template === "react-tailwind-sync" || template === "tauri-react";
|
|
1218
1274
|
}
|
|
1219
1275
|
function formatDbProviderForLog(dbProvider) {
|
|
1220
1276
|
switch (dbProvider) {
|
|
@@ -1299,7 +1355,15 @@ var import_node_path16 = require("path");
|
|
|
1299
1355
|
var import_citty2 = require("citty");
|
|
1300
1356
|
|
|
1301
1357
|
// src/commands/deploy/adapters/adapter.ts
|
|
1302
|
-
var DEPLOY_PLATFORMS = [
|
|
1358
|
+
var DEPLOY_PLATFORMS = [
|
|
1359
|
+
"fly",
|
|
1360
|
+
"railway",
|
|
1361
|
+
"aws-ecs",
|
|
1362
|
+
"aws-lightsail",
|
|
1363
|
+
"render",
|
|
1364
|
+
"docker",
|
|
1365
|
+
"kora-cloud"
|
|
1366
|
+
];
|
|
1303
1367
|
function isDeployPlatform(value) {
|
|
1304
1368
|
return DEPLOY_PLATFORMS.includes(value);
|
|
1305
1369
|
}
|
|
@@ -1310,8 +1374,8 @@ var import_node_path8 = require("path");
|
|
|
1310
1374
|
|
|
1311
1375
|
// src/commands/deploy/builder/client-builder.ts
|
|
1312
1376
|
var import_node_child_process3 = require("child_process");
|
|
1313
|
-
var import_promises5 = require("fs/promises");
|
|
1314
1377
|
var import_node_fs3 = require("fs");
|
|
1378
|
+
var import_promises5 = require("fs/promises");
|
|
1315
1379
|
var import_node_path6 = require("path");
|
|
1316
1380
|
async function buildClient(options) {
|
|
1317
1381
|
const viteEntryPoint = await resolveProjectBinaryEntryPoint(options.projectRoot, "vite", "vite");
|
|
@@ -1469,37 +1533,46 @@ var AwsEcsAdapter = class {
|
|
|
1469
1533
|
};
|
|
1470
1534
|
const region = config.region ?? "us-east-1";
|
|
1471
1535
|
const repoName = `kora/${config.appName}`;
|
|
1472
|
-
const createRepo = await this.runner.run(
|
|
1473
|
-
"
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1536
|
+
const createRepo = await this.runner.run(
|
|
1537
|
+
"aws",
|
|
1538
|
+
[
|
|
1539
|
+
"ecr",
|
|
1540
|
+
"create-repository",
|
|
1541
|
+
"--repository-name",
|
|
1542
|
+
repoName,
|
|
1543
|
+
"--region",
|
|
1544
|
+
region,
|
|
1545
|
+
"--image-scanning-configuration",
|
|
1546
|
+
"scanOnPush=true"
|
|
1547
|
+
],
|
|
1548
|
+
config.projectRoot
|
|
1549
|
+
);
|
|
1482
1550
|
if (createRepo.exitCode !== 0 && !createRepo.stderr.includes("RepositoryAlreadyExistsException")) {
|
|
1483
1551
|
throw new Error(`Failed to create ECR repository: ${createRepo.stderr}`);
|
|
1484
1552
|
}
|
|
1485
|
-
const identity = await this.runner.run(
|
|
1553
|
+
const identity = await this.runner.run(
|
|
1554
|
+
"aws",
|
|
1555
|
+
["sts", "get-caller-identity", "--query", "Account", "--output", "text"],
|
|
1556
|
+
config.projectRoot
|
|
1557
|
+
);
|
|
1486
1558
|
const accountId = identity.stdout.trim();
|
|
1487
|
-
await this.runner.run(
|
|
1488
|
-
"
|
|
1489
|
-
"create-cluster",
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1559
|
+
await this.runner.run(
|
|
1560
|
+
"aws",
|
|
1561
|
+
["ecs", "create-cluster", "--cluster-name", config.appName, "--region", region],
|
|
1562
|
+
config.projectRoot
|
|
1563
|
+
);
|
|
1564
|
+
await this.runner.run(
|
|
1565
|
+
"aws",
|
|
1566
|
+
[
|
|
1567
|
+
"logs",
|
|
1568
|
+
"create-log-group",
|
|
1569
|
+
"--log-group-name",
|
|
1570
|
+
`/ecs/${config.appName}`,
|
|
1571
|
+
"--region",
|
|
1572
|
+
region
|
|
1573
|
+
],
|
|
1574
|
+
config.projectRoot
|
|
1575
|
+
);
|
|
1503
1576
|
return {
|
|
1504
1577
|
applicationId: `${accountId}.dkr.ecr.${region}.amazonaws.com/${repoName}`,
|
|
1505
1578
|
databaseId: null,
|
|
@@ -1532,50 +1605,42 @@ var AwsEcsAdapter = class {
|
|
|
1532
1605
|
const context = this.requireContext();
|
|
1533
1606
|
const region = context.region ?? "us-east-1";
|
|
1534
1607
|
const repoName = `kora/${context.appName}`;
|
|
1535
|
-
const loginPassword = await this.runner.run(
|
|
1536
|
-
"
|
|
1537
|
-
"get-login-password",
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
], context.projectRoot);
|
|
1608
|
+
const loginPassword = await this.runner.run(
|
|
1609
|
+
"aws",
|
|
1610
|
+
["ecr", "get-login-password", "--region", region],
|
|
1611
|
+
context.projectRoot
|
|
1612
|
+
);
|
|
1541
1613
|
if (loginPassword.exitCode !== 0) {
|
|
1542
1614
|
throw new Error(`ECR login failed: ${loginPassword.stderr}`);
|
|
1543
1615
|
}
|
|
1544
|
-
const identity = await this.runner.run(
|
|
1545
|
-
"
|
|
1546
|
-
"get-caller-identity",
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
"--output",
|
|
1550
|
-
"text"
|
|
1551
|
-
], context.projectRoot);
|
|
1616
|
+
const identity = await this.runner.run(
|
|
1617
|
+
"aws",
|
|
1618
|
+
["sts", "get-caller-identity", "--query", "Account", "--output", "text"],
|
|
1619
|
+
context.projectRoot
|
|
1620
|
+
);
|
|
1552
1621
|
const accountId = identity.stdout.trim();
|
|
1553
1622
|
const ecrUri = `${accountId}.dkr.ecr.${region}.amazonaws.com`;
|
|
1554
1623
|
const imageUri = `${ecrUri}/${repoName}:latest`;
|
|
1555
|
-
const dockerLogin = await this.runner.run(
|
|
1556
|
-
"
|
|
1557
|
-
"--username",
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
ecrUri
|
|
1561
|
-
], artifacts.deployDirectory);
|
|
1624
|
+
const dockerLogin = await this.runner.run(
|
|
1625
|
+
"docker",
|
|
1626
|
+
["login", "--username", "AWS", "--password-stdin", ecrUri],
|
|
1627
|
+
artifacts.deployDirectory
|
|
1628
|
+
);
|
|
1562
1629
|
this.logger.step("Building Docker image...");
|
|
1563
|
-
const dockerBuild = await this.runner.run(
|
|
1564
|
-
"
|
|
1565
|
-
"--platform",
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
imageUri,
|
|
1569
|
-
"."
|
|
1570
|
-
], artifacts.deployDirectory);
|
|
1630
|
+
const dockerBuild = await this.runner.run(
|
|
1631
|
+
"docker",
|
|
1632
|
+
["build", "--platform", "linux/amd64", "-t", imageUri, "."],
|
|
1633
|
+
artifacts.deployDirectory
|
|
1634
|
+
);
|
|
1571
1635
|
if (dockerBuild.exitCode !== 0) {
|
|
1572
1636
|
throw new Error(`Docker build failed: ${dockerBuild.stderr}`);
|
|
1573
1637
|
}
|
|
1574
1638
|
this.logger.step("Pushing image to ECR...");
|
|
1575
|
-
const dockerPush = await this.runner.run(
|
|
1576
|
-
"
|
|
1577
|
-
imageUri
|
|
1578
|
-
|
|
1639
|
+
const dockerPush = await this.runner.run(
|
|
1640
|
+
"docker",
|
|
1641
|
+
["push", imageUri],
|
|
1642
|
+
artifacts.deployDirectory
|
|
1643
|
+
);
|
|
1579
1644
|
if (dockerPush.exitCode !== 0) {
|
|
1580
1645
|
throw new Error(`Docker push failed: ${dockerPush.stderr}`);
|
|
1581
1646
|
}
|
|
@@ -1586,52 +1651,55 @@ var AwsEcsAdapter = class {
|
|
|
1586
1651
|
cpu: "256",
|
|
1587
1652
|
memory: "512",
|
|
1588
1653
|
executionRoleArn: `arn:aws:iam::${accountId}:role/ecsTaskExecutionRole`,
|
|
1589
|
-
containerDefinitions: [
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1654
|
+
containerDefinitions: [
|
|
1655
|
+
{
|
|
1656
|
+
name: context.appName,
|
|
1657
|
+
image: imageUri,
|
|
1658
|
+
essential: true,
|
|
1659
|
+
portMappings: [{ containerPort: 3001, protocol: "tcp" }],
|
|
1660
|
+
logConfiguration: {
|
|
1661
|
+
logDriver: "awslogs",
|
|
1662
|
+
options: {
|
|
1663
|
+
"awslogs-group": `/ecs/${context.appName}`,
|
|
1664
|
+
"awslogs-region": region,
|
|
1665
|
+
"awslogs-stream-prefix": "ecs"
|
|
1666
|
+
}
|
|
1667
|
+
},
|
|
1668
|
+
healthCheck: {
|
|
1669
|
+
command: ["CMD-SHELL", "curl -f http://localhost:3001/health || exit 1"],
|
|
1670
|
+
interval: 30,
|
|
1671
|
+
timeout: 5,
|
|
1672
|
+
retries: 3,
|
|
1673
|
+
startPeriod: 60
|
|
1600
1674
|
}
|
|
1601
|
-
},
|
|
1602
|
-
healthCheck: {
|
|
1603
|
-
command: ["CMD-SHELL", "curl -f http://localhost:3001/health || exit 1"],
|
|
1604
|
-
interval: 30,
|
|
1605
|
-
timeout: 5,
|
|
1606
|
-
retries: 3,
|
|
1607
|
-
startPeriod: 60
|
|
1608
1675
|
}
|
|
1609
|
-
|
|
1676
|
+
]
|
|
1610
1677
|
});
|
|
1611
|
-
const registerTask = await this.runner.run(
|
|
1612
|
-
"
|
|
1613
|
-
"register-task-definition",
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
"--region",
|
|
1617
|
-
region
|
|
1618
|
-
], context.projectRoot);
|
|
1678
|
+
const registerTask = await this.runner.run(
|
|
1679
|
+
"aws",
|
|
1680
|
+
["ecs", "register-task-definition", "--cli-input-json", taskDef, "--region", region],
|
|
1681
|
+
context.projectRoot
|
|
1682
|
+
);
|
|
1619
1683
|
if (registerTask.exitCode !== 0) {
|
|
1620
1684
|
throw new Error(`Task definition registration failed: ${registerTask.stderr}`);
|
|
1621
1685
|
}
|
|
1622
|
-
const updateService = await this.runner.run(
|
|
1623
|
-
"
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
|
|
1686
|
+
const updateService = await this.runner.run(
|
|
1687
|
+
"aws",
|
|
1688
|
+
[
|
|
1689
|
+
"ecs",
|
|
1690
|
+
"update-service",
|
|
1691
|
+
"--cluster",
|
|
1692
|
+
context.appName,
|
|
1693
|
+
"--service",
|
|
1694
|
+
context.appName,
|
|
1695
|
+
"--task-definition",
|
|
1696
|
+
context.appName,
|
|
1697
|
+
"--force-new-deployment",
|
|
1698
|
+
"--region",
|
|
1699
|
+
region
|
|
1700
|
+
],
|
|
1701
|
+
context.projectRoot
|
|
1702
|
+
);
|
|
1635
1703
|
const deploymentId = (/* @__PURE__ */ new Date()).toISOString();
|
|
1636
1704
|
if (updateService.exitCode !== 0) {
|
|
1637
1705
|
this.logger.step("Service not found, creating new service...");
|
|
@@ -1656,19 +1724,23 @@ var AwsEcsAdapter = class {
|
|
|
1656
1724
|
async rollback(deploymentId) {
|
|
1657
1725
|
const context = this.requireContext();
|
|
1658
1726
|
const region = context.region ?? "us-east-1";
|
|
1659
|
-
const result = await this.runner.run(
|
|
1660
|
-
"
|
|
1661
|
-
|
|
1662
|
-
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1727
|
+
const result = await this.runner.run(
|
|
1728
|
+
"aws",
|
|
1729
|
+
[
|
|
1730
|
+
"ecs",
|
|
1731
|
+
"update-service",
|
|
1732
|
+
"--cluster",
|
|
1733
|
+
context.appName,
|
|
1734
|
+
"--service",
|
|
1735
|
+
context.appName,
|
|
1736
|
+
"--task-definition",
|
|
1737
|
+
`${context.appName}:${deploymentId}`,
|
|
1738
|
+
"--force-new-deployment",
|
|
1739
|
+
"--region",
|
|
1740
|
+
region
|
|
1741
|
+
],
|
|
1742
|
+
context.projectRoot
|
|
1743
|
+
);
|
|
1672
1744
|
if (result.exitCode !== 0) {
|
|
1673
1745
|
throw new Error(`ECS rollback failed: ${result.stderr}`);
|
|
1674
1746
|
}
|
|
@@ -1711,16 +1783,20 @@ var AwsEcsAdapter = class {
|
|
|
1711
1783
|
async status() {
|
|
1712
1784
|
const context = this.requireContext();
|
|
1713
1785
|
const region = context.region ?? "us-east-1";
|
|
1714
|
-
const result = await this.runner.run(
|
|
1715
|
-
"
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
|
|
1786
|
+
const result = await this.runner.run(
|
|
1787
|
+
"aws",
|
|
1788
|
+
[
|
|
1789
|
+
"ecs",
|
|
1790
|
+
"describe-services",
|
|
1791
|
+
"--cluster",
|
|
1792
|
+
context.appName,
|
|
1793
|
+
"--services",
|
|
1794
|
+
context.appName,
|
|
1795
|
+
"--region",
|
|
1796
|
+
region
|
|
1797
|
+
],
|
|
1798
|
+
context.projectRoot
|
|
1799
|
+
);
|
|
1724
1800
|
if (result.exitCode !== 0) {
|
|
1725
1801
|
return { state: "failed", message: result.stderr };
|
|
1726
1802
|
}
|
|
@@ -1829,18 +1905,22 @@ var AwsLightsailAdapter = class {
|
|
|
1829
1905
|
};
|
|
1830
1906
|
const region = config.region ?? "us-east-1";
|
|
1831
1907
|
const serviceName = sanitizeLightsailName(config.appName);
|
|
1832
|
-
const createService = await this.runner.run(
|
|
1833
|
-
"
|
|
1834
|
-
|
|
1835
|
-
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
|
|
1843
|
-
|
|
1908
|
+
const createService = await this.runner.run(
|
|
1909
|
+
"aws",
|
|
1910
|
+
[
|
|
1911
|
+
"lightsail",
|
|
1912
|
+
"create-container-service",
|
|
1913
|
+
"--service-name",
|
|
1914
|
+
serviceName,
|
|
1915
|
+
"--power",
|
|
1916
|
+
"nano",
|
|
1917
|
+
"--scale",
|
|
1918
|
+
"1",
|
|
1919
|
+
"--region",
|
|
1920
|
+
region
|
|
1921
|
+
],
|
|
1922
|
+
config.projectRoot
|
|
1923
|
+
);
|
|
1844
1924
|
if (createService.exitCode !== 0 && !createService.stderr.includes("already exists")) {
|
|
1845
1925
|
throw new Error(`Failed to create Lightsail container service: ${createService.stderr}`);
|
|
1846
1926
|
}
|
|
@@ -1878,30 +1958,31 @@ var AwsLightsailAdapter = class {
|
|
|
1878
1958
|
const serviceName = sanitizeLightsailName(context.appName);
|
|
1879
1959
|
const imageTag = `${serviceName}:latest`;
|
|
1880
1960
|
this.logger.step("Building Docker image...");
|
|
1881
|
-
const dockerBuild = await this.runner.run(
|
|
1882
|
-
"
|
|
1883
|
-
"--platform",
|
|
1884
|
-
|
|
1885
|
-
|
|
1886
|
-
imageTag,
|
|
1887
|
-
"."
|
|
1888
|
-
], artifacts.deployDirectory);
|
|
1961
|
+
const dockerBuild = await this.runner.run(
|
|
1962
|
+
"docker",
|
|
1963
|
+
["build", "--platform", "linux/amd64", "-t", imageTag, "."],
|
|
1964
|
+
artifacts.deployDirectory
|
|
1965
|
+
);
|
|
1889
1966
|
if (dockerBuild.exitCode !== 0) {
|
|
1890
1967
|
throw new Error(`Docker build failed: ${dockerBuild.stderr}`);
|
|
1891
1968
|
}
|
|
1892
1969
|
this.logger.step("Pushing image to Lightsail...");
|
|
1893
|
-
const pushImage = await this.runner.run(
|
|
1894
|
-
"
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
|
|
1898
|
-
|
|
1899
|
-
|
|
1900
|
-
|
|
1901
|
-
|
|
1902
|
-
|
|
1903
|
-
|
|
1904
|
-
|
|
1970
|
+
const pushImage = await this.runner.run(
|
|
1971
|
+
"aws",
|
|
1972
|
+
[
|
|
1973
|
+
"lightsail",
|
|
1974
|
+
"push-container-image",
|
|
1975
|
+
"--service-name",
|
|
1976
|
+
serviceName,
|
|
1977
|
+
"--label",
|
|
1978
|
+
"latest",
|
|
1979
|
+
"--image",
|
|
1980
|
+
imageTag,
|
|
1981
|
+
"--region",
|
|
1982
|
+
region
|
|
1983
|
+
],
|
|
1984
|
+
artifacts.deployDirectory
|
|
1985
|
+
);
|
|
1905
1986
|
if (pushImage.exitCode !== 0) {
|
|
1906
1987
|
throw new Error(`Lightsail image push failed: ${pushImage.stderr}`);
|
|
1907
1988
|
}
|
|
@@ -1932,29 +2013,30 @@ var AwsLightsailAdapter = class {
|
|
|
1932
2013
|
unhealthyThreshold: 3
|
|
1933
2014
|
}
|
|
1934
2015
|
});
|
|
1935
|
-
const createDeploy = await this.runner.run(
|
|
1936
|
-
"
|
|
1937
|
-
|
|
1938
|
-
|
|
1939
|
-
|
|
1940
|
-
|
|
1941
|
-
|
|
1942
|
-
|
|
1943
|
-
|
|
1944
|
-
|
|
1945
|
-
|
|
1946
|
-
|
|
2016
|
+
const createDeploy = await this.runner.run(
|
|
2017
|
+
"aws",
|
|
2018
|
+
[
|
|
2019
|
+
"lightsail",
|
|
2020
|
+
"create-container-service-deployment",
|
|
2021
|
+
"--service-name",
|
|
2022
|
+
serviceName,
|
|
2023
|
+
"--containers",
|
|
2024
|
+
containers,
|
|
2025
|
+
"--public-endpoint",
|
|
2026
|
+
publicEndpoint,
|
|
2027
|
+
"--region",
|
|
2028
|
+
region
|
|
2029
|
+
],
|
|
2030
|
+
context.projectRoot
|
|
2031
|
+
);
|
|
1947
2032
|
if (createDeploy.exitCode !== 0) {
|
|
1948
2033
|
throw new Error(`Lightsail deployment failed: ${createDeploy.stderr}`);
|
|
1949
2034
|
}
|
|
1950
|
-
const serviceInfo = await this.runner.run(
|
|
1951
|
-
"
|
|
1952
|
-
"get-container-services",
|
|
1953
|
-
|
|
1954
|
-
|
|
1955
|
-
"--region",
|
|
1956
|
-
region
|
|
1957
|
-
], context.projectRoot);
|
|
2035
|
+
const serviceInfo = await this.runner.run(
|
|
2036
|
+
"aws",
|
|
2037
|
+
["lightsail", "get-container-services", "--service-name", serviceName, "--region", region],
|
|
2038
|
+
context.projectRoot
|
|
2039
|
+
);
|
|
1958
2040
|
const rawUrl = parseLightsailUrl(serviceInfo.stdout) ?? `https://${serviceName}.${region}.cs.amazonlightsail.com`;
|
|
1959
2041
|
const serviceUrl = rawUrl.replace(/\/+$/, "");
|
|
1960
2042
|
const deploymentId = (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -1968,14 +2050,18 @@ var AwsLightsailAdapter = class {
|
|
|
1968
2050
|
const context = this.requireContext();
|
|
1969
2051
|
const region = context.region ?? "us-east-1";
|
|
1970
2052
|
const serviceName = sanitizeLightsailName(context.appName);
|
|
1971
|
-
const deployments = await this.runner.run(
|
|
1972
|
-
"
|
|
1973
|
-
|
|
1974
|
-
|
|
1975
|
-
|
|
1976
|
-
|
|
1977
|
-
|
|
1978
|
-
|
|
2053
|
+
const deployments = await this.runner.run(
|
|
2054
|
+
"aws",
|
|
2055
|
+
[
|
|
2056
|
+
"lightsail",
|
|
2057
|
+
"get-container-service-deployments",
|
|
2058
|
+
"--service-name",
|
|
2059
|
+
serviceName,
|
|
2060
|
+
"--region",
|
|
2061
|
+
region
|
|
2062
|
+
],
|
|
2063
|
+
context.projectRoot
|
|
2064
|
+
);
|
|
1979
2065
|
if (deployments.exitCode !== 0) {
|
|
1980
2066
|
throw new Error(`Lightsail rollback failed: ${deployments.stderr}`);
|
|
1981
2067
|
}
|
|
@@ -1983,18 +2069,22 @@ var AwsLightsailAdapter = class {
|
|
|
1983
2069
|
if (!previousDeployment) {
|
|
1984
2070
|
throw new Error("No previous deployment found to rollback to.");
|
|
1985
2071
|
}
|
|
1986
|
-
const redeploy = await this.runner.run(
|
|
1987
|
-
"
|
|
1988
|
-
|
|
1989
|
-
|
|
1990
|
-
|
|
1991
|
-
|
|
1992
|
-
|
|
1993
|
-
|
|
1994
|
-
|
|
1995
|
-
|
|
1996
|
-
|
|
1997
|
-
|
|
2072
|
+
const redeploy = await this.runner.run(
|
|
2073
|
+
"aws",
|
|
2074
|
+
[
|
|
2075
|
+
"lightsail",
|
|
2076
|
+
"create-container-service-deployment",
|
|
2077
|
+
"--service-name",
|
|
2078
|
+
serviceName,
|
|
2079
|
+
"--containers",
|
|
2080
|
+
JSON.stringify(previousDeployment.containers),
|
|
2081
|
+
"--public-endpoint",
|
|
2082
|
+
JSON.stringify(previousDeployment.publicEndpoint),
|
|
2083
|
+
"--region",
|
|
2084
|
+
region
|
|
2085
|
+
],
|
|
2086
|
+
context.projectRoot
|
|
2087
|
+
);
|
|
1998
2088
|
if (redeploy.exitCode !== 0) {
|
|
1999
2089
|
throw new Error(`Lightsail rollback deployment failed: ${redeploy.stderr}`);
|
|
2000
2090
|
}
|
|
@@ -2041,14 +2131,11 @@ var AwsLightsailAdapter = class {
|
|
|
2041
2131
|
const context = this.requireContext();
|
|
2042
2132
|
const region = context.region ?? "us-east-1";
|
|
2043
2133
|
const serviceName = sanitizeLightsailName(context.appName);
|
|
2044
|
-
const result = await this.runner.run(
|
|
2045
|
-
"
|
|
2046
|
-
"get-container-services",
|
|
2047
|
-
|
|
2048
|
-
|
|
2049
|
-
"--region",
|
|
2050
|
-
region
|
|
2051
|
-
], context.projectRoot);
|
|
2134
|
+
const result = await this.runner.run(
|
|
2135
|
+
"aws",
|
|
2136
|
+
["lightsail", "get-container-services", "--service-name", serviceName, "--region", region],
|
|
2137
|
+
context.projectRoot
|
|
2138
|
+
);
|
|
2052
2139
|
if (result.exitCode !== 0) {
|
|
2053
2140
|
return { state: "failed", message: result.stderr };
|
|
2054
2141
|
}
|
|
@@ -2113,12 +2200,7 @@ ${error.message}` });
|
|
|
2113
2200
|
});
|
|
2114
2201
|
}
|
|
2115
2202
|
};
|
|
2116
|
-
var PASSTHROUGH_ENV_VARS = [
|
|
2117
|
-
"DATABASE_URL",
|
|
2118
|
-
"AUTH_SECRET",
|
|
2119
|
-
"PUBLIC_URL",
|
|
2120
|
-
"NODE_ENV"
|
|
2121
|
-
];
|
|
2203
|
+
var PASSTHROUGH_ENV_VARS = ["DATABASE_URL", "AUTH_SECRET", "PUBLIC_URL", "NODE_ENV"];
|
|
2122
2204
|
function sanitizeLightsailName(name) {
|
|
2123
2205
|
return name.toLowerCase().replace(/[^a-z0-9-]/g, "-").replace(/-{2,}/g, "-").replace(/^-|-$/g, "").slice(0, 255) || "kora-app";
|
|
2124
2206
|
}
|
|
@@ -2997,7 +3079,8 @@ function generateDeployPackageJson(nativeDependencies) {
|
|
|
2997
3079
|
type: "module",
|
|
2998
3080
|
dependencies: nativeDependencies
|
|
2999
3081
|
};
|
|
3000
|
-
return JSON.stringify(pkg, null, 2)
|
|
3082
|
+
return `${JSON.stringify(pkg, null, 2)}
|
|
3083
|
+
`;
|
|
3001
3084
|
}
|
|
3002
3085
|
function generateDockerIgnore() {
|
|
3003
3086
|
return [
|
|
@@ -3329,7 +3412,7 @@ var deployCommand = (0, import_citty2.defineCommand)({
|
|
|
3329
3412
|
nativeDependencies: {
|
|
3330
3413
|
"better-sqlite3": "^11.0.0",
|
|
3331
3414
|
"drizzle-orm": "^0.45.2",
|
|
3332
|
-
|
|
3415
|
+
postgres: "^3.4.0"
|
|
3333
3416
|
}
|
|
3334
3417
|
});
|
|
3335
3418
|
await writeDockerIgnoreArtifact(deployDirectory);
|
|
@@ -3683,7 +3766,14 @@ var SchemaWatcher = class {
|
|
|
3683
3766
|
this.watcher = null;
|
|
3684
3767
|
}
|
|
3685
3768
|
async regenerate() {
|
|
3686
|
-
const koraBinJs = (0, import_node_path18.join)(
|
|
3769
|
+
const koraBinJs = (0, import_node_path18.join)(
|
|
3770
|
+
this.config.projectRoot,
|
|
3771
|
+
"node_modules",
|
|
3772
|
+
"@korajs",
|
|
3773
|
+
"cli",
|
|
3774
|
+
"dist",
|
|
3775
|
+
"bin.js"
|
|
3776
|
+
);
|
|
3687
3777
|
const hasTsx = await hasTsxInstalled(this.config.projectRoot);
|
|
3688
3778
|
const command = process.execPath;
|
|
3689
3779
|
const args = hasTsx ? ["--import", "tsx", koraBinJs, "generate", "types", "--schema", this.config.schemaPath] : [koraBinJs, "generate", "types", "--schema", this.config.schemaPath];
|
|
@@ -3819,7 +3909,9 @@ var devCommand = (0, import_citty3.defineCommand)({
|
|
|
3819
3909
|
if (await fileExists2(candidate)) {
|
|
3820
3910
|
configuredSchemaPath = candidate;
|
|
3821
3911
|
} else {
|
|
3822
|
-
logger.warn(
|
|
3912
|
+
logger.warn(
|
|
3913
|
+
`Configured schema file not found: ${candidate}. Falling back to auto-detection.`
|
|
3914
|
+
);
|
|
3823
3915
|
}
|
|
3824
3916
|
}
|
|
3825
3917
|
const schemaPath = configuredSchemaPath ?? await findSchemaFile(projectRoot);
|
|
@@ -3973,7 +4065,8 @@ function isPostgresEnvRequested(config) {
|
|
|
3973
4065
|
const sync = config?.dev?.sync;
|
|
3974
4066
|
if (typeof sync !== "object" || sync === null) return false;
|
|
3975
4067
|
if (sync.store === "postgres") return true;
|
|
3976
|
-
if (typeof sync.store === "object" && sync.store !== null && sync.store.type === "postgres")
|
|
4068
|
+
if (typeof sync.store === "object" && sync.store !== null && sync.store.type === "postgres")
|
|
4069
|
+
return true;
|
|
3977
4070
|
return false;
|
|
3978
4071
|
}
|
|
3979
4072
|
var MANAGED_SYNC_BOOTSTRAP_SCRIPT = `
|
|
@@ -4294,7 +4387,8 @@ function isBreakingChange(change) {
|
|
|
4294
4387
|
if (change.type === "field-changed") {
|
|
4295
4388
|
if (change.before.kind !== change.after.kind) return true;
|
|
4296
4389
|
if (change.before.itemKind !== change.after.itemKind) return true;
|
|
4297
|
-
if (serializeEnum(change.before.enumValues) !== serializeEnum(change.after.enumValues))
|
|
4390
|
+
if (serializeEnum(change.before.enumValues) !== serializeEnum(change.after.enumValues))
|
|
4391
|
+
return true;
|
|
4298
4392
|
if (change.before.required !== change.after.required && change.after.required) return true;
|
|
4299
4393
|
return false;
|
|
4300
4394
|
}
|
|
@@ -4678,9 +4772,7 @@ async function runSqliteMigration(path, statements, migrationId, fromVersion, to
|
|
|
4678
4772
|
async function loadSqliteDriver(projectRoot) {
|
|
4679
4773
|
try {
|
|
4680
4774
|
const { createRequire } = await import("module");
|
|
4681
|
-
const requireFrom = createRequire(
|
|
4682
|
-
projectRoot ? `${projectRoot}/package.json` : import_meta3.url
|
|
4683
|
-
);
|
|
4775
|
+
const requireFrom = createRequire(projectRoot ? `${projectRoot}/package.json` : import_meta3.url);
|
|
4684
4776
|
const Database = requireFrom("better-sqlite3");
|
|
4685
4777
|
return {
|
|
4686
4778
|
open(path) {
|
|
@@ -4958,7 +5050,12 @@ var migrateCommand = (0, import_citty5.defineCommand)({
|
|
|
4958
5050
|
return;
|
|
4959
5051
|
}
|
|
4960
5052
|
await (0, import_promises15.mkdir)(outputDir, { recursive: true });
|
|
4961
|
-
const migrationPath = await writeMigrationFile(
|
|
5053
|
+
const migrationPath = await writeMigrationFile(
|
|
5054
|
+
outputDir,
|
|
5055
|
+
diff.fromVersion,
|
|
5056
|
+
diff.toVersion,
|
|
5057
|
+
generated
|
|
5058
|
+
);
|
|
4962
5059
|
await writeSchemaSnapshot(snapshotFile, currentSchema);
|
|
4963
5060
|
logger.blank();
|
|
4964
5061
|
logger.success(`Generated migration: ${migrationPath}`);
|