@playdrop/playdrop-cli 0.5.2 → 0.5.4
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/config/client-meta.json +4 -4
- package/dist/apps/build.js +49 -6
- package/dist/apps/index.d.ts +2 -0
- package/dist/apps/index.js +2 -0
- package/dist/apps/upload.d.ts +2 -0
- package/dist/apps/upload.js +126 -28
- package/dist/assetSpecs.d.ts +16 -0
- package/dist/assetSpecs.js +263 -0
- package/dist/assets/model-artifacts.js +3 -0
- package/dist/catalogue.d.ts +57 -3
- package/dist/catalogue.js +342 -16
- package/dist/commandContext.d.ts +6 -2
- package/dist/commandContext.js +144 -20
- package/dist/commands/accounts.d.ts +2 -0
- package/dist/commands/accounts.js +48 -0
- package/dist/commands/ads.d.ts +8 -0
- package/dist/commands/ads.js +124 -0
- package/dist/commands/boosts.d.ts +25 -0
- package/dist/commands/boosts.js +209 -0
- package/dist/commands/browse.d.ts +6 -1
- package/dist/commands/browse.js +365 -124
- package/dist/commands/capture.js +30 -9
- package/dist/commands/captureListing.d.ts +53 -0
- package/dist/commands/captureListing.js +815 -0
- package/dist/commands/create.d.ts +1 -0
- package/dist/commands/create.js +183 -3
- package/dist/commands/credits.d.ts +6 -0
- package/dist/commands/credits.js +47 -1
- package/dist/commands/detail.js +38 -4
- package/dist/commands/dev.js +169 -192
- package/dist/commands/devServer.d.ts +26 -3
- package/dist/commands/devServer.js +415 -72
- package/dist/commands/login.js +10 -2
- package/dist/commands/logout.d.ts +6 -1
- package/dist/commands/logout.js +25 -3
- package/dist/commands/search.d.ts +5 -0
- package/dist/commands/search.js +139 -17
- package/dist/commands/tags.d.ts +7 -0
- package/dist/commands/tags.js +63 -0
- package/dist/commands/upload-content.d.ts +13 -3
- package/dist/commands/upload-content.js +86 -20
- package/dist/commands/upload.d.ts +2 -0
- package/dist/commands/upload.js +187 -11
- package/dist/commands/validate.js +163 -2
- package/dist/commands/versionsBrowse.js +128 -91
- package/dist/commands/whoami.js +10 -2
- package/dist/config.d.ts +37 -0
- package/dist/config.js +205 -3
- package/dist/index.js +177 -5
- package/dist/refs.d.ts +2 -2
- package/dist/refs.js +13 -1
- package/dist/taskSelection.js +6 -3
- package/dist/taskUtils.d.ts +2 -2
- package/dist/taskUtils.js +1 -0
- package/dist/uploadLog.d.ts +1 -1
- package/dist/uploadLog.js +2 -2
- package/dist/workspaceAuth.d.ts +14 -0
- package/dist/workspaceAuth.js +75 -0
- package/node_modules/@playdrop/ai-client/package.json +1 -1
- package/node_modules/@playdrop/api-client/dist/client.d.ts +139 -10
- package/node_modules/@playdrop/api-client/dist/client.d.ts.map +1 -1
- package/node_modules/@playdrop/api-client/dist/client.js +6 -0
- package/node_modules/@playdrop/api-client/dist/domains/admin.d.ts +9 -1
- package/node_modules/@playdrop/api-client/dist/domains/admin.d.ts.map +1 -1
- package/node_modules/@playdrop/api-client/dist/domains/admin.js +45 -0
- package/node_modules/@playdrop/api-client/dist/domains/apps.d.ts +7 -1
- package/node_modules/@playdrop/api-client/dist/domains/apps.d.ts.map +1 -1
- package/node_modules/@playdrop/api-client/dist/domains/apps.js +58 -0
- package/node_modules/@playdrop/api-client/dist/domains/asset-packs.d.ts +2 -0
- package/node_modules/@playdrop/api-client/dist/domains/asset-packs.d.ts.map +1 -1
- package/node_modules/@playdrop/api-client/dist/domains/asset-packs.js +16 -0
- package/node_modules/@playdrop/api-client/dist/domains/assets.d.ts +44 -2
- package/node_modules/@playdrop/api-client/dist/domains/assets.d.ts.map +1 -1
- package/node_modules/@playdrop/api-client/dist/domains/assets.js +260 -3
- package/node_modules/@playdrop/api-client/dist/domains/payments.d.ts +22 -1
- package/node_modules/@playdrop/api-client/dist/domains/payments.d.ts.map +1 -1
- package/node_modules/@playdrop/api-client/dist/domains/payments.js +228 -0
- package/node_modules/@playdrop/api-client/dist/domains/search.d.ts.map +1 -1
- package/node_modules/@playdrop/api-client/dist/domains/search.js +39 -11
- package/node_modules/@playdrop/api-client/dist/domains/tags.d.ts +34 -0
- package/node_modules/@playdrop/api-client/dist/domains/tags.d.ts.map +1 -0
- package/node_modules/@playdrop/api-client/dist/domains/tags.js +111 -0
- package/node_modules/@playdrop/api-client/dist/index.d.ts +69 -1
- package/node_modules/@playdrop/api-client/dist/index.d.ts.map +1 -1
- package/node_modules/@playdrop/api-client/dist/index.js +74 -0
- package/node_modules/@playdrop/api-client/package.json +1 -1
- package/node_modules/@playdrop/boxel-core/package.json +1 -1
- package/node_modules/@playdrop/boxel-three/package.json +1 -1
- package/node_modules/@playdrop/config/client-meta.json +4 -4
- package/node_modules/@playdrop/config/dist/src/constants.d.ts +11 -0
- package/node_modules/@playdrop/config/dist/src/constants.d.ts.map +1 -1
- package/node_modules/@playdrop/config/dist/src/constants.js +12 -1
- package/node_modules/@playdrop/config/dist/tsconfig.tsbuildinfo +1 -1
- package/node_modules/@playdrop/config/package.json +1 -1
- package/node_modules/@playdrop/types/dist/api.d.ts +366 -6
- package/node_modules/@playdrop/types/dist/api.d.ts.map +1 -1
- package/node_modules/@playdrop/types/dist/api.js +52 -1
- package/node_modules/@playdrop/types/dist/asset-pack.d.ts +7 -1
- package/node_modules/@playdrop/types/dist/asset-pack.d.ts.map +1 -1
- package/node_modules/@playdrop/types/dist/asset-spec-contract-meta-schema.json +86 -0
- package/node_modules/@playdrop/types/dist/asset-spec.d.ts +163 -0
- package/node_modules/@playdrop/types/dist/asset-spec.d.ts.map +1 -0
- package/node_modules/@playdrop/types/dist/asset-spec.js +101 -0
- package/node_modules/@playdrop/types/dist/asset.d.ts +23 -6
- package/node_modules/@playdrop/types/dist/asset.d.ts.map +1 -1
- package/node_modules/@playdrop/types/dist/asset.js +4 -1
- package/node_modules/@playdrop/types/dist/graph.d.ts +4 -2
- package/node_modules/@playdrop/types/dist/graph.d.ts.map +1 -1
- package/node_modules/@playdrop/types/dist/graph.js +9 -2
- package/node_modules/@playdrop/types/dist/index.d.ts +1 -0
- package/node_modules/@playdrop/types/dist/index.d.ts.map +1 -1
- package/node_modules/@playdrop/types/dist/index.js +1 -0
- package/node_modules/@playdrop/types/dist/version.d.ts +13 -0
- package/node_modules/@playdrop/types/dist/version.d.ts.map +1 -1
- package/node_modules/@playdrop/types/dist/version.js +21 -0
- package/node_modules/@playdrop/types/package.json +6 -1
- package/node_modules/@playdrop/vox-three/package.json +1 -1
- package/package.json +3 -1
|
@@ -57,18 +57,144 @@ function printEntry(entry) {
|
|
|
57
57
|
}
|
|
58
58
|
return;
|
|
59
59
|
}
|
|
60
|
+
if (entry.kind === 'asset-spec') {
|
|
61
|
+
const currentLabel = entry.isCurrent ? ' | current' : '';
|
|
62
|
+
console.log(`${entry.version} | ${entry.visibility.toLowerCase()} | ${entry.status.toLowerCase()}${currentLabel} | ${(0, output_1.formatTimestamp)(entry.createdAt)}`);
|
|
63
|
+
console.log(` Documentation URL: ${(0, output_1.formatOptionalValue)(entry.documentationUrl)}`);
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
60
66
|
const currentLabel = entry.isCurrent ? ' | current' : '';
|
|
61
67
|
console.log(`${entry.version} | ${entry.visibility.toLowerCase()}${currentLabel} | ${(0, output_1.formatTimestamp)(entry.createdAt)}`);
|
|
62
68
|
console.log(` Download URL: ${(0, output_1.formatOptionalValue)(entry.urls.download)}`);
|
|
63
69
|
console.log(` Source URL: ${entry.urls.source}`);
|
|
64
70
|
}
|
|
71
|
+
async function loadVersionEntries(input) {
|
|
72
|
+
const { client, envConfig, ref, limit, offset } = input;
|
|
73
|
+
if (ref.kind === 'app') {
|
|
74
|
+
const [appDetail, response] = await Promise.all([
|
|
75
|
+
client.fetchAppBySlug(ref.creator, ref.name),
|
|
76
|
+
client.listAppVersions(ref.creator, ref.name),
|
|
77
|
+
]);
|
|
78
|
+
const listed = response.versions ?? [];
|
|
79
|
+
const selected = listed.slice(offset, offset + limit);
|
|
80
|
+
const entries = await Promise.all(selected.map(async (version) => {
|
|
81
|
+
const detail = await client.getAppVersion(ref.creator, ref.name, version.version);
|
|
82
|
+
return {
|
|
83
|
+
kind: 'app',
|
|
84
|
+
version: version.version,
|
|
85
|
+
visibility: version.visibility,
|
|
86
|
+
createdAt: version.createdAt,
|
|
87
|
+
updatedAt: detail.version.updatedAt,
|
|
88
|
+
releaseNotes: version.releaseNotes ?? null,
|
|
89
|
+
isCurrent: Boolean(version.isCurrent),
|
|
90
|
+
urls: {
|
|
91
|
+
play: (0, appUrls_1.buildPlatformPlayUrl)(envConfig.webBase, {
|
|
92
|
+
creatorUsername: ref.creator,
|
|
93
|
+
appName: ref.name,
|
|
94
|
+
appType: appDetail.app.type,
|
|
95
|
+
}),
|
|
96
|
+
source: typeof detail.version.sourceUrl === 'string' ? detail.version.sourceUrl : null,
|
|
97
|
+
},
|
|
98
|
+
};
|
|
99
|
+
}));
|
|
100
|
+
return {
|
|
101
|
+
entries,
|
|
102
|
+
pagination: {
|
|
103
|
+
limit,
|
|
104
|
+
offset,
|
|
105
|
+
count: entries.length,
|
|
106
|
+
hasMore: listed.length > offset + limit,
|
|
107
|
+
},
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
if (ref.kind === 'asset') {
|
|
111
|
+
const [detail, response] = await Promise.all([
|
|
112
|
+
client.fetchAssetBySlug(ref.creator, ref.name),
|
|
113
|
+
client.listAssetVersions(ref.creator, ref.name, { limit, offset }),
|
|
114
|
+
]);
|
|
115
|
+
const currentRevision = detail.asset.currentVersion?.revision ?? null;
|
|
116
|
+
return {
|
|
117
|
+
entries: (response.versions ?? []).map((version) => ({
|
|
118
|
+
kind: 'asset',
|
|
119
|
+
revision: version.revision,
|
|
120
|
+
revisionLabel: version.revisionLabel,
|
|
121
|
+
visibility: version.visibility,
|
|
122
|
+
createdAt: version.createdAt,
|
|
123
|
+
updatedAt: version.updatedAt,
|
|
124
|
+
subcategory: version.subcategory,
|
|
125
|
+
format: version.format,
|
|
126
|
+
isCurrent: currentRevision === version.revision,
|
|
127
|
+
urls: {
|
|
128
|
+
source: buildAssetSourceUrl(envConfig.apiBase, ref, version.revision),
|
|
129
|
+
files: assetFileUrls(version),
|
|
130
|
+
},
|
|
131
|
+
})),
|
|
132
|
+
pagination: response.pagination ?? {
|
|
133
|
+
limit,
|
|
134
|
+
offset,
|
|
135
|
+
count: (response.versions ?? []).length,
|
|
136
|
+
hasMore: false,
|
|
137
|
+
},
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
if (ref.kind === 'asset-pack') {
|
|
141
|
+
const [detail, response] = await Promise.all([
|
|
142
|
+
client.fetchAssetPackBySlug(ref.creator, ref.name),
|
|
143
|
+
client.listAssetPackVersions(ref.creator, ref.name, { limit, offset }),
|
|
144
|
+
]);
|
|
145
|
+
const currentVersion = detail.pack.currentVersion?.version ?? null;
|
|
146
|
+
return {
|
|
147
|
+
entries: (response.versions ?? []).map((version) => ({
|
|
148
|
+
kind: 'asset-pack',
|
|
149
|
+
version: version.version,
|
|
150
|
+
visibility: version.visibility,
|
|
151
|
+
createdAt: version.createdAt,
|
|
152
|
+
updatedAt: version.updatedAt,
|
|
153
|
+
isCurrent: currentVersion === version.version,
|
|
154
|
+
urls: {
|
|
155
|
+
download: buildAssetPackDownloadUrl(envConfig.apiBase, ref, version.version),
|
|
156
|
+
source: buildAssetPackSourceUrl(envConfig.apiBase, ref, version.version),
|
|
157
|
+
},
|
|
158
|
+
})),
|
|
159
|
+
pagination: response.pagination ?? {
|
|
160
|
+
limit,
|
|
161
|
+
offset,
|
|
162
|
+
count: (response.versions ?? []).length,
|
|
163
|
+
hasMore: false,
|
|
164
|
+
},
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
const [detail, response] = await Promise.all([
|
|
168
|
+
client.fetchAssetSpecBySlug(ref.creator, ref.name),
|
|
169
|
+
client.listAssetSpecVersions(ref.creator, ref.name, { limit, offset }),
|
|
170
|
+
]);
|
|
171
|
+
const currentVersion = detail.assetSpec.currentVersion?.version ?? null;
|
|
172
|
+
return {
|
|
173
|
+
entries: (response.versions ?? []).map((version) => ({
|
|
174
|
+
kind: 'asset-spec',
|
|
175
|
+
version: version.version,
|
|
176
|
+
visibility: version.visibility,
|
|
177
|
+
status: version.status,
|
|
178
|
+
createdAt: version.createdAt,
|
|
179
|
+
updatedAt: version.updatedAt,
|
|
180
|
+
isCurrent: currentVersion === version.version,
|
|
181
|
+
documentationUrl: version.documentationUrl ?? null,
|
|
182
|
+
})),
|
|
183
|
+
pagination: response.pagination ?? {
|
|
184
|
+
limit,
|
|
185
|
+
offset,
|
|
186
|
+
count: (response.versions ?? []).length,
|
|
187
|
+
hasMore: false,
|
|
188
|
+
},
|
|
189
|
+
};
|
|
190
|
+
}
|
|
65
191
|
async function browseVersions(rawRef, options = {}) {
|
|
66
192
|
let ref;
|
|
67
193
|
try {
|
|
68
194
|
ref = (0, refs_1.parseContentRef)(rawRef ?? '');
|
|
69
195
|
}
|
|
70
196
|
catch {
|
|
71
|
-
(0, messages_1.printErrorWithHelp)('A canonical ref is required.', ['Use the format <creator>/<kind>/<name>.', 'Example: playdrop versions browse playdrop/app/hangingout'], { command: 'versions browse' });
|
|
197
|
+
(0, messages_1.printErrorWithHelp)('A canonical ref is required.', ['Use the format <creator>/<kind>/<name>.', 'Example: playdrop versions browse playdrop/app/hangingout', 'Example: playdrop versions browse playdrop/asset-spec/platformer-level'], { command: 'versions browse' });
|
|
72
198
|
process.exitCode = 1;
|
|
73
199
|
return;
|
|
74
200
|
}
|
|
@@ -86,96 +212,7 @@ async function browseVersions(rawRef, options = {}) {
|
|
|
86
212
|
}
|
|
87
213
|
await (0, commandContext_1.withPublicEnvironment)('versions browse', async ({ client, envConfig }) => {
|
|
88
214
|
try {
|
|
89
|
-
|
|
90
|
-
let pagination;
|
|
91
|
-
if (ref.kind === 'app') {
|
|
92
|
-
const [appDetail, response] = await Promise.all([
|
|
93
|
-
client.fetchAppBySlug(ref.creator, ref.name),
|
|
94
|
-
client.listAppVersions(ref.creator, ref.name),
|
|
95
|
-
]);
|
|
96
|
-
const listed = response.versions ?? [];
|
|
97
|
-
const selected = listed.slice(offset, offset + limit);
|
|
98
|
-
const details = await Promise.all(selected.map(async (version) => {
|
|
99
|
-
const detail = await client.getAppVersion(ref.creator, ref.name, version.version);
|
|
100
|
-
return {
|
|
101
|
-
kind: 'app',
|
|
102
|
-
version: version.version,
|
|
103
|
-
visibility: version.visibility,
|
|
104
|
-
createdAt: version.createdAt,
|
|
105
|
-
updatedAt: detail.version.updatedAt,
|
|
106
|
-
releaseNotes: version.releaseNotes ?? null,
|
|
107
|
-
isCurrent: Boolean(version.isCurrent),
|
|
108
|
-
urls: {
|
|
109
|
-
play: (0, appUrls_1.buildPlatformPlayUrl)(envConfig.webBase, {
|
|
110
|
-
creatorUsername: ref.creator,
|
|
111
|
-
appName: ref.name,
|
|
112
|
-
appType: appDetail.app.type,
|
|
113
|
-
}),
|
|
114
|
-
source: typeof detail.version.sourceUrl === 'string' ? detail.version.sourceUrl : null,
|
|
115
|
-
},
|
|
116
|
-
};
|
|
117
|
-
}));
|
|
118
|
-
entries = details;
|
|
119
|
-
pagination = {
|
|
120
|
-
limit,
|
|
121
|
-
offset,
|
|
122
|
-
count: entries.length,
|
|
123
|
-
hasMore: listed.length > offset + limit,
|
|
124
|
-
};
|
|
125
|
-
}
|
|
126
|
-
else if (ref.kind === 'asset') {
|
|
127
|
-
const [detail, response] = await Promise.all([
|
|
128
|
-
client.fetchAssetBySlug(ref.creator, ref.name),
|
|
129
|
-
client.listAssetVersions(ref.creator, ref.name, { limit, offset }),
|
|
130
|
-
]);
|
|
131
|
-
const currentRevision = detail.asset.currentVersion?.revision ?? null;
|
|
132
|
-
entries = (response.versions ?? []).map((version) => ({
|
|
133
|
-
kind: 'asset',
|
|
134
|
-
revision: version.revision,
|
|
135
|
-
revisionLabel: version.revisionLabel,
|
|
136
|
-
visibility: version.visibility,
|
|
137
|
-
createdAt: version.createdAt,
|
|
138
|
-
updatedAt: version.updatedAt,
|
|
139
|
-
subcategory: version.subcategory,
|
|
140
|
-
format: version.format,
|
|
141
|
-
isCurrent: currentRevision === version.revision,
|
|
142
|
-
urls: {
|
|
143
|
-
source: buildAssetSourceUrl(envConfig.apiBase, ref, version.revision),
|
|
144
|
-
files: assetFileUrls(version),
|
|
145
|
-
},
|
|
146
|
-
}));
|
|
147
|
-
pagination = response.pagination ?? {
|
|
148
|
-
limit,
|
|
149
|
-
offset,
|
|
150
|
-
count: entries.length,
|
|
151
|
-
hasMore: false,
|
|
152
|
-
};
|
|
153
|
-
}
|
|
154
|
-
else {
|
|
155
|
-
const [detail, response] = await Promise.all([
|
|
156
|
-
client.fetchAssetPackBySlug(ref.creator, ref.name),
|
|
157
|
-
client.listAssetPackVersions(ref.creator, ref.name, { limit, offset }),
|
|
158
|
-
]);
|
|
159
|
-
const currentVersion = detail.pack.currentVersion?.version ?? null;
|
|
160
|
-
entries = (response.versions ?? []).map((version) => ({
|
|
161
|
-
kind: 'asset-pack',
|
|
162
|
-
version: version.version,
|
|
163
|
-
visibility: version.visibility,
|
|
164
|
-
createdAt: version.createdAt,
|
|
165
|
-
updatedAt: version.updatedAt,
|
|
166
|
-
isCurrent: currentVersion === version.version,
|
|
167
|
-
urls: {
|
|
168
|
-
download: buildAssetPackDownloadUrl(envConfig.apiBase, ref, version.version),
|
|
169
|
-
source: buildAssetPackSourceUrl(envConfig.apiBase, ref, version.version),
|
|
170
|
-
},
|
|
171
|
-
}));
|
|
172
|
-
pagination = response.pagination ?? {
|
|
173
|
-
limit,
|
|
174
|
-
offset,
|
|
175
|
-
count: entries.length,
|
|
176
|
-
hasMore: false,
|
|
177
|
-
};
|
|
178
|
-
}
|
|
215
|
+
const { entries, pagination } = await loadVersionEntries({ client, envConfig, ref, limit, offset });
|
|
179
216
|
if (options.json) {
|
|
180
217
|
(0, output_1.printJson)({ kind: ref.kind, ref: ref.ref, entries, pagination });
|
|
181
218
|
return;
|
package/dist/commands/whoami.js
CHANGED
|
@@ -9,6 +9,7 @@ const environment_1 = require("../environment");
|
|
|
9
9
|
const messages_1 = require("../messages");
|
|
10
10
|
async function whoami() {
|
|
11
11
|
const cfg = (0, config_1.loadConfig)();
|
|
12
|
+
const currentAccount = (0, config_1.getCurrentAccountSession)(cfg);
|
|
12
13
|
if (!cfg.token || !cfg.env) {
|
|
13
14
|
(0, messages_1.printLoginRequired)('Checking your Playdrop account status', 'whoami');
|
|
14
15
|
process.exitCode = 1;
|
|
@@ -59,7 +60,7 @@ async function whoami() {
|
|
|
59
60
|
}
|
|
60
61
|
if (!data)
|
|
61
62
|
return;
|
|
62
|
-
const username = data.user?.username;
|
|
63
|
+
const username = data.user?.username?.trim();
|
|
63
64
|
if (!username) {
|
|
64
65
|
(0, messages_1.printErrorWithHelp)('The Playdrop API returned an unexpected response.', [
|
|
65
66
|
'Retry "playdrop auth whoami" in a moment.',
|
|
@@ -68,6 +69,13 @@ async function whoami() {
|
|
|
68
69
|
process.exitCode = 1;
|
|
69
70
|
return;
|
|
70
71
|
}
|
|
71
|
-
|
|
72
|
+
if (!currentAccount) {
|
|
73
|
+
(0, config_1.migrateLegacySession)({
|
|
74
|
+
username,
|
|
75
|
+
env: envConfig.name,
|
|
76
|
+
token: cfg.token,
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
console.log(`${username} (${envConfig.name})`);
|
|
72
80
|
console.log('Next: run "playdrop getting-started" to see the recommended workflow.');
|
|
73
81
|
}
|
package/dist/config.d.ts
CHANGED
|
@@ -1,6 +1,20 @@
|
|
|
1
|
+
export interface CliAccountRef {
|
|
2
|
+
username: string;
|
|
3
|
+
env: string;
|
|
4
|
+
}
|
|
5
|
+
export interface CliStoredSession {
|
|
6
|
+
token: string;
|
|
7
|
+
updatedAt: string;
|
|
8
|
+
}
|
|
9
|
+
export interface CliAccountSession extends CliAccountRef, CliStoredSession {
|
|
10
|
+
}
|
|
1
11
|
export interface CliConfig {
|
|
12
|
+
version?: number;
|
|
13
|
+
currentAccount?: CliAccountRef | null;
|
|
14
|
+
accounts?: Record<string, Record<string, CliStoredSession>>;
|
|
2
15
|
token?: string;
|
|
3
16
|
env?: string;
|
|
17
|
+
currentUsername?: string;
|
|
4
18
|
}
|
|
5
19
|
export declare function loadConfig(): CliConfig;
|
|
6
20
|
export declare function saveConfig(cfg: CliConfig): void;
|
|
@@ -8,3 +22,26 @@ export declare function clearConfig(): void;
|
|
|
8
22
|
export declare function getConfig(): {
|
|
9
23
|
path: string;
|
|
10
24
|
};
|
|
25
|
+
export declare function listAccountSessions(cfg?: CliConfig): CliAccountSession[];
|
|
26
|
+
export declare function getCurrentAccountSession(cfg?: CliConfig): CliAccountSession | null;
|
|
27
|
+
export declare function findAccountSession(username: string, env?: string, cfg?: CliConfig): CliAccountSession | null;
|
|
28
|
+
export declare function listAccountSessionsForUsername(username: string, cfg?: CliConfig): CliAccountSession[];
|
|
29
|
+
export declare function saveAccountSession(input: {
|
|
30
|
+
username: string;
|
|
31
|
+
env: string;
|
|
32
|
+
token: string;
|
|
33
|
+
updatedAt?: string;
|
|
34
|
+
}): CliConfig;
|
|
35
|
+
export declare function migrateLegacySession(input: {
|
|
36
|
+
username: string;
|
|
37
|
+
env: string;
|
|
38
|
+
token: string;
|
|
39
|
+
}): CliConfig;
|
|
40
|
+
export declare function setCurrentAccount(input: {
|
|
41
|
+
username: string;
|
|
42
|
+
env?: string;
|
|
43
|
+
}): CliConfig;
|
|
44
|
+
export declare function removeAccountSession(input?: {
|
|
45
|
+
username?: string;
|
|
46
|
+
env?: string;
|
|
47
|
+
}): CliConfig;
|
package/dist/config.js
CHANGED
|
@@ -7,29 +7,74 @@ exports.loadConfig = loadConfig;
|
|
|
7
7
|
exports.saveConfig = saveConfig;
|
|
8
8
|
exports.clearConfig = clearConfig;
|
|
9
9
|
exports.getConfig = getConfig;
|
|
10
|
+
exports.listAccountSessions = listAccountSessions;
|
|
11
|
+
exports.getCurrentAccountSession = getCurrentAccountSession;
|
|
12
|
+
exports.findAccountSession = findAccountSession;
|
|
13
|
+
exports.listAccountSessionsForUsername = listAccountSessionsForUsername;
|
|
14
|
+
exports.saveAccountSession = saveAccountSession;
|
|
15
|
+
exports.migrateLegacySession = migrateLegacySession;
|
|
16
|
+
exports.setCurrentAccount = setCurrentAccount;
|
|
17
|
+
exports.removeAccountSession = removeAccountSession;
|
|
10
18
|
const fs_1 = require("fs");
|
|
11
19
|
const path_1 = require("path");
|
|
12
20
|
const os_1 = __importDefault(require("os"));
|
|
21
|
+
const CONFIG_VERSION = 2;
|
|
13
22
|
function getConfigPath() {
|
|
14
23
|
const custom = process.env.PLAYDROP_CONFIG_PATH;
|
|
15
24
|
if (custom)
|
|
16
25
|
return custom;
|
|
17
26
|
return (0, path_1.join)(os_1.default.homedir(), '.playdrop', 'config.json');
|
|
18
27
|
}
|
|
19
|
-
function
|
|
28
|
+
function normalizeKey(value) {
|
|
29
|
+
return value.trim();
|
|
30
|
+
}
|
|
31
|
+
function clonePersistedConfig(cfg) {
|
|
32
|
+
return JSON.parse(JSON.stringify(cfg));
|
|
33
|
+
}
|
|
34
|
+
function buildDerivedConfig(cfg) {
|
|
35
|
+
const next = clonePersistedConfig(cfg);
|
|
36
|
+
const current = getCurrentAccountSession(next);
|
|
37
|
+
if (current) {
|
|
38
|
+
next.currentUsername = current.username;
|
|
39
|
+
next.env = current.env;
|
|
40
|
+
next.token = current.token;
|
|
41
|
+
}
|
|
42
|
+
return next;
|
|
43
|
+
}
|
|
44
|
+
function readRawConfig() {
|
|
20
45
|
const file = getConfigPath();
|
|
21
46
|
try {
|
|
22
47
|
const data = (0, fs_1.readFileSync)(file, 'utf8');
|
|
23
|
-
|
|
48
|
+
const parsed = JSON.parse(data);
|
|
49
|
+
return parsed && typeof parsed === 'object' ? parsed : {};
|
|
24
50
|
}
|
|
25
51
|
catch {
|
|
26
52
|
return {};
|
|
27
53
|
}
|
|
28
54
|
}
|
|
55
|
+
function stripDerivedFields(cfg) {
|
|
56
|
+
const next = {
|
|
57
|
+
version: typeof cfg.version === 'number' ? cfg.version : undefined,
|
|
58
|
+
currentAccount: cfg.currentAccount ?? undefined,
|
|
59
|
+
accounts: cfg.accounts ? clonePersistedConfig({ accounts: cfg.accounts }).accounts : undefined,
|
|
60
|
+
};
|
|
61
|
+
if (!next.accounts || Object.keys(next.accounts).length === 0) {
|
|
62
|
+
if (typeof cfg.token === 'string' && cfg.token.trim().length > 0) {
|
|
63
|
+
next.token = cfg.token.trim();
|
|
64
|
+
}
|
|
65
|
+
if (typeof cfg.env === 'string' && cfg.env.trim().length > 0) {
|
|
66
|
+
next.env = cfg.env.trim();
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
return next;
|
|
70
|
+
}
|
|
71
|
+
function loadConfig() {
|
|
72
|
+
return buildDerivedConfig(readRawConfig());
|
|
73
|
+
}
|
|
29
74
|
function saveConfig(cfg) {
|
|
30
75
|
const file = getConfigPath();
|
|
31
76
|
(0, fs_1.mkdirSync)((0, path_1.dirname)(file), { recursive: true });
|
|
32
|
-
(0, fs_1.writeFileSync)(file, JSON.stringify(cfg, null, 2));
|
|
77
|
+
(0, fs_1.writeFileSync)(file, JSON.stringify(stripDerivedFields(cfg), null, 2));
|
|
33
78
|
}
|
|
34
79
|
function clearConfig() {
|
|
35
80
|
const file = getConfigPath();
|
|
@@ -39,3 +84,160 @@ function clearConfig() {
|
|
|
39
84
|
function getConfig() {
|
|
40
85
|
return { path: getConfigPath() };
|
|
41
86
|
}
|
|
87
|
+
function listAccountSessions(cfg = loadConfig()) {
|
|
88
|
+
const accounts = cfg.accounts ?? {};
|
|
89
|
+
const sessions = [];
|
|
90
|
+
for (const [username, envMap] of Object.entries(accounts)) {
|
|
91
|
+
for (const [env, session] of Object.entries(envMap ?? {})) {
|
|
92
|
+
if (!session || typeof session.token !== 'string' || session.token.trim().length === 0) {
|
|
93
|
+
continue;
|
|
94
|
+
}
|
|
95
|
+
sessions.push({
|
|
96
|
+
username,
|
|
97
|
+
env,
|
|
98
|
+
token: session.token,
|
|
99
|
+
updatedAt: typeof session.updatedAt === 'string' ? session.updatedAt : '',
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
sessions.sort((left, right) => {
|
|
104
|
+
if (left.username === right.username) {
|
|
105
|
+
return left.env.localeCompare(right.env);
|
|
106
|
+
}
|
|
107
|
+
return left.username.localeCompare(right.username);
|
|
108
|
+
});
|
|
109
|
+
return sessions;
|
|
110
|
+
}
|
|
111
|
+
function getCurrentAccountSession(cfg = loadConfig()) {
|
|
112
|
+
const current = cfg.currentAccount;
|
|
113
|
+
if (!current) {
|
|
114
|
+
return null;
|
|
115
|
+
}
|
|
116
|
+
return findAccountSession(current.username, current.env, cfg);
|
|
117
|
+
}
|
|
118
|
+
function findAccountSession(username, env, cfg = loadConfig()) {
|
|
119
|
+
const normalizedUsername = normalizeKey(username);
|
|
120
|
+
if (!normalizedUsername) {
|
|
121
|
+
return null;
|
|
122
|
+
}
|
|
123
|
+
const envMap = cfg.accounts?.[normalizedUsername];
|
|
124
|
+
if (!envMap) {
|
|
125
|
+
return null;
|
|
126
|
+
}
|
|
127
|
+
if (typeof env === 'string' && env.trim().length > 0) {
|
|
128
|
+
const session = envMap[env.trim()];
|
|
129
|
+
if (!session?.token) {
|
|
130
|
+
return null;
|
|
131
|
+
}
|
|
132
|
+
return {
|
|
133
|
+
username: normalizedUsername,
|
|
134
|
+
env: env.trim(),
|
|
135
|
+
token: session.token,
|
|
136
|
+
updatedAt: typeof session.updatedAt === 'string' ? session.updatedAt : '',
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
const envs = Object.keys(envMap);
|
|
140
|
+
if (envs.length === 1) {
|
|
141
|
+
const selectedEnv = envs[0];
|
|
142
|
+
const session = envMap[selectedEnv];
|
|
143
|
+
if (!session?.token) {
|
|
144
|
+
return null;
|
|
145
|
+
}
|
|
146
|
+
return {
|
|
147
|
+
username: normalizedUsername,
|
|
148
|
+
env: selectedEnv,
|
|
149
|
+
token: session.token,
|
|
150
|
+
updatedAt: typeof session.updatedAt === 'string' ? session.updatedAt : '',
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
return null;
|
|
154
|
+
}
|
|
155
|
+
function listAccountSessionsForUsername(username, cfg = loadConfig()) {
|
|
156
|
+
const normalizedUsername = normalizeKey(username);
|
|
157
|
+
if (!normalizedUsername) {
|
|
158
|
+
return [];
|
|
159
|
+
}
|
|
160
|
+
return listAccountSessions(cfg).filter((session) => session.username === normalizedUsername);
|
|
161
|
+
}
|
|
162
|
+
function saveAccountSession(input) {
|
|
163
|
+
const cfg = loadConfig();
|
|
164
|
+
const username = normalizeKey(input.username);
|
|
165
|
+
const env = normalizeKey(input.env);
|
|
166
|
+
const token = input.token.trim();
|
|
167
|
+
if (!username || !env || !token) {
|
|
168
|
+
throw new Error('invalid_account_session');
|
|
169
|
+
}
|
|
170
|
+
const next = {
|
|
171
|
+
version: CONFIG_VERSION,
|
|
172
|
+
currentAccount: { username, env },
|
|
173
|
+
accounts: {
|
|
174
|
+
...(cfg.accounts ?? {}),
|
|
175
|
+
[username]: {
|
|
176
|
+
...(cfg.accounts?.[username] ?? {}),
|
|
177
|
+
[env]: {
|
|
178
|
+
token,
|
|
179
|
+
updatedAt: input.updatedAt ?? new Date().toISOString(),
|
|
180
|
+
},
|
|
181
|
+
},
|
|
182
|
+
},
|
|
183
|
+
};
|
|
184
|
+
saveConfig(next);
|
|
185
|
+
return loadConfig();
|
|
186
|
+
}
|
|
187
|
+
function migrateLegacySession(input) {
|
|
188
|
+
return saveAccountSession(input);
|
|
189
|
+
}
|
|
190
|
+
function setCurrentAccount(input) {
|
|
191
|
+
const cfg = loadConfig();
|
|
192
|
+
const username = normalizeKey(input.username);
|
|
193
|
+
const env = typeof input.env === 'string' ? normalizeKey(input.env) : '';
|
|
194
|
+
const session = findAccountSession(username, env || undefined, cfg);
|
|
195
|
+
if (!session) {
|
|
196
|
+
throw new Error(env ? 'account_session_not_found' : 'account_not_found');
|
|
197
|
+
}
|
|
198
|
+
const next = {
|
|
199
|
+
version: CONFIG_VERSION,
|
|
200
|
+
currentAccount: { username: session.username, env: session.env },
|
|
201
|
+
accounts: cfg.accounts ?? {},
|
|
202
|
+
};
|
|
203
|
+
saveConfig(next);
|
|
204
|
+
return loadConfig();
|
|
205
|
+
}
|
|
206
|
+
// eslint-disable-next-line complexity
|
|
207
|
+
function removeAccountSession(input = {}) {
|
|
208
|
+
const cfg = loadConfig();
|
|
209
|
+
const current = getCurrentAccountSession(cfg);
|
|
210
|
+
const username = normalizeKey(input.username ?? current?.username ?? '');
|
|
211
|
+
const env = normalizeKey(input.env ?? current?.env ?? '');
|
|
212
|
+
if (!username) {
|
|
213
|
+
return cfg;
|
|
214
|
+
}
|
|
215
|
+
const accounts = clonePersistedConfig({ accounts: cfg.accounts ?? {} }).accounts ?? {};
|
|
216
|
+
if (!accounts[username]) {
|
|
217
|
+
return cfg;
|
|
218
|
+
}
|
|
219
|
+
if (env) {
|
|
220
|
+
delete accounts[username][env];
|
|
221
|
+
}
|
|
222
|
+
else {
|
|
223
|
+
delete accounts[username];
|
|
224
|
+
}
|
|
225
|
+
if (accounts[username] && Object.keys(accounts[username]).length === 0) {
|
|
226
|
+
delete accounts[username];
|
|
227
|
+
}
|
|
228
|
+
const remainingSessions = listAccountSessions({ accounts });
|
|
229
|
+
const nextCurrent = remainingSessions[0]
|
|
230
|
+
? { username: remainingSessions[0].username, env: remainingSessions[0].env }
|
|
231
|
+
: null;
|
|
232
|
+
const next = {
|
|
233
|
+
version: CONFIG_VERSION,
|
|
234
|
+
currentAccount: nextCurrent,
|
|
235
|
+
accounts,
|
|
236
|
+
};
|
|
237
|
+
if (!nextCurrent && typeof cfg.token === 'string' && typeof cfg.env === 'string' && (!cfg.accounts || Object.keys(cfg.accounts).length === 0)) {
|
|
238
|
+
clearConfig();
|
|
239
|
+
return {};
|
|
240
|
+
}
|
|
241
|
+
saveConfig(next);
|
|
242
|
+
return loadConfig();
|
|
243
|
+
}
|