@onexapis/cli 1.1.42 → 1.1.44
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/cli.js +194 -15
- package/dist/cli.js.map +1 -1
- package/dist/cli.mjs +194 -15
- package/dist/cli.mjs.map +1 -1
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +8 -0
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -792,6 +792,14 @@ async function compileStandaloneTheme(themePath, themeName) {
|
|
|
792
792
|
} catch {
|
|
793
793
|
}
|
|
794
794
|
await contentHashEntry(outputDir);
|
|
795
|
+
const themeAssetsDir = path9__default.default.join(themePath, "assets");
|
|
796
|
+
const distThemeAssets = path9__default.default.join(outputDir, "theme-assets");
|
|
797
|
+
try {
|
|
798
|
+
await fs8__default.default.access(themeAssetsDir);
|
|
799
|
+
await fs8__default.default.cp(themeAssetsDir, distThemeAssets, { recursive: true });
|
|
800
|
+
logger.info("Copied static assets to dist/theme-assets/");
|
|
801
|
+
} catch {
|
|
802
|
+
}
|
|
795
803
|
await generateManifest(themeName, themePath, outputDir);
|
|
796
804
|
await generateThemeData(themePath, outputDir, themeName);
|
|
797
805
|
await generateThemeCSS(themePath, outputDir);
|
|
@@ -4338,20 +4346,27 @@ function createDevServer(options) {
|
|
|
4338
4346
|
if (pathname.startsWith("/assets/")) {
|
|
4339
4347
|
const subpath = pathname.replace(/^\/assets\//, "");
|
|
4340
4348
|
const segments = subpath.split("/");
|
|
4349
|
+
const assetsBase = path9__default.default.join(options.themePath, "assets");
|
|
4341
4350
|
let assetPath;
|
|
4342
4351
|
if (segments[0] === options.themeName || segments[0] === options.themeName.replace(/^my-/, "")) {
|
|
4343
|
-
assetPath = path9__default.default.join(
|
|
4344
|
-
options.themePath,
|
|
4345
|
-
"assets",
|
|
4346
|
-
segments.slice(1).join("/")
|
|
4347
|
-
);
|
|
4352
|
+
assetPath = path9__default.default.join(assetsBase, segments.slice(1).join("/"));
|
|
4348
4353
|
} else {
|
|
4349
|
-
assetPath = path9__default.default.join(
|
|
4354
|
+
assetPath = path9__default.default.join(assetsBase, subpath);
|
|
4350
4355
|
}
|
|
4351
|
-
if (assetPath.startsWith(
|
|
4356
|
+
if (assetPath.startsWith(assetsBase) && fs3__default.default.existsSync(assetPath)) {
|
|
4352
4357
|
serveFile(res, assetPath);
|
|
4353
4358
|
return;
|
|
4354
4359
|
}
|
|
4360
|
+
if (segments.length > 1) {
|
|
4361
|
+
const fallbackPath = path9__default.default.join(
|
|
4362
|
+
assetsBase,
|
|
4363
|
+
segments.slice(1).join("/")
|
|
4364
|
+
);
|
|
4365
|
+
if (fallbackPath.startsWith(assetsBase) && fs3__default.default.existsSync(fallbackPath)) {
|
|
4366
|
+
serveFile(res, fallbackPath);
|
|
4367
|
+
return;
|
|
4368
|
+
}
|
|
4369
|
+
}
|
|
4355
4370
|
}
|
|
4356
4371
|
const filePath = path9__default.default.join(options.distDir, pathname);
|
|
4357
4372
|
if (!filePath.startsWith(options.distDir)) {
|
|
@@ -4858,6 +4873,82 @@ async function whoamiCommand() {
|
|
|
4858
4873
|
|
|
4859
4874
|
// src/commands/publish.ts
|
|
4860
4875
|
init_logger();
|
|
4876
|
+
var MIME_MAP = {
|
|
4877
|
+
".png": "image/png",
|
|
4878
|
+
".jpg": "image/jpeg",
|
|
4879
|
+
".jpeg": "image/jpeg",
|
|
4880
|
+
".gif": "image/gif",
|
|
4881
|
+
".webp": "image/webp",
|
|
4882
|
+
".avif": "image/avif",
|
|
4883
|
+
".svg": "image/svg+xml",
|
|
4884
|
+
".ico": "image/x-icon",
|
|
4885
|
+
".bmp": "image/bmp",
|
|
4886
|
+
".woff": "font/woff",
|
|
4887
|
+
".woff2": "font/woff2",
|
|
4888
|
+
".ttf": "font/ttf",
|
|
4889
|
+
".otf": "font/otf",
|
|
4890
|
+
".eot": "application/vnd.ms-fontobject",
|
|
4891
|
+
".mp4": "video/mp4",
|
|
4892
|
+
".webm": "video/webm",
|
|
4893
|
+
".mov": "video/quicktime",
|
|
4894
|
+
".ogg": "video/ogg",
|
|
4895
|
+
".json": "application/json"
|
|
4896
|
+
};
|
|
4897
|
+
var HASH_LEN = 8;
|
|
4898
|
+
function mimeFor(filename) {
|
|
4899
|
+
const ext = path9__default.default.extname(filename).toLowerCase();
|
|
4900
|
+
return MIME_MAP[ext] || "application/octet-stream";
|
|
4901
|
+
}
|
|
4902
|
+
async function sha256Prefix(absPath, len) {
|
|
4903
|
+
const buf = await fs__default.default.readFile(absPath);
|
|
4904
|
+
return crypto__default.default.createHash("sha256").update(buf).digest("hex").slice(0, len);
|
|
4905
|
+
}
|
|
4906
|
+
function insertHashIntoName(relPath, hash) {
|
|
4907
|
+
const dir = path9__default.default.posix.dirname(relPath);
|
|
4908
|
+
const base = path9__default.default.posix.basename(relPath);
|
|
4909
|
+
const ext = path9__default.default.posix.extname(base);
|
|
4910
|
+
const stem = ext ? base.slice(0, -ext.length) : base;
|
|
4911
|
+
const hashed = `${stem}-${hash}${ext}`;
|
|
4912
|
+
return dir === "." ? hashed : `${dir}/${hashed}`;
|
|
4913
|
+
}
|
|
4914
|
+
async function scanThemeAssets(distDir) {
|
|
4915
|
+
const assetsDir = path9__default.default.join(distDir, "theme-assets");
|
|
4916
|
+
if (!await fs__default.default.pathExists(assetsDir)) return [];
|
|
4917
|
+
const files = await glob.glob("**/*", {
|
|
4918
|
+
cwd: assetsDir,
|
|
4919
|
+
nodir: true,
|
|
4920
|
+
dot: false
|
|
4921
|
+
});
|
|
4922
|
+
const results = [];
|
|
4923
|
+
for (const rel of files) {
|
|
4924
|
+
const absPath = path9__default.default.join(assetsDir, rel);
|
|
4925
|
+
const stat = await fs__default.default.stat(absPath);
|
|
4926
|
+
if (!stat.isFile()) continue;
|
|
4927
|
+
const originalPath = rel.split(path9__default.default.sep).join("/");
|
|
4928
|
+
const hash = await sha256Prefix(absPath, HASH_LEN);
|
|
4929
|
+
const hashedPath = insertHashIntoName(originalPath, hash);
|
|
4930
|
+
const contentType = mimeFor(rel);
|
|
4931
|
+
results.push({
|
|
4932
|
+
originalPath,
|
|
4933
|
+
hashedPath,
|
|
4934
|
+
hash,
|
|
4935
|
+
size: stat.size,
|
|
4936
|
+
contentType,
|
|
4937
|
+
absPath
|
|
4938
|
+
});
|
|
4939
|
+
}
|
|
4940
|
+
results.sort((a, b) => a.originalPath.localeCompare(b.originalPath));
|
|
4941
|
+
return results;
|
|
4942
|
+
}
|
|
4943
|
+
function buildAssetMap(entries) {
|
|
4944
|
+
const map = {};
|
|
4945
|
+
for (const e of entries) {
|
|
4946
|
+
map[e.originalPath] = e.hashedPath;
|
|
4947
|
+
}
|
|
4948
|
+
return map;
|
|
4949
|
+
}
|
|
4950
|
+
|
|
4951
|
+
// src/commands/publish.ts
|
|
4861
4952
|
async function publishCommand(options) {
|
|
4862
4953
|
logger.header("OneX Theme Publish");
|
|
4863
4954
|
const tokens = await getValidTokens();
|
|
@@ -4992,37 +5083,123 @@ Or use the --bump flag:
|
|
|
4992
5083
|
logger.error(error instanceof Error ? error.message : "Build error");
|
|
4993
5084
|
process.exit(1);
|
|
4994
5085
|
}
|
|
4995
|
-
|
|
5086
|
+
const distDir = path9__default.default.join(themePath, "dist");
|
|
5087
|
+
let assetEntries = [];
|
|
5088
|
+
try {
|
|
5089
|
+
assetEntries = await scanThemeAssets(distDir);
|
|
5090
|
+
if (assetEntries.length > 0) {
|
|
5091
|
+
logger.info(`Found ${assetEntries.length} theme asset file(s)`);
|
|
5092
|
+
}
|
|
5093
|
+
} catch (error) {
|
|
5094
|
+
logger.error(
|
|
5095
|
+
`Asset scan failed: ${error instanceof Error ? error.message : "unknown"}`
|
|
5096
|
+
);
|
|
5097
|
+
process.exit(1);
|
|
5098
|
+
}
|
|
5099
|
+
try {
|
|
5100
|
+
const assetMap = buildAssetMap(assetEntries);
|
|
5101
|
+
const assetMapPath = path9__default.default.join(distDir, "asset-map.json");
|
|
5102
|
+
await fs__default.default.writeFile(assetMapPath, JSON.stringify(assetMap, null, 2));
|
|
5103
|
+
} catch (error) {
|
|
5104
|
+
logger.error(
|
|
5105
|
+
`Failed to write asset-map.json: ${error instanceof Error ? error.message : "unknown"}`
|
|
5106
|
+
);
|
|
5107
|
+
process.exit(1);
|
|
5108
|
+
}
|
|
5109
|
+
logger.startSpinner("Getting upload URLs...");
|
|
4996
5110
|
let bundleUploadUrl;
|
|
4997
5111
|
let sourceUploadUrl;
|
|
5112
|
+
let assetUploads = [];
|
|
5113
|
+
let alreadyUploaded = [];
|
|
4998
5114
|
try {
|
|
4999
5115
|
const pubResponse = await authenticatedFetch(
|
|
5000
5116
|
`${apiUrl}/website-api/themes/${encodeURIComponent(themeId)}/versions`,
|
|
5001
5117
|
{
|
|
5002
5118
|
method: "POST",
|
|
5003
|
-
body: JSON.stringify({
|
|
5119
|
+
body: JSON.stringify({
|
|
5120
|
+
version: version2,
|
|
5121
|
+
assets: assetEntries.map((a) => ({
|
|
5122
|
+
path: a.hashedPath,
|
|
5123
|
+
hash: a.hash,
|
|
5124
|
+
size: a.size,
|
|
5125
|
+
content_type: a.contentType
|
|
5126
|
+
}))
|
|
5127
|
+
})
|
|
5004
5128
|
}
|
|
5005
5129
|
);
|
|
5006
5130
|
const pubData = await pubResponse.json();
|
|
5007
5131
|
const pubBody = pubData.statusCode ? pubData.body : pubData;
|
|
5008
5132
|
if (!pubResponse.ok || !pubBody.bundleUploadUrl) {
|
|
5009
|
-
logger.stopSpinner(false, "Failed to get upload
|
|
5133
|
+
logger.stopSpinner(false, "Failed to get upload URLs");
|
|
5010
5134
|
logger.error(pubBody.error || "Server error");
|
|
5011
5135
|
process.exit(1);
|
|
5012
5136
|
}
|
|
5013
5137
|
bundleUploadUrl = pubBody.bundleUploadUrl;
|
|
5014
5138
|
sourceUploadUrl = pubBody.sourceUploadUrl;
|
|
5015
|
-
|
|
5139
|
+
assetUploads = pubBody.assetUploads || [];
|
|
5140
|
+
alreadyUploaded = pubBody.alreadyUploaded || [];
|
|
5141
|
+
logger.stopSpinner(
|
|
5142
|
+
true,
|
|
5143
|
+
`Upload URLs obtained (${assetUploads.length} new, ${alreadyUploaded.length} reused)`
|
|
5144
|
+
);
|
|
5016
5145
|
} catch (error) {
|
|
5017
5146
|
logger.stopSpinner(false, "Failed");
|
|
5018
5147
|
logger.error(error instanceof Error ? error.message : "Connection failed");
|
|
5019
5148
|
process.exit(1);
|
|
5020
5149
|
}
|
|
5150
|
+
if (assetUploads.length > 0) {
|
|
5151
|
+
logger.startSpinner(`Uploading ${assetUploads.length} asset(s) to S3...`);
|
|
5152
|
+
const CONCURRENCY = 8;
|
|
5153
|
+
const byHashedPath = new Map(assetEntries.map((a) => [a.hashedPath, a]));
|
|
5154
|
+
const queue = [...assetUploads];
|
|
5155
|
+
let uploaded = 0;
|
|
5156
|
+
let failed = 0;
|
|
5157
|
+
async function worker() {
|
|
5158
|
+
while (queue.length > 0) {
|
|
5159
|
+
const item = queue.shift();
|
|
5160
|
+
if (!item) break;
|
|
5161
|
+
const entry = byHashedPath.get(item.path);
|
|
5162
|
+
if (!entry) {
|
|
5163
|
+
failed++;
|
|
5164
|
+
logger.error(` \u2717 ${item.path}: no local file found`);
|
|
5165
|
+
continue;
|
|
5166
|
+
}
|
|
5167
|
+
try {
|
|
5168
|
+
const buf = await fs__default.default.promises.readFile(entry.absPath);
|
|
5169
|
+
const res = await fetch(item.upload_url, {
|
|
5170
|
+
method: "PUT",
|
|
5171
|
+
headers: {
|
|
5172
|
+
"Content-Type": entry.contentType,
|
|
5173
|
+
"x-amz-acl": "public-read"
|
|
5174
|
+
},
|
|
5175
|
+
body: buf
|
|
5176
|
+
});
|
|
5177
|
+
if (!res.ok) {
|
|
5178
|
+
throw new Error(`HTTP ${res.status}`);
|
|
5179
|
+
}
|
|
5180
|
+
uploaded++;
|
|
5181
|
+
} catch (e) {
|
|
5182
|
+
failed++;
|
|
5183
|
+
logger.error(
|
|
5184
|
+
` \u2717 ${item.path}: ${e instanceof Error ? e.message : "failed"}`
|
|
5185
|
+
);
|
|
5186
|
+
}
|
|
5187
|
+
}
|
|
5188
|
+
}
|
|
5189
|
+
await Promise.all(
|
|
5190
|
+
Array.from(
|
|
5191
|
+
{ length: Math.min(CONCURRENCY, assetUploads.length) },
|
|
5192
|
+
() => worker()
|
|
5193
|
+
)
|
|
5194
|
+
);
|
|
5195
|
+
if (failed > 0) {
|
|
5196
|
+
logger.stopSpinner(false, `${failed} asset(s) failed`);
|
|
5197
|
+
process.exit(1);
|
|
5198
|
+
}
|
|
5199
|
+
logger.stopSpinner(true, `Uploaded ${uploaded} asset(s)`);
|
|
5200
|
+
}
|
|
5021
5201
|
logger.startSpinner("Uploading bundle...");
|
|
5022
5202
|
try {
|
|
5023
|
-
const archiver3 = await import('archiver');
|
|
5024
|
-
const { createWriteStream } = await import('fs');
|
|
5025
|
-
const distDir = path9__default.default.join(themePath, "dist");
|
|
5026
5203
|
if (!fs__default.default.existsSync(distDir)) {
|
|
5027
5204
|
logger.stopSpinner(false, "No dist/ directory");
|
|
5028
5205
|
logger.error("Build the theme first: onexthm build");
|
|
@@ -5033,7 +5210,9 @@ Or use the --bump flag:
|
|
|
5033
5210
|
"bundle.zip",
|
|
5034
5211
|
"source.zip",
|
|
5035
5212
|
"preview-runtime.js",
|
|
5036
|
-
"preview-runtime.js.map"
|
|
5213
|
+
"preview-runtime.js.map",
|
|
5214
|
+
"theme-assets",
|
|
5215
|
+
"theme-assets/**"
|
|
5037
5216
|
]);
|
|
5038
5217
|
const bundleBuffer = fs__default.default.readFileSync(bundleZipPath);
|
|
5039
5218
|
const bundleRes = await fetch(bundleUploadUrl, {
|