gencow 0.1.165 → 0.1.166
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/bin/gencow.mjs +1 -1
- package/lib/auth-command.mjs +9 -4
- package/lib/backup-command.mjs +57 -3
- package/lib/cli-project-runtime.mjs +16 -4
- package/lib/codegen/index.mjs +6 -6
- package/lib/cron-manifest.mjs +128 -28
- package/lib/db-command.mjs +18 -8
- package/lib/deploy-package-runtime.mjs +27 -10
- package/lib/dev-cloud-migrations.mjs +6 -3
- package/lib/dev-local-command.mjs +31 -7
- package/lib/drizzle-generate.mjs +34 -0
- package/lib/static-deploy-command.mjs +9 -6
- package/lib/tar-archive.mjs +61 -0
- package/lib/template-marketplace-command.mjs +41 -18
- package/package.json +1 -1
- package/server/index.js +1 -0
- package/server/index.js.map +2 -2
|
@@ -7,13 +7,33 @@ import {
|
|
|
7
7
|
formatAuthSchemaConflictMessage,
|
|
8
8
|
isServerCodegenWatchPath,
|
|
9
9
|
} from "./codegen-command.mjs";
|
|
10
|
+
import { runDrizzleGenerateWithFallback } from "./drizzle-generate.mjs";
|
|
10
11
|
|
|
11
12
|
export function shouldUseLocalDev({ devArgs, processEnv = process.env }) {
|
|
12
13
|
return processEnv.GENCOW_LOCAL === "1" || devArgs.includes("--local");
|
|
13
14
|
}
|
|
14
15
|
|
|
15
|
-
|
|
16
|
-
const
|
|
16
|
+
function normalizePortList(ports) {
|
|
17
|
+
const seen = new Set();
|
|
18
|
+
const normalized = [];
|
|
19
|
+
for (const port of ports) {
|
|
20
|
+
const value = String(port).trim();
|
|
21
|
+
if (!/^\d+$/.test(value)) continue;
|
|
22
|
+
if (seen.has(value)) continue;
|
|
23
|
+
seen.add(value);
|
|
24
|
+
normalized.push(value);
|
|
25
|
+
}
|
|
26
|
+
return normalized;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export function buildKillPortsCommand(ports, platform = process.platform) {
|
|
30
|
+
const normalized = normalizePortList(ports);
|
|
31
|
+
if (normalized.length === 0) return "";
|
|
32
|
+
if (platform === "win32") {
|
|
33
|
+
const list = normalized.join(",");
|
|
34
|
+
return `powershell -NoProfile -ExecutionPolicy Bypass -Command "$ports=@(${list}); Get-NetTCPConnection -LocalPort $ports -ErrorAction SilentlyContinue | Select-Object -ExpandProperty OwningProcess -Unique | ForEach-Object { Stop-Process -Id $_ -Force -ErrorAction SilentlyContinue }"`;
|
|
35
|
+
}
|
|
36
|
+
const flags = normalized.map((port) => `-ti:${port}`).join(" ");
|
|
17
37
|
return `lsof ${flags} 2>/dev/null | xargs kill -9 2>/dev/null || true`;
|
|
18
38
|
}
|
|
19
39
|
|
|
@@ -121,7 +141,8 @@ export function createDevLocalCommands({
|
|
|
121
141
|
const dashPort = config.dashboardPort || 5100;
|
|
122
142
|
const samplePort = config.samplePort || 5001;
|
|
123
143
|
try {
|
|
124
|
-
|
|
144
|
+
const killCommand = buildKillPortsCommand([apiPort, dashPort, samplePort]);
|
|
145
|
+
if (killCommand) execSyncImpl(killCommand, { stdio: "ignore" });
|
|
125
146
|
} catch {
|
|
126
147
|
/* ignore */
|
|
127
148
|
}
|
|
@@ -147,11 +168,13 @@ export function createDevLocalCommands({
|
|
|
147
168
|
stdio: "inherit",
|
|
148
169
|
});
|
|
149
170
|
} else {
|
|
150
|
-
|
|
151
|
-
execSyncImpl(dk.cmd, {
|
|
171
|
+
runDrizzleGenerateWithFallback({
|
|
152
172
|
cwd,
|
|
153
|
-
|
|
173
|
+
drizzleKitCmdImpl,
|
|
174
|
+
env: genEnv,
|
|
175
|
+
execSyncImpl,
|
|
154
176
|
stdio: "inherit",
|
|
177
|
+
warnImpl,
|
|
155
178
|
});
|
|
156
179
|
}
|
|
157
180
|
successImpl("Schema -> migrations synced");
|
|
@@ -237,7 +260,8 @@ export function createDevLocalCommands({
|
|
|
237
260
|
|
|
238
261
|
const killAll = () => {
|
|
239
262
|
try {
|
|
240
|
-
|
|
263
|
+
const killCommand = buildKillPortsCommand([dashPort, samplePort]);
|
|
264
|
+
if (killCommand) execSyncImpl(killCommand, { stdio: "ignore" });
|
|
241
265
|
} catch {
|
|
242
266
|
/* ignore */
|
|
243
267
|
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
export function getCommandErrorMessage(error) {
|
|
2
|
+
return (error?.stderr?.toString() || error?.message || "").trim();
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
export function shouldRetryLegacyGenerate(error) {
|
|
6
|
+
const message = getCommandErrorMessage(error);
|
|
7
|
+
return message.includes("unknown command 'generate'") && message.includes("generate:pg");
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export function runDrizzleGenerateWithFallback({
|
|
11
|
+
cwd,
|
|
12
|
+
drizzleKitCmdImpl,
|
|
13
|
+
env = {},
|
|
14
|
+
execSyncImpl,
|
|
15
|
+
stdio = "inherit",
|
|
16
|
+
warnImpl,
|
|
17
|
+
}) {
|
|
18
|
+
const run = (subcmd) => {
|
|
19
|
+
const dk = drizzleKitCmdImpl(subcmd);
|
|
20
|
+
execSyncImpl(dk.cmd, {
|
|
21
|
+
cwd,
|
|
22
|
+
env: { ...env, ...dk.env },
|
|
23
|
+
stdio,
|
|
24
|
+
});
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
try {
|
|
28
|
+
run("generate");
|
|
29
|
+
} catch (error) {
|
|
30
|
+
if (!shouldRetryLegacyGenerate(error)) throw error;
|
|
31
|
+
warnImpl?.("drizzle-kit uses legacy generate:pg; retrying migration generation...");
|
|
32
|
+
run("generate:pg");
|
|
33
|
+
}
|
|
34
|
+
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { execSync } from "child_process";
|
|
2
1
|
import { existsSync, mkdirSync, readFileSync, readdirSync, statSync, unlinkSync, writeFileSync } from "fs";
|
|
3
|
-
import { resolve } from "path";
|
|
2
|
+
import { relative, resolve } from "path";
|
|
4
3
|
import { BOLD, CYAN, DIM, RESET, YELLOW, error, info, log, success, warn } from "./output.mjs";
|
|
5
4
|
import { platformFetch, rpcMutation } from "./platform-client.mjs";
|
|
5
|
+
import { createTarGzipArchive } from "./tar-archive.mjs";
|
|
6
6
|
|
|
7
7
|
export function resolveStaticDeployDir({
|
|
8
8
|
staticDirArg,
|
|
@@ -94,7 +94,7 @@ export function findBuiltApiReferenceFiles({
|
|
|
94
94
|
const content = readFileSyncImpl(file, "utf8");
|
|
95
95
|
return content.includes("/api/query") || content.includes("/api/mutation");
|
|
96
96
|
})
|
|
97
|
-
.map((file) => file.replace(
|
|
97
|
+
.map((file) => relative(targetDir, file).replace(/\\/g, "/"))
|
|
98
98
|
.sort();
|
|
99
99
|
}
|
|
100
100
|
|
|
@@ -134,7 +134,6 @@ export function createStaticDeployRuntime({
|
|
|
134
134
|
createInterfaceImpl,
|
|
135
135
|
cwdImpl = () => process.cwd(),
|
|
136
136
|
errorImpl = error,
|
|
137
|
-
execSyncImpl = execSync,
|
|
138
137
|
existsSyncImpl = existsSync,
|
|
139
138
|
exitImpl = (code) => process.exit(code),
|
|
140
139
|
infoImpl = info,
|
|
@@ -147,6 +146,7 @@ export function createStaticDeployRuntime({
|
|
|
147
146
|
setTimeoutImpl = setTimeout,
|
|
148
147
|
statSyncImpl = statSync,
|
|
149
148
|
successImpl = success,
|
|
149
|
+
tarCreateImpl,
|
|
150
150
|
unlinkSyncImpl = unlinkSync,
|
|
151
151
|
warnImpl = warn,
|
|
152
152
|
writeFileSyncImpl = writeFileSync,
|
|
@@ -223,8 +223,11 @@ export function createStaticDeployRuntime({
|
|
|
223
223
|
mkdirSyncImpl(resolvePathImpl(tmpBundle, ".."), { recursive: true });
|
|
224
224
|
|
|
225
225
|
try {
|
|
226
|
-
|
|
227
|
-
cwd,
|
|
226
|
+
await createTarGzipArchive({
|
|
227
|
+
cwd: resolvePathImpl(cwd, targetDir),
|
|
228
|
+
file: tmpBundle,
|
|
229
|
+
entries: ["."],
|
|
230
|
+
tarCreateImpl,
|
|
228
231
|
});
|
|
229
232
|
} catch (error) {
|
|
230
233
|
errorImpl(`Packaging failed: ${error.message}`);
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
function normalizeTarPath(value) {
|
|
2
|
+
return String(value || "")
|
|
3
|
+
.replace(/\\/g, "/")
|
|
4
|
+
.replace(/^\.\//, "")
|
|
5
|
+
.replace(/\/+$/, "");
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
function splitTarPath(value) {
|
|
9
|
+
return normalizeTarPath(value).split("/").filter(Boolean);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
function segmentMatchesPattern(segment, pattern) {
|
|
13
|
+
if (pattern.endsWith(".*")) {
|
|
14
|
+
return segment.startsWith(pattern.slice(0, -1));
|
|
15
|
+
}
|
|
16
|
+
return segment === pattern;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function matchesTarExclude(entryPath, pattern) {
|
|
20
|
+
const normalizedPattern = normalizeTarPath(pattern);
|
|
21
|
+
if (!normalizedPattern) return false;
|
|
22
|
+
const entrySegments = splitTarPath(entryPath);
|
|
23
|
+
const patternSegments = splitTarPath(normalizedPattern);
|
|
24
|
+
if (entrySegments.length === 0 || patternSegments.length === 0) return false;
|
|
25
|
+
|
|
26
|
+
if (patternSegments.length === 1) {
|
|
27
|
+
return entrySegments.some((segment) => segmentMatchesPattern(segment, patternSegments[0]));
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
for (let index = 0; index <= entrySegments.length - patternSegments.length; index += 1) {
|
|
31
|
+
const matches = patternSegments.every((segment, offset) =>
|
|
32
|
+
segmentMatchesPattern(entrySegments[index + offset], segment),
|
|
33
|
+
);
|
|
34
|
+
if (matches) return true;
|
|
35
|
+
}
|
|
36
|
+
return false;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export function shouldIncludeTarEntry(entryPath, excludes = []) {
|
|
40
|
+
return !excludes.some((pattern) => matchesTarExclude(entryPath, pattern));
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export async function createTarGzipArchive({
|
|
44
|
+
cwd,
|
|
45
|
+
file,
|
|
46
|
+
entries = ["."],
|
|
47
|
+
excludes = [],
|
|
48
|
+
tarCreateImpl,
|
|
49
|
+
}) {
|
|
50
|
+
const createImpl = tarCreateImpl ?? (await import("tar")).create;
|
|
51
|
+
const options = {
|
|
52
|
+
cwd,
|
|
53
|
+
file,
|
|
54
|
+
gzip: true,
|
|
55
|
+
portable: true,
|
|
56
|
+
};
|
|
57
|
+
if (excludes.length > 0) {
|
|
58
|
+
options.filter = (entryPath) => shouldIncludeTarEntry(entryPath, excludes);
|
|
59
|
+
}
|
|
60
|
+
await createImpl(options, entries);
|
|
61
|
+
}
|
|
@@ -3,6 +3,7 @@ import { existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from "fs";
|
|
|
3
3
|
import { basename, resolve } from "path";
|
|
4
4
|
import { BOLD, CYAN, DIM, GREEN, RESET, error, info, log, success } from "./output.mjs";
|
|
5
5
|
import { platformFetch, requireCreds } from "./platform-client.mjs";
|
|
6
|
+
import { createTarGzipArchive } from "./tar-archive.mjs";
|
|
6
7
|
import {
|
|
7
8
|
buildTemplateTarExcludes,
|
|
8
9
|
detectStaticTemplateProject,
|
|
@@ -39,29 +40,42 @@ function centsFromPrice(value) {
|
|
|
39
40
|
return Math.round(numeric * 100);
|
|
40
41
|
}
|
|
41
42
|
|
|
42
|
-
function
|
|
43
|
-
return `'${String(value).replace(/'/g, "'\\''")}'`;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
function createSourceBundle({ cwd, staticOutputDir, execSyncImpl = execSync, mkdirSyncImpl = mkdirSync }) {
|
|
43
|
+
async function createSourceBundle({ cwd, staticOutputDir, mkdirSyncImpl = mkdirSync, tarCreateImpl }) {
|
|
47
44
|
const out = resolve(cwd, ".gencow", "template-source.tar.gz");
|
|
48
45
|
mkdirSyncImpl(resolve(cwd, ".gencow"), { recursive: true });
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
46
|
+
await createTarGzipArchive({
|
|
47
|
+
cwd,
|
|
48
|
+
file: out,
|
|
49
|
+
entries: ["."],
|
|
50
|
+
excludes: buildTemplateTarExcludes(staticOutputDir),
|
|
51
|
+
tarCreateImpl,
|
|
52
|
+
});
|
|
53
53
|
return out;
|
|
54
54
|
}
|
|
55
55
|
|
|
56
|
-
function createStaticBundle({ cwd, outputDir,
|
|
56
|
+
async function createStaticBundle({ cwd, outputDir, mkdirSyncImpl = mkdirSync, resolvePathImpl = resolve, tarCreateImpl }) {
|
|
57
57
|
const out = resolve(cwd, ".gencow", "template-static.tar.gz");
|
|
58
58
|
mkdirSyncImpl(resolve(cwd, ".gencow"), { recursive: true });
|
|
59
|
-
|
|
60
|
-
cwd,
|
|
59
|
+
await createTarGzipArchive({
|
|
60
|
+
cwd: resolvePathImpl(cwd, outputDir),
|
|
61
|
+
file: out,
|
|
62
|
+
entries: ["."],
|
|
63
|
+
tarCreateImpl,
|
|
61
64
|
});
|
|
62
65
|
return out;
|
|
63
66
|
}
|
|
64
67
|
|
|
68
|
+
async function extractTemplateArchive({
|
|
69
|
+
archive,
|
|
70
|
+
targetDir,
|
|
71
|
+
mkdirSyncImpl = mkdirSync,
|
|
72
|
+
tarExtractImpl,
|
|
73
|
+
}) {
|
|
74
|
+
mkdirSyncImpl(targetDir, { recursive: true });
|
|
75
|
+
const extractImpl = tarExtractImpl ?? (await import("tar")).extract;
|
|
76
|
+
await extractImpl({ file: archive, cwd: targetDir });
|
|
77
|
+
}
|
|
78
|
+
|
|
65
79
|
async function rpc(creds, name, args, platformFetchImpl) {
|
|
66
80
|
const res = await platformFetchImpl(creds, "/api/query", {
|
|
67
81
|
method: "POST",
|
|
@@ -81,12 +95,15 @@ export function createTemplateMarketplaceCommand({
|
|
|
81
95
|
exitImpl = (code) => process.exit(code),
|
|
82
96
|
infoImpl = info,
|
|
83
97
|
logImpl = log,
|
|
98
|
+
mkdirSyncImpl = mkdirSync,
|
|
84
99
|
platformFetchImpl = platformFetch,
|
|
85
100
|
readFileSyncImpl = readFileSync,
|
|
86
101
|
requireCredsImpl = requireCreds,
|
|
87
102
|
resolvePathImpl = resolve,
|
|
88
103
|
rmSyncImpl = rmSync,
|
|
89
104
|
successImpl = success,
|
|
105
|
+
tarCreateImpl,
|
|
106
|
+
tarExtractImpl,
|
|
90
107
|
writeFileSyncImpl = writeFileSync,
|
|
91
108
|
} = {}) {
|
|
92
109
|
async function publish(options) {
|
|
@@ -124,15 +141,18 @@ export function createTemplateMarketplaceCommand({
|
|
|
124
141
|
});
|
|
125
142
|
if (!outputValidation.ok) throw new Error(outputValidation.error);
|
|
126
143
|
|
|
127
|
-
const sourceBundle = createSourceBundle({
|
|
144
|
+
const sourceBundle = await createSourceBundle({
|
|
128
145
|
cwd,
|
|
129
146
|
staticOutputDir: detection.staticOutputDir,
|
|
130
|
-
|
|
147
|
+
mkdirSyncImpl,
|
|
148
|
+
tarCreateImpl,
|
|
131
149
|
});
|
|
132
|
-
const staticBundle = createStaticBundle({
|
|
150
|
+
const staticBundle = await createStaticBundle({
|
|
133
151
|
cwd: resolvePathImpl(cwd, detection.buildWorkdir),
|
|
134
152
|
outputDir: detection.staticOutputDir,
|
|
135
|
-
|
|
153
|
+
mkdirSyncImpl,
|
|
154
|
+
resolvePathImpl,
|
|
155
|
+
tarCreateImpl,
|
|
136
156
|
});
|
|
137
157
|
|
|
138
158
|
const creds = requireCredsImpl();
|
|
@@ -215,8 +235,11 @@ export function createTemplateMarketplaceCommand({
|
|
|
215
235
|
const slug = options._[0];
|
|
216
236
|
const dir = options._[1] || slug;
|
|
217
237
|
const archive = await download(slug, { ...options, outFile: ".gencow-template-clone.tar.gz" }, true);
|
|
218
|
-
|
|
219
|
-
|
|
238
|
+
await extractTemplateArchive({
|
|
239
|
+
archive,
|
|
240
|
+
targetDir: resolvePathImpl(cwdImpl(), dir),
|
|
241
|
+
mkdirSyncImpl,
|
|
242
|
+
tarExtractImpl,
|
|
220
243
|
});
|
|
221
244
|
rmSyncImpl(archive, { force: true });
|
|
222
245
|
successImpl(`Cloned into: ${dir}`);
|
package/package.json
CHANGED
package/server/index.js
CHANGED
|
@@ -117234,6 +117234,7 @@ function createHttpActionRequest(c) {
|
|
|
117234
117234
|
params: c.req.param(),
|
|
117235
117235
|
query: c.req.query(),
|
|
117236
117236
|
headers: Object.fromEntries(c.req.raw.headers.entries()),
|
|
117237
|
+
raw: c.req.raw,
|
|
117237
117238
|
json: () => c.req.json(),
|
|
117238
117239
|
formData: () => c.req.formData(),
|
|
117239
117240
|
arrayBuffer: () => c.req.arrayBuffer(),
|