playcademy 0.13.21 → 0.13.23

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/index.d.ts CHANGED
@@ -169,6 +169,45 @@ interface BackendFeatures {
169
169
  hasSecrets: boolean;
170
170
  }
171
171
 
172
+ /**
173
+ * Bucket command types
174
+ */
175
+ /**
176
+ * Base options shared across bucket commands
177
+ */
178
+ interface BaseBucketOptions {
179
+ /** Output in raw format */
180
+ raw?: boolean;
181
+ /** Output in JSON format */
182
+ json?: boolean;
183
+ /** Use remote bucket storage */
184
+ remote?: boolean;
185
+ /** Environment (staging or production) */
186
+ env?: string;
187
+ }
188
+ /**
189
+ * Options for the bucket list command
190
+ */
191
+ interface BucketListOptions extends BaseBucketOptions {
192
+ /** Filter files by key prefix */
193
+ prefix?: string;
194
+ }
195
+ /**
196
+ * Options for the bucket get command
197
+ */
198
+ interface BucketGetOptions extends BaseBucketOptions {
199
+ /** Output file path */
200
+ output?: string;
201
+ }
202
+ /**
203
+ * Options for the bucket put command
204
+ */
205
+ type BucketPutOptions = BaseBucketOptions;
206
+ /**
207
+ * Options for the bucket delete command
208
+ */
209
+ type BucketDeleteOptions = BaseBucketOptions;
210
+
172
211
  /**
173
212
  * @fileoverview Server SDK Type Definitions
174
213
  *
@@ -954,4 +993,4 @@ interface KeyMetadata {
954
993
  valueType?: 'json' | 'string';
955
994
  }
956
995
 
957
- export type { ApiConfig, ApiErrorResponse, ApiKeyListItem, ApiKeyWithSecret, ApiRequestOptions, AuthProfile, AuthStore, BackendBundle, BackendDeploymentWithHash, BackendDiff, BackendFeatures, BuildDiff, BundleOptions, CallbackServerResult, ConfigDiff, CreateApiKeyResponse, CustomRoutesIntegrationOptions, DatabaseIntegrationOptions, DeployConfig, DeployNewGameOptions, DeployedGameInfo, DeploymentChanges, DeploymentContext, DeploymentDiffOptions, DeploymentPlan, DeploymentResult, DevServerOptions, EmbeddedSourcePaths, EnvironmentAuthProfiles, GameStore, IntegrationChangeDetector, IntegrationChangeDetectors, IntegrationConfigChange, IntegrationsConfig, IntegrationsDiff, KeyMetadata, KeyStats, LoginCredentials, LoginResponse, PlaycademyConfig, PreviewOptions, PreviewResponse, SecretsDiff, SignInResponse, SsoCallbackData, TimebackIntegrationConfig, TokenType, UpdateExistingGameOptions };
996
+ export type { ApiConfig, ApiErrorResponse, ApiKeyListItem, ApiKeyWithSecret, ApiRequestOptions, AuthProfile, AuthStore, BackendBundle, BackendDeploymentWithHash, BackendDiff, BackendFeatures, BucketDeleteOptions, BucketGetOptions, BucketListOptions, BucketPutOptions, BuildDiff, BundleOptions, CallbackServerResult, ConfigDiff, CreateApiKeyResponse, CustomRoutesIntegrationOptions, DatabaseIntegrationOptions, DeployConfig, DeployNewGameOptions, DeployedGameInfo, DeploymentChanges, DeploymentContext, DeploymentDiffOptions, DeploymentPlan, DeploymentResult, DevServerOptions, EmbeddedSourcePaths, EnvironmentAuthProfiles, GameStore, IntegrationChangeDetector, IntegrationChangeDetectors, IntegrationConfigChange, IntegrationsConfig, IntegrationsDiff, KeyMetadata, KeyStats, LoginCredentials, LoginResponse, PlaycademyConfig, PreviewOptions, PreviewResponse, SecretsDiff, SignInResponse, SsoCallbackData, TimebackIntegrationConfig, TokenType, UpdateExistingGameOptions };
package/dist/index.js CHANGED
@@ -3724,6 +3724,57 @@ var init_import = __esm({
3724
3724
  }
3725
3725
  });
3726
3726
 
3727
+ // src/lib/core/mime.ts
3728
+ function getContentType(filePath) {
3729
+ const ext = filePath.split(".").pop()?.toLowerCase();
3730
+ const types = {
3731
+ // Images
3732
+ jpg: "image/jpeg",
3733
+ jpeg: "image/jpeg",
3734
+ png: "image/png",
3735
+ gif: "image/gif",
3736
+ webp: "image/webp",
3737
+ svg: "image/svg+xml",
3738
+ ico: "image/x-icon",
3739
+ // Audio
3740
+ mp3: "audio/mpeg",
3741
+ wav: "audio/wav",
3742
+ ogg: "audio/ogg",
3743
+ m4a: "audio/mp4",
3744
+ // Video
3745
+ mp4: "video/mp4",
3746
+ webm: "video/webm",
3747
+ mov: "video/quicktime",
3748
+ // Documents
3749
+ pdf: "application/pdf",
3750
+ txt: "text/plain",
3751
+ md: "text/markdown",
3752
+ // Web
3753
+ html: "text/html",
3754
+ htm: "text/html",
3755
+ css: "text/css",
3756
+ js: "application/javascript",
3757
+ mjs: "application/javascript",
3758
+ json: "application/json",
3759
+ xml: "application/xml",
3760
+ // Archives
3761
+ zip: "application/zip",
3762
+ gz: "application/gzip",
3763
+ tar: "application/x-tar",
3764
+ // Fonts
3765
+ woff: "font/woff",
3766
+ woff2: "font/woff2",
3767
+ ttf: "font/ttf",
3768
+ otf: "font/otf"
3769
+ };
3770
+ return types[ext || ""] || "application/octet-stream";
3771
+ }
3772
+ var init_mime2 = __esm({
3773
+ "src/lib/core/mime.ts"() {
3774
+ "use strict";
3775
+ }
3776
+ });
3777
+
3727
3778
  // src/lib/core/index.ts
3728
3779
  var core_exports = {};
3729
3780
  __export(core_exports, {
@@ -3733,6 +3784,7 @@ __export(core_exports, {
3733
3784
  getApiUrl: () => getApiUrl,
3734
3785
  getBaseUrl: () => getBaseUrl,
3735
3786
  getCliContext: () => getCliContext,
3787
+ getContentType: () => getContentType,
3736
3788
  getEnvironment: () => getEnvironment,
3737
3789
  getErrorMessage: () => getErrorMessage,
3738
3790
  getGameFromConfig: () => getGameFromConfig,
@@ -3760,6 +3812,7 @@ var init_core = __esm({
3760
3812
  init_game();
3761
3813
  init_import();
3762
3814
  init_logger();
3815
+ init_mime2();
3763
3816
  }
3764
3817
  });
3765
3818
 
@@ -4936,6 +4989,9 @@ var isDevelopment = () => {
4936
4989
  var isInteractiveTTY = () => {
4937
4990
  return typeof process !== "undefined" && Boolean(process.stdout && process.stdout.isTTY);
4938
4991
  };
4992
+ var isSilent = () => {
4993
+ return typeof process !== "undefined" && process.env.LOG_SILENT === "true";
4994
+ };
4939
4995
  var detectOutputFormat = () => {
4940
4996
  if (isBrowser()) {
4941
4997
  return "browser";
@@ -5056,6 +5112,7 @@ var getMinimumLogLevel = () => {
5056
5112
  return isProduction() ? "info" : "debug";
5057
5113
  };
5058
5114
  var shouldLog = (level) => {
5115
+ if (isSilent()) return false;
5059
5116
  const minLevel = getMinimumLogLevel();
5060
5117
  return levelPriority[level] >= levelPriority[minLevel];
5061
5118
  };
@@ -9506,7 +9563,6 @@ async function runDbInit() {
9506
9563
  }
9507
9564
 
9508
9565
  // src/commands/db/reset.ts
9509
- init_src2();
9510
9566
  init_src();
9511
9567
  import { spawn } from "child_process";
9512
9568
  import { existsSync as existsSync19, rmSync as rmSync2 } from "fs";
@@ -9557,24 +9613,10 @@ async function runDbReset() {
9557
9613
  logger.newLine();
9558
9614
  return;
9559
9615
  }
9560
- const config = await loadConfig();
9561
- const { code } = await bundleBackend(config);
9616
+ await loadConfig();
9562
9617
  try {
9563
9618
  const mf = new Miniflare2({
9564
- port: 0,
9565
- // Random available port
9566
- modules: [
9567
- {
9568
- type: "ESModule",
9569
- path: "index.mjs",
9570
- contents: code
9571
- }
9572
- ],
9573
- bindings: {
9574
- PLAYCADEMY_API_KEY: "dev-api-key",
9575
- GAME_ID: CORE_GAME_UUIDS.PLAYGROUND,
9576
- PLAYCADEMY_BASE_URL: "http://localhost:5174"
9577
- },
9619
+ modules: [{ type: "ESModule", path: "index.mjs", contents: "" }],
9578
9620
  d1Databases: ["DB"],
9579
9621
  d1Persist: dbDir,
9580
9622
  compatibilityDate: CLOUDFLARE_COMPATIBILITY_DATE
@@ -9598,7 +9640,7 @@ async function runDbReset() {
9598
9640
  // stdin: ignore, stdout: ignore, stderr: inherit
9599
9641
  env: process.env
9600
9642
  });
9601
- child.on("close", (code2) => resolve11(code2 || 0));
9643
+ child.on("close", (code) => resolve11(code || 0));
9602
9644
  child.on("error", () => resolve11(1));
9603
9645
  });
9604
9646
  return exitCode2;
@@ -9696,19 +9738,9 @@ async function runKVClear(options = {}) {
9696
9738
  }
9697
9739
  process.exit(1);
9698
9740
  }
9699
- const bundle = await bundleBackend(config, {
9700
- sourcemap: false,
9701
- minify: false
9702
- });
9703
9741
  const kvDir = join24(getWorkspace(), CLI_DIRECTORIES.KV);
9704
9742
  const mf = new Miniflare3({
9705
- modules: [
9706
- {
9707
- type: "ESModule",
9708
- path: "index.mjs",
9709
- contents: bundle.code
9710
- }
9711
- ],
9743
+ modules: [{ type: "ESModule", path: "index.mjs", contents: "" }],
9712
9744
  kvNamespaces: ["KV"],
9713
9745
  kvPersist: kvDir,
9714
9746
  compatibilityDate: CLOUDFLARE_COMPATIBILITY_DATE
@@ -9819,19 +9851,9 @@ async function runKVDelete(key, options = {}) {
9819
9851
  }
9820
9852
  process.exit(1);
9821
9853
  }
9822
- const bundle = await bundleBackend(config, {
9823
- sourcemap: false,
9824
- minify: false
9825
- });
9826
9854
  const kvDir = join25(getWorkspace(), CLI_DIRECTORIES.KV);
9827
9855
  const mf = new Miniflare4({
9828
- modules: [
9829
- {
9830
- type: "ESModule",
9831
- path: "index.mjs",
9832
- contents: bundle.code
9833
- }
9834
- ],
9856
+ modules: [{ type: "ESModule", path: "index.mjs", contents: "" }],
9835
9857
  kvNamespaces: ["KV"],
9836
9858
  kvPersist: kvDir,
9837
9859
  compatibilityDate: CLOUDFLARE_COMPATIBILITY_DATE
@@ -9907,19 +9929,9 @@ async function runKVGet(key, options = {}) {
9907
9929
  }
9908
9930
  process.exit(1);
9909
9931
  }
9910
- const bundle = await bundleBackend(config, {
9911
- sourcemap: false,
9912
- minify: false
9913
- });
9914
9932
  const kvDir = join26(getWorkspace(), CLI_DIRECTORIES.KV);
9915
9933
  const mf = new Miniflare5({
9916
- modules: [
9917
- {
9918
- type: "ESModule",
9919
- path: "index.mjs",
9920
- contents: bundle.code
9921
- }
9922
- ],
9934
+ modules: [{ type: "ESModule", path: "index.mjs", contents: "" }],
9923
9935
  kvNamespaces: ["KV"],
9924
9936
  kvPersist: kvDir,
9925
9937
  compatibilityDate: CLOUDFLARE_COMPATIBILITY_DATE
@@ -10097,19 +10109,9 @@ async function runKVInspect(key, options = {}) {
10097
10109
  }
10098
10110
  process.exit(1);
10099
10111
  }
10100
- const bundle = await bundleBackend(config, {
10101
- sourcemap: false,
10102
- minify: false
10103
- });
10104
10112
  const kvDir = join27(getWorkspace(), CLI_DIRECTORIES.KV);
10105
10113
  const mf = new Miniflare6({
10106
- modules: [
10107
- {
10108
- type: "ESModule",
10109
- path: "index.mjs",
10110
- contents: bundle.code
10111
- }
10112
- ],
10114
+ modules: [{ type: "ESModule", path: "index.mjs", contents: "" }],
10113
10115
  kvNamespaces: ["KV"],
10114
10116
  kvPersist: kvDir,
10115
10117
  compatibilityDate: CLOUDFLARE_COMPATIBILITY_DATE
@@ -10227,19 +10229,9 @@ async function runKVList(options = {}) {
10227
10229
  }
10228
10230
  process.exit(1);
10229
10231
  }
10230
- const bundle = await bundleBackend(config, {
10231
- sourcemap: false,
10232
- minify: false
10233
- });
10234
10232
  const kvDir = join28(getWorkspace(), CLI_DIRECTORIES.KV);
10235
10233
  const mf = new Miniflare7({
10236
- modules: [
10237
- {
10238
- type: "ESModule",
10239
- path: "index.mjs",
10240
- contents: bundle.code
10241
- }
10242
- ],
10234
+ modules: [{ type: "ESModule", path: "index.mjs", contents: "" }],
10243
10235
  kvNamespaces: ["KV"],
10244
10236
  kvPersist: kvDir,
10245
10237
  compatibilityDate: CLOUDFLARE_COMPATIBILITY_DATE
@@ -10352,19 +10344,9 @@ async function runKVSeed(seedFile, options = {}) {
10352
10344
  }
10353
10345
  process.exit(1);
10354
10346
  }
10355
- const bundle = await bundleBackend(config, {
10356
- sourcemap: false,
10357
- minify: false
10358
- });
10359
10347
  const kvDir = join29(workspace, CLI_DIRECTORIES.KV);
10360
10348
  const mf = new Miniflare8({
10361
- modules: [
10362
- {
10363
- type: "ESModule",
10364
- path: "index.mjs",
10365
- contents: bundle.code
10366
- }
10367
- ],
10349
+ modules: [{ type: "ESModule", path: "index.mjs", contents: "" }],
10368
10350
  kvNamespaces: ["KV"],
10369
10351
  kvPersist: kvDir,
10370
10352
  compatibilityDate: CLOUDFLARE_COMPATIBILITY_DATE
@@ -10513,19 +10495,9 @@ async function runKVSet(key, value, options = {}) {
10513
10495
  }
10514
10496
  process.exit(1);
10515
10497
  }
10516
- const bundle = await bundleBackend(config, {
10517
- sourcemap: false,
10518
- minify: false
10519
- });
10520
10498
  const kvDir = join30(getWorkspace(), CLI_DIRECTORIES.KV);
10521
10499
  const mf = new Miniflare9({
10522
- modules: [
10523
- {
10524
- type: "ESModule",
10525
- path: "index.mjs",
10526
- contents: bundle.code
10527
- }
10528
- ],
10500
+ modules: [{ type: "ESModule", path: "index.mjs", contents: "" }],
10529
10501
  kvNamespaces: ["KV"],
10530
10502
  kvPersist: kvDir,
10531
10503
  compatibilityDate: CLOUDFLARE_COMPATIBILITY_DATE
@@ -10593,19 +10565,9 @@ async function runKVStats(options = {}) {
10593
10565
  }
10594
10566
  process.exit(1);
10595
10567
  }
10596
- const bundle = await bundleBackend(config, {
10597
- sourcemap: false,
10598
- minify: false
10599
- });
10600
10568
  const kvDir = join31(getWorkspace(), CLI_DIRECTORIES.KV);
10601
10569
  const mf = new Miniflare10({
10602
- modules: [
10603
- {
10604
- type: "ESModule",
10605
- path: "index.mjs",
10606
- contents: bundle.code
10607
- }
10608
- ],
10570
+ modules: [{ type: "ESModule", path: "index.mjs", contents: "" }],
10609
10571
  kvNamespaces: ["KV"],
10610
10572
  kvPersist: kvDir,
10611
10573
  compatibilityDate: CLOUDFLARE_COMPATIBILITY_DATE
@@ -10722,93 +10684,109 @@ import { Command as Command16 } from "commander";
10722
10684
  init_constants2();
10723
10685
  import { join as join32 } from "path";
10724
10686
  import { Miniflare as Miniflare11 } from "miniflare";
10725
- async function runBucketDelete(key, options = {}) {
10726
- try {
10687
+ async function runBucketDeleteRemote(key, options) {
10688
+ const environment = ensureEnvironment(options.env);
10689
+ const client = await requireAuthenticatedClient();
10690
+ const workspace = getWorkspace();
10691
+ const deployedGame = await getDeployedGame(workspace);
10692
+ if (!deployedGame) {
10727
10693
  if (!options.raw && !options.json) {
10694
+ logger.admonition("warning", "Deploy First", [
10695
+ `Deploy your game before accessing remote bucket: \`playcademy deploy\``
10696
+ ]);
10728
10697
  logger.newLine();
10729
10698
  }
10730
- if (options.remote) {
10731
- if (!options.raw && !options.json) {
10732
- logger.newLine();
10733
- logger.warn("Remote bucket operations are not yet implemented");
10734
- logger.newLine();
10735
- logger.admonition("warning", "Coming Soon", [
10736
- "Remote bucket support is on the roadmap and will be available soon.",
10737
- "For now, bucket commands only work with local development storage."
10738
- ]);
10739
- logger.newLine();
10740
- }
10741
- process.exit(1);
10699
+ process.exit(1);
10700
+ }
10701
+ const game = await client.games.fetch(deployedGame.gameId);
10702
+ await client.dev.games.bucket.delete(game.slug, key);
10703
+ if (options.json) {
10704
+ logger.json({
10705
+ success: true,
10706
+ key,
10707
+ message: "File deleted successfully"
10708
+ });
10709
+ return;
10710
+ }
10711
+ if (options.raw) {
10712
+ logger.raw(`Deleted ${key}`);
10713
+ return;
10714
+ }
10715
+ logger.newLine();
10716
+ logger.success(`Deleted '${key}' from ${environment}`);
10717
+ logger.newLine();
10718
+ }
10719
+ async function runBucketDeleteLocal(key, options) {
10720
+ if (!key) {
10721
+ if (!options.raw && !options.json) {
10722
+ logger.error("File key is required");
10723
+ logger.newLine();
10724
+ logger.admonition("tip", "Usage", ["`playcademy bucket delete <key>`"]);
10725
+ logger.newLine();
10742
10726
  }
10743
- if (!key) {
10744
- if (!options.raw && !options.json) {
10745
- logger.error("File key is required");
10746
- logger.newLine();
10747
- logger.admonition("tip", "Usage", ["`playcademy bucket delete <key>`"]);
10748
- logger.newLine();
10749
- }
10750
- process.exit(1);
10727
+ process.exit(1);
10728
+ }
10729
+ const config = await loadConfig();
10730
+ if (!hasBucketSetup(config)) {
10731
+ if (!options.raw && !options.json) {
10732
+ logger.error("Bucket storage is not configured");
10733
+ logger.newLine();
10734
+ logger.admonition("tip", "Getting Started", [
10735
+ "Run `playcademy bucket init` to enable bucket storage"
10736
+ ]);
10737
+ logger.newLine();
10751
10738
  }
10752
- const config = await loadConfig();
10753
- if (!hasBucketSetup(config)) {
10739
+ process.exit(1);
10740
+ }
10741
+ const bucketDir = join32(getWorkspace(), CLI_DIRECTORIES.BUCKET);
10742
+ const mf = new Miniflare11({
10743
+ modules: [{ type: "ESModule", path: "index.mjs", contents: "" }],
10744
+ r2Buckets: ["BUCKET"],
10745
+ r2Persist: bucketDir,
10746
+ compatibilityDate: CLOUDFLARE_COMPATIBILITY_DATE
10747
+ });
10748
+ try {
10749
+ const bucket = await mf.getR2Bucket("BUCKET");
10750
+ const object = await bucket.get(key);
10751
+ if (!object) {
10754
10752
  if (!options.raw && !options.json) {
10755
- logger.error("Bucket storage is not configured");
10753
+ logger.warn(`File '${key}' not found`);
10756
10754
  logger.newLine();
10757
- logger.admonition("tip", "Getting Started", [
10758
- "Run `playcademy bucket init` to enable bucket storage"
10755
+ logger.admonition("tip", "Hint", [
10756
+ "Use `playcademy bucket list` to see all available files"
10759
10757
  ]);
10760
10758
  logger.newLine();
10761
10759
  }
10762
10760
  process.exit(1);
10763
10761
  }
10764
- const bundle = await bundleBackend(config, {
10765
- sourcemap: false,
10766
- minify: false
10767
- });
10768
- const bucketDir = join32(getWorkspace(), CLI_DIRECTORIES.BUCKET);
10769
- const mf = new Miniflare11({
10770
- modules: [
10771
- {
10772
- type: "ESModule",
10773
- path: "index.mjs",
10774
- contents: bundle.code
10775
- }
10776
- ],
10777
- r2Buckets: ["BUCKET"],
10778
- r2Persist: bucketDir,
10779
- compatibilityDate: CLOUDFLARE_COMPATIBILITY_DATE
10780
- });
10781
- try {
10782
- const bucket = await mf.getR2Bucket("BUCKET");
10783
- const object = await bucket.get(key);
10784
- if (!object) {
10785
- if (!options.raw && !options.json) {
10786
- logger.warn(`File '${key}' not found`);
10787
- logger.newLine();
10788
- logger.admonition("tip", "Hint", [
10789
- "Use `playcademy bucket list` to see all available files"
10790
- ]);
10791
- logger.newLine();
10792
- }
10793
- process.exit(1);
10794
- }
10795
- await bucket.delete(key);
10796
- if (options.json) {
10797
- logger.json({
10798
- success: true,
10799
- key,
10800
- message: "File deleted successfully"
10801
- });
10802
- return;
10803
- }
10804
- if (options.raw) {
10805
- logger.raw(`Deleted ${key}`);
10806
- return;
10807
- }
10808
- logger.success(`Deleted '${key}'`);
10762
+ await bucket.delete(key);
10763
+ if (options.json) {
10764
+ logger.json({
10765
+ success: true,
10766
+ key,
10767
+ message: "File deleted successfully"
10768
+ });
10769
+ return;
10770
+ }
10771
+ if (options.raw) {
10772
+ logger.raw(`Deleted ${key}`);
10773
+ return;
10774
+ }
10775
+ logger.success(`Deleted '${key}'`);
10776
+ logger.newLine();
10777
+ } finally {
10778
+ await mf.dispose();
10779
+ }
10780
+ }
10781
+ async function runBucketDelete(key, options = {}) {
10782
+ try {
10783
+ if (!options.raw && !options.json) {
10809
10784
  logger.newLine();
10810
- } finally {
10811
- await mf.dispose();
10785
+ }
10786
+ if (options.remote) {
10787
+ await runBucketDeleteRemote(key, options);
10788
+ } else {
10789
+ await runBucketDeleteLocal(key, options);
10812
10790
  }
10813
10791
  } catch (error) {
10814
10792
  if (!options.raw && !options.json) {
@@ -10826,116 +10804,167 @@ init_constants2();
10826
10804
  import { writeFileSync as writeFileSync10 } from "fs";
10827
10805
  import { join as join33 } from "path";
10828
10806
  import { Miniflare as Miniflare12 } from "miniflare";
10829
- async function runBucketGet(key, options = {}) {
10830
- try {
10807
+ async function runBucketGetRemote(key, options) {
10808
+ const environment = ensureEnvironment(options.env);
10809
+ const client = await requireAuthenticatedClient();
10810
+ const workspace = getWorkspace();
10811
+ const deployedGame = await getDeployedGame(workspace);
10812
+ if (!deployedGame) {
10831
10813
  if (!options.raw && !options.json) {
10814
+ logger.admonition("warning", "Deploy First", [
10815
+ `Deploy your game before accessing remote bucket: \`playcademy deploy\``
10816
+ ]);
10832
10817
  logger.newLine();
10833
10818
  }
10834
- if (options.remote) {
10819
+ process.exit(1);
10820
+ }
10821
+ const game = await client.games.fetch(deployedGame.gameId);
10822
+ let arrayBuffer;
10823
+ try {
10824
+ arrayBuffer = await client.dev.games.bucket.get(game.slug, key);
10825
+ } catch (error) {
10826
+ const errorMessage = error instanceof Error ? error.message : String(error);
10827
+ if (errorMessage.includes("not found")) {
10835
10828
  if (!options.raw && !options.json) {
10829
+ logger.warn(`File '${key}' not found in ${environment}`);
10836
10830
  logger.newLine();
10837
- logger.warn("Remote bucket operations are not yet implemented");
10838
- logger.newLine();
10839
- logger.admonition("info", "Coming Soon", [
10840
- "Remote bucket support is on the roadmap and will be available soon.",
10841
- "For now, bucket commands only work with local development storage."
10831
+ logger.admonition("note", "Hint", [
10832
+ `Use \`playcademy bucket list --remote\` to see all available files`
10842
10833
  ]);
10843
10834
  logger.newLine();
10844
10835
  }
10845
10836
  process.exit(1);
10846
10837
  }
10847
- if (!key) {
10838
+ throw error;
10839
+ }
10840
+ if (options.json) {
10841
+ logger.json({
10842
+ key,
10843
+ size: arrayBuffer.byteLength,
10844
+ message: "Use --output to save file"
10845
+ });
10846
+ return;
10847
+ }
10848
+ if (options.output) {
10849
+ writeFileSync10(options.output, Buffer.from(arrayBuffer));
10850
+ if (!options.raw) {
10851
+ logger.newLine();
10852
+ logger.success(`Downloaded '${key}' from ${environment} to '${options.output}'`);
10853
+ logger.newLine();
10854
+ logger.data("Size", `${arrayBuffer.byteLength} bytes`, 1);
10855
+ logger.newLine();
10856
+ }
10857
+ return;
10858
+ }
10859
+ if (options.raw) {
10860
+ process.stdout.write(Buffer.from(arrayBuffer));
10861
+ return;
10862
+ }
10863
+ logger.newLine();
10864
+ logger.success(`File: ${key}`);
10865
+ logger.newLine();
10866
+ logger.data("Size", `${arrayBuffer.byteLength} bytes`, 1);
10867
+ logger.data("Environment", environment, 1);
10868
+ logger.newLine();
10869
+ logger.admonition("tip", "Download File", [
10870
+ `Use \`playcademy bucket get ${key} --output path/to/file --remote\` to download`
10871
+ ]);
10872
+ logger.newLine();
10873
+ }
10874
+ async function runBucketGetLocal(key, options) {
10875
+ if (!key) {
10876
+ if (!options.raw && !options.json) {
10877
+ logger.error("File key is required");
10878
+ logger.newLine();
10879
+ logger.admonition("tip", "Usage", ["`playcademy bucket get <key> --output <file>`"]);
10880
+ logger.newLine();
10881
+ }
10882
+ process.exit(1);
10883
+ }
10884
+ const config = await loadConfig();
10885
+ if (!hasBucketSetup(config)) {
10886
+ if (!options.raw && !options.json) {
10887
+ logger.error("Bucket storage is not configured");
10888
+ logger.newLine();
10889
+ logger.admonition("tip", "Getting Started", [
10890
+ "Run `playcademy bucket init` to enable bucket storage"
10891
+ ]);
10892
+ logger.newLine();
10893
+ }
10894
+ process.exit(1);
10895
+ }
10896
+ const bucketDir = join33(getWorkspace(), CLI_DIRECTORIES.BUCKET);
10897
+ const mf = new Miniflare12({
10898
+ modules: [{ type: "ESModule", path: "index.mjs", contents: "" }],
10899
+ r2Buckets: ["BUCKET"],
10900
+ r2Persist: bucketDir,
10901
+ compatibilityDate: CLOUDFLARE_COMPATIBILITY_DATE
10902
+ });
10903
+ try {
10904
+ const bucket = await mf.getR2Bucket("BUCKET");
10905
+ const object = await bucket.get(key);
10906
+ if (!object) {
10848
10907
  if (!options.raw && !options.json) {
10849
- logger.error("File key is required");
10908
+ logger.warn(`Failed to get object: File '${key}' not found`);
10850
10909
  logger.newLine();
10851
- logger.admonition("tip", "Usage", ["`playcademy bucket get <key> --output <file>`"]);
10910
+ logger.admonition("tip", "Hint", [
10911
+ "Use `playcademy bucket list` to see all available files"
10912
+ ]);
10852
10913
  logger.newLine();
10853
10914
  }
10854
10915
  process.exit(1);
10855
10916
  }
10856
- const config = await loadConfig();
10857
- if (!hasBucketSetup(config)) {
10858
- if (!options.raw && !options.json) {
10859
- logger.error("Bucket storage is not configured");
10917
+ if (options.json) {
10918
+ const metadata = {
10919
+ key: object.key,
10920
+ size: object.size,
10921
+ uploaded: object.uploaded.toISOString(),
10922
+ httpMetadata: object.httpMetadata,
10923
+ customMetadata: object.customMetadata
10924
+ };
10925
+ logger.json(metadata);
10926
+ return;
10927
+ }
10928
+ if (options.output) {
10929
+ const buffer = await object.arrayBuffer();
10930
+ writeFileSync10(options.output, Buffer.from(buffer));
10931
+ if (!options.raw) {
10932
+ logger.success(`Downloaded '${key}' to '${options.output}'`);
10860
10933
  logger.newLine();
10861
- logger.admonition("tip", "Getting Started", [
10862
- "Run `playcademy bucket init` to enable bucket storage"
10863
- ]);
10934
+ logger.data("Size", `${object.size} bytes`, 1);
10935
+ logger.data("Content-Type", object.httpMetadata?.contentType || "unknown", 1);
10864
10936
  logger.newLine();
10865
10937
  }
10866
- process.exit(1);
10938
+ return;
10867
10939
  }
10868
- const bundle = await bundleBackend(config, {
10869
- sourcemap: false,
10870
- minify: false
10871
- });
10872
- const bucketDir = join33(getWorkspace(), CLI_DIRECTORIES.BUCKET);
10873
- const mf = new Miniflare12({
10874
- modules: [
10875
- {
10876
- type: "ESModule",
10877
- path: "index.mjs",
10878
- contents: bundle.code
10879
- }
10880
- ],
10881
- r2Buckets: ["BUCKET"],
10882
- r2Persist: bucketDir,
10883
- compatibilityDate: CLOUDFLARE_COMPATIBILITY_DATE
10884
- });
10885
- try {
10886
- const bucket = await mf.getR2Bucket("BUCKET");
10887
- const object = await bucket.get(key);
10888
- if (!object) {
10889
- if (!options.raw && !options.json) {
10890
- logger.warn(`File '${key}' not found`);
10891
- logger.newLine();
10892
- logger.admonition("tip", "Hint", [
10893
- "Use `playcademy bucket list` to see all available files"
10894
- ]);
10895
- logger.newLine();
10896
- }
10897
- process.exit(1);
10898
- }
10899
- if (options.json) {
10900
- const metadata = {
10901
- key: object.key,
10902
- size: object.size,
10903
- uploaded: object.uploaded.toISOString(),
10904
- httpMetadata: object.httpMetadata,
10905
- customMetadata: object.customMetadata
10906
- };
10907
- logger.json(metadata);
10908
- return;
10909
- }
10910
- if (options.output) {
10911
- const buffer = await object.arrayBuffer();
10912
- writeFileSync10(options.output, Buffer.from(buffer));
10913
- if (!options.raw) {
10914
- logger.success(`Downloaded '${key}' to '${options.output}'`);
10915
- logger.newLine();
10916
- logger.data("Size", `${object.size} bytes`, 1);
10917
- logger.data("Content-Type", object.httpMetadata?.contentType || "unknown", 1);
10918
- logger.newLine();
10919
- }
10920
- return;
10921
- }
10922
- if (options.raw) {
10923
- const text5 = await object.text();
10924
- logger.raw(text5);
10925
- return;
10926
- }
10927
- logger.success(`File: ${key}`);
10928
- logger.newLine();
10929
- logger.data("Size", `${object.size} bytes`, 1);
10930
- logger.data("Content-Type", object.httpMetadata?.contentType || "unknown", 1);
10931
- logger.data("Uploaded", new Date(object.uploaded).toLocaleString(), 1);
10932
- logger.newLine();
10933
- logger.admonition("tip", "Download File", [
10934
- `Use \`playcademy bucket get ${key} --output <file>\` to download`
10935
- ]);
10940
+ if (options.raw) {
10941
+ const text5 = await object.text();
10942
+ logger.raw(text5);
10943
+ return;
10944
+ }
10945
+ logger.success(`File: ${key}`);
10946
+ logger.newLine();
10947
+ logger.data("Size", `${object.size} bytes`, 1);
10948
+ logger.data("Content-Type", object.httpMetadata?.contentType || "unknown", 1);
10949
+ logger.data("Uploaded", new Date(object.uploaded).toLocaleString(), 1);
10950
+ logger.newLine();
10951
+ logger.admonition("tip", "Download File", [
10952
+ `Use \`playcademy bucket get ${key} --output <file>\` to download`
10953
+ ]);
10954
+ logger.newLine();
10955
+ } finally {
10956
+ await mf.dispose();
10957
+ }
10958
+ }
10959
+ async function runBucketGet(key, options = {}) {
10960
+ try {
10961
+ if (!options.raw && !options.json) {
10936
10962
  logger.newLine();
10937
- } finally {
10938
- await mf.dispose();
10963
+ }
10964
+ if (options.remote) {
10965
+ await runBucketGetRemote(key, options);
10966
+ } else {
10967
+ await runBucketGetLocal(key, options);
10939
10968
  }
10940
10969
  } catch (error) {
10941
10970
  if (!options.raw && !options.json) {
@@ -11026,102 +11055,138 @@ async function runBucketInit() {
11026
11055
  init_constants2();
11027
11056
  import { join as join34 } from "path";
11028
11057
  import { Miniflare as Miniflare13 } from "miniflare";
11029
- async function runBucketList(options = {}) {
11030
- try {
11058
+ async function runBucketListRemote(options) {
11059
+ const environment = ensureEnvironment(options.env);
11060
+ const client = await requireAuthenticatedClient();
11061
+ const workspace = getWorkspace();
11062
+ const deployedGame = await getDeployedGame(workspace);
11063
+ if (!deployedGame) {
11031
11064
  if (!options.raw && !options.json) {
11065
+ logger.admonition("warning", "Deploy First", [
11066
+ `Deploy your game before accessing remote bucket: \`playcademy deploy\``
11067
+ ]);
11032
11068
  logger.newLine();
11033
11069
  }
11034
- if (options.remote) {
11035
- if (!options.raw && !options.json) {
11036
- logger.newLine();
11037
- logger.warn("Remote bucket operations are not yet implemented");
11038
- logger.newLine();
11039
- logger.admonition("info", "Coming Soon", [
11040
- "Remote bucket support is on the roadmap and will be available soon.",
11041
- "For now, bucket commands only work with local development storage."
11042
- ]);
11043
- logger.newLine();
11044
- }
11045
- process.exit(1);
11070
+ process.exit(1);
11071
+ }
11072
+ const game = await client.games.fetch(deployedGame.gameId);
11073
+ const files = await client.dev.games.bucket.list(game.slug, options.prefix);
11074
+ if (options.json) {
11075
+ logger.json(files);
11076
+ return;
11077
+ }
11078
+ if (options.raw) {
11079
+ for (const file of files) {
11080
+ logger.raw(file.key);
11046
11081
  }
11047
- const config = await loadConfig();
11048
- if (!hasBucketSetup(config)) {
11049
- if (!options.raw && !options.json) {
11050
- logger.error("Bucket storage is not configured");
11051
- logger.newLine();
11052
- logger.admonition("tip", "Getting Started", [
11053
- "Run `playcademy bucket init` to enable bucket storage"
11054
- ]);
11055
- logger.newLine();
11056
- }
11057
- process.exit(1);
11082
+ return;
11083
+ }
11084
+ if (!options.raw && !options.json) {
11085
+ logger.newLine();
11086
+ }
11087
+ if (files.length === 0) {
11088
+ logger.remark("No files found in remote bucket");
11089
+ if (options.prefix) {
11090
+ logger.newLine();
11091
+ logger.data("Prefix", options.prefix, 1);
11058
11092
  }
11059
- const bundle = await bundleBackend(config, {
11060
- sourcemap: false,
11061
- minify: false
11062
- });
11063
- const bucketDir = join34(getWorkspace(), CLI_DIRECTORIES.BUCKET);
11064
- const mf = new Miniflare13({
11065
- modules: [
11066
- {
11067
- type: "ESModule",
11068
- path: "index.mjs",
11069
- contents: bundle.code
11070
- }
11071
- ],
11072
- r2Buckets: ["BUCKET"],
11073
- r2Persist: bucketDir,
11074
- compatibilityDate: CLOUDFLARE_COMPATIBILITY_DATE
11075
- });
11076
- try {
11077
- const bucket = await mf.getR2Bucket("BUCKET");
11078
- const listed = await bucket.list({ prefix: options.prefix });
11079
- const files = listed.objects;
11080
- if (options.json) {
11081
- const fileData = files.map((obj) => ({
11082
- key: obj.key,
11083
- size: obj.size,
11084
- uploaded: obj.uploaded.toISOString()
11085
- }));
11086
- logger.json(fileData);
11087
- return;
11088
- }
11089
- if (options.raw) {
11090
- for (const file of files) {
11091
- logger.raw(file.key);
11092
- }
11093
- return;
11094
- }
11095
- if (files.length === 0) {
11096
- logger.remark("No files found in bucket");
11097
- if (options.prefix) {
11098
- logger.newLine();
11099
- logger.data("Prefix", options.prefix, 1);
11100
- }
11101
- logger.newLine();
11102
- return;
11093
+ logger.newLine();
11094
+ return;
11095
+ }
11096
+ logger.success(`Found ${files.length} file${files.length === 1 ? "" : "s"} in ${environment}`);
11097
+ if (options.prefix) {
11098
+ logger.data("Prefix", options.prefix, 1);
11099
+ }
11100
+ logger.newLine();
11101
+ logger.table(
11102
+ files.map((file) => ({
11103
+ Key: file.key,
11104
+ Size: formatBytes(file.size),
11105
+ Uploaded: new Date(file.uploaded).toLocaleString()
11106
+ }))
11107
+ );
11108
+ logger.newLine();
11109
+ }
11110
+ async function runBucketListLocal(options) {
11111
+ const config = await loadConfig();
11112
+ if (!hasBucketSetup(config)) {
11113
+ if (!options.raw && !options.json) {
11114
+ logger.error("Bucket storage is not configured");
11115
+ logger.newLine();
11116
+ logger.admonition("tip", "Getting Started", [
11117
+ "Run `playcademy bucket init` to enable bucket storage"
11118
+ ]);
11119
+ logger.newLine();
11120
+ }
11121
+ process.exit(1);
11122
+ }
11123
+ const bucketDir = join34(getWorkspace(), CLI_DIRECTORIES.BUCKET);
11124
+ const mf = new Miniflare13({
11125
+ modules: [{ type: "ESModule", path: "index.mjs", contents: "" }],
11126
+ r2Buckets: ["BUCKET"],
11127
+ r2Persist: bucketDir,
11128
+ compatibilityDate: CLOUDFLARE_COMPATIBILITY_DATE
11129
+ });
11130
+ try {
11131
+ const bucket = await mf.getR2Bucket("BUCKET");
11132
+ const listed = await bucket.list({ prefix: options.prefix });
11133
+ const files = listed.objects;
11134
+ if (options.json) {
11135
+ const fileData = files.map((obj) => ({
11136
+ key: obj.key,
11137
+ size: obj.size,
11138
+ uploaded: obj.uploaded.toISOString()
11139
+ }));
11140
+ logger.json(fileData);
11141
+ return;
11142
+ }
11143
+ if (options.raw) {
11144
+ for (const file of files) {
11145
+ logger.raw(file.key);
11103
11146
  }
11104
- logger.success(`Found ${files.length} file${files.length === 1 ? "" : "s"}`);
11147
+ return;
11148
+ }
11149
+ if (files.length === 0) {
11150
+ logger.remark("No files found in bucket");
11105
11151
  if (options.prefix) {
11152
+ logger.newLine();
11106
11153
  logger.data("Prefix", options.prefix, 1);
11107
11154
  }
11108
11155
  logger.newLine();
11109
- logger.table(
11110
- files.map((obj) => ({
11111
- Key: obj.key,
11112
- Size: formatBytes(obj.size),
11113
- Uploaded: new Date(obj.uploaded).toLocaleString()
11114
- }))
11115
- );
11156
+ return;
11157
+ }
11158
+ logger.success(`Found ${files.length} file${files.length === 1 ? "" : "s"}`);
11159
+ if (options.prefix) {
11160
+ logger.data("Prefix", options.prefix, 1);
11161
+ }
11162
+ logger.newLine();
11163
+ logger.table(
11164
+ files.map((obj) => ({
11165
+ Key: obj.key,
11166
+ Size: formatBytes(obj.size),
11167
+ Uploaded: new Date(obj.uploaded).toLocaleString()
11168
+ }))
11169
+ );
11170
+ logger.newLine();
11171
+ if (listed.truncated) {
11172
+ logger.admonition("info", "Truncated Results", [
11173
+ "The list was truncated. Use --prefix to narrow down results."
11174
+ ]);
11116
11175
  logger.newLine();
11117
- if (listed.truncated) {
11118
- logger.admonition("info", "Truncated Results", [
11119
- "The list was truncated. Use --prefix to narrow down results."
11120
- ]);
11121
- logger.newLine();
11122
- }
11123
- } finally {
11124
- await mf.dispose();
11176
+ }
11177
+ } finally {
11178
+ await mf.dispose();
11179
+ }
11180
+ }
11181
+ async function runBucketList(options = {}) {
11182
+ try {
11183
+ if (!options.raw && !options.json) {
11184
+ logger.newLine();
11185
+ }
11186
+ if (options.remote) {
11187
+ await runBucketListRemote(options);
11188
+ } else {
11189
+ await runBucketListLocal(options);
11125
11190
  }
11126
11191
  } catch (error) {
11127
11192
  if (!options.raw && !options.json) {
@@ -11146,102 +11211,134 @@ init_constants2();
11146
11211
  import { readFileSync as readFileSync8, statSync as statSync2 } from "fs";
11147
11212
  import { join as join35 } from "path";
11148
11213
  import { Miniflare as Miniflare14 } from "miniflare";
11149
- async function runBucketPut(key, filePath, options = {}) {
11214
+ async function runBucketPutRemote(key, filePath, options) {
11215
+ const environment = ensureEnvironment(options.env);
11216
+ const client = await requireAuthenticatedClient();
11217
+ const workspace = getWorkspace();
11218
+ const deployedGame = await getDeployedGame(workspace);
11219
+ if (!deployedGame) {
11220
+ if (!options.raw && !options.json) {
11221
+ logger.admonition("warning", "Deploy First", [
11222
+ `Deploy your game before accessing remote bucket: \`playcademy deploy\``
11223
+ ]);
11224
+ logger.newLine();
11225
+ }
11226
+ process.exit(1);
11227
+ }
11228
+ let fileBuffer;
11229
+ let fileSize;
11150
11230
  try {
11231
+ fileBuffer = readFileSync8(filePath);
11232
+ fileSize = statSync2(filePath).size;
11233
+ } catch {
11151
11234
  if (!options.raw && !options.json) {
11235
+ logger.error(`File not found: ${filePath}`);
11152
11236
  logger.newLine();
11153
11237
  }
11154
- if (options.remote) {
11155
- if (!options.raw && !options.json) {
11156
- logger.newLine();
11157
- logger.warn("Remote bucket operations are not yet implemented");
11158
- logger.newLine();
11159
- logger.admonition("info", "Coming Soon", [
11160
- "Remote bucket support is on the roadmap and will be available soon.",
11161
- "For now, bucket commands only work with local development storage."
11162
- ]);
11163
- logger.newLine();
11164
- }
11165
- process.exit(1);
11238
+ process.exit(1);
11239
+ }
11240
+ const game = await client.games.fetch(deployedGame.gameId);
11241
+ const contentType = getContentType(filePath);
11242
+ await client.dev.games.bucket.put(game.slug, key, fileBuffer, contentType);
11243
+ if (options.json) {
11244
+ logger.json({
11245
+ success: true,
11246
+ key,
11247
+ size: fileSize,
11248
+ uploaded: (/* @__PURE__ */ new Date()).toISOString()
11249
+ });
11250
+ return;
11251
+ }
11252
+ if (options.raw) {
11253
+ logger.raw(`Uploaded ${key}`);
11254
+ return;
11255
+ }
11256
+ logger.newLine();
11257
+ logger.success(`Uploaded '${filePath}' to '${key}' in ${environment}`);
11258
+ logger.newLine();
11259
+ logger.data("Size", `${fileSize} bytes`, 1);
11260
+ logger.data("Content-Type", contentType, 1);
11261
+ logger.newLine();
11262
+ }
11263
+ async function runBucketPutLocal(key, filePath, options) {
11264
+ if (!key || !filePath) {
11265
+ if (!options.raw && !options.json) {
11266
+ logger.error("File key and path are required");
11267
+ logger.newLine();
11268
+ logger.admonition("tip", "Usage", ["`playcademy bucket put <key> <file>`"]);
11269
+ logger.newLine();
11166
11270
  }
11167
- if (!key || !filePath) {
11168
- if (!options.raw && !options.json) {
11169
- logger.error("File key and path are required");
11170
- logger.newLine();
11171
- logger.admonition("tip", "Usage", ["`playcademy bucket put <key> <file>`"]);
11172
- logger.newLine();
11173
- }
11174
- process.exit(1);
11271
+ process.exit(1);
11272
+ }
11273
+ const config = await loadConfig();
11274
+ if (!hasBucketSetup(config)) {
11275
+ if (!options.raw && !options.json) {
11276
+ logger.error("Bucket storage is not configured");
11277
+ logger.newLine();
11278
+ logger.admonition("tip", "Getting Started", [
11279
+ "Run `playcademy bucket init` to enable bucket storage"
11280
+ ]);
11281
+ logger.newLine();
11175
11282
  }
11176
- const config = await loadConfig();
11177
- if (!hasBucketSetup(config)) {
11178
- if (!options.raw && !options.json) {
11179
- logger.error("Bucket storage is not configured");
11180
- logger.newLine();
11181
- logger.admonition("tip", "Getting Started", [
11182
- "Run `playcademy bucket init` to enable bucket storage"
11183
- ]);
11184
- logger.newLine();
11185
- }
11186
- process.exit(1);
11283
+ process.exit(1);
11284
+ }
11285
+ let fileBuffer;
11286
+ let fileSize;
11287
+ try {
11288
+ fileBuffer = readFileSync8(filePath);
11289
+ fileSize = statSync2(filePath).size;
11290
+ } catch {
11291
+ if (!options.raw && !options.json) {
11292
+ logger.error(`File not found: ${filePath}`);
11293
+ logger.newLine();
11187
11294
  }
11188
- let fileBuffer;
11189
- let fileSize;
11190
- try {
11191
- fileBuffer = readFileSync8(filePath);
11192
- fileSize = statSync2(filePath).size;
11193
- } catch {
11194
- if (!options.raw && !options.json) {
11195
- logger.error(`File not found: ${filePath}`);
11196
- logger.newLine();
11295
+ process.exit(1);
11296
+ }
11297
+ const bucketDir = join35(getWorkspace(), CLI_DIRECTORIES.BUCKET);
11298
+ const mf = new Miniflare14({
11299
+ modules: [{ type: "ESModule", path: "index.mjs", contents: "" }],
11300
+ r2Buckets: ["BUCKET"],
11301
+ r2Persist: bucketDir,
11302
+ compatibilityDate: CLOUDFLARE_COMPATIBILITY_DATE
11303
+ });
11304
+ try {
11305
+ const bucket = await mf.getR2Bucket("BUCKET");
11306
+ await bucket.put(key, new Uint8Array(fileBuffer).buffer, {
11307
+ httpMetadata: {
11308
+ contentType: getContentType(filePath)
11197
11309
  }
11198
- process.exit(1);
11199
- }
11200
- const bundle = await bundleBackend(config, {
11201
- sourcemap: false,
11202
- minify: false
11203
- });
11204
- const bucketDir = join35(getWorkspace(), CLI_DIRECTORIES.BUCKET);
11205
- const mf = new Miniflare14({
11206
- modules: [
11207
- {
11208
- type: "ESModule",
11209
- path: "index.mjs",
11210
- contents: bundle.code
11211
- }
11212
- ],
11213
- r2Buckets: ["BUCKET"],
11214
- r2Persist: bucketDir,
11215
- compatibilityDate: CLOUDFLARE_COMPATIBILITY_DATE
11216
11310
  });
11217
- try {
11218
- const bucket = await mf.getR2Bucket("BUCKET");
11219
- const contentType = getContentType(filePath);
11220
- await bucket.put(key, fileBuffer, {
11221
- httpMetadata: {
11222
- contentType
11223
- }
11311
+ if (options.json) {
11312
+ logger.json({
11313
+ success: true,
11314
+ key,
11315
+ size: fileSize,
11316
+ uploaded: (/* @__PURE__ */ new Date()).toISOString()
11224
11317
  });
11225
- if (options.json) {
11226
- logger.json({
11227
- success: true,
11228
- key,
11229
- size: fileSize,
11230
- uploaded: (/* @__PURE__ */ new Date()).toISOString()
11231
- });
11232
- return;
11233
- }
11234
- if (options.raw) {
11235
- logger.raw(`Uploaded ${key}`);
11236
- return;
11237
- }
11238
- logger.success(`Uploaded '${filePath}' to '${key}'`);
11239
- logger.newLine();
11240
- logger.data("Size", `${fileSize} bytes`, 1);
11241
- logger.data("Content-Type", contentType, 1);
11318
+ return;
11319
+ }
11320
+ if (options.raw) {
11321
+ logger.raw(`Uploaded ${key}`);
11322
+ return;
11323
+ }
11324
+ logger.success(`Uploaded '${filePath}' to '${key}'`);
11325
+ logger.newLine();
11326
+ logger.data("Size", `${fileSize} bytes`, 1);
11327
+ logger.data("Content-Type", getContentType(filePath), 1);
11328
+ logger.newLine();
11329
+ } finally {
11330
+ await mf.dispose();
11331
+ }
11332
+ }
11333
+ async function runBucketPut(key, filePath, options = {}) {
11334
+ try {
11335
+ if (!options.raw && !options.json) {
11242
11336
  logger.newLine();
11243
- } finally {
11244
- await mf.dispose();
11337
+ }
11338
+ if (options.remote) {
11339
+ await runBucketPutRemote(key, filePath, options);
11340
+ } else {
11341
+ await runBucketPutLocal(key, filePath, options);
11245
11342
  }
11246
11343
  } catch (error) {
11247
11344
  if (!options.raw && !options.json) {
@@ -11253,29 +11350,6 @@ async function runBucketPut(key, filePath, options = {}) {
11253
11350
  process.exit(1);
11254
11351
  }
11255
11352
  }
11256
- function getContentType(filePath) {
11257
- const ext = filePath.split(".").pop()?.toLowerCase();
11258
- const types = {
11259
- jpg: "image/jpeg",
11260
- jpeg: "image/jpeg",
11261
- png: "image/png",
11262
- gif: "image/gif",
11263
- webp: "image/webp",
11264
- svg: "image/svg+xml",
11265
- mp3: "audio/mpeg",
11266
- wav: "audio/wav",
11267
- ogg: "audio/ogg",
11268
- mp4: "video/mp4",
11269
- webm: "video/webm",
11270
- pdf: "application/pdf",
11271
- json: "application/json",
11272
- txt: "text/plain",
11273
- html: "text/html",
11274
- css: "text/css",
11275
- js: "application/javascript"
11276
- };
11277
- return types[ext || ""] || "application/octet-stream";
11278
- }
11279
11353
 
11280
11354
  // src/commands/bucket/index.ts
11281
11355
  var bucketCommand = new Command16("bucket").description("Manage bucket storage integration").action(() => {
@@ -12139,6 +12213,7 @@ export {
12139
12213
  getBestUnit,
12140
12214
  getCallbackUrl,
12141
12215
  getCliContext,
12216
+ getContentType,
12142
12217
  getCurrentProfile,
12143
12218
  getCustomRoutesDirectory,
12144
12219
  getCustomRoutesHash,
package/dist/utils.js CHANGED
@@ -1292,6 +1292,13 @@ var init_import = __esm({
1292
1292
  }
1293
1293
  });
1294
1294
 
1295
+ // src/lib/core/mime.ts
1296
+ var init_mime2 = __esm({
1297
+ "src/lib/core/mime.ts"() {
1298
+ "use strict";
1299
+ }
1300
+ });
1301
+
1295
1302
  // src/lib/core/index.ts
1296
1303
  var init_core = __esm({
1297
1304
  "src/lib/core/index.ts"() {
@@ -1303,6 +1310,7 @@ var init_core = __esm({
1303
1310
  init_game();
1304
1311
  init_import();
1305
1312
  init_logger();
1313
+ init_mime2();
1306
1314
  }
1307
1315
  });
1308
1316
 
@@ -1434,6 +1442,9 @@ var isDevelopment = () => {
1434
1442
  var isInteractiveTTY = () => {
1435
1443
  return typeof process !== "undefined" && Boolean(process.stdout && process.stdout.isTTY);
1436
1444
  };
1445
+ var isSilent = () => {
1446
+ return typeof process !== "undefined" && process.env.LOG_SILENT === "true";
1447
+ };
1437
1448
  var detectOutputFormat = () => {
1438
1449
  if (isBrowser()) {
1439
1450
  return "browser";
@@ -1554,6 +1565,7 @@ var getMinimumLogLevel = () => {
1554
1565
  return isProduction() ? "info" : "debug";
1555
1566
  };
1556
1567
  var shouldLog = (level) => {
1568
+ if (isSilent()) return false;
1557
1569
  const minLevel = getMinimumLogLevel();
1558
1570
  return levelPriority[level] >= levelPriority[minLevel];
1559
1571
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "playcademy",
3
- "version": "0.13.21",
3
+ "version": "0.13.23",
4
4
  "type": "module",
5
5
  "module": "./dist/index.js",
6
6
  "main": "./dist/index.js",
@@ -40,7 +40,7 @@
40
40
  },
41
41
  "dependencies": {
42
42
  "@inquirer/prompts": "^7.8.6",
43
- "@playcademy/sdk": "0.1.9",
43
+ "@playcademy/sdk": "0.1.11",
44
44
  "better-sqlite3": "^12.4.1",
45
45
  "chokidar": "^4.0.3",
46
46
  "colorette": "^2.0.20",