@playdrop/playdrop-cli 0.10.21 → 0.11.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.
@@ -23,6 +23,8 @@ __export(version_exports, {
23
23
  APP_UPLOAD_INIT_STATUS_VALUES: () => APP_UPLOAD_INIT_STATUS_VALUES,
24
24
  APP_UPLOAD_LAUNCH_CHECK_STATUS_VALUES: () => APP_UPLOAD_LAUNCH_CHECK_STATUS_VALUES,
25
25
  APP_UPLOAD_SESSION_STATUS_VALUES: () => APP_UPLOAD_SESSION_STATUS_VALUES,
26
+ APP_VERSION_DESIGN_GROUP_VALUES: () => APP_VERSION_DESIGN_GROUP_VALUES,
27
+ APP_VERSION_DESIGN_SHAPE_HELP: () => APP_VERSION_DESIGN_SHAPE_HELP,
26
28
  APP_VERSION_VISIBILITY_VALUES: () => APP_VERSION_VISIBILITY_VALUES,
27
29
  DEFAULT_APP_AUTH_MODE: () => DEFAULT_APP_AUTH_MODE,
28
30
  DEFAULT_APP_CONTROLLER_MODE: () => DEFAULT_APP_CONTROLLER_MODE,
@@ -39,6 +41,7 @@ __export(version_exports, {
39
41
  isAppVersionVisibility: () => isAppVersionVisibility,
40
42
  isReviewState: () => isReviewState,
41
43
  isValidVersion: () => isValidVersion,
44
+ normalizeAppVersionDesign: () => normalizeAppVersionDesign,
42
45
  parseAppAuthMode: () => parseAppAuthMode,
43
46
  parseAppControllerMode: () => parseAppControllerMode,
44
47
  parseAppHostingMode: () => parseAppHostingMode,
@@ -102,6 +105,108 @@ function parseReviewState(value) {
102
105
  const normalized = value.trim().toUpperCase();
103
106
  return isReviewState(normalized) ? normalized : null;
104
107
  }
108
+ const APP_VERSION_DESIGN_GROUP_VALUES = [
109
+ "genre",
110
+ "coreGameplay",
111
+ "render",
112
+ "camera",
113
+ "input",
114
+ "progression",
115
+ "artStyle",
116
+ "coreAssets",
117
+ "assetStrategy",
118
+ "engine",
119
+ "features",
120
+ "references"
121
+ ];
122
+ const APP_VERSION_DESIGN_GROUPS = new Set(APP_VERSION_DESIGN_GROUP_VALUES);
123
+ const APP_VERSION_DESIGN_NOTE_MAX_LENGTH = 140;
124
+ const APP_VERSION_DESIGN_SHAPE_HELP = 'Expected catalogue design shape: {"genre":{"value":"arcade"},"coreGameplay":{"value":"short loop"},"render":{"value":"2d"},"camera":{"value":"fixed-screen"},"input":{"values":["tap","pointer"]},"progression":{"value":"waves"},"artStyle":{"value":"bright cartoon"},"assetStrategy":{"value":"procedural","note":"honest procedural draft"},"engine":{"value":"plain-html"},"coreAssets":{"values":[]},"features":{"values":[]},"references":{"values":[]}}. Allowed groups: genre, coreGameplay, render, camera, input, progression, artStyle, coreAssets, assetStrategy, engine, features, references. Use value for one-value groups and values for many-value groups.';
125
+ const APP_VERSION_DESIGN_RULES = {
126
+ genre: { cardinality: "one" },
127
+ coreGameplay: { cardinality: "one" },
128
+ render: { cardinality: "one", values: ["2d", "3d"] },
129
+ camera: { cardinality: "one", values: ["top-down", "side", "isometric", "third-person", "first-person", "fixed-screen"] },
130
+ input: { cardinality: "many", values: ["one-thumb", "tap", "drag", "keyboard", "pointer", "virtual-stick", "gamepad"] },
131
+ progression: { cardinality: "one", values: ["endless", "levels", "waves", "rounds", "story"] },
132
+ artStyle: { cardinality: "one" },
133
+ coreAssets: { cardinality: "many", maxValues: 2 },
134
+ assetStrategy: { cardinality: "one", values: ["pack-first", "owned-assets", "mixed", "procedural"] },
135
+ engine: { cardinality: "one", values: ["phaser-2d", "three-js", "plain-html"] },
136
+ features: { cardinality: "many", values: ["multiplayer", "avatars", "achievements", "leaderboard", "saves", "ai-generation", "shop", "ads"] },
137
+ references: { cardinality: "many", maxValues: 2 }
138
+ };
139
+ function formatAppVersionDesignError(error) {
140
+ return `${error}. ${APP_VERSION_DESIGN_SHAPE_HELP}`;
141
+ }
142
+ function normalizeDesignString(value) {
143
+ return typeof value === "string" && value.trim() ? value.trim() : null;
144
+ }
145
+ function normalizeAppVersionDesign(value, options = {}) {
146
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
147
+ return { ok: false, error: formatAppVersionDesignError("invalid_design") };
148
+ }
149
+ const record = value;
150
+ const allowedPackRefs = new Set((options.allowedPackRefs ?? []).map((ref) => ref.trim()).filter(Boolean));
151
+ const design = {};
152
+ for (const [rawGroup, rawEntry] of Object.entries(record)) {
153
+ if (!APP_VERSION_DESIGN_GROUPS.has(rawGroup)) {
154
+ return { ok: false, error: formatAppVersionDesignError(`invalid_design_group:${rawGroup}`) };
155
+ }
156
+ const group = rawGroup;
157
+ if (!rawEntry || typeof rawEntry !== "object" || Array.isArray(rawEntry)) {
158
+ return { ok: false, error: formatAppVersionDesignError(`invalid_design_entry:${group}`) };
159
+ }
160
+ const entry = rawEntry;
161
+ for (const key of Object.keys(entry)) {
162
+ if (key !== "value" && key !== "values" && key !== "note") {
163
+ return { ok: false, error: formatAppVersionDesignError(`invalid_design_entry_key:${group}:${key}`) };
164
+ }
165
+ }
166
+ const hasValue = Object.prototype.hasOwnProperty.call(entry, "value");
167
+ const hasValues = Object.prototype.hasOwnProperty.call(entry, "values");
168
+ if (hasValue === hasValues) {
169
+ return { ok: false, error: formatAppVersionDesignError(`invalid_design_value_shape:${group}`) };
170
+ }
171
+ const rule = APP_VERSION_DESIGN_RULES[group];
172
+ const values = hasValue ? [normalizeDesignString(entry["value"])] : Array.isArray(entry["values"]) ? entry["values"].map((item) => normalizeDesignString(item)) : null;
173
+ if (!values || values.some((item) => item === null)) {
174
+ return { ok: false, error: formatAppVersionDesignError(`invalid_design_value:${group}`) };
175
+ }
176
+ const normalizedValues = Array.from(new Set(values));
177
+ if (rule.cardinality === "one" && normalizedValues.length !== 1) {
178
+ return { ok: false, error: formatAppVersionDesignError(`invalid_design_value_count:${group}`) };
179
+ }
180
+ if (rule.maxValues !== void 0 && normalizedValues.length > rule.maxValues) {
181
+ return { ok: false, error: formatAppVersionDesignError(`invalid_design_value_count:${group}`) };
182
+ }
183
+ if (rule.values) {
184
+ const allowedValues = new Set(rule.values);
185
+ const invalidValue = normalizedValues.find((item) => !allowedValues.has(item));
186
+ if (invalidValue) {
187
+ return { ok: false, error: formatAppVersionDesignError(`invalid_design_value:${group}:${invalidValue}`) };
188
+ }
189
+ }
190
+ if (group === "coreAssets") {
191
+ const missingPackRef = normalizedValues.find((item) => !allowedPackRefs.has(item));
192
+ if (missingPackRef) {
193
+ return { ok: false, error: formatAppVersionDesignError(`design_core_asset_not_in_uses_packs:${missingPackRef}`) };
194
+ }
195
+ }
196
+ const note = Object.prototype.hasOwnProperty.call(entry, "note") ? normalizeDesignString(entry["note"]) : null;
197
+ if (Object.prototype.hasOwnProperty.call(entry, "note") && note === null) {
198
+ return { ok: false, error: formatAppVersionDesignError(`invalid_design_note:${group}`) };
199
+ }
200
+ if (note && note.length > APP_VERSION_DESIGN_NOTE_MAX_LENGTH) {
201
+ return { ok: false, error: formatAppVersionDesignError(`design_note_too_long:${group}`) };
202
+ }
203
+ design[group] = {
204
+ ...rule.cardinality === "one" ? { value: normalizedValues[0] } : { values: normalizedValues },
205
+ ...note ? { note } : {}
206
+ };
207
+ }
208
+ return { ok: true, value: design };
209
+ }
105
210
  const APP_AUTH_MODE_VALUES = ["REQUIRED", "OPTIONAL", "NONE"];
106
211
  const DEFAULT_APP_AUTH_MODE = "REQUIRED";
107
212
  function isAppAuthMode(value) {
@@ -172,6 +277,8 @@ const APP_UPLOAD_LAUNCH_CHECK_STATUS_VALUES = ["NOT_RUN", "PASSED", "FAILED"];
172
277
  APP_UPLOAD_INIT_STATUS_VALUES,
173
278
  APP_UPLOAD_LAUNCH_CHECK_STATUS_VALUES,
174
279
  APP_UPLOAD_SESSION_STATUS_VALUES,
280
+ APP_VERSION_DESIGN_GROUP_VALUES,
281
+ APP_VERSION_DESIGN_SHAPE_HELP,
175
282
  APP_VERSION_VISIBILITY_VALUES,
176
283
  DEFAULT_APP_AUTH_MODE,
177
284
  DEFAULT_APP_CONTROLLER_MODE,
@@ -188,6 +295,7 @@ const APP_UPLOAD_LAUNCH_CHECK_STATUS_VALUES = ["NOT_RUN", "PASSED", "FAILED"];
188
295
  isAppVersionVisibility,
189
296
  isReviewState,
190
297
  isValidVersion,
298
+ normalizeAppVersionDesign,
191
299
  parseAppAuthMode,
192
300
  parseAppControllerMode,
193
301
  parseAppHostingMode,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@playdrop/playdrop-cli",
3
- "version": "0.10.21",
3
+ "version": "0.11.4",
4
4
  "description": "Official Playdrop CLI for publishing browser games, creator apps, and AI-generated game assets on playdrop.ai",
5
5
  "homepage": "https://www.playdrop.ai",
6
6
  "repository": {