@zveltio/cli 3.0.0-beta.3 → 3.0.0-beta.5
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 +189 -214
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -1886,45 +1886,10 @@ var require_commander = __commonJS((exports) => {
|
|
|
1886
1886
|
exports.InvalidOptionArgumentError = InvalidArgumentError;
|
|
1887
1887
|
});
|
|
1888
1888
|
|
|
1889
|
-
// src/lib/publisher-tier.ts
|
|
1890
|
-
function tierAllowsInline(tier) {
|
|
1891
|
-
return tier === "first-party" || tier === "verified";
|
|
1892
|
-
}
|
|
1893
|
-
async function resolvePublisherTier(opts = {}) {
|
|
1894
|
-
if (opts.firstParty) {
|
|
1895
|
-
return { tier: "first-party", allowsInline: true, source: "flag" };
|
|
1896
|
-
}
|
|
1897
|
-
const token = opts.token ?? process.env.ZVELTIO_REGISTRY_TOKEN;
|
|
1898
|
-
const registryUrl = opts.registryUrl ?? process.env.ZVELTIO_REGISTRY_URL ?? "https://registry.zveltio.com";
|
|
1899
|
-
if (token) {
|
|
1900
|
-
try {
|
|
1901
|
-
const base = registryUrl.replace(/\/$/, "");
|
|
1902
|
-
const url = new URL(`${base}/api/dev/publisher/self`);
|
|
1903
|
-
if (opts.keyId)
|
|
1904
|
-
url.searchParams.set("keyId", opts.keyId);
|
|
1905
|
-
const res = await fetch(url.toString(), {
|
|
1906
|
-
headers: { Authorization: `Bearer ${token}` },
|
|
1907
|
-
signal: AbortSignal.timeout(5000)
|
|
1908
|
-
});
|
|
1909
|
-
if (res.ok) {
|
|
1910
|
-
const data = await res.json();
|
|
1911
|
-
const tier = normalizeTier(data.tier);
|
|
1912
|
-
if (tier) {
|
|
1913
|
-
return { tier, allowsInline: tierAllowsInline(tier), source: "registry" };
|
|
1914
|
-
}
|
|
1915
|
-
}
|
|
1916
|
-
} catch {}
|
|
1917
|
-
}
|
|
1918
|
-
return { tier: "community", allowsInline: false, source: "default" };
|
|
1919
|
-
}
|
|
1920
|
-
function normalizeTier(v) {
|
|
1921
|
-
return v === "first-party" || v === "verified" || v === "community" ? v : null;
|
|
1922
|
-
}
|
|
1923
|
-
|
|
1924
1889
|
// ../sdk/dist/build/index.js
|
|
1925
1890
|
import { createRequire } from "module";
|
|
1926
|
-
import { existsSync as
|
|
1927
|
-
import { dirname, join as
|
|
1891
|
+
import { existsSync as existsSync5, readFileSync } from "fs";
|
|
1892
|
+
import { dirname, join as join5 } from "path";
|
|
1928
1893
|
function escapeRegExp(s) {
|
|
1929
1894
|
return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
1930
1895
|
}
|
|
@@ -1948,7 +1913,7 @@ function resolveSearchPaths(resolveFromDir) {
|
|
|
1948
1913
|
for (let i = 0;i < 6; i++) {
|
|
1949
1914
|
cur = dirname(cur);
|
|
1950
1915
|
paths.push(cur);
|
|
1951
|
-
if (
|
|
1916
|
+
if (existsSync5(join5(cur, "node_modules")))
|
|
1952
1917
|
break;
|
|
1953
1918
|
}
|
|
1954
1919
|
return [...new Set(paths)];
|
|
@@ -1961,9 +1926,9 @@ function resolvePackageRoot(pkg, searchPaths) {
|
|
|
1961
1926
|
throw new Error(`Cannot find package "${pkg}" from ${searchPaths[0]}. ` + `Run \`bun install\` in the extension directory or monorepo root.`);
|
|
1962
1927
|
}
|
|
1963
1928
|
for (;; ) {
|
|
1964
|
-
const pkgJsonPath =
|
|
1965
|
-
if (
|
|
1966
|
-
const manifest = JSON.parse(
|
|
1929
|
+
const pkgJsonPath = join5(candidate, "package.json");
|
|
1930
|
+
if (existsSync5(pkgJsonPath)) {
|
|
1931
|
+
const manifest = JSON.parse(readFileSync(pkgJsonPath, "utf8"));
|
|
1967
1932
|
if (manifest.name === pkg)
|
|
1968
1933
|
return candidate;
|
|
1969
1934
|
}
|
|
@@ -1977,16 +1942,16 @@ function resolvePackageRoot(pkg, searchPaths) {
|
|
|
1977
1942
|
function resolvePackageEsmEntry(pkg, resolveFromDir) {
|
|
1978
1943
|
const searchPaths = resolveSearchPaths(resolveFromDir);
|
|
1979
1944
|
const root = resolvePackageRoot(pkg, searchPaths);
|
|
1980
|
-
const pkgJsonPath =
|
|
1981
|
-
const manifest = JSON.parse(
|
|
1945
|
+
const pkgJsonPath = join5(root, "package.json");
|
|
1946
|
+
const manifest = JSON.parse(readFileSync(pkgJsonPath, "utf8"));
|
|
1982
1947
|
const dot = manifest.exports?.["."];
|
|
1983
1948
|
let rel = pickExportTarget(dot);
|
|
1984
1949
|
rel ??= manifest.module ?? manifest.main;
|
|
1985
1950
|
if (!rel || typeof rel !== "string") {
|
|
1986
1951
|
throw new Error(`Cannot determine ESM entry for package "${pkg}"`);
|
|
1987
1952
|
}
|
|
1988
|
-
const abs =
|
|
1989
|
-
if (!
|
|
1953
|
+
const abs = join5(root, rel.replace(/^\.\//, ""));
|
|
1954
|
+
if (!existsSync5(abs)) {
|
|
1990
1955
|
throw new Error(`ESM entry missing for "${pkg}": ${abs}`);
|
|
1991
1956
|
}
|
|
1992
1957
|
if (abs.endsWith(".d.ts")) {
|
|
@@ -2032,12 +1997,12 @@ var init_build = __esm(() => {
|
|
|
2032
1997
|
});
|
|
2033
1998
|
|
|
2034
1999
|
// src/lib/extension-bundle.ts
|
|
2035
|
-
import { existsSync as
|
|
2036
|
-
import { basename, dirname as dirname2, join as
|
|
2000
|
+
import { existsSync as existsSync6, renameSync } from "fs";
|
|
2001
|
+
import { basename, dirname as dirname2, join as join6 } from "path";
|
|
2037
2002
|
async function bundleExtensionEngine(opts) {
|
|
2038
2003
|
const outdir = dirname2(opts.outfile);
|
|
2039
2004
|
const entryBase = basename(opts.entry).replace(/\.[^.]+$/, "");
|
|
2040
|
-
const builtPath =
|
|
2005
|
+
const builtPath = join6(outdir, `${entryBase}.js`);
|
|
2041
2006
|
const result = await Bun.build({
|
|
2042
2007
|
...createExtensionBuildConfig({
|
|
2043
2008
|
entry: opts.entry,
|
|
@@ -2053,7 +2018,7 @@ async function bundleExtensionEngine(opts) {
|
|
|
2053
2018
|
`);
|
|
2054
2019
|
throw new Error(messages || "Bun.build failed");
|
|
2055
2020
|
}
|
|
2056
|
-
if (!
|
|
2021
|
+
if (!existsSync6(builtPath)) {
|
|
2057
2022
|
throw new Error(`Bun.build succeeded but ${builtPath} was not produced`);
|
|
2058
2023
|
}
|
|
2059
2024
|
if (builtPath !== opts.outfile) {
|
|
@@ -2066,23 +2031,58 @@ var init_extension_bundle = __esm(() => {
|
|
|
2066
2031
|
EXTENSION_BUNDLE_CORE_DEPS2 = EXTENSION_BUNDLE_CORE_DEPS;
|
|
2067
2032
|
});
|
|
2068
2033
|
|
|
2034
|
+
// src/lib/publisher-tier.ts
|
|
2035
|
+
function tierAllowsInline(tier) {
|
|
2036
|
+
return tier === "first-party" || tier === "verified";
|
|
2037
|
+
}
|
|
2038
|
+
async function resolvePublisherTier(opts = {}) {
|
|
2039
|
+
if (opts.firstParty) {
|
|
2040
|
+
return { tier: "first-party", allowsInline: true, source: "flag" };
|
|
2041
|
+
}
|
|
2042
|
+
const token = opts.token ?? process.env.ZVELTIO_REGISTRY_TOKEN;
|
|
2043
|
+
const registryUrl = opts.registryUrl ?? process.env.ZVELTIO_REGISTRY_URL ?? "https://registry.zveltio.com";
|
|
2044
|
+
if (token) {
|
|
2045
|
+
try {
|
|
2046
|
+
const base = registryUrl.replace(/\/$/, "");
|
|
2047
|
+
const url = new URL(`${base}/api/dev/publisher/self`);
|
|
2048
|
+
if (opts.keyId)
|
|
2049
|
+
url.searchParams.set("keyId", opts.keyId);
|
|
2050
|
+
const res = await fetch(url.toString(), {
|
|
2051
|
+
headers: { Authorization: `Bearer ${token}` },
|
|
2052
|
+
signal: AbortSignal.timeout(5000)
|
|
2053
|
+
});
|
|
2054
|
+
if (res.ok) {
|
|
2055
|
+
const data = await res.json();
|
|
2056
|
+
const tier = normalizeTier(data.tier);
|
|
2057
|
+
if (tier) {
|
|
2058
|
+
return { tier, allowsInline: tierAllowsInline(tier), source: "registry" };
|
|
2059
|
+
}
|
|
2060
|
+
}
|
|
2061
|
+
} catch {}
|
|
2062
|
+
}
|
|
2063
|
+
return { tier: "community", allowsInline: false, source: "default" };
|
|
2064
|
+
}
|
|
2065
|
+
function normalizeTier(v) {
|
|
2066
|
+
return v === "first-party" || v === "verified" || v === "community" ? v : null;
|
|
2067
|
+
}
|
|
2068
|
+
|
|
2069
2069
|
// src/commands/extension-pack.ts
|
|
2070
2070
|
var exports_extension_pack = {};
|
|
2071
2071
|
__export(exports_extension_pack, {
|
|
2072
2072
|
extensionPackCommand: () => extensionPackCommand
|
|
2073
2073
|
});
|
|
2074
2074
|
import { createHash } from "crypto";
|
|
2075
|
-
import { existsSync as
|
|
2076
|
-
import { join as
|
|
2075
|
+
import { existsSync as existsSync7, readFileSync as readFileSync2, writeFileSync } from "fs";
|
|
2076
|
+
import { join as join7, resolve } from "path";
|
|
2077
2077
|
function readManifest(dir) {
|
|
2078
|
-
const path =
|
|
2079
|
-
if (!
|
|
2078
|
+
const path = join7(dir, "manifest.json");
|
|
2079
|
+
if (!existsSync7(path)) {
|
|
2080
2080
|
throw new Error(`No manifest.json at ${path}.`);
|
|
2081
2081
|
}
|
|
2082
|
-
return JSON.parse(
|
|
2082
|
+
return JSON.parse(readFileSync2(path, "utf8"));
|
|
2083
2083
|
}
|
|
2084
2084
|
function writeManifest(dir, m) {
|
|
2085
|
-
|
|
2085
|
+
writeFileSync(join7(dir, "manifest.json"), `${JSON.stringify(m, null, 2)}
|
|
2086
2086
|
`, "utf8");
|
|
2087
2087
|
}
|
|
2088
2088
|
function validatePeerDeps(m) {
|
|
@@ -2097,13 +2097,13 @@ function validatePeerDeps(m) {
|
|
|
2097
2097
|
}
|
|
2098
2098
|
async function extensionPackCommand(opts) {
|
|
2099
2099
|
const dir = resolve(opts.dir ?? process.cwd());
|
|
2100
|
-
const entry =
|
|
2101
|
-
const outfile =
|
|
2102
|
-
if (!
|
|
2100
|
+
const entry = join7(dir, "engine", "index.ts");
|
|
2101
|
+
const outfile = join7(dir, "engine", "index.js");
|
|
2102
|
+
if (!existsSync7(entry)) {
|
|
2103
2103
|
throw new Error(`No engine/index.ts at ${entry}. ` + `Run from the extension root or pass --dir. Extensions without an engine entry don't need pack.`);
|
|
2104
2104
|
}
|
|
2105
2105
|
const manifest = readManifest(dir);
|
|
2106
|
-
console.log(`\uD83D\uDCE6 Packing ${
|
|
2106
|
+
console.log(`\uD83D\uDCE6 Packing ${c5.bold(manifest.name)} v${manifest.version}`);
|
|
2107
2107
|
const violations = validatePeerDeps(manifest);
|
|
2108
2108
|
if (violations.length > 0) {
|
|
2109
2109
|
throw new Error(`peerDependencies declared without engine.bundlePeers=true:
|
|
@@ -2113,7 +2113,7 @@ async function extensionPackCommand(opts) {
|
|
|
2113
2113
|
` + `Bun compiled binary cannot resolve bare specifiers from a ` + `dynamically-imported extension bundle, so external peer deps don't ` + `work in production. Either set engine.bundlePeers=true in ` + `manifest.json (and install the deps locally so Bun.build can ` + `inline them), or drop the peerDependencies entry if the import ` + `is dead code.`);
|
|
2114
2114
|
}
|
|
2115
2115
|
const externals = [];
|
|
2116
|
-
console.log(` ${
|
|
2116
|
+
console.log(` ${c5.dim(`$ bun build ${entry} (zveltio extension-bundle plugin)`)}` + (externals.length > 0 ? c5.dim(` external:${externals.join(",")}`) : ""));
|
|
2117
2117
|
try {
|
|
2118
2118
|
await bundleExtensionEngine({
|
|
2119
2119
|
entry,
|
|
@@ -2122,10 +2122,10 @@ async function extensionPackCommand(opts) {
|
|
|
2122
2122
|
sourcemap: opts.sourcemap,
|
|
2123
2123
|
resolveDir: dir
|
|
2124
2124
|
});
|
|
2125
|
-
} catch (
|
|
2126
|
-
throw new Error(`Bun bundle failed: ${
|
|
2125
|
+
} catch (err) {
|
|
2126
|
+
throw new Error(`Bun bundle failed: ${err.message}`);
|
|
2127
2127
|
}
|
|
2128
|
-
const bundleBytes =
|
|
2128
|
+
const bundleBytes = readFileSync2(outfile);
|
|
2129
2129
|
const engineSha256 = createHash("sha256").update(bundleBytes).digest("hex");
|
|
2130
2130
|
const bundleText = bundleBytes.toString("utf8").replace(/\/\*[\s\S]*?\*\//g, "").replace(/(^|\s)\/\/[^\n]*/g, "$1");
|
|
2131
2131
|
for (const dep of CORE_DEPS) {
|
|
@@ -2135,7 +2135,7 @@ async function extensionPackCommand(opts) {
|
|
|
2135
2135
|
}
|
|
2136
2136
|
}
|
|
2137
2137
|
const sizeKb = Math.round(bundleBytes.byteLength / 1024);
|
|
2138
|
-
console.log(` ${
|
|
2138
|
+
console.log(` ${c5.green("\u2713")} ${c5.bold(`engine/index.js`)} ${c5.dim(`(${sizeKb} KB, sha256=${engineSha256.slice(0, 12)}\u2026)`)}`);
|
|
2139
2139
|
let resolvedIsolation = manifest.engine?.isolation;
|
|
2140
2140
|
if (!resolvedIsolation) {
|
|
2141
2141
|
const resolved = await resolvePublisherTier({
|
|
@@ -2145,9 +2145,9 @@ async function extensionPackCommand(opts) {
|
|
|
2145
2145
|
});
|
|
2146
2146
|
if (!resolved.allowsInline) {
|
|
2147
2147
|
resolvedIsolation = "worker";
|
|
2148
|
-
console.log(` ${
|
|
2148
|
+
console.log(` ${c5.yellow("\u26A0")} ${resolved.tier} publisher \u2014 auto-set ${c5.bold('engine.isolation: "worker"')} ` + `(community extensions can't run inline).`);
|
|
2149
2149
|
if (resolved.source === "default") {
|
|
2150
|
-
console.log(
|
|
2150
|
+
console.log(c5.dim(" Tier defaulted to community (no --first-party flag, no registry token). " + "If you are verified/first-party, pass --first-party or set ZVELTIO_REGISTRY_TOKEN."));
|
|
2151
2151
|
}
|
|
2152
2152
|
}
|
|
2153
2153
|
}
|
|
@@ -2165,16 +2165,16 @@ async function extensionPackCommand(opts) {
|
|
|
2165
2165
|
...manifest.integrity?.archiveSha256 ? { archiveSha256: manifest.integrity.archiveSha256 } : {}
|
|
2166
2166
|
};
|
|
2167
2167
|
writeManifest(dir, manifest);
|
|
2168
|
-
console.log(` ${
|
|
2168
|
+
console.log(` ${c5.green("\u2713")} manifest.json updated with engine + integrity blocks`);
|
|
2169
2169
|
}
|
|
2170
|
-
console.log(`${
|
|
2170
|
+
console.log(`${c5.green("\u2713")} pack complete`);
|
|
2171
2171
|
}
|
|
2172
|
-
var PEER_DEP_ALLOWLIST, CORE_DEPS,
|
|
2172
|
+
var PEER_DEP_ALLOWLIST, CORE_DEPS, c5;
|
|
2173
2173
|
var init_extension_pack = __esm(() => {
|
|
2174
2174
|
init_extension_bundle();
|
|
2175
2175
|
PEER_DEP_ALLOWLIST = new Set;
|
|
2176
2176
|
CORE_DEPS = [...EXTENSION_BUNDLE_CORE_DEPS2];
|
|
2177
|
-
|
|
2177
|
+
c5 = {
|
|
2178
2178
|
bold: (s) => `\x1B[1m${s}\x1B[0m`,
|
|
2179
2179
|
green: (s) => `\x1B[32m${s}\x1B[0m`,
|
|
2180
2180
|
red: (s) => `\x1B[31m${s}\x1B[0m`,
|
|
@@ -3229,39 +3229,36 @@ async function runMigrationsViaAPI(opts) {
|
|
|
3229
3229
|
}
|
|
3230
3230
|
|
|
3231
3231
|
// src/commands/extension.ts
|
|
3232
|
-
import { existsSync as
|
|
3233
|
-
import { mkdir,
|
|
3234
|
-
import { join as
|
|
3232
|
+
import { existsSync as existsSync8 } from "fs";
|
|
3233
|
+
import { mkdir, writeFile } from "fs/promises";
|
|
3234
|
+
import { join as join8 } from "path";
|
|
3235
3235
|
async function extensionCommand(action, name, opts) {
|
|
3236
3236
|
switch (action) {
|
|
3237
3237
|
case "create":
|
|
3238
3238
|
await createExtension(name, opts.category || "custom");
|
|
3239
3239
|
break;
|
|
3240
3240
|
case "build":
|
|
3241
|
-
await buildExtension();
|
|
3241
|
+
await buildExtension(opts);
|
|
3242
3242
|
break;
|
|
3243
3243
|
case "dev":
|
|
3244
3244
|
await devExtension();
|
|
3245
3245
|
break;
|
|
3246
|
-
case "publish":
|
|
3247
|
-
await publishExtension(opts.token);
|
|
3248
|
-
break;
|
|
3249
3246
|
}
|
|
3250
3247
|
}
|
|
3251
3248
|
async function createExtension(name, category) {
|
|
3252
3249
|
const safeName = name.toLowerCase().replace(/[^a-z0-9-]/g, "-");
|
|
3253
|
-
const targetDir =
|
|
3254
|
-
if (
|
|
3250
|
+
const targetDir = join8(process.cwd(), "extensions", category, safeName);
|
|
3251
|
+
if (existsSync8(targetDir)) {
|
|
3255
3252
|
console.error(`Extension already exists: ${targetDir}`);
|
|
3256
3253
|
process.exit(1);
|
|
3257
3254
|
}
|
|
3258
3255
|
console.log(`
|
|
3259
3256
|
Creating extension: ${category}/${safeName}
|
|
3260
3257
|
`);
|
|
3261
|
-
await mkdir(
|
|
3262
|
-
await mkdir(
|
|
3263
|
-
await mkdir(
|
|
3264
|
-
await writeFile(
|
|
3258
|
+
await mkdir(join8(targetDir, "engine"), { recursive: true });
|
|
3259
|
+
await mkdir(join8(targetDir, "studio", "src", "pages"), { recursive: true });
|
|
3260
|
+
await mkdir(join8(targetDir, "engine", "migrations"), { recursive: true });
|
|
3261
|
+
await writeFile(join8(targetDir, "manifest.json"), JSON.stringify({
|
|
3265
3262
|
name: safeName,
|
|
3266
3263
|
package: `@zveltio/ext-${safeName}`,
|
|
3267
3264
|
category,
|
|
@@ -3273,7 +3270,7 @@ Creating extension: ${category}/${safeName}
|
|
|
3273
3270
|
permissions: ["database"],
|
|
3274
3271
|
contributes: { engine: true, studio: true, fieldTypes: [] }
|
|
3275
3272
|
}, null, 2));
|
|
3276
|
-
await writeFile(
|
|
3273
|
+
await writeFile(join8(targetDir, "engine", "index.ts"), `import type { ZveltioExtension } from '@zveltio/sdk/extension';
|
|
3277
3274
|
import { join } from 'path';
|
|
3278
3275
|
|
|
3279
3276
|
const extension: ZveltioExtension = {
|
|
@@ -3294,7 +3291,7 @@ const extension: ZveltioExtension = {
|
|
|
3294
3291
|
|
|
3295
3292
|
export default extension;
|
|
3296
3293
|
`);
|
|
3297
|
-
await writeFile(
|
|
3294
|
+
await writeFile(join8(targetDir, "engine", "migrations", "001_init.sql"), `-- ${name} extension initial schema
|
|
3298
3295
|
-- Add your tables here
|
|
3299
3296
|
|
|
3300
3297
|
-- Example:
|
|
@@ -3304,7 +3301,7 @@ export default extension;
|
|
|
3304
3301
|
-- created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
3305
3302
|
-- );
|
|
3306
3303
|
`);
|
|
3307
|
-
await writeFile(
|
|
3304
|
+
await writeFile(join8(targetDir, "studio", "src", "index.ts"), `import MainPage from './pages/MainPage.svelte';
|
|
3308
3305
|
|
|
3309
3306
|
export default function register() {
|
|
3310
3307
|
const zveltio = (window as any).__zveltio;
|
|
@@ -3322,7 +3319,7 @@ export default function register() {
|
|
|
3322
3319
|
});
|
|
3323
3320
|
}
|
|
3324
3321
|
`);
|
|
3325
|
-
await writeFile(
|
|
3322
|
+
await writeFile(join8(targetDir, "studio", "src", "pages", "MainPage.svelte"), `<script lang="ts">
|
|
3326
3323
|
const engineUrl = (window as any).__ZVELTIO_ENGINE_URL__;
|
|
3327
3324
|
</script>
|
|
3328
3325
|
|
|
@@ -3331,7 +3328,7 @@ export default function register() {
|
|
|
3331
3328
|
<p class="text-base-content/60">Welcome to the ${name} extension.</p>
|
|
3332
3329
|
</div>
|
|
3333
3330
|
`);
|
|
3334
|
-
await writeFile(
|
|
3331
|
+
await writeFile(join8(targetDir, "studio", "vite.config.ts"), `import { svelte } from '@sveltejs/vite-plugin-svelte';
|
|
3335
3332
|
import { defineConfig } from 'vite';
|
|
3336
3333
|
|
|
3337
3334
|
export default defineConfig({
|
|
@@ -3355,7 +3352,7 @@ export default defineConfig({
|
|
|
3355
3352
|
},
|
|
3356
3353
|
});
|
|
3357
3354
|
`);
|
|
3358
|
-
await writeFile(
|
|
3355
|
+
await writeFile(join8(targetDir, "studio", "package.json"), JSON.stringify({
|
|
3359
3356
|
name: `@zveltio/ext-${safeName}-studio`,
|
|
3360
3357
|
version: "1.0.0",
|
|
3361
3358
|
type: "module",
|
|
@@ -3369,15 +3366,15 @@ export default defineConfig({
|
|
|
3369
3366
|
vite: "^6.0.0"
|
|
3370
3367
|
}
|
|
3371
3368
|
}, null, 2));
|
|
3372
|
-
await writeFile(
|
|
3369
|
+
await writeFile(join8(targetDir, ".gitattributes"), `* text=auto eol=lf
|
|
3373
3370
|
|
|
3374
3371
|
# Packed engine bundle: byte-identical across OSes. Manifest
|
|
3375
3372
|
# integrity.engineSha256 is computed over these exact bytes.
|
|
3376
3373
|
engine/index.js binary
|
|
3377
3374
|
engine/index.js.map binary
|
|
3378
3375
|
`);
|
|
3379
|
-
await mkdir(
|
|
3380
|
-
await writeFile(
|
|
3376
|
+
await mkdir(join8(targetDir, ".github", "workflows"), { recursive: true });
|
|
3377
|
+
await writeFile(join8(targetDir, ".github", "workflows", "ci.yml"), `name: Extension CI
|
|
3381
3378
|
|
|
3382
3379
|
on:
|
|
3383
3380
|
push:
|
|
@@ -3447,33 +3444,11 @@ Isolation (MARKETPLACE-POLICY \xA72):
|
|
|
3447
3444
|
--first-party. See https://github.com/zveltio-devs/zveltio/blob/master/docs/EXTENSION-DEVELOPER-GUIDE.md#135-isolation-tiers-be-honest-about-what-you-ship
|
|
3448
3445
|
`);
|
|
3449
3446
|
}
|
|
3450
|
-
async function buildExtension() {
|
|
3451
|
-
console.
|
|
3452
|
-
|
|
3453
|
-
|
|
3454
|
-
|
|
3455
|
-
console.error("No manifest.json found. Run this command from an extension directory.");
|
|
3456
|
-
process.exit(1);
|
|
3457
|
-
}
|
|
3458
|
-
const manifest = JSON.parse(await readFile("manifest.json", "utf-8"));
|
|
3459
|
-
if (existsSync5("studio")) {
|
|
3460
|
-
const studioProc = Bun.spawn(["bun", "run", "build"], {
|
|
3461
|
-
cwd: "studio",
|
|
3462
|
-
stdout: "inherit",
|
|
3463
|
-
stderr: "inherit"
|
|
3464
|
-
});
|
|
3465
|
-
const code = await studioProc.exited;
|
|
3466
|
-
if (code !== 0)
|
|
3467
|
-
throw new Error(`Studio build failed with exit code ${code}`);
|
|
3468
|
-
console.log(" Studio bundle built");
|
|
3469
|
-
}
|
|
3470
|
-
const engineProc = Bun.spawn(["bun", "build", "engine/index.ts", "--outdir", "engine/dist", "--target", "bun"], { stdout: "inherit", stderr: "inherit" });
|
|
3471
|
-
const engineCode = await engineProc.exited;
|
|
3472
|
-
if (engineCode !== 0)
|
|
3473
|
-
throw new Error(`Engine build failed with exit code ${engineCode}`);
|
|
3474
|
-
console.log(" Engine built");
|
|
3475
|
-
console.log(`
|
|
3476
|
-
Extension built: ${manifest.name} v${manifest.version}`);
|
|
3447
|
+
async function buildExtension(opts) {
|
|
3448
|
+
console.warn("\x1B[33m`zveltio extension build` is deprecated \u2014 use `zveltio extension pack`.\x1B[0m");
|
|
3449
|
+
console.warn("\x1B[2m Running pack for you (produces the v2 engine/index.js + integrity).\x1B[0m");
|
|
3450
|
+
const { extensionPackCommand: extensionPackCommand2 } = await Promise.resolve().then(() => (init_extension_pack(), exports_extension_pack));
|
|
3451
|
+
await extensionPackCommand2({ dir: opts.dir });
|
|
3477
3452
|
}
|
|
3478
3453
|
async function devExtension() {
|
|
3479
3454
|
console.log(`
|
|
@@ -3491,19 +3466,10 @@ Starting extension dev mode...
|
|
|
3491
3466
|
});
|
|
3492
3467
|
await studioProc.exited;
|
|
3493
3468
|
}
|
|
3494
|
-
async function publishExtension(token) {
|
|
3495
|
-
if (!token) {
|
|
3496
|
-
console.error("Marketplace token required. Use --token <token>");
|
|
3497
|
-
process.exit(1);
|
|
3498
|
-
}
|
|
3499
|
-
console.log(`
|
|
3500
|
-
Publishing to Zveltio marketplace...`);
|
|
3501
|
-
console.log(" (Marketplace coming soon!)");
|
|
3502
|
-
}
|
|
3503
3469
|
|
|
3504
3470
|
// src/commands/extension-types.ts
|
|
3505
|
-
import { existsSync as
|
|
3506
|
-
import { join as
|
|
3471
|
+
import { existsSync as existsSync9, readdirSync, readFileSync as readFileSync3, mkdirSync as mkdirSync2, writeFileSync as writeFileSync2 } from "fs";
|
|
3472
|
+
import { join as join9, relative } from "path";
|
|
3507
3473
|
|
|
3508
3474
|
// ../sdk/dist/schema-codegen.js
|
|
3509
3475
|
var NUMERIC_TYPES = new Set([
|
|
@@ -3763,8 +3729,8 @@ function parseSchema(sqlChunks) {
|
|
|
3763
3729
|
const body = allSql.substring(openIdx + 1, closeIdx);
|
|
3764
3730
|
const columns = parseColumnList(body);
|
|
3765
3731
|
const tableCols = ensureTable(tableName);
|
|
3766
|
-
for (const
|
|
3767
|
-
tableCols.set(
|
|
3732
|
+
for (const c6 of columns)
|
|
3733
|
+
tableCols.set(c6.name, c6);
|
|
3768
3734
|
createRe.lastIndex = closeIdx + 1;
|
|
3769
3735
|
}
|
|
3770
3736
|
const alterRe = /ALTER\s+TABLE\s+(?:"([^"]+)"|([a-zA-Z_][a-zA-Z0-9_]*))\s+ADD\s+COLUMN\s+(?:IF\s+NOT\s+EXISTS\s+)?(?:"([^"]+)"|([a-zA-Z_][a-zA-Z0-9_]*))\s+([^;]+?)(?=;|$)/gi;
|
|
@@ -3798,8 +3764,8 @@ function emitTypeScript(schema, opts = {}) {
|
|
|
3798
3764
|
}
|
|
3799
3765
|
for (const t of schema.tables) {
|
|
3800
3766
|
lines.push(` ${quoteIdentifierIfNeeded(t.name)}: {`);
|
|
3801
|
-
for (const
|
|
3802
|
-
lines.push(` ${quoteIdentifierIfNeeded(
|
|
3767
|
+
for (const c6 of t.columns) {
|
|
3768
|
+
lines.push(` ${quoteIdentifierIfNeeded(c6.name)}: ${c6.tsType}; // ${c6.pgType}`);
|
|
3803
3769
|
}
|
|
3804
3770
|
lines.push(" };");
|
|
3805
3771
|
}
|
|
@@ -3813,7 +3779,7 @@ function quoteIdentifierIfNeeded(name) {
|
|
|
3813
3779
|
}
|
|
3814
3780
|
|
|
3815
3781
|
// src/commands/extension-types.ts
|
|
3816
|
-
var
|
|
3782
|
+
var c6 = {
|
|
3817
3783
|
bold: (s) => `\x1B[1m${s}\x1B[0m`,
|
|
3818
3784
|
green: (s) => `\x1B[32m${s}\x1B[0m`,
|
|
3819
3785
|
dim: (s) => `\x1B[2m${s}\x1B[0m`,
|
|
@@ -3823,57 +3789,57 @@ var c5 = {
|
|
|
3823
3789
|
async function extensionTypesCommand(opts = {}) {
|
|
3824
3790
|
const dir = opts.dir ?? process.cwd();
|
|
3825
3791
|
console.log(`
|
|
3826
|
-
${
|
|
3792
|
+
${c6.bold("Extension types")}
|
|
3827
3793
|
`);
|
|
3828
|
-
console.log(` Extension dir: ${
|
|
3829
|
-
const manifestPath =
|
|
3830
|
-
if (!
|
|
3831
|
-
console.error(
|
|
3832
|
-
console.error(
|
|
3794
|
+
console.log(` Extension dir: ${c6.dim(dir)}`);
|
|
3795
|
+
const manifestPath = join9(dir, "manifest.json");
|
|
3796
|
+
if (!existsSync9(manifestPath)) {
|
|
3797
|
+
console.error(c6.red(`No manifest.json found in ${dir}`));
|
|
3798
|
+
console.error(c6.dim(" Run this command from your extension's root folder, or pass --dir."));
|
|
3833
3799
|
process.exit(1);
|
|
3834
3800
|
}
|
|
3835
|
-
const migrationsDir =
|
|
3836
|
-
if (!
|
|
3837
|
-
console.error(
|
|
3838
|
-
console.error(
|
|
3801
|
+
const migrationsDir = join9(dir, "engine", "migrations");
|
|
3802
|
+
if (!existsSync9(migrationsDir)) {
|
|
3803
|
+
console.error(c6.yellow(`No engine/migrations directory found at ${migrationsDir}`));
|
|
3804
|
+
console.error(c6.dim(" Nothing to generate. Add SQL migrations first."));
|
|
3839
3805
|
process.exit(0);
|
|
3840
3806
|
}
|
|
3841
3807
|
const sqlFiles = readdirSync(migrationsDir).filter((f) => f.endsWith(".sql")).sort();
|
|
3842
3808
|
if (sqlFiles.length === 0) {
|
|
3843
|
-
console.error(
|
|
3809
|
+
console.error(c6.yellow(`No .sql files in ${migrationsDir}`));
|
|
3844
3810
|
process.exit(0);
|
|
3845
3811
|
}
|
|
3846
|
-
console.log(` Migrations: ${
|
|
3847
|
-
const chunks = sqlFiles.map((f) =>
|
|
3812
|
+
console.log(` Migrations: ${c6.dim(`${sqlFiles.length} file(s)`)}`);
|
|
3813
|
+
const chunks = sqlFiles.map((f) => readFileSync3(join9(migrationsDir, f), "utf8"));
|
|
3848
3814
|
const schema = parseSchema(chunks);
|
|
3849
3815
|
if (schema.tables.length === 0) {
|
|
3850
|
-
console.log(
|
|
3816
|
+
console.log(c6.yellow(" No tables parsed. Check that CREATE TABLE statements are well-formed."));
|
|
3851
3817
|
} else {
|
|
3852
|
-
console.log(` Tables parsed: ${
|
|
3818
|
+
console.log(` Tables parsed: ${c6.dim(`${schema.tables.length}`)}`);
|
|
3853
3819
|
for (const t of schema.tables) {
|
|
3854
3820
|
console.log(` - ${t.name} (${t.columns.length} cols)`);
|
|
3855
3821
|
}
|
|
3856
3822
|
}
|
|
3857
3823
|
let extName = "<unknown>";
|
|
3858
3824
|
try {
|
|
3859
|
-
const m = JSON.parse(
|
|
3825
|
+
const m = JSON.parse(readFileSync3(manifestPath, "utf8"));
|
|
3860
3826
|
if (typeof m.name === "string")
|
|
3861
3827
|
extName = m.name;
|
|
3862
3828
|
} catch {}
|
|
3863
3829
|
const banner = `Generated from ${extName} migrations: ${sqlFiles.join(", ")}`;
|
|
3864
3830
|
const tsBody = emitTypeScript(schema, { banner });
|
|
3865
|
-
const outputPath = opts.output ??
|
|
3866
|
-
mkdirSync2(
|
|
3867
|
-
|
|
3831
|
+
const outputPath = opts.output ?? join9(dir, ".zveltio", "db.d.ts");
|
|
3832
|
+
mkdirSync2(join9(outputPath, ".."), { recursive: true });
|
|
3833
|
+
writeFileSync2(outputPath, tsBody, "utf8");
|
|
3868
3834
|
console.log(`
|
|
3869
|
-
${
|
|
3870
|
-
console.log(
|
|
3835
|
+
${c6.green("Written:")} ${relative(process.cwd(), outputPath) || outputPath}`);
|
|
3836
|
+
console.log(c6.dim(" Add `.zveltio/` to your .gitignore. Regenerate with this command after every migration."));
|
|
3871
3837
|
console.log("");
|
|
3872
3838
|
}
|
|
3873
3839
|
|
|
3874
3840
|
// src/commands/extension-validate.ts
|
|
3875
|
-
import { existsSync as
|
|
3876
|
-
import { join as
|
|
3841
|
+
import { existsSync as existsSync10, readdirSync as readdirSync2, readFileSync as readFileSync4, statSync } from "fs";
|
|
3842
|
+
import { join as join10 } from "path";
|
|
3877
3843
|
|
|
3878
3844
|
// ../sdk/dist/validate/migration-parse.js
|
|
3879
3845
|
function parseMigrationSql(raw) {
|
|
@@ -4051,7 +4017,7 @@ function validateExtension(input) {
|
|
|
4051
4017
|
}
|
|
4052
4018
|
|
|
4053
4019
|
// src/commands/extension-validate.ts
|
|
4054
|
-
var
|
|
4020
|
+
var c7 = {
|
|
4055
4021
|
bold: (s) => `\x1B[1m${s}\x1B[0m`,
|
|
4056
4022
|
green: (s) => `\x1B[32m${s}\x1B[0m`,
|
|
4057
4023
|
red: (s) => `\x1B[31m${s}\x1B[0m`,
|
|
@@ -4073,10 +4039,10 @@ var PEER_DEPS_ALLOWLIST = new Set([
|
|
|
4073
4039
|
]);
|
|
4074
4040
|
function recursiveSize(dir) {
|
|
4075
4041
|
let total = 0;
|
|
4076
|
-
if (!
|
|
4042
|
+
if (!existsSync10(dir))
|
|
4077
4043
|
return 0;
|
|
4078
4044
|
for (const name of readdirSync2(dir)) {
|
|
4079
|
-
const full =
|
|
4045
|
+
const full = join10(dir, name);
|
|
4080
4046
|
if (name === "node_modules" || name === ".zveltio" || name === "dist")
|
|
4081
4047
|
continue;
|
|
4082
4048
|
let st;
|
|
@@ -4103,26 +4069,27 @@ function inferExpectedName(dir) {
|
|
|
4103
4069
|
async function extensionValidateCommand(opts = {}) {
|
|
4104
4070
|
const dir = opts.dir ?? process.cwd();
|
|
4105
4071
|
console.log(`
|
|
4106
|
-
${
|
|
4072
|
+
${c7.bold("Extension validate")}
|
|
4107
4073
|
`);
|
|
4108
|
-
console.log(` Extension dir: ${
|
|
4109
|
-
const manifestPath =
|
|
4074
|
+
console.log(` Extension dir: ${c7.dim(dir)}`);
|
|
4075
|
+
const manifestPath = join10(dir, "manifest.json");
|
|
4110
4076
|
let manifest = null;
|
|
4111
|
-
if (
|
|
4077
|
+
if (existsSync10(manifestPath)) {
|
|
4112
4078
|
try {
|
|
4113
|
-
manifest = JSON.parse(
|
|
4079
|
+
manifest = JSON.parse(readFileSync4(manifestPath, "utf8"));
|
|
4114
4080
|
} catch (e) {
|
|
4115
|
-
console.error(
|
|
4081
|
+
console.error(c7.red(` manifest.json is not valid JSON: ${e.message}`));
|
|
4116
4082
|
manifest = null;
|
|
4117
4083
|
}
|
|
4118
4084
|
}
|
|
4119
|
-
const
|
|
4085
|
+
const isStudioOnly = manifest != null && typeof manifest === "object" && manifest?.contributes?.engine === false && !manifest?.engine;
|
|
4086
|
+
const migrationsDir = join10(dir, "engine", "migrations");
|
|
4120
4087
|
let sqlFiles = [];
|
|
4121
4088
|
let parsedTableCount = 0;
|
|
4122
|
-
if (
|
|
4089
|
+
if (existsSync10(migrationsDir)) {
|
|
4123
4090
|
sqlFiles = readdirSync2(migrationsDir).filter((f) => f.endsWith(".sql")).sort().map((filename) => ({
|
|
4124
4091
|
filename,
|
|
4125
|
-
sql:
|
|
4092
|
+
sql: readFileSync4(join10(migrationsDir, filename), "utf8")
|
|
4126
4093
|
}));
|
|
4127
4094
|
try {
|
|
4128
4095
|
parsedTableCount = parseSchema(sqlFiles.map((f) => f.sql)).tables.length;
|
|
@@ -4132,10 +4099,10 @@ ${c6.bold("Extension validate")}
|
|
|
4132
4099
|
}
|
|
4133
4100
|
const paths = {};
|
|
4134
4101
|
for (const rel of ["manifest.json", "engine/index.ts", "engine/index.js"]) {
|
|
4135
|
-
paths[rel] =
|
|
4102
|
+
paths[rel] = existsSync10(join10(dir, rel));
|
|
4136
4103
|
}
|
|
4137
4104
|
const required = ["manifest.json"];
|
|
4138
|
-
if (!(paths["engine/index.ts"] || paths["engine/index.js"])) {
|
|
4105
|
+
if (!isStudioOnly && !(paths["engine/index.ts"] || paths["engine/index.js"])) {
|
|
4139
4106
|
required.push("engine/index.ts");
|
|
4140
4107
|
}
|
|
4141
4108
|
const bundleBytes = recursiveSize(dir);
|
|
@@ -4160,9 +4127,12 @@ ${c6.bold("Extension validate")}
|
|
|
4160
4127
|
stats: { tables: parsedTableCount, migrations: sqlFiles.length }
|
|
4161
4128
|
});
|
|
4162
4129
|
const m = manifest;
|
|
4130
|
+
const studioOnly = isStudioOnly;
|
|
4163
4131
|
const v2Status = (() => {
|
|
4164
4132
|
if (!m)
|
|
4165
4133
|
return "unknown";
|
|
4134
|
+
if (studioOnly)
|
|
4135
|
+
return "studio-only";
|
|
4166
4136
|
if (!m.engine)
|
|
4167
4137
|
return "v1-legacy";
|
|
4168
4138
|
if (m.engine.bundled !== true)
|
|
@@ -4173,56 +4143,61 @@ ${c6.bold("Extension validate")}
|
|
|
4173
4143
|
return "missing-engine-sha";
|
|
4174
4144
|
return "v2-ok";
|
|
4175
4145
|
})();
|
|
4176
|
-
console.log(` Manifest: ${manifest ?
|
|
4177
|
-
console.log(` Migrations: ${
|
|
4178
|
-
console.log(` Peer deps: ${
|
|
4179
|
-
console.log(` Bundle size: ${
|
|
4180
|
-
const v2Label = v2Status === "v2-ok" ?
|
|
4146
|
+
console.log(` Manifest: ${manifest ? c7.green("OK") : c7.red("missing or invalid")}`);
|
|
4147
|
+
console.log(` Migrations: ${c7.dim(`${result.stats.migrations} file(s), ${result.stats.tables} table(s) parsed`)}`);
|
|
4148
|
+
console.log(` Peer deps: ${c7.dim(`${result.stats.peerDeps} declared`)}`);
|
|
4149
|
+
console.log(` Bundle size: ${c7.dim(`${Math.ceil(bundleBytes / 1024)} KB`)}`);
|
|
4150
|
+
const v2Label = v2Status === "v2-ok" ? c7.green("v2 (bundled)") : v2Status === "studio-only" ? c7.green("studio/client-only (no engine)") : v2Status === "v1-legacy" ? c7.yellow("v1 (no engine block \u2014 run `zveltio extension pack`)") : v2Status === "engine-not-bundled" ? c7.red("engine.bundled !== true \u2014 re-pack required") : v2Status === "missing-engine-entry" ? c7.red("engine.entry missing") : v2Status === "missing-engine-sha" ? c7.red("integrity.engineSha256 missing \u2014 re-pack required") : c7.dim("unknown");
|
|
4181
4151
|
console.log(` Manifest v2: ${v2Label}`);
|
|
4182
|
-
|
|
4183
|
-
|
|
4184
|
-
|
|
4185
|
-
token: opts.token,
|
|
4186
|
-
registryUrl: opts.registryUrl
|
|
4187
|
-
});
|
|
4188
|
-
const inlineOk = tierAllowsInline(resolved.tier);
|
|
4189
|
-
const tierSrc = resolved.source === "flag" ? "--first-party" : resolved.source === "registry" ? "registry" : "default";
|
|
4190
|
-
if (isolation === "worker") {
|
|
4191
|
-
console.log(` Isolation: ${c6.green("worker (runs in any tier)")}`);
|
|
4192
|
-
} else if (inlineOk) {
|
|
4193
|
-
console.log(` Isolation: ${c6.dim(`inline (${resolved.tier} \u2014 allowed, via ${tierSrc})`)}`);
|
|
4152
|
+
if (studioOnly) {
|
|
4153
|
+
console.log(` Isolation: ${c7.dim("n/a (no engine)")}`);
|
|
4154
|
+
console.log("");
|
|
4194
4155
|
} else {
|
|
4195
|
-
|
|
4196
|
-
|
|
4197
|
-
|
|
4198
|
-
|
|
4199
|
-
|
|
4200
|
-
|
|
4201
|
-
|
|
4202
|
-
|
|
4203
|
-
|
|
4156
|
+
const isolation = m?.engine?.isolation ?? "inline";
|
|
4157
|
+
const resolved = await resolvePublisherTier({
|
|
4158
|
+
firstParty: opts.firstParty,
|
|
4159
|
+
token: opts.token,
|
|
4160
|
+
registryUrl: opts.registryUrl
|
|
4161
|
+
});
|
|
4162
|
+
const inlineOk = tierAllowsInline(resolved.tier);
|
|
4163
|
+
const tierSrc = resolved.source === "flag" ? "--first-party" : resolved.source === "registry" ? "registry" : "default";
|
|
4164
|
+
if (isolation === "worker") {
|
|
4165
|
+
console.log(` Isolation: ${c7.green("worker (runs in any tier)")}`);
|
|
4166
|
+
} else if (inlineOk) {
|
|
4167
|
+
console.log(` Isolation: ${c7.dim(`inline (${resolved.tier} \u2014 allowed, via ${tierSrc})`)}`);
|
|
4168
|
+
} else {
|
|
4169
|
+
console.log(` Isolation: ${c7.red(`inline \u2014 ${resolved.tier} publishers MUST use 'worker'`)}`);
|
|
4170
|
+
}
|
|
4171
|
+
console.log("");
|
|
4172
|
+
if (isolation !== "worker" && !inlineOk) {
|
|
4173
|
+
console.error(c7.red(`Validation failed: ${resolved.tier} publishers must declare ` + `engine.isolation: "worker" (MARKETPLACE-POLICY \xA72).`));
|
|
4174
|
+
console.error(c7.dim(' Add `"isolation": "worker"` to the engine block in manifest.json, ' + "then re-pack. If you are a verified/first-party publisher, pass " + "--first-party or set ZVELTIO_REGISTRY_TOKEN so the tier can be confirmed. " + "See docs/MARKETPLACE-POLICY.md \xA72."));
|
|
4175
|
+
if (opts.silentExit)
|
|
4176
|
+
throw new Error("Validation failed: community inline isolation");
|
|
4177
|
+
process.exit(1);
|
|
4178
|
+
}
|
|
4204
4179
|
}
|
|
4205
4180
|
if (v2Status === "v1-legacy") {
|
|
4206
|
-
console.error(
|
|
4207
|
-
console.error(
|
|
4181
|
+
console.error(c7.red("Validation failed: manifest is v1 (no engine.bundled block)."));
|
|
4182
|
+
console.error(c7.dim(" v1 manifests are unsupported since 1.0.0-beta.1. Run `zveltio extension pack` to " + "generate the v2 engine + integrity blocks. See docs/EXTENSION-DEVELOPER-GUIDE.md \xA74."));
|
|
4208
4183
|
if (opts.silentExit)
|
|
4209
4184
|
throw new Error("Validation failed: v1 manifest unsupported");
|
|
4210
4185
|
process.exit(1);
|
|
4211
4186
|
}
|
|
4212
4187
|
if (v2Status === "engine-not-bundled" || v2Status === "missing-engine-entry" || v2Status === "missing-engine-sha") {
|
|
4213
|
-
console.error(
|
|
4214
|
-
console.error(
|
|
4188
|
+
console.error(c7.red("Validation failed: manifest declares v2 engine block but is incomplete."));
|
|
4189
|
+
console.error(c7.dim(" Run `zveltio extension pack --dir <ext>` to regenerate engine + integrity blocks."));
|
|
4215
4190
|
if (opts.silentExit)
|
|
4216
4191
|
throw new Error("Validation failed: incomplete v2 manifest");
|
|
4217
4192
|
process.exit(1);
|
|
4218
4193
|
}
|
|
4219
4194
|
if (result.ok) {
|
|
4220
|
-
console.log(
|
|
4221
|
-
console.log(
|
|
4195
|
+
console.log(c7.green("Validation passed."));
|
|
4196
|
+
console.log(c7.dim(" Run `zveltio extension types` to refresh generated types, then `zveltio extension publish` when ready."));
|
|
4222
4197
|
console.log("");
|
|
4223
4198
|
return;
|
|
4224
4199
|
}
|
|
4225
|
-
console.log(
|
|
4200
|
+
console.log(c7.red(`Validation failed with ${result.errors.length} error(s):`));
|
|
4226
4201
|
console.log("");
|
|
4227
4202
|
for (const e of result.errors) {
|
|
4228
4203
|
printError(e);
|
|
@@ -4232,8 +4207,8 @@ ${c6.bold("Extension validate")}
|
|
|
4232
4207
|
process.exit(1);
|
|
4233
4208
|
}
|
|
4234
4209
|
function printError(e) {
|
|
4235
|
-
const loc = e.file ?
|
|
4236
|
-
console.log(` ${
|
|
4210
|
+
const loc = e.file ? c7.dim(` (${e.file})`) : "";
|
|
4211
|
+
console.log(` ${c7.red(e.code)} ${e.message}${loc}`);
|
|
4237
4212
|
}
|
|
4238
4213
|
|
|
4239
4214
|
// src/commands/extension-publish.ts
|
|
@@ -4925,7 +4900,7 @@ ${c11.bold("Generate Types")}
|
|
|
4925
4900
|
|
|
4926
4901
|
// src/commands/install.ts
|
|
4927
4902
|
import { existsSync as existsSync14 } from "fs";
|
|
4928
|
-
import { readFile
|
|
4903
|
+
import { readFile, mkdir as mkdir2, cp } from "fs/promises";
|
|
4929
4904
|
import { join as join14 } from "path";
|
|
4930
4905
|
async function installCommand(name, opts) {
|
|
4931
4906
|
const engineUrl = opts.url || process.env.ENGINE_URL || "http://localhost:3000";
|
|
@@ -4945,7 +4920,7 @@ async function installFromPath(name, sourcePath, engineUrl, force) {
|
|
|
4945
4920
|
}
|
|
4946
4921
|
let manifest;
|
|
4947
4922
|
try {
|
|
4948
|
-
manifest = JSON.parse(await
|
|
4923
|
+
manifest = JSON.parse(await readFile(join14(sourcePath, "manifest.json"), "utf-8"));
|
|
4949
4924
|
} catch {
|
|
4950
4925
|
console.error("\u274C Failed to read manifest.json");
|
|
4951
4926
|
process.exit(1);
|
|
@@ -4971,8 +4946,8 @@ async function installFromPath(name, sourcePath, engineUrl, force) {
|
|
|
4971
4946
|
console.log(` Category: ${category}`);
|
|
4972
4947
|
const enginePkgPath = join14(process.cwd(), "packages/engine/package.json");
|
|
4973
4948
|
if (existsSync14(enginePkgPath)) {
|
|
4974
|
-
const enginePkg = JSON.parse(await
|
|
4975
|
-
const engineVersion = enginePkg.version || "
|
|
4949
|
+
const enginePkg = JSON.parse(await readFile(enginePkgPath, "utf-8"));
|
|
4950
|
+
const engineVersion = enginePkg.version || "unknown";
|
|
4976
4951
|
if (manifest.zveltioMinVersion) {
|
|
4977
4952
|
console.log(` Engine required: >= ${manifest.zveltioMinVersion} (current: ${engineVersion})`);
|
|
4978
4953
|
}
|
|
@@ -5817,7 +5792,7 @@ async function getLocalVersion() {
|
|
|
5817
5792
|
// package.json
|
|
5818
5793
|
var package_default = {
|
|
5819
5794
|
name: "@zveltio/cli",
|
|
5820
|
-
version: "3.0.0-beta.
|
|
5795
|
+
version: "3.0.0-beta.5",
|
|
5821
5796
|
type: "module",
|
|
5822
5797
|
bin: {
|
|
5823
5798
|
zveltio: "./dist/index.js"
|
|
@@ -5832,7 +5807,7 @@ var package_default = {
|
|
|
5832
5807
|
dev: "bun run --watch src/index.ts"
|
|
5833
5808
|
},
|
|
5834
5809
|
dependencies: {
|
|
5835
|
-
"@zveltio/sdk": "3.0.0-beta.
|
|
5810
|
+
"@zveltio/sdk": "3.0.0-beta.5",
|
|
5836
5811
|
commander: "^12.0.0"
|
|
5837
5812
|
},
|
|
5838
5813
|
devDependencies: {
|
|
@@ -5886,7 +5861,7 @@ extensions.command("disable <name>").description("Disable an active extension").
|
|
|
5886
5861
|
});
|
|
5887
5862
|
var ext = program2.command("extension").description('Manage Zveltio extensions (use "extensions" for new commands)');
|
|
5888
5863
|
ext.command("create <name>").description("Scaffold a new extension").option("--category <category>", "Extension category", "custom").action((name, opts) => extensionCommand("create", name, opts));
|
|
5889
|
-
ext.command("build").description("
|
|
5864
|
+
ext.command("build").description("[deprecated] Alias for `extension pack` \u2014 produces the v2 engine bundle").option("--dir <dir>", "Extension root directory (defaults to cwd)").action((opts) => extensionCommand("build", "", opts));
|
|
5890
5865
|
ext.command("dev").description("Watch engine/ + studio/, hot-reload the running engine on changes (S4-03)").option("--dir <dir>", "Extension root directory (defaults to cwd)").option("--url <url>", "Engine URL (env: ZVELTIO_ENGINE_URL)", "http://localhost:3000").option("--name <name>", "Extension name (default: read from manifest.json)").option("--no-studio", "Skip the Studio dev process (engine watch only)").action((opts) => extensionDevCommand(opts));
|
|
5891
5866
|
ext.command("pack").description("Bundle engine/index.ts \u2192 engine/index.js (target=bun, ESM) and write engine + integrity blocks into manifest.json. Required before publish on v2 channels.").option("--dir <dir>", "Extension root directory (defaults to cwd)").option("--sourcemap", "Emit engine/index.js.map alongside the bundle").option("--no-manifest-update", "Build the bundle but do not patch manifest.json").option("--first-party", "Vendor / monorepo build \u2014 keep inline isolation, skip worker auto-inject").option("--token <token>", "Registry token for the publisher-tier lookup (env: ZVELTIO_REGISTRY_TOKEN)").option("--registry-url <url>", "Registry base URL (env: ZVELTIO_REGISTRY_URL)").action(async (opts) => {
|
|
5892
5867
|
const { extensionPackCommand: extensionPackCommand2 } = await Promise.resolve().then(() => (init_extension_pack(), exports_extension_pack));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zveltio/cli",
|
|
3
|
-
"version": "3.0.0-beta.
|
|
3
|
+
"version": "3.0.0-beta.5",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"bin": {
|
|
6
6
|
"zveltio": "./dist/index.js"
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
"dev": "bun run --watch src/index.ts"
|
|
16
16
|
},
|
|
17
17
|
"dependencies": {
|
|
18
|
-
"@zveltio/sdk": "3.0.0-beta.
|
|
18
|
+
"@zveltio/sdk": "3.0.0-beta.5",
|
|
19
19
|
"commander": "^12.0.0"
|
|
20
20
|
},
|
|
21
21
|
"devDependencies": {
|