@insforge/cli 0.1.23 → 0.1.25
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 +77 -39
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
// src/index.ts
|
|
4
4
|
import { readFileSync as readFileSync6 } from "fs";
|
|
5
|
-
import { join as
|
|
5
|
+
import { join as join7, dirname } from "path";
|
|
6
6
|
import { fileURLToPath } from "url";
|
|
7
7
|
import { Command } from "commander";
|
|
8
8
|
import * as clack14 from "@clack/prompts";
|
|
@@ -360,7 +360,7 @@ async function refreshAccessToken(apiUrl) {
|
|
|
360
360
|
}
|
|
361
361
|
|
|
362
362
|
// src/lib/api/platform.ts
|
|
363
|
-
async function platformFetch(
|
|
363
|
+
async function platformFetch(path4, options = {}, apiUrl) {
|
|
364
364
|
const baseUrl = getPlatformApiUrl(apiUrl);
|
|
365
365
|
const token = getAccessToken();
|
|
366
366
|
if (!token) {
|
|
@@ -371,11 +371,11 @@ async function platformFetch(path3, options = {}, apiUrl) {
|
|
|
371
371
|
Authorization: `Bearer ${token}`,
|
|
372
372
|
...options.headers ?? {}
|
|
373
373
|
};
|
|
374
|
-
const res = await fetch(`${baseUrl}${
|
|
374
|
+
const res = await fetch(`${baseUrl}${path4}`, { ...options, headers });
|
|
375
375
|
if (res.status === 401) {
|
|
376
376
|
const newToken = await refreshAccessToken(apiUrl);
|
|
377
377
|
headers.Authorization = `Bearer ${newToken}`;
|
|
378
|
-
const retryRes = await fetch(`${baseUrl}${
|
|
378
|
+
const retryRes = await fetch(`${baseUrl}${path4}`, { ...options, headers });
|
|
379
379
|
if (!retryRes.ok) {
|
|
380
380
|
const err = await retryRes.json().catch(() => ({}));
|
|
381
381
|
throw new CLIError(err.error ?? `Request failed: ${retryRes.status}`, retryRes.status === 403 ? 5 : 1);
|
|
@@ -866,14 +866,14 @@ async function getAnonKey() {
|
|
|
866
866
|
const data = await res.json();
|
|
867
867
|
return data.accessToken;
|
|
868
868
|
}
|
|
869
|
-
async function ossFetch(
|
|
869
|
+
async function ossFetch(path4, options = {}) {
|
|
870
870
|
const config = requireProjectConfig();
|
|
871
871
|
const headers = {
|
|
872
872
|
"Content-Type": "application/json",
|
|
873
873
|
Authorization: `Bearer ${config.api_key}`,
|
|
874
874
|
...options.headers ?? {}
|
|
875
875
|
};
|
|
876
|
-
const res = await fetch(`${config.oss_host}${
|
|
876
|
+
const res = await fetch(`${config.oss_host}${path4}`, { ...options, headers });
|
|
877
877
|
if (!res.ok) {
|
|
878
878
|
const err = await res.json().catch(() => ({}));
|
|
879
879
|
throw new CLIError(err.error ?? `OSS request failed: ${res.status}`);
|
|
@@ -1215,8 +1215,8 @@ function registerRecordsCommands(recordsCmd2) {
|
|
|
1215
1215
|
if (opts.limit) params.set("limit", String(opts.limit));
|
|
1216
1216
|
if (opts.offset) params.set("offset", String(opts.offset));
|
|
1217
1217
|
const query = params.toString();
|
|
1218
|
-
const
|
|
1219
|
-
const res = await ossFetch(
|
|
1218
|
+
const path4 = `/api/database/records/${encodeURIComponent(table)}${query ? `?${query}` : ""}`;
|
|
1219
|
+
const res = await ossFetch(path4);
|
|
1220
1220
|
const data = await res.json();
|
|
1221
1221
|
const records = data.data ?? [];
|
|
1222
1222
|
if (json) {
|
|
@@ -1779,13 +1779,41 @@ function registerStorageListObjectsCommand(storageCmd2) {
|
|
|
1779
1779
|
import { exec as exec2 } from "child_process";
|
|
1780
1780
|
import { tmpdir } from "os";
|
|
1781
1781
|
import { promisify as promisify2 } from "util";
|
|
1782
|
-
import * as
|
|
1783
|
-
import * as
|
|
1782
|
+
import * as fs3 from "fs/promises";
|
|
1783
|
+
import * as path3 from "path";
|
|
1784
1784
|
import * as clack10 from "@clack/prompts";
|
|
1785
1785
|
|
|
1786
|
-
// src/
|
|
1787
|
-
import * as path from "path";
|
|
1786
|
+
// src/lib/env.ts
|
|
1788
1787
|
import * as fs from "fs/promises";
|
|
1788
|
+
import * as path from "path";
|
|
1789
|
+
async function readEnvFile(cwd) {
|
|
1790
|
+
const candidates = [".env.local", ".env.production", ".env"];
|
|
1791
|
+
for (const name of candidates) {
|
|
1792
|
+
const filePath = path.join(cwd, name);
|
|
1793
|
+
const exists = await fs.stat(filePath).catch(() => null);
|
|
1794
|
+
if (!exists) continue;
|
|
1795
|
+
const content = await fs.readFile(filePath, "utf-8");
|
|
1796
|
+
const vars = [];
|
|
1797
|
+
for (const line of content.split("\n")) {
|
|
1798
|
+
const trimmed = line.trim();
|
|
1799
|
+
if (!trimmed || trimmed.startsWith("#")) continue;
|
|
1800
|
+
const eqIndex = trimmed.indexOf("=");
|
|
1801
|
+
if (eqIndex === -1) continue;
|
|
1802
|
+
const key = trimmed.slice(0, eqIndex).trim();
|
|
1803
|
+
let value = trimmed.slice(eqIndex + 1).trim();
|
|
1804
|
+
if (value.startsWith('"') && value.endsWith('"') || value.startsWith("'") && value.endsWith("'")) {
|
|
1805
|
+
value = value.slice(1, -1);
|
|
1806
|
+
}
|
|
1807
|
+
if (key) vars.push({ key, value });
|
|
1808
|
+
}
|
|
1809
|
+
return vars;
|
|
1810
|
+
}
|
|
1811
|
+
return [];
|
|
1812
|
+
}
|
|
1813
|
+
|
|
1814
|
+
// src/commands/deployments/deploy.ts
|
|
1815
|
+
import * as path2 from "path";
|
|
1816
|
+
import * as fs2 from "fs/promises";
|
|
1789
1817
|
import * as clack9 from "@clack/prompts";
|
|
1790
1818
|
import archiver from "archiver";
|
|
1791
1819
|
var POLL_INTERVAL_MS = 5e3;
|
|
@@ -1885,8 +1913,8 @@ function registerDeploymentsDeployCommand(deploymentsCmd2) {
|
|
|
1885
1913
|
await requireAuth();
|
|
1886
1914
|
const config = getProjectConfig();
|
|
1887
1915
|
if (!config) throw new ProjectNotLinkedError();
|
|
1888
|
-
const sourceDir =
|
|
1889
|
-
const stats = await
|
|
1916
|
+
const sourceDir = path2.resolve(directory ?? ".");
|
|
1917
|
+
const stats = await fs2.stat(sourceDir).catch(() => null);
|
|
1890
1918
|
if (!stats?.isDirectory()) {
|
|
1891
1919
|
throw new CLIError(`"${sourceDir}" is not a valid directory.`);
|
|
1892
1920
|
}
|
|
@@ -1955,15 +1983,15 @@ async function waitForProjectActive(projectId, apiUrl, timeoutMs = 12e4) {
|
|
|
1955
1983
|
throw new CLIError("Project creation timed out. Check the dashboard for status.");
|
|
1956
1984
|
}
|
|
1957
1985
|
async function copyDir(src, dest) {
|
|
1958
|
-
const entries = await
|
|
1986
|
+
const entries = await fs3.readdir(src, { withFileTypes: true });
|
|
1959
1987
|
for (const entry of entries) {
|
|
1960
|
-
const srcPath =
|
|
1961
|
-
const destPath =
|
|
1988
|
+
const srcPath = path3.join(src, entry.name);
|
|
1989
|
+
const destPath = path3.join(dest, entry.name);
|
|
1962
1990
|
if (entry.isDirectory()) {
|
|
1963
|
-
await
|
|
1991
|
+
await fs3.mkdir(destPath, { recursive: true });
|
|
1964
1992
|
await copyDir(srcPath, destPath);
|
|
1965
1993
|
} else {
|
|
1966
|
-
await
|
|
1994
|
+
await fs3.copyFile(srcPath, destPath);
|
|
1967
1995
|
}
|
|
1968
1996
|
}
|
|
1969
1997
|
}
|
|
@@ -2007,7 +2035,11 @@ function registerCreateCommand(program2) {
|
|
|
2007
2035
|
if (clack10.isCancel(name)) process.exit(0);
|
|
2008
2036
|
projectName = name;
|
|
2009
2037
|
}
|
|
2038
|
+
const validTemplates = ["react", "nextjs", "chatbot", "empty"];
|
|
2010
2039
|
let template = opts.template;
|
|
2040
|
+
if (template && !validTemplates.includes(template)) {
|
|
2041
|
+
throw new CLIError(`Invalid template "${template}". Valid options: ${validTemplates.join(", ")}`);
|
|
2042
|
+
}
|
|
2011
2043
|
if (!template) {
|
|
2012
2044
|
if (json) {
|
|
2013
2045
|
template = "empty";
|
|
@@ -2072,9 +2104,15 @@ function registerCreateCommand(program2) {
|
|
|
2072
2104
|
});
|
|
2073
2105
|
if (!clack10.isCancel(shouldDeploy) && shouldDeploy) {
|
|
2074
2106
|
try {
|
|
2107
|
+
const envVars = await readEnvFile(process.cwd());
|
|
2108
|
+
const startBody = {};
|
|
2109
|
+
if (envVars.length > 0) {
|
|
2110
|
+
startBody.envVars = envVars;
|
|
2111
|
+
}
|
|
2075
2112
|
const deploySpinner = clack10.spinner();
|
|
2076
2113
|
const result = await deployProject({
|
|
2077
2114
|
sourceDir: process.cwd(),
|
|
2115
|
+
startBody,
|
|
2078
2116
|
spinner: deploySpinner
|
|
2079
2117
|
});
|
|
2080
2118
|
if (result.isReady) {
|
|
@@ -2124,9 +2162,9 @@ async function downloadTemplate(framework, projectConfig, projectName, json, _ap
|
|
|
2124
2162
|
}
|
|
2125
2163
|
const tempDir = tmpdir();
|
|
2126
2164
|
const targetDir = projectName;
|
|
2127
|
-
const templatePath =
|
|
2165
|
+
const templatePath = path3.join(tempDir, targetDir);
|
|
2128
2166
|
try {
|
|
2129
|
-
await
|
|
2167
|
+
await fs3.rm(templatePath, { recursive: true, force: true });
|
|
2130
2168
|
} catch {
|
|
2131
2169
|
}
|
|
2132
2170
|
const frame = framework === "nextjs" ? "nextjs" : "react";
|
|
@@ -2140,7 +2178,7 @@ async function downloadTemplate(framework, projectConfig, projectName, json, _ap
|
|
|
2140
2178
|
s?.message("Copying template files...");
|
|
2141
2179
|
const cwd = process.cwd();
|
|
2142
2180
|
await copyDir(templatePath, cwd);
|
|
2143
|
-
await
|
|
2181
|
+
await fs3.rm(templatePath, { recursive: true, force: true }).catch(() => {
|
|
2144
2182
|
});
|
|
2145
2183
|
s?.stop("Template files downloaded");
|
|
2146
2184
|
} catch (err) {
|
|
@@ -2154,28 +2192,28 @@ async function downloadTemplate(framework, projectConfig, projectName, json, _ap
|
|
|
2154
2192
|
async function downloadGitHubTemplate(templateName, projectConfig, json) {
|
|
2155
2193
|
const s = !json ? clack10.spinner() : null;
|
|
2156
2194
|
s?.start(`Downloading ${templateName} template...`);
|
|
2157
|
-
const tempDir =
|
|
2195
|
+
const tempDir = path3.join(tmpdir(), `insforge-template-${Date.now()}`);
|
|
2158
2196
|
try {
|
|
2159
|
-
await
|
|
2197
|
+
await fs3.mkdir(tempDir, { recursive: true });
|
|
2160
2198
|
await execAsync2(
|
|
2161
2199
|
"git clone --depth 1 https://github.com/InsForge/insforge-templates.git .",
|
|
2162
2200
|
{ cwd: tempDir, maxBuffer: 10 * 1024 * 1024, timeout: 6e4 }
|
|
2163
2201
|
);
|
|
2164
|
-
const templateDir =
|
|
2165
|
-
const
|
|
2166
|
-
if (!
|
|
2202
|
+
const templateDir = path3.join(tempDir, templateName);
|
|
2203
|
+
const stat4 = await fs3.stat(templateDir).catch(() => null);
|
|
2204
|
+
if (!stat4?.isDirectory()) {
|
|
2167
2205
|
throw new Error(`Template "${templateName}" not found in repository`);
|
|
2168
2206
|
}
|
|
2169
2207
|
s?.message("Copying template files...");
|
|
2170
2208
|
const cwd = process.cwd();
|
|
2171
2209
|
await copyDir(templateDir, cwd);
|
|
2172
|
-
const envExamplePath =
|
|
2173
|
-
const envExampleExists = await
|
|
2210
|
+
const envExamplePath = path3.join(cwd, ".env.example");
|
|
2211
|
+
const envExampleExists = await fs3.stat(envExamplePath).catch(() => null);
|
|
2174
2212
|
if (envExampleExists) {
|
|
2175
2213
|
const anonKey = await getAnonKey();
|
|
2176
|
-
const envExample = await
|
|
2214
|
+
const envExample = await fs3.readFile(envExamplePath, "utf-8");
|
|
2177
2215
|
const envContent = envExample.replace(
|
|
2178
|
-
/^([A-
|
|
2216
|
+
/^([A-Z][A-Z0-9_]*=)(.*)$/gm,
|
|
2179
2217
|
(_, prefix, _value) => {
|
|
2180
2218
|
const key = prefix.slice(0, -1);
|
|
2181
2219
|
if (/INSFORGE.*(URL|BASE_URL)$/.test(key)) return `${prefix}${projectConfig.oss_host}`;
|
|
@@ -2183,16 +2221,16 @@ async function downloadGitHubTemplate(templateName, projectConfig, json) {
|
|
|
2183
2221
|
return `${prefix}${_value}`;
|
|
2184
2222
|
}
|
|
2185
2223
|
);
|
|
2186
|
-
await
|
|
2224
|
+
await fs3.writeFile(path3.join(cwd, ".env.local"), envContent);
|
|
2187
2225
|
}
|
|
2188
2226
|
s?.stop(`${templateName} template downloaded`);
|
|
2189
|
-
const migrationPath =
|
|
2190
|
-
const migrationExists = await
|
|
2227
|
+
const migrationPath = path3.join(cwd, "migrations", "db_int.sql");
|
|
2228
|
+
const migrationExists = await fs3.stat(migrationPath).catch(() => null);
|
|
2191
2229
|
if (migrationExists) {
|
|
2192
2230
|
const dbSpinner = !json ? clack10.spinner() : null;
|
|
2193
2231
|
dbSpinner?.start("Running database migrations...");
|
|
2194
2232
|
try {
|
|
2195
|
-
const sql = await
|
|
2233
|
+
const sql = await fs3.readFile(migrationPath, "utf-8");
|
|
2196
2234
|
await ossFetch("/api/database/advance/rawsql/unrestricted", {
|
|
2197
2235
|
method: "POST",
|
|
2198
2236
|
body: JSON.stringify({ query: sql })
|
|
@@ -2213,7 +2251,7 @@ async function downloadGitHubTemplate(templateName, projectConfig, json) {
|
|
|
2213
2251
|
clack10.log.info("You can manually clone from: https://github.com/InsForge/insforge-templates");
|
|
2214
2252
|
}
|
|
2215
2253
|
} finally {
|
|
2216
|
-
await
|
|
2254
|
+
await fs3.rm(tempDir, { recursive: true, force: true }).catch(() => {
|
|
2217
2255
|
});
|
|
2218
2256
|
}
|
|
2219
2257
|
}
|
|
@@ -2475,8 +2513,8 @@ async function listDocs(json) {
|
|
|
2475
2513
|
);
|
|
2476
2514
|
}
|
|
2477
2515
|
}
|
|
2478
|
-
async function fetchDoc(
|
|
2479
|
-
const res = await ossFetch(
|
|
2516
|
+
async function fetchDoc(path4, label, json) {
|
|
2517
|
+
const res = await ossFetch(path4);
|
|
2480
2518
|
const data = await res.json();
|
|
2481
2519
|
const doc = data.data ?? data;
|
|
2482
2520
|
if (json) {
|
|
@@ -2990,7 +3028,7 @@ function formatSize2(gb) {
|
|
|
2990
3028
|
|
|
2991
3029
|
// src/index.ts
|
|
2992
3030
|
var __dirname = dirname(fileURLToPath(import.meta.url));
|
|
2993
|
-
var pkg = JSON.parse(readFileSync6(
|
|
3031
|
+
var pkg = JSON.parse(readFileSync6(join7(__dirname, "../package.json"), "utf-8"));
|
|
2994
3032
|
var INSFORGE_LOGO = `
|
|
2995
3033
|
\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
|
|
2996
3034
|
\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
|