@solana-mobile/dapp-store-cli 0.16.0 → 0.16.1
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/dapp-store.js +3 -1
- package/lib/CliSetup.js +304 -505
- package/lib/CliUtils.js +6 -376
- package/lib/__tests__/CliSetupTest.js +484 -74
- package/lib/cli/__tests__/parseErrors.test.js +25 -0
- package/lib/cli/__tests__/signer.test.js +436 -0
- package/lib/cli/constants.js +23 -0
- package/lib/cli/messages.js +21 -0
- package/lib/cli/parseErrors.js +41 -0
- package/lib/{commands/publish/PublishCliSupport.js → cli/selfUpdate.js} +72 -38
- package/lib/{commands/publish/PublishCliRemove.js → cli/signer.js} +35 -56
- package/lib/index.js +96 -5
- package/lib/package.json +5 -24
- package/lib/portal/__tests__/releaseMetadata.test.js +647 -0
- package/lib/portal/__tests__/translators.test.js +76 -0
- package/lib/portal/__tests__/workflowClient.test.js +457 -0
- package/lib/portal/attestationClient.js +143 -0
- package/lib/portal/files.js +64 -0
- package/lib/portal/http.js +364 -0
- package/lib/portal/records.js +64 -0
- package/lib/portal/releaseMetadata.js +748 -0
- package/lib/portal/translators.js +460 -0
- package/lib/portal/types.js +1 -0
- package/lib/portal/workflowClient.js +704 -0
- package/lib/publication/PublicationProgressReporter.js +1051 -0
- package/lib/publication/__tests__/PublicationProgressReporter.test.js +174 -0
- package/lib/{commands/ValidateCommand.js → publication/__tests__/fundingPreflight.test.js} +90 -66
- package/lib/publication/__tests__/publicationSummary.test.js +26 -0
- package/lib/publication/cliValidation.js +482 -0
- package/lib/publication/fundingPreflight.js +246 -0
- package/lib/publication/publicationSummary.js +99 -0
- package/lib/{commands/utils.js → publication/runPublicationWorkflow.js} +16 -46
- package/package.json +5 -24
- package/src/CliSetup.ts +370 -505
- package/src/CliUtils.ts +9 -233
- package/src/__tests__/CliSetupTest.ts +272 -120
- package/src/cli/__tests__/parseErrors.test.ts +34 -0
- package/src/cli/__tests__/signer.test.ts +359 -0
- package/src/cli/constants.ts +3 -0
- package/src/cli/messages.ts +27 -0
- package/src/cli/parseErrors.ts +62 -0
- package/src/cli/selfUpdate.ts +59 -0
- package/src/cli/signer.ts +38 -0
- package/src/index.ts +31 -4
- package/src/portal/__tests__/releaseMetadata.test.ts +508 -0
- package/src/portal/__tests__/translators.test.ts +82 -0
- package/src/portal/__tests__/workflowClient.test.ts +278 -0
- package/src/portal/attestationClient.ts +19 -0
- package/src/portal/files.ts +73 -0
- package/src/portal/http.ts +170 -0
- package/src/portal/records.ts +38 -0
- package/src/portal/releaseMetadata.ts +489 -0
- package/src/portal/translators.ts +750 -0
- package/src/portal/types.ts +27 -0
- package/src/portal/workflowClient.ts +575 -0
- package/src/publication/PublicationProgressReporter.ts +1026 -0
- package/src/publication/__tests__/PublicationProgressReporter.test.ts +210 -0
- package/src/publication/__tests__/fundingPreflight.test.ts +78 -0
- package/src/publication/__tests__/publicationSummary.test.ts +30 -0
- package/src/publication/cliValidation.ts +264 -0
- package/src/publication/fundingPreflight.ts +123 -0
- package/src/publication/publicationSummary.ts +26 -0
- package/src/publication/runPublicationWorkflow.ts +46 -0
- package/lib/commands/create/CreateCliApp.js +0 -223
- package/lib/commands/create/CreateCliRelease.js +0 -290
- package/lib/commands/create/index.js +0 -40
- package/lib/commands/index.js +0 -3
- package/lib/commands/publish/PublishCliSubmit.js +0 -208
- package/lib/commands/publish/PublishCliUpdate.js +0 -211
- package/lib/commands/publish/index.js +0 -22
- package/lib/commands/scaffolding/ScaffoldInit.js +0 -15
- package/lib/commands/scaffolding/index.js +0 -1
- package/lib/config/EnvVariables.js +0 -59
- package/lib/config/PublishDetails.js +0 -915
- package/lib/config/S3StorageManager.js +0 -93
- package/lib/config/index.js +0 -2
- package/lib/generated/config_obj.json +0 -1
- package/lib/generated/config_schema.json +0 -1
- package/lib/prebuild_schema/publishing_source.yaml +0 -64
- package/lib/prebuild_schema/schemagen.js +0 -25
- package/lib/upload/CachedStorageDriver.js +0 -458
- package/lib/upload/TurboStorageDriver.js +0 -718
- package/lib/upload/__tests__/CachedStorageDriver.test.js +0 -437
- package/lib/upload/__tests__/TurboStorageDriver.test.js +0 -17
- package/lib/upload/__tests__/contentGateway.test.js +0 -17
- package/lib/upload/contentGateway.js +0 -23
- package/lib/upload/index.js +0 -2
- package/src/commands/ValidateCommand.ts +0 -82
- package/src/commands/create/CreateCliApp.ts +0 -93
- package/src/commands/create/CreateCliRelease.ts +0 -149
- package/src/commands/create/index.ts +0 -47
- package/src/commands/index.ts +0 -3
- package/src/commands/publish/PublishCliRemove.ts +0 -66
- package/src/commands/publish/PublishCliSubmit.ts +0 -93
- package/src/commands/publish/PublishCliSupport.ts +0 -66
- package/src/commands/publish/PublishCliUpdate.ts +0 -101
- package/src/commands/publish/index.ts +0 -29
- package/src/commands/scaffolding/ScaffoldInit.ts +0 -20
- package/src/commands/scaffolding/index.ts +0 -1
- package/src/commands/utils.ts +0 -33
- package/src/config/EnvVariables.ts +0 -39
- package/src/config/PublishDetails.ts +0 -456
- package/src/config/S3StorageManager.ts +0 -47
- package/src/config/index.ts +0 -2
- package/src/prebuild_schema/publishing_source.yaml +0 -64
- package/src/prebuild_schema/schemagen.js +0 -31
- package/src/upload/CachedStorageDriver.ts +0 -179
- package/src/upload/TurboStorageDriver.ts +0 -283
- package/src/upload/__tests__/CachedStorageDriver.test.ts +0 -246
- package/src/upload/__tests__/TurboStorageDriver.test.ts +0 -15
- package/src/upload/__tests__/contentGateway.test.ts +0 -31
- package/src/upload/contentGateway.ts +0 -37
- package/src/upload/index.ts +0 -2
|
@@ -1,437 +0,0 @@
|
|
|
1
|
-
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
|
|
2
|
-
try {
|
|
3
|
-
var info = gen[key](arg);
|
|
4
|
-
var value = info.value;
|
|
5
|
-
} catch (error) {
|
|
6
|
-
reject(error);
|
|
7
|
-
return;
|
|
8
|
-
}
|
|
9
|
-
if (info.done) {
|
|
10
|
-
resolve(value);
|
|
11
|
-
} else {
|
|
12
|
-
Promise.resolve(value).then(_next, _throw);
|
|
13
|
-
}
|
|
14
|
-
}
|
|
15
|
-
function _async_to_generator(fn) {
|
|
16
|
-
return function() {
|
|
17
|
-
var self = this, args = arguments;
|
|
18
|
-
return new Promise(function(resolve, reject) {
|
|
19
|
-
var gen = fn.apply(self, args);
|
|
20
|
-
function _next(value) {
|
|
21
|
-
asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value);
|
|
22
|
-
}
|
|
23
|
-
function _throw(err) {
|
|
24
|
-
asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err);
|
|
25
|
-
}
|
|
26
|
-
_next(undefined);
|
|
27
|
-
});
|
|
28
|
-
};
|
|
29
|
-
}
|
|
30
|
-
function _define_property(obj, key, value) {
|
|
31
|
-
if (key in obj) {
|
|
32
|
-
Object.defineProperty(obj, key, {
|
|
33
|
-
value: value,
|
|
34
|
-
enumerable: true,
|
|
35
|
-
configurable: true,
|
|
36
|
-
writable: true
|
|
37
|
-
});
|
|
38
|
-
} else {
|
|
39
|
-
obj[key] = value;
|
|
40
|
-
}
|
|
41
|
-
return obj;
|
|
42
|
-
}
|
|
43
|
-
function _ts_generator(thisArg, body) {
|
|
44
|
-
var f, y, t, _ = {
|
|
45
|
-
label: 0,
|
|
46
|
-
sent: function() {
|
|
47
|
-
if (t[0] & 1) throw t[1];
|
|
48
|
-
return t[1];
|
|
49
|
-
},
|
|
50
|
-
trys: [],
|
|
51
|
-
ops: []
|
|
52
|
-
}, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
|
|
53
|
-
return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() {
|
|
54
|
-
return this;
|
|
55
|
-
}), g;
|
|
56
|
-
function verb(n) {
|
|
57
|
-
return function(v) {
|
|
58
|
-
return step([
|
|
59
|
-
n,
|
|
60
|
-
v
|
|
61
|
-
]);
|
|
62
|
-
};
|
|
63
|
-
}
|
|
64
|
-
function step(op) {
|
|
65
|
-
if (f) throw new TypeError("Generator is already executing.");
|
|
66
|
-
while(g && (g = 0, op[0] && (_ = 0)), _)try {
|
|
67
|
-
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
68
|
-
if (y = 0, t) op = [
|
|
69
|
-
op[0] & 2,
|
|
70
|
-
t.value
|
|
71
|
-
];
|
|
72
|
-
switch(op[0]){
|
|
73
|
-
case 0:
|
|
74
|
-
case 1:
|
|
75
|
-
t = op;
|
|
76
|
-
break;
|
|
77
|
-
case 4:
|
|
78
|
-
_.label++;
|
|
79
|
-
return {
|
|
80
|
-
value: op[1],
|
|
81
|
-
done: false
|
|
82
|
-
};
|
|
83
|
-
case 5:
|
|
84
|
-
_.label++;
|
|
85
|
-
y = op[1];
|
|
86
|
-
op = [
|
|
87
|
-
0
|
|
88
|
-
];
|
|
89
|
-
continue;
|
|
90
|
-
case 7:
|
|
91
|
-
op = _.ops.pop();
|
|
92
|
-
_.trys.pop();
|
|
93
|
-
continue;
|
|
94
|
-
default:
|
|
95
|
-
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) {
|
|
96
|
-
_ = 0;
|
|
97
|
-
continue;
|
|
98
|
-
}
|
|
99
|
-
if (op[0] === 3 && (!t || op[1] > t[0] && op[1] < t[3])) {
|
|
100
|
-
_.label = op[1];
|
|
101
|
-
break;
|
|
102
|
-
}
|
|
103
|
-
if (op[0] === 6 && _.label < t[1]) {
|
|
104
|
-
_.label = t[1];
|
|
105
|
-
t = op;
|
|
106
|
-
break;
|
|
107
|
-
}
|
|
108
|
-
if (t && _.label < t[2]) {
|
|
109
|
-
_.label = t[2];
|
|
110
|
-
_.ops.push(op);
|
|
111
|
-
break;
|
|
112
|
-
}
|
|
113
|
-
if (t[2]) _.ops.pop();
|
|
114
|
-
_.trys.pop();
|
|
115
|
-
continue;
|
|
116
|
-
}
|
|
117
|
-
op = body.call(thisArg, _);
|
|
118
|
-
} catch (e) {
|
|
119
|
-
op = [
|
|
120
|
-
6,
|
|
121
|
-
e
|
|
122
|
-
];
|
|
123
|
-
y = 0;
|
|
124
|
-
} finally{
|
|
125
|
-
f = t = 0;
|
|
126
|
-
}
|
|
127
|
-
if (op[0] & 5) throw op[1];
|
|
128
|
-
return {
|
|
129
|
-
value: op[0] ? op[1] : void 0,
|
|
130
|
-
done: true
|
|
131
|
-
};
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
import fs from "fs";
|
|
135
|
-
import os from "os";
|
|
136
|
-
import path from "path";
|
|
137
|
-
import { createHash } from "crypto";
|
|
138
|
-
import { jest } from "@jest/globals";
|
|
139
|
-
import { CachedStorageDriver } from "../CachedStorageDriver";
|
|
140
|
-
describe("CachedStorageDriver", function() {
|
|
141
|
-
var originalCwd = process.cwd();
|
|
142
|
-
var tempDir;
|
|
143
|
-
beforeEach(function() {
|
|
144
|
-
tempDir = fs.mkdtempSync(path.join(os.tmpdir(), "cached-storage-driver-"));
|
|
145
|
-
process.chdir(tempDir);
|
|
146
|
-
});
|
|
147
|
-
afterEach(function() {
|
|
148
|
-
process.chdir(originalCwd);
|
|
149
|
-
fs.rmSync(tempDir, {
|
|
150
|
-
recursive: true,
|
|
151
|
-
force: true
|
|
152
|
-
});
|
|
153
|
-
});
|
|
154
|
-
test("normalizes a cached legacy arweave URL and persists the rewritten manifest", function() {
|
|
155
|
-
return _async_to_generator(function() {
|
|
156
|
-
var file, hash, manifestPath, uploadCalls, storageDriver, driver, rewrittenManifest;
|
|
157
|
-
return _ts_generator(this, function(_state) {
|
|
158
|
-
switch(_state.label){
|
|
159
|
-
case 0:
|
|
160
|
-
file = makeMetaplexFile("icon.png", Buffer.from("cached-asset"));
|
|
161
|
-
hash = hashBuffer(file.buffer);
|
|
162
|
-
manifestPath = ".asset-manifest.json";
|
|
163
|
-
fs.writeFileSync(path.join(tempDir, manifestPath), JSON.stringify({
|
|
164
|
-
assets: _define_property({}, file.fileName, {
|
|
165
|
-
path: file.fileName,
|
|
166
|
-
sha256: hash,
|
|
167
|
-
uri: "https://arweave.net/legacy-id"
|
|
168
|
-
})
|
|
169
|
-
}, null, 2));
|
|
170
|
-
uploadCalls = 0;
|
|
171
|
-
storageDriver = {
|
|
172
|
-
getUploadPrice: function(_bytes) {
|
|
173
|
-
return _async_to_generator(function() {
|
|
174
|
-
return _ts_generator(this, function(_state) {
|
|
175
|
-
throw new Error("getUploadPrice should not be called in this test");
|
|
176
|
-
});
|
|
177
|
-
})();
|
|
178
|
-
},
|
|
179
|
-
upload: function(_file) {
|
|
180
|
-
return _async_to_generator(function() {
|
|
181
|
-
return _ts_generator(this, function(_state) {
|
|
182
|
-
uploadCalls += 1;
|
|
183
|
-
throw new Error("upload should not be called in this test");
|
|
184
|
-
});
|
|
185
|
-
})();
|
|
186
|
-
}
|
|
187
|
-
};
|
|
188
|
-
driver = new CachedStorageDriver(storageDriver, {
|
|
189
|
-
assetManifestPath: manifestPath
|
|
190
|
-
});
|
|
191
|
-
return [
|
|
192
|
-
4,
|
|
193
|
-
expect(driver.upload(file)).resolves.toBe("https://dappstorecontent.com/legacy-id")
|
|
194
|
-
];
|
|
195
|
-
case 1:
|
|
196
|
-
_state.sent();
|
|
197
|
-
expect(uploadCalls).toBe(0);
|
|
198
|
-
rewrittenManifest = JSON.parse(fs.readFileSync(path.join(tempDir, manifestPath), "utf-8"));
|
|
199
|
-
expect(rewrittenManifest.schema_version).toBe("0.1");
|
|
200
|
-
expect(rewrittenManifest.assets[file.fileName].uri).toBe("https://dappstorecontent.com/legacy-id");
|
|
201
|
-
return [
|
|
202
|
-
2
|
|
203
|
-
];
|
|
204
|
-
}
|
|
205
|
-
});
|
|
206
|
-
})();
|
|
207
|
-
});
|
|
208
|
-
test("supports absolute asset manifest paths", function() {
|
|
209
|
-
return _async_to_generator(function() {
|
|
210
|
-
var file, hash, manifestPath, uploadCalls, storageDriver, driver, rewrittenManifest;
|
|
211
|
-
return _ts_generator(this, function(_state) {
|
|
212
|
-
switch(_state.label){
|
|
213
|
-
case 0:
|
|
214
|
-
file = makeMetaplexFile("absolute-icon.png", Buffer.from("cached-asset"));
|
|
215
|
-
hash = hashBuffer(file.buffer);
|
|
216
|
-
manifestPath = path.join(tempDir, ".asset-manifest.json");
|
|
217
|
-
fs.writeFileSync(manifestPath, JSON.stringify({
|
|
218
|
-
assets: _define_property({}, file.fileName, {
|
|
219
|
-
path: file.fileName,
|
|
220
|
-
sha256: hash,
|
|
221
|
-
uri: "https://arweave.net/absolute-id"
|
|
222
|
-
})
|
|
223
|
-
}, null, 2));
|
|
224
|
-
uploadCalls = 0;
|
|
225
|
-
storageDriver = {
|
|
226
|
-
getUploadPrice: function(_bytes) {
|
|
227
|
-
return _async_to_generator(function() {
|
|
228
|
-
return _ts_generator(this, function(_state) {
|
|
229
|
-
throw new Error("getUploadPrice should not be called in this test");
|
|
230
|
-
});
|
|
231
|
-
})();
|
|
232
|
-
},
|
|
233
|
-
upload: function(_file) {
|
|
234
|
-
return _async_to_generator(function() {
|
|
235
|
-
return _ts_generator(this, function(_state) {
|
|
236
|
-
uploadCalls += 1;
|
|
237
|
-
throw new Error("upload should not be called in this test");
|
|
238
|
-
});
|
|
239
|
-
})();
|
|
240
|
-
}
|
|
241
|
-
};
|
|
242
|
-
driver = new CachedStorageDriver(storageDriver, {
|
|
243
|
-
assetManifestPath: manifestPath
|
|
244
|
-
});
|
|
245
|
-
return [
|
|
246
|
-
4,
|
|
247
|
-
expect(driver.upload(file)).resolves.toBe("https://dappstorecontent.com/absolute-id")
|
|
248
|
-
];
|
|
249
|
-
case 1:
|
|
250
|
-
_state.sent();
|
|
251
|
-
expect(uploadCalls).toBe(0);
|
|
252
|
-
rewrittenManifest = JSON.parse(fs.readFileSync(manifestPath, "utf-8"));
|
|
253
|
-
expect(rewrittenManifest.assets[file.fileName].uri).toBe("https://dappstorecontent.com/absolute-id");
|
|
254
|
-
return [
|
|
255
|
-
2
|
|
256
|
-
];
|
|
257
|
-
}
|
|
258
|
-
});
|
|
259
|
-
})();
|
|
260
|
-
});
|
|
261
|
-
test("normalizes fresh uploads before persisting them in the manifest", function() {
|
|
262
|
-
return _async_to_generator(function() {
|
|
263
|
-
var file, manifestPath, uploadCalls, storageDriver, driver, persistedManifest;
|
|
264
|
-
return _ts_generator(this, function(_state) {
|
|
265
|
-
switch(_state.label){
|
|
266
|
-
case 0:
|
|
267
|
-
file = makeMetaplexFile("banner.png", Buffer.from("fresh-asset"));
|
|
268
|
-
manifestPath = ".asset-manifest.json";
|
|
269
|
-
uploadCalls = 0;
|
|
270
|
-
storageDriver = {
|
|
271
|
-
getUploadPrice: function(_bytes) {
|
|
272
|
-
return _async_to_generator(function() {
|
|
273
|
-
return _ts_generator(this, function(_state) {
|
|
274
|
-
throw new Error("getUploadPrice should not be called in this test");
|
|
275
|
-
});
|
|
276
|
-
})();
|
|
277
|
-
},
|
|
278
|
-
upload: function(_file) {
|
|
279
|
-
return _async_to_generator(function() {
|
|
280
|
-
return _ts_generator(this, function(_state) {
|
|
281
|
-
uploadCalls += 1;
|
|
282
|
-
return [
|
|
283
|
-
2,
|
|
284
|
-
"https://arweave.com/fresh-id"
|
|
285
|
-
];
|
|
286
|
-
});
|
|
287
|
-
})();
|
|
288
|
-
}
|
|
289
|
-
};
|
|
290
|
-
driver = new CachedStorageDriver(storageDriver, {
|
|
291
|
-
assetManifestPath: manifestPath
|
|
292
|
-
});
|
|
293
|
-
return [
|
|
294
|
-
4,
|
|
295
|
-
expect(driver.upload(file)).resolves.toBe("https://dappstorecontent.com/fresh-id")
|
|
296
|
-
];
|
|
297
|
-
case 1:
|
|
298
|
-
_state.sent();
|
|
299
|
-
expect(uploadCalls).toBe(1);
|
|
300
|
-
persistedManifest = JSON.parse(fs.readFileSync(path.join(tempDir, manifestPath), "utf-8"));
|
|
301
|
-
expect(persistedManifest.schema_version).toBe("0.1");
|
|
302
|
-
expect(persistedManifest.assets[file.fileName].uri).toBe("https://dappstorecontent.com/fresh-id");
|
|
303
|
-
return [
|
|
304
|
-
2
|
|
305
|
-
];
|
|
306
|
-
}
|
|
307
|
-
});
|
|
308
|
-
})();
|
|
309
|
-
});
|
|
310
|
-
test("normalizes inline metadata uploads without caching them", function() {
|
|
311
|
-
return _async_to_generator(function() {
|
|
312
|
-
var file, uploadCalls, storageDriver, driver;
|
|
313
|
-
return _ts_generator(this, function(_state) {
|
|
314
|
-
switch(_state.label){
|
|
315
|
-
case 0:
|
|
316
|
-
file = makeMetaplexFile("inline.json", Buffer.from("{}"));
|
|
317
|
-
uploadCalls = 0;
|
|
318
|
-
storageDriver = {
|
|
319
|
-
getUploadPrice: function(_bytes) {
|
|
320
|
-
return _async_to_generator(function() {
|
|
321
|
-
return _ts_generator(this, function(_state) {
|
|
322
|
-
throw new Error("getUploadPrice should not be called in this test");
|
|
323
|
-
});
|
|
324
|
-
})();
|
|
325
|
-
},
|
|
326
|
-
upload: function(_file) {
|
|
327
|
-
return _async_to_generator(function() {
|
|
328
|
-
return _ts_generator(this, function(_state) {
|
|
329
|
-
uploadCalls += 1;
|
|
330
|
-
return [
|
|
331
|
-
2,
|
|
332
|
-
"https://arweave.net/metadata-id"
|
|
333
|
-
];
|
|
334
|
-
});
|
|
335
|
-
})();
|
|
336
|
-
}
|
|
337
|
-
};
|
|
338
|
-
driver = new CachedStorageDriver(storageDriver, {
|
|
339
|
-
assetManifestPath: ".asset-manifest.json"
|
|
340
|
-
});
|
|
341
|
-
return [
|
|
342
|
-
4,
|
|
343
|
-
expect(driver.upload(file)).resolves.toBe("https://dappstorecontent.com/metadata-id")
|
|
344
|
-
];
|
|
345
|
-
case 1:
|
|
346
|
-
_state.sent();
|
|
347
|
-
expect(uploadCalls).toBe(1);
|
|
348
|
-
expect(fs.existsSync(path.join(tempDir, ".asset-manifest.json"))).toBe(false);
|
|
349
|
-
return [
|
|
350
|
-
2
|
|
351
|
-
];
|
|
352
|
-
}
|
|
353
|
-
});
|
|
354
|
-
})();
|
|
355
|
-
});
|
|
356
|
-
test("returns a normalized cached URL even when manifest rewrite persistence fails", function() {
|
|
357
|
-
return _async_to_generator(function() {
|
|
358
|
-
var file, hash, manifestPath, writeFileSpy, warnSpy, storageDriver, driver;
|
|
359
|
-
return _ts_generator(this, function(_state) {
|
|
360
|
-
switch(_state.label){
|
|
361
|
-
case 0:
|
|
362
|
-
file = makeMetaplexFile("icon.png", Buffer.from("cached-asset"));
|
|
363
|
-
hash = hashBuffer(file.buffer);
|
|
364
|
-
manifestPath = ".asset-manifest.json";
|
|
365
|
-
fs.writeFileSync(path.join(tempDir, manifestPath), JSON.stringify({
|
|
366
|
-
assets: _define_property({}, file.fileName, {
|
|
367
|
-
path: file.fileName,
|
|
368
|
-
sha256: hash,
|
|
369
|
-
uri: "https://arweave.net/rewrite-failure-id"
|
|
370
|
-
})
|
|
371
|
-
}, null, 2));
|
|
372
|
-
writeFileSpy = jest.spyOn(fs.promises, "writeFile").mockRejectedValueOnce(new Error("disk full"));
|
|
373
|
-
warnSpy = jest.spyOn(console, "warn").mockImplementation(function() {
|
|
374
|
-
return undefined;
|
|
375
|
-
});
|
|
376
|
-
storageDriver = {
|
|
377
|
-
getUploadPrice: function(_bytes) {
|
|
378
|
-
return _async_to_generator(function() {
|
|
379
|
-
return _ts_generator(this, function(_state) {
|
|
380
|
-
throw new Error("getUploadPrice should not be called in this test");
|
|
381
|
-
});
|
|
382
|
-
})();
|
|
383
|
-
},
|
|
384
|
-
upload: function(_file) {
|
|
385
|
-
return _async_to_generator(function() {
|
|
386
|
-
return _ts_generator(this, function(_state) {
|
|
387
|
-
throw new Error("upload should not be called in this test");
|
|
388
|
-
});
|
|
389
|
-
})();
|
|
390
|
-
}
|
|
391
|
-
};
|
|
392
|
-
driver = new CachedStorageDriver(storageDriver, {
|
|
393
|
-
assetManifestPath: manifestPath
|
|
394
|
-
});
|
|
395
|
-
_state.label = 1;
|
|
396
|
-
case 1:
|
|
397
|
-
_state.trys.push([
|
|
398
|
-
1,
|
|
399
|
-
,
|
|
400
|
-
3,
|
|
401
|
-
4
|
|
402
|
-
]);
|
|
403
|
-
return [
|
|
404
|
-
4,
|
|
405
|
-
expect(driver.upload(file)).resolves.toBe("https://dappstorecontent.com/rewrite-failure-id")
|
|
406
|
-
];
|
|
407
|
-
case 2:
|
|
408
|
-
_state.sent();
|
|
409
|
-
expect(warnSpy).toHaveBeenCalledWith(expect.stringContaining("Failed to rewrite .asset-manifest.json; continuing with normalized URL"));
|
|
410
|
-
return [
|
|
411
|
-
3,
|
|
412
|
-
4
|
|
413
|
-
];
|
|
414
|
-
case 3:
|
|
415
|
-
writeFileSpy.mockRestore();
|
|
416
|
-
warnSpy.mockRestore();
|
|
417
|
-
return [
|
|
418
|
-
7
|
|
419
|
-
];
|
|
420
|
-
case 4:
|
|
421
|
-
return [
|
|
422
|
-
2
|
|
423
|
-
];
|
|
424
|
-
}
|
|
425
|
-
});
|
|
426
|
-
})();
|
|
427
|
-
});
|
|
428
|
-
});
|
|
429
|
-
var makeMetaplexFile = function(fileName, buffer) {
|
|
430
|
-
return {
|
|
431
|
-
fileName: fileName,
|
|
432
|
-
buffer: buffer
|
|
433
|
-
};
|
|
434
|
-
};
|
|
435
|
-
var hashBuffer = function(buffer) {
|
|
436
|
-
return createHash("sha256").update(buffer).digest("base64");
|
|
437
|
-
};
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import { getTurboServiceConfig } from "../TurboStorageDriver";
|
|
2
|
-
describe("TurboStorageDriver", function() {
|
|
3
|
-
test("uses the latest Turbo SDK service config shape for devnet", function() {
|
|
4
|
-
expect(getTurboServiceConfig("devnet")).toEqual({
|
|
5
|
-
gatewayUrl: "https://api.devnet.solana.com",
|
|
6
|
-
uploadServiceConfig: {
|
|
7
|
-
url: "https://upload.ardrive.dev"
|
|
8
|
-
},
|
|
9
|
-
paymentServiceConfig: {
|
|
10
|
-
url: "https://payment.ardrive.dev"
|
|
11
|
-
}
|
|
12
|
-
});
|
|
13
|
-
});
|
|
14
|
-
test("relies on the SDK defaults for mainnet service URLs", function() {
|
|
15
|
-
expect(getTurboServiceConfig("mainnet")).toEqual({});
|
|
16
|
-
});
|
|
17
|
-
});
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import { buildPublicContentUrl, normalizePublicContentUrl } from "../contentGateway";
|
|
2
|
-
describe("contentGateway", function() {
|
|
3
|
-
test("builds a mainnet dappstorecontent URL from an upload id", function() {
|
|
4
|
-
expect(buildPublicContentUrl("abc123", "mainnet")).toBe("https://dappstorecontent.com/abc123");
|
|
5
|
-
});
|
|
6
|
-
test("builds a devnet Turbo raw URL from an upload id", function() {
|
|
7
|
-
expect(buildPublicContentUrl("abc123", "devnet")).toBe("https://turbo.ardrive.dev/raw/abc123");
|
|
8
|
-
});
|
|
9
|
-
test("normalizes arweave.net and arweave.com URLs to dappstorecontent", function() {
|
|
10
|
-
expect(normalizePublicContentUrl("https://arweave.net/abc123")).toBe("https://dappstorecontent.com/abc123");
|
|
11
|
-
expect(normalizePublicContentUrl("https://www.arweave.com/abc123?ext=png")).toBe("https://dappstorecontent.com/abc123?ext=png");
|
|
12
|
-
});
|
|
13
|
-
test("leaves non-arweave URLs unchanged", function() {
|
|
14
|
-
expect(normalizePublicContentUrl("https://turbo.ardrive.dev/raw/abc123")).toBe("https://turbo.ardrive.dev/raw/abc123");
|
|
15
|
-
expect(normalizePublicContentUrl("not-a-url")).toBe("not-a-url");
|
|
16
|
-
});
|
|
17
|
-
});
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
var MAINNET_PUBLIC_CONTENT_GATEWAY = "https://dappstorecontent.com";
|
|
2
|
-
var DEVNET_PUBLIC_CONTENT_GATEWAY = "https://turbo.ardrive.dev/raw";
|
|
3
|
-
var LEGACY_MAINNET_CONTENT_HOSTS = new Set([
|
|
4
|
-
"arweave.net",
|
|
5
|
-
"www.arweave.net",
|
|
6
|
-
"arweave.com",
|
|
7
|
-
"www.arweave.com"
|
|
8
|
-
]);
|
|
9
|
-
export var buildPublicContentUrl = function(id, network) {
|
|
10
|
-
var gateway = network === "devnet" ? DEVNET_PUBLIC_CONTENT_GATEWAY : MAINNET_PUBLIC_CONTENT_GATEWAY;
|
|
11
|
-
return "".concat(gateway, "/").concat(id);
|
|
12
|
-
};
|
|
13
|
-
export var normalizePublicContentUrl = function(url) {
|
|
14
|
-
try {
|
|
15
|
-
var parsed = new URL(url);
|
|
16
|
-
if (!LEGACY_MAINNET_CONTENT_HOSTS.has(parsed.host.toLowerCase())) {
|
|
17
|
-
return url;
|
|
18
|
-
}
|
|
19
|
-
return "".concat(MAINNET_PUBLIC_CONTENT_GATEWAY).concat(parsed.pathname).concat(parsed.search).concat(parsed.hash);
|
|
20
|
-
} catch (e) {
|
|
21
|
-
return url;
|
|
22
|
-
}
|
|
23
|
-
};
|
package/lib/upload/index.js
DELETED
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
createAppJson,
|
|
3
|
-
createReleaseJson,
|
|
4
|
-
validateApp,
|
|
5
|
-
validateRelease,
|
|
6
|
-
metaplexFileReplacer,
|
|
7
|
-
} from "@solana-mobile/dapp-store-publishing-tools";
|
|
8
|
-
import { debug, showMessage } from "../CliUtils.js";
|
|
9
|
-
|
|
10
|
-
import type { Keypair } from "@solana/web3.js";
|
|
11
|
-
import type { MetaplexFile } from "@metaplex-foundation/js";
|
|
12
|
-
import { loadPublishDetailsWithChecks } from "../config/PublishDetails.js";
|
|
13
|
-
|
|
14
|
-
export const validateCommand = async ({
|
|
15
|
-
signer,
|
|
16
|
-
buildToolsPath,
|
|
17
|
-
}: {
|
|
18
|
-
signer: Keypair;
|
|
19
|
-
buildToolsPath?: string;
|
|
20
|
-
}) => {
|
|
21
|
-
const {
|
|
22
|
-
publisher: publisherDetails,
|
|
23
|
-
app: appDetails,
|
|
24
|
-
release: releaseDetails,
|
|
25
|
-
} = await loadPublishDetailsWithChecks(buildToolsPath);
|
|
26
|
-
|
|
27
|
-
debug({ publisherDetails, appDetails, releaseDetails });
|
|
28
|
-
|
|
29
|
-
const appJson = createAppJson(appDetails, signer.publicKey);
|
|
30
|
-
if (typeof appJson.image !== "string") {
|
|
31
|
-
appJson.image = (appJson.image as MetaplexFile)?.fileName;
|
|
32
|
-
}
|
|
33
|
-
debug("appJson=", JSON.stringify({ appJson }, metaplexFileReplacer, 2));
|
|
34
|
-
|
|
35
|
-
try {
|
|
36
|
-
validateApp(appJson);
|
|
37
|
-
} catch (e) {
|
|
38
|
-
const errorMsg = (e as Error | null)?.message ?? "";
|
|
39
|
-
showMessage(
|
|
40
|
-
"App JSON invalid",
|
|
41
|
-
errorMsg,
|
|
42
|
-
"error"
|
|
43
|
-
)
|
|
44
|
-
return
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
const releaseJson = await createReleaseJson(
|
|
48
|
-
{ releaseDetails, appDetails, publisherDetails },
|
|
49
|
-
signer.publicKey
|
|
50
|
-
);
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
if (appDetails.android_package != releaseDetails.android_details.android_package) {
|
|
54
|
-
showMessage(
|
|
55
|
-
"App package name and release package name do not match",
|
|
56
|
-
"App release specifies " + appDetails.android_package + " while release specifies " + releaseDetails.android_details.android_package,
|
|
57
|
-
"error"
|
|
58
|
-
)
|
|
59
|
-
return
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
const objStringified = JSON.stringify(releaseJson, metaplexFileReplacer, 2);
|
|
63
|
-
debug("releaseJson=", objStringified);
|
|
64
|
-
|
|
65
|
-
try {
|
|
66
|
-
validateRelease(JSON.parse(objStringified));
|
|
67
|
-
} catch (e) {
|
|
68
|
-
const errorMsg = (e as Error | null)?.message ?? "";
|
|
69
|
-
showMessage(
|
|
70
|
-
"Release JSON invalid",
|
|
71
|
-
errorMsg,
|
|
72
|
-
"error"
|
|
73
|
-
)
|
|
74
|
-
return
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
showMessage(
|
|
78
|
-
"Json is Valid",
|
|
79
|
-
"Input data is valid",
|
|
80
|
-
"standard"
|
|
81
|
-
)
|
|
82
|
-
};
|
|
@@ -1,93 +0,0 @@
|
|
|
1
|
-
import type { App } from "@solana-mobile/dapp-store-publishing-tools";
|
|
2
|
-
import { createApp } from "@solana-mobile/dapp-store-publishing-tools";
|
|
3
|
-
import {
|
|
4
|
-
Connection,
|
|
5
|
-
Keypair,
|
|
6
|
-
} from "@solana/web3.js";
|
|
7
|
-
|
|
8
|
-
import {
|
|
9
|
-
Constants,
|
|
10
|
-
getMetaplexInstance,
|
|
11
|
-
} from "../../CliUtils.js";
|
|
12
|
-
import { loadPublishDetailsWithChecks, writeToPublishDetails } from "../../config/PublishDetails.js";
|
|
13
|
-
import { sendAndConfirmTransaction } from "../utils.js";
|
|
14
|
-
|
|
15
|
-
const createAppNft = async (
|
|
16
|
-
{
|
|
17
|
-
appDetails,
|
|
18
|
-
connection,
|
|
19
|
-
publisher,
|
|
20
|
-
storageParams,
|
|
21
|
-
priorityFeeLamports,
|
|
22
|
-
}: {
|
|
23
|
-
appDetails: App;
|
|
24
|
-
connection: Connection;
|
|
25
|
-
publisher: Keypair;
|
|
26
|
-
storageParams: string;
|
|
27
|
-
priorityFeeLamports: number;
|
|
28
|
-
},
|
|
29
|
-
) => {
|
|
30
|
-
console.info(`Creating App NFT`);
|
|
31
|
-
|
|
32
|
-
const mintAddress = Keypair.generate();
|
|
33
|
-
const metaplex = getMetaplexInstance(connection, publisher, storageParams);
|
|
34
|
-
const txBuilder = await createApp(
|
|
35
|
-
{
|
|
36
|
-
mintAddress,
|
|
37
|
-
appDetails,
|
|
38
|
-
priorityFeeLamports
|
|
39
|
-
},
|
|
40
|
-
{ metaplex, publisher }
|
|
41
|
-
);
|
|
42
|
-
|
|
43
|
-
console.info(`App NFT data upload complete\nSigning transaction now`);
|
|
44
|
-
|
|
45
|
-
const { response } = await sendAndConfirmTransaction(metaplex, txBuilder);
|
|
46
|
-
|
|
47
|
-
return {
|
|
48
|
-
appAddress: mintAddress.publicKey.toBase58(),
|
|
49
|
-
transactionSignature: response.signature,
|
|
50
|
-
};
|
|
51
|
-
};
|
|
52
|
-
|
|
53
|
-
type CreateAppCommandInput = {
|
|
54
|
-
signer: Keypair;
|
|
55
|
-
url: string;
|
|
56
|
-
dryRun?: boolean;
|
|
57
|
-
storageParams: string;
|
|
58
|
-
priorityFeeLamports: number;
|
|
59
|
-
};
|
|
60
|
-
|
|
61
|
-
export const createAppCommand = async ({
|
|
62
|
-
signer,
|
|
63
|
-
url,
|
|
64
|
-
dryRun,
|
|
65
|
-
storageParams,
|
|
66
|
-
priorityFeeLamports = Constants.DEFAULT_PRIORITY_FEE,
|
|
67
|
-
}: CreateAppCommandInput) => {
|
|
68
|
-
const connection = new Connection(
|
|
69
|
-
url,
|
|
70
|
-
{
|
|
71
|
-
commitment: "confirmed",
|
|
72
|
-
}
|
|
73
|
-
);
|
|
74
|
-
|
|
75
|
-
const { app: appDetails } =
|
|
76
|
-
await loadPublishDetailsWithChecks();
|
|
77
|
-
|
|
78
|
-
if (!dryRun) {
|
|
79
|
-
const { appAddress, transactionSignature } = await createAppNft(
|
|
80
|
-
{
|
|
81
|
-
connection,
|
|
82
|
-
publisher: signer,
|
|
83
|
-
appDetails,
|
|
84
|
-
storageParams,
|
|
85
|
-
priorityFeeLamports
|
|
86
|
-
},
|
|
87
|
-
);
|
|
88
|
-
|
|
89
|
-
await writeToPublishDetails({ app: { address: appAddress } });
|
|
90
|
-
|
|
91
|
-
return { appAddress, transactionSignature };
|
|
92
|
-
}
|
|
93
|
-
};
|