pakstr 0.23.0 → 0.24.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/commands/publish.js +22 -0
- package/dist/core/zapStore.js +2 -0
- package/dist/core/zapstoreConfig.js +19 -1
- package/package.json +1 -1
package/dist/commands/publish.js
CHANGED
|
@@ -15,6 +15,18 @@ const pakstrConfig_1 = require("../core/pakstrConfig");
|
|
|
15
15
|
const nsite_1 = require("../core/nsite");
|
|
16
16
|
const zapStore_1 = require("../core/zapStore");
|
|
17
17
|
const zapstoreConfig_1 = require("../core/zapstoreConfig");
|
|
18
|
+
function imageContentType(filePath) {
|
|
19
|
+
switch (path_1.default.extname(filePath).toLowerCase()) {
|
|
20
|
+
case ".png": return "image/png";
|
|
21
|
+
case ".jpg":
|
|
22
|
+
case ".jpeg": return "image/jpeg";
|
|
23
|
+
case ".gif": return "image/gif";
|
|
24
|
+
case ".webp": return "image/webp";
|
|
25
|
+
case ".svg": return "image/svg+xml";
|
|
26
|
+
case ".ico": return "image/x-icon";
|
|
27
|
+
default: return "application/octet-stream";
|
|
28
|
+
}
|
|
29
|
+
}
|
|
18
30
|
/** `pakstr publish` — optionally upload the signed APK and publish its Zapstore events. */
|
|
19
31
|
async function publishCommand(configPath, options = {}) {
|
|
20
32
|
if (options.blossomFetch && options.fetchImpl) {
|
|
@@ -108,6 +120,15 @@ async function publishCommand(configPath, options = {}) {
|
|
|
108
120
|
console.log("Publishing as:", publishNsec.envVar);
|
|
109
121
|
console.log("Publisher npub:", npub);
|
|
110
122
|
console.log("Relay:", config.publish.relay);
|
|
123
|
+
const iconUrl = zapstoreConfig?.icon
|
|
124
|
+
? (await (0, blossom_1.uploadToBlossom)({
|
|
125
|
+
serverUrl: config.publish.blossom,
|
|
126
|
+
filePath: zapstoreConfig.icon,
|
|
127
|
+
secret: publishNsec.bytes,
|
|
128
|
+
contentType: imageContentType(zapstoreConfig.icon),
|
|
129
|
+
fetchImpl,
|
|
130
|
+
})).url
|
|
131
|
+
: undefined;
|
|
111
132
|
app = {
|
|
112
133
|
appId: config.app.appId,
|
|
113
134
|
appName: zapstoreConfig?.name ?? config.app.appName,
|
|
@@ -118,6 +139,7 @@ async function publishCommand(configPath, options = {}) {
|
|
|
118
139
|
tags: zapstoreConfig?.tags,
|
|
119
140
|
license: zapstoreConfig?.license,
|
|
120
141
|
website: zapstoreConfig?.website,
|
|
142
|
+
icon: iconUrl,
|
|
121
143
|
releaseNotes: zapstoreConfig?.releaseNotes,
|
|
122
144
|
repository: zapstoreConfig?.repository ?? (0, zapstoreConfig_1.loadZapstoreRepository)(config.configDir),
|
|
123
145
|
};
|
package/dist/core/zapStore.js
CHANGED
|
@@ -77,6 +77,7 @@ async function buildAppMetadataEvent(input) {
|
|
|
77
77
|
const npub = (0, nostr_1.pubkeyHexToNpub)(pubkeyHex);
|
|
78
78
|
const communities = input.communities?.length ? input.communities : [exports.DEFAULT_COMMUNITY];
|
|
79
79
|
const summaryTags = input.app.summary !== undefined ? [["summary", input.app.summary]] : [];
|
|
80
|
+
const iconTags = input.app.icon !== undefined ? [["icon", input.app.icon]] : [];
|
|
80
81
|
const topicTags = (input.app.tags ?? []).map(tag => ["t", tag]);
|
|
81
82
|
const licenseTags = input.app.license !== undefined ? [["license", input.app.license]] : [];
|
|
82
83
|
const websiteTags = input.app.website !== undefined ? [["url", input.app.website]] : [];
|
|
@@ -88,6 +89,7 @@ async function buildAppMetadataEvent(input) {
|
|
|
88
89
|
["d", input.app.appId],
|
|
89
90
|
["name", input.app.appName],
|
|
90
91
|
...summaryTags,
|
|
92
|
+
...iconTags,
|
|
91
93
|
["f", PLATFORM],
|
|
92
94
|
...communities.map(c => ["h", c]),
|
|
93
95
|
...topicTags,
|
|
@@ -58,6 +58,10 @@ function loadZapstorePublisherConfig(configDir) {
|
|
|
58
58
|
const tags = optionalTags(config.tags, configPath);
|
|
59
59
|
const license = optionalString(config.license, "license", configPath);
|
|
60
60
|
const website = optionalString(config.website, "website", configPath);
|
|
61
|
+
const iconPath = optionalString(config.icon, "icon", configPath);
|
|
62
|
+
const icon = iconPath === undefined
|
|
63
|
+
? undefined
|
|
64
|
+
: resolveIconPath(iconPath, configDir, configPath);
|
|
61
65
|
const releaseNotesPath = optionalString(config.release_notes, "release_notes", configPath);
|
|
62
66
|
const releaseNotes = releaseNotesPath === undefined
|
|
63
67
|
? undefined
|
|
@@ -79,6 +83,7 @@ function loadZapstorePublisherConfig(configDir) {
|
|
|
79
83
|
tags,
|
|
80
84
|
license,
|
|
81
85
|
website,
|
|
86
|
+
icon,
|
|
82
87
|
releaseNotes,
|
|
83
88
|
};
|
|
84
89
|
}
|
|
@@ -94,7 +99,7 @@ function optionalString(value, field, configPath, trim = true) {
|
|
|
94
99
|
if (typeof value !== "string") {
|
|
95
100
|
throw new ZapstoreConfigError(`${exports.ZAPSTORE_CONFIG_FILENAME} field ${field} must be a string`, configPath);
|
|
96
101
|
}
|
|
97
|
-
if (value.trim().length === 0 && field === "release_notes") {
|
|
102
|
+
if (value.trim().length === 0 && (field === "release_notes" || field === "icon")) {
|
|
98
103
|
throw new ZapstoreConfigError(`${exports.ZAPSTORE_CONFIG_FILENAME} field ${field} must not be empty`, configPath);
|
|
99
104
|
}
|
|
100
105
|
return trim ? value.trim() : value;
|
|
@@ -112,6 +117,19 @@ function optionalTags(value, configPath) {
|
|
|
112
117
|
return tag.trim();
|
|
113
118
|
});
|
|
114
119
|
}
|
|
120
|
+
function resolveIconPath(iconPath, configDir, configPath) {
|
|
121
|
+
const resolved = path_1.default.resolve(configDir, iconPath);
|
|
122
|
+
if (!fs_1.default.existsSync(resolved) || !fs_1.default.lstatSync(resolved).isFile()) {
|
|
123
|
+
throw new ZapstoreConfigError(`${exports.ZAPSTORE_CONFIG_FILENAME} icon file not found: ${resolved}`, configPath);
|
|
124
|
+
}
|
|
125
|
+
try {
|
|
126
|
+
fs_1.default.accessSync(resolved, fs_1.default.constants.R_OK);
|
|
127
|
+
}
|
|
128
|
+
catch (error) {
|
|
129
|
+
throw new ZapstoreConfigError(`Could not read ${exports.ZAPSTORE_CONFIG_FILENAME} icon file ${resolved}: ${error instanceof Error ? error.message : String(error)}`, configPath);
|
|
130
|
+
}
|
|
131
|
+
return resolved;
|
|
132
|
+
}
|
|
115
133
|
function readReleaseNotes(releaseNotesPath, configDir, configPath) {
|
|
116
134
|
const resolved = path_1.default.resolve(configDir, releaseNotesPath);
|
|
117
135
|
if (!fs_1.default.existsSync(resolved) || !fs_1.default.lstatSync(resolved).isFile()) {
|