dewctl 0.5.0 → 0.5.2
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/package.json +1 -1
- package/src/client.js +1 -0
- package/src/main.js +22 -10
- package/src/project.js +1 -1
package/package.json
CHANGED
package/src/client.js
CHANGED
|
@@ -47,6 +47,7 @@ export class Client {
|
|
|
47
47
|
async api(path,options={}){return this.request(path,{...options,token:this.session().token});}
|
|
48
48
|
game(game,signal){return this.api(`/v1/games/${game}`,{signal});}
|
|
49
49
|
releases(game){return this.api(`/v1/games/${game}/releases`);}
|
|
50
|
+
deleteRelease(game,release){return this.api(`/v1/games/${game}/releases/${release}`,{method:'DELETE'});}
|
|
50
51
|
// Makes the game this developer's if it is new, and confirms it is theirs if not: asked before anything is built, so
|
|
51
52
|
// a name someone else has, or a sign-in that has ended, is known at once.
|
|
52
53
|
async claim(game,signal) {
|
package/src/main.js
CHANGED
|
@@ -18,22 +18,25 @@ const HELP=`${RUN} — make three.js games on Dewdrop
|
|
|
18
18
|
login Sign in: prints a link to open in your browser and approve
|
|
19
19
|
logout Sign this computer out
|
|
20
20
|
dev [--watch] [--release ID] Build, upload and play the dev version; --watch repeats this on every
|
|
21
|
-
save, --release plays
|
|
22
|
-
stop Stop the dev version and disconnect its players
|
|
21
|
+
save, --release plays a kept upload without building
|
|
22
|
+
stop Stop the dev version and disconnect its players
|
|
23
23
|
publish [--release ID] Publish the dev version, or an earlier upload, for players; uploads
|
|
24
24
|
the thumbnail dewdrop.json names when it has changed
|
|
25
25
|
unpublish Take the game down for players
|
|
26
26
|
share EMAIL Let another developer play and update the dev version
|
|
27
27
|
unshare EMAIL Take that back
|
|
28
28
|
status Show the dev and published versions and where to play them
|
|
29
|
-
releases List
|
|
29
|
+
releases List the uploads Dewdrop keeps: every published version, the dev version
|
|
30
|
+
and each member's latest upload; any id, or its first 8 characters,
|
|
31
|
+
feeds --release and delete
|
|
32
|
+
delete ID Delete a published version nothing runs, freeing its space (owner only)
|
|
30
33
|
--version Show this CLI's version
|
|
31
34
|
|
|
32
35
|
Run the commands in your game's folder: they read the game from its dewdrop.json.
|
|
33
36
|
Docs: ${DEWDROP}/docs
|
|
34
37
|
`;
|
|
35
|
-
// Each command's flags; share and unshare also take one address. Anything else on the line is refused.
|
|
36
|
-
const COMMANDS={init:['--game'],login:[],logout:[],dev:['--watch','--release'],stop:[],publish:['--release'],unpublish:[],share:[],unshare:[],status:[],releases:[]};
|
|
38
|
+
// Each command's flags; share and unshare also take one address, and delete one release. Anything else on the line is refused.
|
|
39
|
+
const COMMANDS={init:['--game'],login:[],logout:[],dev:['--watch','--release'],stop:[],publish:['--release'],unpublish:[],share:[],unshare:[],status:[],releases:[],delete:[]};
|
|
37
40
|
const VALUED=['--game','--release'];
|
|
38
41
|
function options(command,args) {
|
|
39
42
|
const out={};
|
|
@@ -44,9 +47,10 @@ function options(command,args) {
|
|
|
44
47
|
else if(!args[i+1]||args[i+1].startsWith('--'))throw new Error(`${key} needs a value.`);
|
|
45
48
|
else out[key.slice(2)]=args[++i];
|
|
46
49
|
} else if(['share','unshare'].includes(command)&&!key.startsWith('-')&&out.email===undefined)out.email=key;
|
|
50
|
+
else if(command==='delete'&&!key.startsWith('-')&&out.release===undefined)out.release=key;
|
|
47
51
|
else throw new Error(`${command} doesn't take ${key}. Run ${RUN} --help to see what it takes.`);
|
|
48
52
|
}
|
|
49
|
-
if(out.release!==undefined&&!/^[a-f0-9]{8,64}$/.test(out.release))throw new Error(
|
|
53
|
+
if(out.release!==undefined&&!/^[a-f0-9]{8,64}$/.test(out.release))throw new Error(`${command==='delete'?'delete':'--release'} takes a release id, or its first 8 or more characters, from ${RUN} releases.`);
|
|
50
54
|
if(out.watch&&out.release)throw new Error('Choose --watch or --release, not both.');
|
|
51
55
|
return out;
|
|
52
56
|
}
|
|
@@ -135,11 +139,19 @@ async function main() {
|
|
|
135
139
|
return;
|
|
136
140
|
}
|
|
137
141
|
if(command==='releases'){
|
|
138
|
-
const {releases}=await client.releases(game);
|
|
142
|
+
const [{releases},state]=await Promise.all([client.releases(game),client.game(game)]);
|
|
139
143
|
if(!releases.length){console.log(`No uploads of ${game} yet. Run ${RUN} dev to make one.`);return;}
|
|
140
|
-
|
|
144
|
+
// What each release is to the game, the reason Dewdrop keeps it.
|
|
145
|
+
const status=release=>[release.sha256===state.dev.release&&'dev',release.sha256===state.live.release&&'published'].filter(Boolean).join(', ')||(release.published?'published before':'latest upload');
|
|
146
|
+
console.log(columns([['RELEASE','UPLOADED (UTC)','SIZE','STATUS','BY'],...releases.map(release=>[release.sha256.slice(0,12),new Date(release.created).toISOString().slice(0,16).replace('T',' '),size(release.bytes),status(release),release.email])]));
|
|
141
147
|
return;
|
|
142
148
|
}
|
|
149
|
+
if(command==='delete'){
|
|
150
|
+
if(!flags.release)throw new Error(`delete needs a release id from ${RUN} releases.`);
|
|
151
|
+
const release=await releaseId(client,game,flags.release);
|
|
152
|
+
await client.deleteRelease(game,release);
|
|
153
|
+
console.log(`Deleted ${release.slice(0,12)} from ${game}.`);return;
|
|
154
|
+
}
|
|
143
155
|
if(['share','unshare'].includes(command)) {
|
|
144
156
|
if(!flags.email)throw new Error(`${command} needs the developer's email address.`);
|
|
145
157
|
await client.member(game,flags.email,command==='share');
|
|
@@ -148,13 +160,13 @@ async function main() {
|
|
|
148
160
|
}
|
|
149
161
|
if(command==='stop'){
|
|
150
162
|
await client.stop(game,signal);
|
|
151
|
-
console.log(`Stopped ${game}'s dev version.
|
|
163
|
+
console.log(`Stopped ${game}'s dev version. Run ${RUN} dev to start it again.`);return;
|
|
152
164
|
}
|
|
153
165
|
if(command==='unpublish'){await client.publish(game,null,signal);console.log(`Unpublished ${game}. Players can no longer open it.`);return;}
|
|
154
166
|
if(command==='publish') {
|
|
155
167
|
const current=await client.game(game,signal);
|
|
156
168
|
const release=flags.release?await releaseId(client,game,flags.release):current.dev.release;
|
|
157
|
-
if(!release)throw new Error(`${game} has no dev version to publish. Run ${RUN} dev first, or publish
|
|
169
|
+
if(!release)throw new Error(`${game} has no dev version to publish. Run ${RUN} dev first, or publish a kept upload with --release (see ${RUN} releases).`);
|
|
158
170
|
// The thumbnail goes first, so an image Dewdrop refuses stops the publish before anything changes for players.
|
|
159
171
|
if(project.thumbnail&&await syncThumbnail(project,client,current,signal))console.log(`Uploaded the thumbnail, ${project.thumbnail}.`);
|
|
160
172
|
const state=await client.publish(game,release,signal);
|
package/src/project.js
CHANGED
|
@@ -158,7 +158,7 @@ export async function build(project, signal) {
|
|
|
158
158
|
// dewdrop.json alone, so nothing of it is touched and no starter is left half written.
|
|
159
159
|
const STARTER_FILES=['package.json','src','index.html','vite.config.js'];
|
|
160
160
|
// The SDK a new game depends on, and this CLI, at its own version.
|
|
161
|
-
const SDK_RANGE='^0.
|
|
161
|
+
const SDK_RANGE='^0.4.0';
|
|
162
162
|
const CLI_RANGE=`^${JSON.parse(readFileSync(new URL('../package.json',import.meta.url),'utf8')).version}`;
|
|
163
163
|
// A game name from the project directory, or a random one when the directory name yields nothing usable.
|
|
164
164
|
function gameNameFrom(root) {
|