@insforge/cli 0.1.52 → 0.1.53-dev.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +315 -29
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
// src/index.ts
|
|
4
|
-
import { readFileSync as
|
|
5
|
-
import { join as
|
|
4
|
+
import { readFileSync as readFileSync8 } from "fs";
|
|
5
|
+
import { join as join12, dirname } from "path";
|
|
6
6
|
import { fileURLToPath } from "url";
|
|
7
7
|
import { Command } from "commander";
|
|
8
8
|
import * as clack11 from "@clack/prompts";
|
|
@@ -1123,7 +1123,7 @@ async function reportCliUsage(toolName, success, maxRetries = 1, explicitConfig)
|
|
|
1123
1123
|
|
|
1124
1124
|
// src/lib/analytics.ts
|
|
1125
1125
|
import { PostHog } from "posthog-node";
|
|
1126
|
-
var POSTHOG_API_KEY = "
|
|
1126
|
+
var POSTHOG_API_KEY = "";
|
|
1127
1127
|
var POSTHOG_HOST = process.env.POSTHOG_HOST || "https://us.i.posthog.com";
|
|
1128
1128
|
var client = null;
|
|
1129
1129
|
function getClient() {
|
|
@@ -2671,6 +2671,291 @@ function registerDbImportCommand(dbCmd2) {
|
|
|
2671
2671
|
});
|
|
2672
2672
|
}
|
|
2673
2673
|
|
|
2674
|
+
// src/commands/db/migrations.ts
|
|
2675
|
+
import { existsSync as existsSync4, readFileSync as readFileSync4, writeFileSync as writeFileSync3 } from "fs";
|
|
2676
|
+
import { join as join8 } from "path";
|
|
2677
|
+
|
|
2678
|
+
// src/lib/migrations.ts
|
|
2679
|
+
import { existsSync as existsSync3, mkdirSync as mkdirSync2, readdirSync } from "fs";
|
|
2680
|
+
import { join as join7 } from "path";
|
|
2681
|
+
var MIGRATION_FILENAME_REGEX = /^([1-9][0-9]*)_([a-z0-9-]+)\.sql$/;
|
|
2682
|
+
function parseMigrationFilename(filename) {
|
|
2683
|
+
const match = MIGRATION_FILENAME_REGEX.exec(filename);
|
|
2684
|
+
if (!match) {
|
|
2685
|
+
return null;
|
|
2686
|
+
}
|
|
2687
|
+
return {
|
|
2688
|
+
filename,
|
|
2689
|
+
sequenceNumber: Number(match[1]),
|
|
2690
|
+
name: match[2]
|
|
2691
|
+
};
|
|
2692
|
+
}
|
|
2693
|
+
function getMigrationsDir(cwd = process.cwd()) {
|
|
2694
|
+
return join7(cwd, ".insforge", "migrations");
|
|
2695
|
+
}
|
|
2696
|
+
function ensureMigrationsDir(cwd = process.cwd()) {
|
|
2697
|
+
const migrationsDir = getMigrationsDir(cwd);
|
|
2698
|
+
if (!existsSync3(migrationsDir)) {
|
|
2699
|
+
mkdirSync2(migrationsDir, { recursive: true });
|
|
2700
|
+
}
|
|
2701
|
+
return migrationsDir;
|
|
2702
|
+
}
|
|
2703
|
+
function listLocalMigrationFilenames(cwd = process.cwd()) {
|
|
2704
|
+
const migrationsDir = getMigrationsDir(cwd);
|
|
2705
|
+
if (!existsSync3(migrationsDir)) {
|
|
2706
|
+
return [];
|
|
2707
|
+
}
|
|
2708
|
+
return readdirSync(migrationsDir).sort((left, right) => left.localeCompare(right));
|
|
2709
|
+
}
|
|
2710
|
+
function parseStrictLocalMigrations(filenames) {
|
|
2711
|
+
const migrations = filenames.map((filename) => {
|
|
2712
|
+
const parsedMigration = parseMigrationFilename(filename);
|
|
2713
|
+
if (!parsedMigration) {
|
|
2714
|
+
throw new CLIError(
|
|
2715
|
+
`Invalid migration filename: ${filename}. Expected <sequence_number>_<migration-name>.sql.`
|
|
2716
|
+
);
|
|
2717
|
+
}
|
|
2718
|
+
return parsedMigration;
|
|
2719
|
+
});
|
|
2720
|
+
assertNoDuplicateMigrationSequences(migrations);
|
|
2721
|
+
return migrations.sort((left, right) => left.sequenceNumber - right.sequenceNumber);
|
|
2722
|
+
}
|
|
2723
|
+
function assertNoDuplicateMigrationSequences(migrations) {
|
|
2724
|
+
const seen = /* @__PURE__ */ new Set();
|
|
2725
|
+
for (const migration of migrations) {
|
|
2726
|
+
if (seen.has(migration.sequenceNumber)) {
|
|
2727
|
+
throw new CLIError(`Duplicate local migration sequence found: ${migration.sequenceNumber}`);
|
|
2728
|
+
}
|
|
2729
|
+
seen.add(migration.sequenceNumber);
|
|
2730
|
+
}
|
|
2731
|
+
}
|
|
2732
|
+
function getNextLocalMigrationSequence(migrations, latestRemoteSequenceNumber) {
|
|
2733
|
+
const orderedMigrations = [...migrations].sort((left, right) => left.sequenceNumber - right.sequenceNumber);
|
|
2734
|
+
assertNoDuplicateMigrationSequences(orderedMigrations);
|
|
2735
|
+
let expectedSequenceNumber = latestRemoteSequenceNumber + 1;
|
|
2736
|
+
for (const migration of orderedMigrations) {
|
|
2737
|
+
if (migration.sequenceNumber <= latestRemoteSequenceNumber) {
|
|
2738
|
+
continue;
|
|
2739
|
+
}
|
|
2740
|
+
if (migration.sequenceNumber !== expectedSequenceNumber) {
|
|
2741
|
+
throw new CLIError(
|
|
2742
|
+
`Local pending migrations must be contiguous after remote sequence ${latestRemoteSequenceNumber}.`
|
|
2743
|
+
);
|
|
2744
|
+
}
|
|
2745
|
+
expectedSequenceNumber += 1;
|
|
2746
|
+
}
|
|
2747
|
+
return expectedSequenceNumber;
|
|
2748
|
+
}
|
|
2749
|
+
function formatMigrationSql(statements) {
|
|
2750
|
+
return statements.map((statement) => statement.trim().replace(/;\s*$/u, "")).filter(Boolean).join(";\n\n").concat(statements.length > 0 ? ";\n" : "");
|
|
2751
|
+
}
|
|
2752
|
+
function findLocalMigrationBySequence(sequenceNumber, filenames) {
|
|
2753
|
+
const matches = filenames.map((filename) => parseMigrationFilename(filename)).filter(
|
|
2754
|
+
(migration) => migration !== null && migration.sequenceNumber === sequenceNumber
|
|
2755
|
+
);
|
|
2756
|
+
if (matches.length === 0) {
|
|
2757
|
+
throw new CLIError(`Local migration for sequence ${sequenceNumber} not found.`);
|
|
2758
|
+
}
|
|
2759
|
+
if (matches.length > 1) {
|
|
2760
|
+
throw new CLIError(
|
|
2761
|
+
`Multiple local migration files found for sequence ${sequenceNumber}.`
|
|
2762
|
+
);
|
|
2763
|
+
}
|
|
2764
|
+
return matches[0];
|
|
2765
|
+
}
|
|
2766
|
+
function resolveMigrationTarget(target, filenames) {
|
|
2767
|
+
if (/^[1-9][0-9]*$/u.test(target)) {
|
|
2768
|
+
return findLocalMigrationBySequence(Number(target), filenames);
|
|
2769
|
+
}
|
|
2770
|
+
const parsedTarget = parseMigrationFilename(target);
|
|
2771
|
+
if (!parsedTarget) {
|
|
2772
|
+
throw new CLIError(
|
|
2773
|
+
"Migration file names must match <sequence_number>_<migration-name>.sql."
|
|
2774
|
+
);
|
|
2775
|
+
}
|
|
2776
|
+
if (!filenames.includes(target)) {
|
|
2777
|
+
throw new CLIError(`Local migration file not found: ${target}`);
|
|
2778
|
+
}
|
|
2779
|
+
return findLocalMigrationBySequence(parsedTarget.sequenceNumber, filenames);
|
|
2780
|
+
}
|
|
2781
|
+
|
|
2782
|
+
// src/commands/db/migrations.ts
|
|
2783
|
+
function getLatestRemoteSequenceNumber(migrations) {
|
|
2784
|
+
return migrations.reduce(
|
|
2785
|
+
(latestSequenceNumber, migration) => Math.max(latestSequenceNumber, migration.sequenceNumber),
|
|
2786
|
+
0
|
|
2787
|
+
);
|
|
2788
|
+
}
|
|
2789
|
+
function buildMigrationFilename(sequenceNumber, name) {
|
|
2790
|
+
return `${sequenceNumber}_${name}.sql`;
|
|
2791
|
+
}
|
|
2792
|
+
function formatCreatedAt(createdAt) {
|
|
2793
|
+
const date = new Date(createdAt);
|
|
2794
|
+
return Number.isNaN(date.getTime()) ? createdAt : date.toLocaleString();
|
|
2795
|
+
}
|
|
2796
|
+
async function fetchRemoteMigrations() {
|
|
2797
|
+
const res = await ossFetch("/api/database/migrations");
|
|
2798
|
+
const raw = await res.json();
|
|
2799
|
+
return Array.isArray(raw.migrations) ? raw.migrations : [];
|
|
2800
|
+
}
|
|
2801
|
+
function assertValidMigrationName(name) {
|
|
2802
|
+
if (!/^[a-z0-9-]+$/u.test(name)) {
|
|
2803
|
+
throw new CLIError("Migration name must use lowercase letters, numbers, and hyphens only.");
|
|
2804
|
+
}
|
|
2805
|
+
}
|
|
2806
|
+
function registerDbMigrationsCommand(dbCmd2) {
|
|
2807
|
+
const migrationsCmd = dbCmd2.command("migrations").description("Manage database migration files");
|
|
2808
|
+
migrationsCmd.command("list").description("List applied remote database migrations").action(async (_opts, cmd) => {
|
|
2809
|
+
const { json } = getRootOpts(cmd);
|
|
2810
|
+
try {
|
|
2811
|
+
await requireAuth();
|
|
2812
|
+
const migrations = await fetchRemoteMigrations();
|
|
2813
|
+
if (json) {
|
|
2814
|
+
outputJson({ migrations });
|
|
2815
|
+
} else if (migrations.length === 0) {
|
|
2816
|
+
console.log("No database migrations found.");
|
|
2817
|
+
} else {
|
|
2818
|
+
outputTable(
|
|
2819
|
+
["Sequence", "Name", "Created At"],
|
|
2820
|
+
migrations.map((migration) => [
|
|
2821
|
+
String(migration.sequenceNumber),
|
|
2822
|
+
migration.name,
|
|
2823
|
+
formatCreatedAt(migration.createdAt)
|
|
2824
|
+
])
|
|
2825
|
+
);
|
|
2826
|
+
}
|
|
2827
|
+
await reportCliUsage("cli.db.migrations.list", true);
|
|
2828
|
+
} catch (err) {
|
|
2829
|
+
await reportCliUsage("cli.db.migrations.list", false);
|
|
2830
|
+
handleError(err, json);
|
|
2831
|
+
}
|
|
2832
|
+
});
|
|
2833
|
+
migrationsCmd.command("fetch").description("Fetch applied remote migrations into .insforge/migrations/").action(async (_opts, cmd) => {
|
|
2834
|
+
const { json } = getRootOpts(cmd);
|
|
2835
|
+
try {
|
|
2836
|
+
await requireAuth();
|
|
2837
|
+
const migrations = await fetchRemoteMigrations();
|
|
2838
|
+
const migrationsDir = ensureMigrationsDir();
|
|
2839
|
+
const createdFiles = [];
|
|
2840
|
+
const skippedFiles = [];
|
|
2841
|
+
for (const migration of [...migrations].sort(
|
|
2842
|
+
(left, right) => left.sequenceNumber - right.sequenceNumber
|
|
2843
|
+
)) {
|
|
2844
|
+
const filename = buildMigrationFilename(
|
|
2845
|
+
migration.sequenceNumber,
|
|
2846
|
+
migration.name
|
|
2847
|
+
);
|
|
2848
|
+
const filePath = join8(migrationsDir, filename);
|
|
2849
|
+
if (existsSync4(filePath)) {
|
|
2850
|
+
skippedFiles.push(filename);
|
|
2851
|
+
continue;
|
|
2852
|
+
}
|
|
2853
|
+
writeFileSync3(filePath, formatMigrationSql(migration.statements));
|
|
2854
|
+
createdFiles.push(filename);
|
|
2855
|
+
}
|
|
2856
|
+
if (json) {
|
|
2857
|
+
outputJson({
|
|
2858
|
+
directory: migrationsDir,
|
|
2859
|
+
totalRemoteMigrations: migrations.length,
|
|
2860
|
+
createdFiles,
|
|
2861
|
+
skippedFiles
|
|
2862
|
+
});
|
|
2863
|
+
} else {
|
|
2864
|
+
outputSuccess(
|
|
2865
|
+
`Fetched ${migrations.length} remote migration(s) into ${migrationsDir}.`
|
|
2866
|
+
);
|
|
2867
|
+
console.log(`Created: ${createdFiles.length}`);
|
|
2868
|
+
console.log(`Skipped: ${skippedFiles.length}`);
|
|
2869
|
+
}
|
|
2870
|
+
await reportCliUsage("cli.db.migrations.fetch", true);
|
|
2871
|
+
} catch (err) {
|
|
2872
|
+
await reportCliUsage("cli.db.migrations.fetch", false);
|
|
2873
|
+
handleError(err, json);
|
|
2874
|
+
}
|
|
2875
|
+
});
|
|
2876
|
+
migrationsCmd.command("new <migration-name>").description("Create a new local migration file").action(async (migrationName, _opts, cmd) => {
|
|
2877
|
+
const { json } = getRootOpts(cmd);
|
|
2878
|
+
try {
|
|
2879
|
+
await requireAuth();
|
|
2880
|
+
assertValidMigrationName(migrationName);
|
|
2881
|
+
const migrations = await fetchRemoteMigrations();
|
|
2882
|
+
const latestRemoteSequenceNumber = getLatestRemoteSequenceNumber(migrations);
|
|
2883
|
+
const localMigrations = parseStrictLocalMigrations(listLocalMigrationFilenames());
|
|
2884
|
+
const nextSequenceNumber = getNextLocalMigrationSequence(
|
|
2885
|
+
localMigrations,
|
|
2886
|
+
latestRemoteSequenceNumber
|
|
2887
|
+
);
|
|
2888
|
+
const filename = buildMigrationFilename(nextSequenceNumber, migrationName);
|
|
2889
|
+
const migrationsDir = ensureMigrationsDir();
|
|
2890
|
+
const filePath = join8(migrationsDir, filename);
|
|
2891
|
+
if (existsSync4(filePath)) {
|
|
2892
|
+
throw new CLIError(`Migration file already exists: ${filename}`);
|
|
2893
|
+
}
|
|
2894
|
+
writeFileSync3(filePath, "");
|
|
2895
|
+
if (json) {
|
|
2896
|
+
outputJson({ filename, path: filePath, sequenceNumber: nextSequenceNumber });
|
|
2897
|
+
} else {
|
|
2898
|
+
outputSuccess(`Created migration file ${filename}`);
|
|
2899
|
+
}
|
|
2900
|
+
await reportCliUsage("cli.db.migrations.new", true);
|
|
2901
|
+
} catch (err) {
|
|
2902
|
+
await reportCliUsage("cli.db.migrations.new", false);
|
|
2903
|
+
handleError(err, json);
|
|
2904
|
+
}
|
|
2905
|
+
});
|
|
2906
|
+
migrationsCmd.command("up <target>").description("Apply exactly one local migration file").action(async (target, _opts, cmd) => {
|
|
2907
|
+
const { json } = getRootOpts(cmd);
|
|
2908
|
+
try {
|
|
2909
|
+
await requireAuth();
|
|
2910
|
+
const migrations = await fetchRemoteMigrations();
|
|
2911
|
+
const latestRemoteSequenceNumber = getLatestRemoteSequenceNumber(migrations);
|
|
2912
|
+
const filenames = listLocalMigrationFilenames();
|
|
2913
|
+
const targetMigration = resolveMigrationTarget(target, filenames);
|
|
2914
|
+
if (targetMigration.sequenceNumber <= latestRemoteSequenceNumber) {
|
|
2915
|
+
throw new CLIError(
|
|
2916
|
+
`Migration ${targetMigration.filename} is already applied remotely.`
|
|
2917
|
+
);
|
|
2918
|
+
}
|
|
2919
|
+
if (targetMigration.sequenceNumber !== latestRemoteSequenceNumber + 1) {
|
|
2920
|
+
throw new CLIError(
|
|
2921
|
+
`Migration ${targetMigration.filename} is not the next remote sequence. Expected ${latestRemoteSequenceNumber + 1}.`
|
|
2922
|
+
);
|
|
2923
|
+
}
|
|
2924
|
+
const filePath = join8(getMigrationsDir(), targetMigration.filename);
|
|
2925
|
+
if (!existsSync4(filePath)) {
|
|
2926
|
+
throw new CLIError(`Local migration file not found: ${targetMigration.filename}`);
|
|
2927
|
+
}
|
|
2928
|
+
const sql = readFileSync4(filePath, "utf-8");
|
|
2929
|
+
if (!sql.trim()) {
|
|
2930
|
+
throw new CLIError(`Migration file is empty: ${targetMigration.filename}`);
|
|
2931
|
+
}
|
|
2932
|
+
const body = {
|
|
2933
|
+
name: targetMigration.name,
|
|
2934
|
+
sql
|
|
2935
|
+
};
|
|
2936
|
+
const res = await ossFetch("/api/database/migrations", {
|
|
2937
|
+
method: "POST",
|
|
2938
|
+
body: JSON.stringify(body)
|
|
2939
|
+
});
|
|
2940
|
+
const createdMigration = await res.json();
|
|
2941
|
+
if (createdMigration.sequenceNumber !== targetMigration.sequenceNumber) {
|
|
2942
|
+
throw new CLIError(
|
|
2943
|
+
`Applied migration sequence mismatch. Expected ${targetMigration.sequenceNumber}, received ${createdMigration.sequenceNumber}.`
|
|
2944
|
+
);
|
|
2945
|
+
}
|
|
2946
|
+
if (json) {
|
|
2947
|
+
outputJson(createdMigration);
|
|
2948
|
+
} else {
|
|
2949
|
+
outputSuccess(`Applied migration ${targetMigration.filename}`);
|
|
2950
|
+
}
|
|
2951
|
+
await reportCliUsage("cli.db.migrations.up", true);
|
|
2952
|
+
} catch (err) {
|
|
2953
|
+
await reportCliUsage("cli.db.migrations.up", false);
|
|
2954
|
+
handleError(err, json);
|
|
2955
|
+
}
|
|
2956
|
+
});
|
|
2957
|
+
}
|
|
2958
|
+
|
|
2674
2959
|
// src/commands/records/list.ts
|
|
2675
2960
|
function registerRecordsCommands(recordsCmd2) {
|
|
2676
2961
|
recordsCmd2.command("list <table>").description("List records from a table").option("--select <columns>", "Columns to select (comma-separated)").option("--filter <filter>", 'Filter expression (e.g. "name=eq.John")').option("--order <order>", 'Order by (e.g. "created_at.desc")').option("--limit <n>", "Limit number of records", parseInt).option("--offset <n>", "Offset for pagination", parseInt).action(async (table, opts, cmd) => {
|
|
@@ -2854,21 +3139,21 @@ function registerFunctionsCommands(functionsCmd2) {
|
|
|
2854
3139
|
}
|
|
2855
3140
|
|
|
2856
3141
|
// src/commands/functions/deploy.ts
|
|
2857
|
-
import { readFileSync as
|
|
2858
|
-
import { join as
|
|
3142
|
+
import { readFileSync as readFileSync5, existsSync as existsSync5 } from "fs";
|
|
3143
|
+
import { join as join9 } from "path";
|
|
2859
3144
|
function registerFunctionsDeployCommand(functionsCmd2) {
|
|
2860
3145
|
functionsCmd2.command("deploy <slug>").description("Deploy an edge function (create or update)").option("--file <path>", "Path to the function source file").option("--name <name>", "Function display name").option("--description <desc>", "Function description").action(async (slug, opts, cmd) => {
|
|
2861
3146
|
const { json } = getRootOpts(cmd);
|
|
2862
3147
|
try {
|
|
2863
3148
|
await requireAuth();
|
|
2864
|
-
const filePath = opts.file ??
|
|
2865
|
-
if (!
|
|
3149
|
+
const filePath = opts.file ?? join9(process.cwd(), "insforge", "functions", slug, "index.ts");
|
|
3150
|
+
if (!existsSync5(filePath)) {
|
|
2866
3151
|
throw new CLIError(
|
|
2867
3152
|
`Source file not found: ${filePath}
|
|
2868
|
-
Specify --file <path> or create ${
|
|
3153
|
+
Specify --file <path> or create ${join9("insforge", "functions", slug, "index.ts")}`
|
|
2869
3154
|
);
|
|
2870
3155
|
}
|
|
2871
|
-
const code =
|
|
3156
|
+
const code = readFileSync5(filePath, "utf-8");
|
|
2872
3157
|
const name = opts.name ?? slug;
|
|
2873
3158
|
const description = opts.description ?? "";
|
|
2874
3159
|
let exists = false;
|
|
@@ -3055,7 +3340,7 @@ function registerStorageBucketsCommand(storageCmd2) {
|
|
|
3055
3340
|
}
|
|
3056
3341
|
|
|
3057
3342
|
// src/commands/storage/upload.ts
|
|
3058
|
-
import { readFileSync as
|
|
3343
|
+
import { readFileSync as readFileSync6, existsSync as existsSync6 } from "fs";
|
|
3059
3344
|
import { basename as basename5 } from "path";
|
|
3060
3345
|
function registerStorageUploadCommand(storageCmd2) {
|
|
3061
3346
|
storageCmd2.command("upload <file>").description("Upload a file to a storage bucket").requiredOption("--bucket <name>", "Target bucket name").option("--key <objectKey>", "Object key (defaults to filename)").action(async (file, opts, cmd) => {
|
|
@@ -3064,10 +3349,10 @@ function registerStorageUploadCommand(storageCmd2) {
|
|
|
3064
3349
|
await requireAuth();
|
|
3065
3350
|
const config = getProjectConfig();
|
|
3066
3351
|
if (!config) throw new ProjectNotLinkedError();
|
|
3067
|
-
if (!
|
|
3352
|
+
if (!existsSync6(file)) {
|
|
3068
3353
|
throw new CLIError(`File not found: ${file}`);
|
|
3069
3354
|
}
|
|
3070
|
-
const fileContent =
|
|
3355
|
+
const fileContent = readFileSync6(file);
|
|
3071
3356
|
const objectKey = opts.key ?? basename5(file);
|
|
3072
3357
|
const bucketName = opts.bucket;
|
|
3073
3358
|
const formData = new FormData();
|
|
@@ -3098,8 +3383,8 @@ function registerStorageUploadCommand(storageCmd2) {
|
|
|
3098
3383
|
}
|
|
3099
3384
|
|
|
3100
3385
|
// src/commands/storage/download.ts
|
|
3101
|
-
import { writeFileSync as
|
|
3102
|
-
import { join as
|
|
3386
|
+
import { writeFileSync as writeFileSync4 } from "fs";
|
|
3387
|
+
import { join as join10, basename as basename6 } from "path";
|
|
3103
3388
|
function registerStorageDownloadCommand(storageCmd2) {
|
|
3104
3389
|
storageCmd2.command("download <objectKey>").description("Download a file from a storage bucket").requiredOption("--bucket <name>", "Source bucket name").option("--output <path>", "Output file path (defaults to current directory)").action(async (objectKey, opts, cmd) => {
|
|
3105
3390
|
const { json } = getRootOpts(cmd);
|
|
@@ -3119,8 +3404,8 @@ function registerStorageDownloadCommand(storageCmd2) {
|
|
|
3119
3404
|
throw new CLIError(err.error ?? `Download failed: ${res.status}`);
|
|
3120
3405
|
}
|
|
3121
3406
|
const buffer = Buffer.from(await res.arrayBuffer());
|
|
3122
|
-
const outputPath = opts.output ??
|
|
3123
|
-
|
|
3407
|
+
const outputPath = opts.output ?? join10(process.cwd(), basename6(objectKey));
|
|
3408
|
+
writeFileSync4(outputPath, buffer);
|
|
3124
3409
|
if (json) {
|
|
3125
3410
|
outputJson({ success: true, path: outputPath, size: buffer.length });
|
|
3126
3411
|
} else {
|
|
@@ -4226,13 +4511,13 @@ function registerComputeLogsCommand(computeCmd2) {
|
|
|
4226
4511
|
}
|
|
4227
4512
|
|
|
4228
4513
|
// src/commands/compute/deploy.ts
|
|
4229
|
-
import { existsSync as
|
|
4230
|
-
import { join as
|
|
4514
|
+
import { existsSync as existsSync7, readFileSync as readFileSync7, writeFileSync as writeFileSync5, unlinkSync as unlinkSync2, renameSync } from "fs";
|
|
4515
|
+
import { join as join11 } from "path";
|
|
4231
4516
|
import { execSync, spawn } from "child_process";
|
|
4232
4517
|
function parseFlyToml(dir) {
|
|
4233
|
-
const tomlPath =
|
|
4234
|
-
if (!
|
|
4235
|
-
const content =
|
|
4518
|
+
const tomlPath = join11(dir, "fly.toml");
|
|
4519
|
+
if (!existsSync7(tomlPath)) return {};
|
|
4520
|
+
const content = readFileSync7(tomlPath, "utf-8");
|
|
4236
4521
|
const config = {};
|
|
4237
4522
|
const portMatch = content.match(/internal_port\s*=\s*(\d+)/);
|
|
4238
4523
|
if (portMatch) config.internalPort = Number(portMatch[1]);
|
|
@@ -4302,8 +4587,8 @@ function registerComputeDeployCommand(computeCmd2) {
|
|
|
4302
4587
|
checkFlyctl();
|
|
4303
4588
|
const flyToken = getFlyToken();
|
|
4304
4589
|
const dir = directory ?? process.cwd();
|
|
4305
|
-
const dockerfilePath =
|
|
4306
|
-
if (!
|
|
4590
|
+
const dockerfilePath = join11(dir, "Dockerfile");
|
|
4591
|
+
if (!existsSync7(dockerfilePath)) {
|
|
4307
4592
|
throw new CLIError(`No Dockerfile found in ${dir}`);
|
|
4308
4593
|
}
|
|
4309
4594
|
const flyTomlDefaults = parseFlyToml(dir);
|
|
@@ -4348,15 +4633,15 @@ function registerComputeDeployCommand(computeCmd2) {
|
|
|
4348
4633
|
serviceId = service.id;
|
|
4349
4634
|
flyAppId = service.flyAppId;
|
|
4350
4635
|
}
|
|
4351
|
-
const existingTomlPath =
|
|
4352
|
-
const backupTomlPath =
|
|
4636
|
+
const existingTomlPath = join11(dir, "fly.toml");
|
|
4637
|
+
const backupTomlPath = join11(dir, "fly.toml.insforge-backup");
|
|
4353
4638
|
let hadExistingToml = false;
|
|
4354
|
-
if (
|
|
4639
|
+
if (existsSync7(existingTomlPath)) {
|
|
4355
4640
|
hadExistingToml = true;
|
|
4356
4641
|
renameSync(existingTomlPath, backupTomlPath);
|
|
4357
4642
|
}
|
|
4358
4643
|
const tomlContent = generateFlyToml(flyAppId, { port, memory, cpu, region });
|
|
4359
|
-
|
|
4644
|
+
writeFileSync5(existingTomlPath, tomlContent);
|
|
4360
4645
|
try {
|
|
4361
4646
|
if (!json) outputInfo("Building and deploying (this may take a few minutes)...");
|
|
4362
4647
|
await new Promise((resolve4, reject) => {
|
|
@@ -5081,7 +5366,7 @@ function registerDiagnoseCommands(diagnoseCmd2) {
|
|
|
5081
5366
|
const s = !json ? clack10.spinner() : null;
|
|
5082
5367
|
s?.start("Collecting diagnostic data...");
|
|
5083
5368
|
const data2 = await collectDiagnosticData(projectId, ossMode, apiUrl);
|
|
5084
|
-
const cliVersion = "0.1.
|
|
5369
|
+
const cliVersion = "0.1.53-dev.0";
|
|
5085
5370
|
s?.stop("Data collected");
|
|
5086
5371
|
if (!json) {
|
|
5087
5372
|
console.log(`
|
|
@@ -5310,7 +5595,7 @@ function formatBytesCompact(bytes) {
|
|
|
5310
5595
|
|
|
5311
5596
|
// src/index.ts
|
|
5312
5597
|
var __dirname = dirname(fileURLToPath(import.meta.url));
|
|
5313
|
-
var pkg = JSON.parse(
|
|
5598
|
+
var pkg = JSON.parse(readFileSync8(join12(__dirname, "../package.json"), "utf-8"));
|
|
5314
5599
|
var INSFORGE_LOGO = `
|
|
5315
5600
|
\u2588\u2588\u2557\u2588\u2588\u2588\u2557 \u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557
|
|
5316
5601
|
\u2588\u2588\u2551\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D\u2588\u2588\u2554\u2550\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D \u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D
|
|
@@ -5344,6 +5629,7 @@ registerDbTriggersCommand(dbCmd);
|
|
|
5344
5629
|
registerDbRpcCommand(dbCmd);
|
|
5345
5630
|
registerDbExportCommand(dbCmd);
|
|
5346
5631
|
registerDbImportCommand(dbCmd);
|
|
5632
|
+
registerDbMigrationsCommand(dbCmd);
|
|
5347
5633
|
var recordsCmd = program.command("records", { hidden: true }).description("CRUD operations on table records");
|
|
5348
5634
|
registerRecordsCommands(recordsCmd);
|
|
5349
5635
|
registerRecordsCreateCommand(recordsCmd);
|