@quenty/nevermore-cli 4.46.0 → 4.47.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (84) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/dist/commands/batch-command/batch-deploy-command.d.ts.map +1 -1
  3. package/dist/commands/batch-command/batch-deploy-command.js +4 -3
  4. package/dist/commands/batch-command/batch-deploy-command.js.map +1 -1
  5. package/dist/commands/deploy-command/asset-command.d.ts +44 -0
  6. package/dist/commands/deploy-command/asset-command.d.ts.map +1 -0
  7. package/dist/commands/deploy-command/asset-command.js +182 -0
  8. package/dist/commands/deploy-command/asset-command.js.map +1 -0
  9. package/dist/commands/deploy-command/index.d.ts.map +1 -1
  10. package/dist/commands/deploy-command/index.js +62 -0
  11. package/dist/commands/deploy-command/index.js.map +1 -1
  12. package/dist/utils/assets/asset-creator.d.ts +32 -0
  13. package/dist/utils/assets/asset-creator.d.ts.map +1 -0
  14. package/dist/utils/assets/asset-creator.js +62 -0
  15. package/dist/utils/assets/asset-creator.js.map +1 -0
  16. package/dist/utils/assets/asset-creator.test.d.ts +2 -0
  17. package/dist/utils/assets/asset-creator.test.d.ts.map +1 -0
  18. package/dist/utils/assets/asset-creator.test.js +71 -0
  19. package/dist/utils/assets/asset-creator.test.js.map +1 -0
  20. package/dist/utils/assets/asset-formats.d.ts +28 -0
  21. package/dist/utils/assets/asset-formats.d.ts.map +1 -0
  22. package/dist/utils/assets/asset-formats.js +72 -0
  23. package/dist/utils/assets/asset-formats.js.map +1 -0
  24. package/dist/utils/assets/asset-formats.test.d.ts +2 -0
  25. package/dist/utils/assets/asset-formats.test.d.ts.map +1 -0
  26. package/dist/utils/assets/asset-formats.test.js +43 -0
  27. package/dist/utils/assets/asset-formats.test.js.map +1 -0
  28. package/dist/utils/assets/asset-upload-plan.d.ts +27 -0
  29. package/dist/utils/assets/asset-upload-plan.d.ts.map +1 -0
  30. package/dist/utils/assets/asset-upload-plan.js +43 -0
  31. package/dist/utils/assets/asset-upload-plan.js.map +1 -0
  32. package/dist/utils/assets/asset-upload-plan.test.d.ts +2 -0
  33. package/dist/utils/assets/asset-upload-plan.test.d.ts.map +1 -0
  34. package/dist/utils/assets/asset-upload-plan.test.js +57 -0
  35. package/dist/utils/assets/asset-upload-plan.test.js.map +1 -0
  36. package/dist/utils/build/upload.d.ts.map +1 -1
  37. package/dist/utils/build/upload.js +4 -1
  38. package/dist/utils/build/upload.js.map +1 -1
  39. package/dist/utils/job-context/cloud-job-context.d.ts.map +1 -1
  40. package/dist/utils/job-context/cloud-job-context.js +5 -3
  41. package/dist/utils/job-context/cloud-job-context.js.map +1 -1
  42. package/dist/utils/open-cloud/open-cloud-client.d.ts +81 -4
  43. package/dist/utils/open-cloud/open-cloud-client.d.ts.map +1 -1
  44. package/dist/utils/open-cloud/open-cloud-client.js +172 -11
  45. package/dist/utils/open-cloud/open-cloud-client.js.map +1 -1
  46. package/dist/utils/open-cloud/open-cloud-client.test.js +258 -0
  47. package/dist/utils/open-cloud/open-cloud-client.test.js.map +1 -1
  48. package/dist/utils/open-cloud/rate-limiter.d.ts +29 -2
  49. package/dist/utils/open-cloud/rate-limiter.d.ts.map +1 -1
  50. package/dist/utils/open-cloud/rate-limiter.js +98 -20
  51. package/dist/utils/open-cloud/rate-limiter.js.map +1 -1
  52. package/dist/utils/open-cloud/rate-limiter.test.js +64 -4
  53. package/dist/utils/open-cloud/rate-limiter.test.js.map +1 -1
  54. package/dist/utils/testing/parsers/batch-log-parser.test.js +1 -1
  55. package/dist/utils/testing/parsers/batch-log-parser.test.js.map +1 -1
  56. package/dist/utils/testing/runner/test-runner.d.ts.map +1 -1
  57. package/dist/utils/testing/runner/test-runner.js +8 -7
  58. package/dist/utils/testing/runner/test-runner.js.map +1 -1
  59. package/dist/utils/testing/runner/test-runner.test.js +1 -1
  60. package/dist/utils/testing/runner/test-runner.test.js.map +1 -1
  61. package/package.json +4 -4
  62. package/src/commands/batch-command/batch-deploy-command.ts +11 -3
  63. package/src/commands/deploy-command/asset-command.ts +279 -0
  64. package/src/commands/deploy-command/index.ts +85 -0
  65. package/src/utils/assets/asset-creator.test.ts +106 -0
  66. package/src/utils/assets/asset-creator.ts +96 -0
  67. package/src/utils/assets/asset-formats.test.ts +57 -0
  68. package/src/utils/assets/asset-formats.ts +102 -0
  69. package/src/utils/assets/asset-upload-plan.test.ts +75 -0
  70. package/src/utils/assets/asset-upload-plan.ts +79 -0
  71. package/src/utils/build/upload.ts +5 -1
  72. package/src/utils/job-context/cloud-job-context.ts +24 -15
  73. package/src/utils/open-cloud/open-cloud-client.test.ts +361 -0
  74. package/src/utils/open-cloud/open-cloud-client.ts +341 -24
  75. package/src/utils/open-cloud/rate-limiter.test.ts +106 -4
  76. package/src/utils/open-cloud/rate-limiter.ts +150 -21
  77. package/src/utils/testing/parsers/batch-log-parser.test.ts +3 -3
  78. package/src/utils/testing/runner/test-runner.test.ts +1 -1
  79. package/src/utils/testing/runner/test-runner.ts +8 -9
  80. package/templates/batch-test-runner.lua +176 -172
  81. package/templates/game-template/src/scripts/Server/ServerMain.server.lua +3 -2
  82. package/templates/nevermore-library-package-template/test/scripts/Server/ServerMain.server.lua +3 -2
  83. package/templates/nevermore-service-package-template/test/scripts/Server/ServerMain.server.lua +3 -2
  84. package/tsconfig.tsbuildinfo +1 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"asset-creator.js","sourceRoot":"","sources":["../../../src/utils/assets/asset-creator.ts"],"names":[],"mappings":"AAwBA,MAAM,UAAU,kBAAkB,CAAC,OAAqB;IACtD,OAAO,QAAQ,IAAI,OAAO;QACxB,CAAC,CAAC,QAAQ,OAAO,CAAC,MAAM,EAAE;QAC1B,CAAC,CAAC,SAAS,OAAO,CAAC,OAAO,EAAE,CAAC;AACjC,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAC5C,OAAmC;IAEnC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC;IAExD,IAAI,MAAM,IAAI,IAAI,IAAI,OAAO,IAAI,IAAI,EAAE,CAAC;QACtC,MAAM,IAAI,KAAK,CAAC,yCAAyC,CAAC,CAAC;IAC7D,CAAC;IACD,KAAK,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI;QACvB,CAAC,WAAW,EAAE,MAAM,CAAC;QACrB,CAAC,YAAY,EAAE,OAAO,CAAC;KACf,EAAE,CAAC;QACX,IAAI,EAAE,IAAI,IAAI,IAAI,CAAC,CAAC,MAAM,CAAC,aAAa,CAAC,EAAE,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,EAAE,CAAC;YACxD,MAAM,IAAI,KAAK,CAAC,GAAG,IAAI,8BAA8B,CAAC,CAAC;QACzD,CAAC;IACH,CAAC;IAED,IAAI,MAAM,IAAI,IAAI,EAAE,CAAC;QACnB,OAAO,EAAE,OAAO,EAAE,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC;IACtD,CAAC;IACD,IAAI,OAAO,IAAI,IAAI,EAAE,CAAC;QACpB,OAAO,EAAE,OAAO,EAAE,EAAE,OAAO,EAAE,EAAE,MAAM,EAAE,YAAY,EAAE,CAAC;IACxD,CAAC;IAED,IAAI,UAAU,IAAI,IAAI,EAAE,CAAC;QACvB,IAAI,CAAC;YACH,OAAO;gBACL,OAAO,EAAE,MAAM,MAAM,CAAC,qBAAqB,CAAC,UAAU,CAAC;gBACvD,MAAM,EAAE,iBAAiB,UAAU,8BAA8B;aAClE,CAAC;QACJ,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,UAAU,EAAE,CAClB,oCAAoC,UAAU,GAAG;gBAC/C,IAAI,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK;gBACzD,2CAA2C,CAC9C,CAAC;QACJ,CAAC;IACH,CAAC;IAED,IAAI,CAAC;QACH,OAAO;YACL,OAAO,EAAE,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC,oBAAoB,EAAE,EAAE;YACxD,MAAM,EAAE,kBAAkB;SAC3B,CAAC;IACJ,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CACb;YACE,qDACE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CACjD,EAAE;YACF,mEAAmE;YACnE,yDAAyD;YACzD,0DAA0D;SAC3D,CAAC,IAAI,CAAC,IAAI,CAAC,CACb,CAAC;IACJ,CAAC;AACH,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=asset-creator.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"asset-creator.test.d.ts","sourceRoot":"","sources":["../../../src/utils/assets/asset-creator.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,71 @@
1
+ import { describe, it, expect, vi } from 'vitest';
2
+ import { formatAssetCreator, resolveAssetCreatorAsync, } from './asset-creator.js';
3
+ function makeSource(overrides = {}) {
4
+ return {
5
+ getUniverseOwnerAsync: vi.fn(async () => ({ groupId: 77 })),
6
+ getApiKeyUserIdAsync: vi.fn(async () => 4397833),
7
+ ...overrides,
8
+ };
9
+ }
10
+ describe('resolveAssetCreatorAsync', () => {
11
+ it('takes an explicit owner without asking Roblox anything', async () => {
12
+ const source = makeSource();
13
+ expect(await resolveAssetCreatorAsync({ userId: 5, universeId: 1, source })).toEqual({ creator: { userId: 5 }, reason: '--user-id' });
14
+ expect(await resolveAssetCreatorAsync({ groupId: 6, universeId: 1, source })).toEqual({ creator: { groupId: 6 }, reason: '--group-id' });
15
+ expect(source.getUniverseOwnerAsync).not.toHaveBeenCalled();
16
+ expect(source.getApiKeyUserIdAsync).not.toHaveBeenCalled();
17
+ });
18
+ it('refuses both owner flags, and an id that is not one', async () => {
19
+ const source = makeSource();
20
+ await expect(resolveAssetCreatorAsync({ userId: 5, groupId: 6, source })).rejects.toThrowError(/--user-id or --group-id, not both/);
21
+ await expect(resolveAssetCreatorAsync({ userId: NaN, source })).rejects.toThrowError(/--user-id must be a positive integer/);
22
+ });
23
+ it("prefers the project universe's owner over the key's", async () => {
24
+ // In a group's game the person holding the key is the wrong owner: the
25
+ // experience loads assets its own creator owns.
26
+ const source = makeSource();
27
+ expect(await resolveAssetCreatorAsync({ universeId: 123, source })).toEqual({
28
+ creator: { groupId: 77 },
29
+ reason: 'owns universe 123, from deploy.nevermore.json',
30
+ });
31
+ expect(source.getApiKeyUserIdAsync).not.toHaveBeenCalled();
32
+ });
33
+ it("uses the API key's owner outside a project", async () => {
34
+ const source = makeSource();
35
+ expect(await resolveAssetCreatorAsync({ source })).toEqual({
36
+ creator: { userId: 4397833 },
37
+ reason: 'owns the API key',
38
+ });
39
+ expect(source.getUniverseOwnerAsync).not.toHaveBeenCalled();
40
+ });
41
+ it("falls back to the key's owner, out loud, when the universe is unreadable", async () => {
42
+ const onFallback = vi.fn();
43
+ const source = makeSource({
44
+ getUniverseOwnerAsync: vi.fn(async () => {
45
+ throw new Error('Read universe 123 failed: 403 Forbidden');
46
+ }),
47
+ });
48
+ const resolved = await resolveAssetCreatorAsync({
49
+ universeId: 123,
50
+ source,
51
+ onFallback,
52
+ });
53
+ expect(resolved.creator).toEqual({ userId: 4397833 });
54
+ expect(onFallback).toHaveBeenCalledWith(expect.stringMatching(/universe 123 \(.*403 Forbidden\)/));
55
+ });
56
+ it('says which flags to pass when no owner can be inferred', async () => {
57
+ const source = makeSource({
58
+ getApiKeyUserIdAsync: vi.fn(async () => {
59
+ throw new Error('Read API key owner failed: 401 Unauthorized');
60
+ }),
61
+ });
62
+ await expect(resolveAssetCreatorAsync({ source })).rejects.toThrowError(/401 Unauthorized[\s\S]*--user-id <id>[\s\S]*--group-id <id>/);
63
+ });
64
+ });
65
+ describe('formatAssetCreator', () => {
66
+ it('names the kind of owner', () => {
67
+ expect(formatAssetCreator({ userId: 5 })).toBe('user 5');
68
+ expect(formatAssetCreator({ groupId: 6 })).toBe('group 6');
69
+ });
70
+ });
71
+ //# sourceMappingURL=asset-creator.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"asset-creator.test.js","sourceRoot":"","sources":["../../../src/utils/assets/asset-creator.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * The `assetType` values `nevermore deploy asset upload` can send to the Open
3
+ * Cloud Assets API. Mesh is left out on purpose: the API only accepts mesh data
4
+ * that was itself downloaded from Roblox, which is not something a file on disk
5
+ * can be recognized as.
6
+ *
7
+ * https://create.roblox.com/docs/cloud/guides/usage-assets
8
+ */
9
+ export declare const ASSET_TYPES: readonly ["Animation", "Audio", "Decal", "Image", "Model", "Video"];
10
+ export type AssetType = typeof ASSET_TYPES[number];
11
+ export interface ResolvedAssetFormat {
12
+ assetType: AssetType;
13
+ contentType: string;
14
+ }
15
+ /**
16
+ * Work out how a file uploads: its asset type and the content type to send.
17
+ * The extension decides both unless `explicitType` picks one of the
18
+ * alternatives it allows (`Decal` for an image, `Animation` for an `.rbxm`).
19
+ */
20
+ export declare function resolveAssetFormat(filePath: string, explicitType?: AssetType): ResolvedAssetFormat;
21
+ /**
22
+ * Whether an existing asset of this type can have its file replaced in place,
23
+ * keeping its id. The API documents this for models only, and marks images,
24
+ * audio and video "not available for updating" — so a changed image or sound
25
+ * is always a new asset with a new id.
26
+ */
27
+ export declare function canUpdateAssetContent(assetType: AssetType): boolean;
28
+ //# sourceMappingURL=asset-formats.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"asset-formats.d.ts","sourceRoot":"","sources":["../../../src/utils/assets/asset-formats.ts"],"names":[],"mappings":"AAEA;;;;;;;GAOG;AACH,eAAO,MAAM,WAAW,qEAOd,CAAC;AAEX,MAAM,MAAM,SAAS,GAAG,OAAO,WAAW,CAAC,MAAM,CAAC,CAAC;AAoCnD,MAAM,WAAW,mBAAmB;IAClC,SAAS,EAAE,SAAS,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,MAAM,EAChB,YAAY,CAAC,EAAE,SAAS,GACvB,mBAAmB,CAuBrB;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,SAAS,EAAE,SAAS,GAAG,OAAO,CAEnE"}
@@ -0,0 +1,72 @@
1
+ import * as path from 'path';
2
+ /**
3
+ * The `assetType` values `nevermore deploy asset upload` can send to the Open
4
+ * Cloud Assets API. Mesh is left out on purpose: the API only accepts mesh data
5
+ * that was itself downloaded from Roblox, which is not something a file on disk
6
+ * can be recognized as.
7
+ *
8
+ * https://create.roblox.com/docs/cloud/guides/usage-assets
9
+ */
10
+ export const ASSET_TYPES = [
11
+ 'Animation',
12
+ 'Audio',
13
+ 'Decal',
14
+ 'Image',
15
+ 'Model',
16
+ 'Video',
17
+ ];
18
+ // An image defaults to Image rather than Decal: an Image id is usable directly
19
+ // as `rbxassetid://`, where a Decal is a wrapper whose id has to be resolved to
20
+ // the image inside it before an ImageLabel can show it.
21
+ const IMAGE_TYPES = ['Image', 'Decal'];
22
+ // A Roblox model file holds either, and nothing in its name says which.
23
+ const ROBLOX_MODEL_TYPES = ['Model', 'Animation'];
24
+ const ASSET_FILE_FORMATS = {
25
+ '.mp3': { contentType: 'audio/mpeg', assetTypes: ['Audio'] },
26
+ '.ogg': { contentType: 'audio/ogg', assetTypes: ['Audio'] },
27
+ '.wav': { contentType: 'audio/wav', assetTypes: ['Audio'] },
28
+ '.flac': { contentType: 'audio/flac', assetTypes: ['Audio'] },
29
+ '.png': { contentType: 'image/png', assetTypes: IMAGE_TYPES },
30
+ '.jpg': { contentType: 'image/jpeg', assetTypes: IMAGE_TYPES },
31
+ '.jpeg': { contentType: 'image/jpeg', assetTypes: IMAGE_TYPES },
32
+ '.bmp': { contentType: 'image/bmp', assetTypes: IMAGE_TYPES },
33
+ '.tga': { contentType: 'image/tga', assetTypes: IMAGE_TYPES },
34
+ '.fbx': { contentType: 'model/fbx', assetTypes: ['Model'] },
35
+ '.gltf': { contentType: 'model/gltf+json', assetTypes: ['Model'] },
36
+ '.glb': { contentType: 'model/gltf-binary', assetTypes: ['Model'] },
37
+ '.rbxm': { contentType: 'model/x-rbxm', assetTypes: ROBLOX_MODEL_TYPES },
38
+ '.rbxmx': { contentType: 'model/x-rbxm', assetTypes: ROBLOX_MODEL_TYPES },
39
+ '.mp4': { contentType: 'video/mp4', assetTypes: ['Video'] },
40
+ '.mov': { contentType: 'video/mov', assetTypes: ['Video'] },
41
+ };
42
+ /**
43
+ * Work out how a file uploads: its asset type and the content type to send.
44
+ * The extension decides both unless `explicitType` picks one of the
45
+ * alternatives it allows (`Decal` for an image, `Animation` for an `.rbxm`).
46
+ */
47
+ export function resolveAssetFormat(filePath, explicitType) {
48
+ const extension = path.extname(filePath).toLowerCase();
49
+ const format = ASSET_FILE_FORMATS[extension];
50
+ if (!format) {
51
+ throw new Error(`Cannot upload "${filePath}": ${extension === '' ? 'a file with no extension' : `"${extension}"`} is not an asset format the Open Cloud Assets API accepts.\n` +
52
+ `Supported: ${Object.keys(ASSET_FILE_FORMATS).join(', ')}`);
53
+ }
54
+ if (explicitType != null && !format.assetTypes.includes(explicitType)) {
55
+ throw new Error(`Cannot upload "${filePath}" as ${explicitType}: ` +
56
+ `a "${extension}" file uploads as ${format.assetTypes.join(' or ')}.`);
57
+ }
58
+ return {
59
+ assetType: explicitType ?? format.assetTypes[0],
60
+ contentType: format.contentType,
61
+ };
62
+ }
63
+ /**
64
+ * Whether an existing asset of this type can have its file replaced in place,
65
+ * keeping its id. The API documents this for models only, and marks images,
66
+ * audio and video "not available for updating" — so a changed image or sound
67
+ * is always a new asset with a new id.
68
+ */
69
+ export function canUpdateAssetContent(assetType) {
70
+ return assetType === 'Model';
71
+ }
72
+ //# sourceMappingURL=asset-formats.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"asset-formats.js","sourceRoot":"","sources":["../../../src/utils/assets/asset-formats.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=asset-formats.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"asset-formats.test.d.ts","sourceRoot":"","sources":["../../../src/utils/assets/asset-formats.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,43 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { canUpdateAssetContent, resolveAssetFormat } from './asset-formats.js';
3
+ describe('resolveAssetFormat', () => {
4
+ it('reads the asset type and content type off the extension', () => {
5
+ expect(resolveAssetFormat('models/City.fbx')).toEqual({
6
+ assetType: 'Model',
7
+ contentType: 'model/fbx',
8
+ });
9
+ expect(resolveAssetFormat('sfx/click.ogg')).toEqual({
10
+ assetType: 'Audio',
11
+ contentType: 'audio/ogg',
12
+ });
13
+ });
14
+ it('ignores the case of the extension', () => {
15
+ expect(resolveAssetFormat('ICON.PNG').contentType).toBe('image/png');
16
+ });
17
+ it('uploads an image as an Image unless told Decal', () => {
18
+ expect(resolveAssetFormat('icon.png').assetType).toBe('Image');
19
+ expect(resolveAssetFormat('icon.png', 'Decal')).toEqual({
20
+ assetType: 'Decal',
21
+ contentType: 'image/png',
22
+ });
23
+ });
24
+ it('uploads an .rbxm as a Model unless told Animation', () => {
25
+ expect(resolveAssetFormat('rig.rbxm').assetType).toBe('Model');
26
+ expect(resolveAssetFormat('walk.rbxm', 'Animation').assetType).toBe('Animation');
27
+ });
28
+ it('refuses a type the extension cannot upload as', () => {
29
+ expect(() => resolveAssetFormat('icon.png', 'Audio')).toThrowError(/a "\.png" file uploads as Image or Decal/);
30
+ });
31
+ it('refuses an extension the API does not accept, naming the ones it does', () => {
32
+ expect(() => resolveAssetFormat('notes.txt')).toThrowError(/"\.txt" is not an asset format[\s\S]*\.fbx/);
33
+ expect(() => resolveAssetFormat('README')).toThrowError(/a file with no extension/);
34
+ });
35
+ });
36
+ describe('canUpdateAssetContent', () => {
37
+ it('is only true for models', () => {
38
+ expect(canUpdateAssetContent('Model')).toBe(true);
39
+ expect(canUpdateAssetContent('Image')).toBe(false);
40
+ expect(canUpdateAssetContent('Audio')).toBe(false);
41
+ });
42
+ });
43
+ //# sourceMappingURL=asset-formats.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"asset-formats.test.js","sourceRoot":"","sources":["../../../src/utils/assets/asset-formats.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,qBAAqB,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAE/E,QAAQ,CAAC,oBAAoB,EAAE,GAAG,EAAE;IAClC,EAAE,CAAC,yDAAyD,EAAE,GAAG,EAAE;QACjE,MAAM,CAAC,kBAAkB,CAAC,iBAAiB,CAAC,CAAC,CAAC,OAAO,CAAC;YACpD,SAAS,EAAE,OAAO;YAClB,WAAW,EAAE,WAAW;SACzB,CAAC,CAAC;QACH,MAAM,CAAC,kBAAkB,CAAC,eAAe,CAAC,CAAC,CAAC,OAAO,CAAC;YAClD,SAAS,EAAE,OAAO;YAClB,WAAW,EAAE,WAAW;SACzB,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mCAAmC,EAAE,GAAG,EAAE;QAC3C,MAAM,CAAC,kBAAkB,CAAC,UAAU,CAAC,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IACvE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gDAAgD,EAAE,GAAG,EAAE;QACxD,MAAM,CAAC,kBAAkB,CAAC,UAAU,CAAC,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAC/D,MAAM,CAAC,kBAAkB,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC;YACtD,SAAS,EAAE,OAAO;YAClB,WAAW,EAAE,WAAW;SACzB,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mDAAmD,EAAE,GAAG,EAAE;QAC3D,MAAM,CAAC,kBAAkB,CAAC,UAAU,CAAC,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAC/D,MAAM,CAAC,kBAAkB,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC,SAAS,CAAC,CAAC,IAAI,CACjE,WAAW,CACZ,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+CAA+C,EAAE,GAAG,EAAE;QACvD,MAAM,CAAC,GAAG,EAAE,CAAC,kBAAkB,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC,CAAC,YAAY,CAChE,0CAA0C,CAC3C,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uEAAuE,EAAE,GAAG,EAAE;QAC/E,MAAM,CAAC,GAAG,EAAE,CAAC,kBAAkB,CAAC,WAAW,CAAC,CAAC,CAAC,YAAY,CACxD,4CAA4C,CAC7C,CAAC;QACF,MAAM,CAAC,GAAG,EAAE,CAAC,kBAAkB,CAAC,QAAQ,CAAC,CAAC,CAAC,YAAY,CACrD,0BAA0B,CAC3B,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,uBAAuB,EAAE,GAAG,EAAE;IACrC,EAAE,CAAC,yBAAyB,EAAE,GAAG,EAAE;QACjC,MAAM,CAAC,qBAAqB,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAClD,MAAM,CAAC,qBAAqB,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACnD,MAAM,CAAC,qBAAqB,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACrD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,27 @@
1
+ import { type AssetType } from './asset-formats.js';
2
+ export interface AssetUploadPlanOptions {
3
+ files: string[];
4
+ /** Applied to every file; each must be able to upload as it. */
5
+ type?: AssetType;
6
+ /** Display name. Single file only — defaults to the file's base name. */
7
+ name?: string;
8
+ description?: string;
9
+ /** Replace this asset's content instead of creating one. Single file only. */
10
+ assetId?: number;
11
+ }
12
+ export interface AssetUploadPlanEntry {
13
+ filePath: string;
14
+ assetType: AssetType;
15
+ contentType: string;
16
+ displayName: string;
17
+ description: string;
18
+ /** Set when the upload replaces an existing asset's content in place. */
19
+ assetId?: number;
20
+ }
21
+ /**
22
+ * Turn the command line into one upload per file, rejecting anything that
23
+ * could not work before a single request is sent — a batch that fails on its
24
+ * fifth file has already created four assets.
25
+ */
26
+ export declare function buildAssetUploadPlan(options: AssetUploadPlanOptions): AssetUploadPlanEntry[];
27
+ //# sourceMappingURL=asset-upload-plan.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"asset-upload-plan.d.ts","sourceRoot":"","sources":["../../../src/utils/assets/asset-upload-plan.ts"],"names":[],"mappings":"AACA,OAAO,EAGL,KAAK,SAAS,EACf,MAAM,oBAAoB,CAAC;AAE5B,MAAM,WAAW,sBAAsB;IACrC,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,gEAAgE;IAChE,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,yEAAyE;IACzE,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,8EAA8E;IAC9E,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,oBAAoB;IACnC,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,SAAS,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,yEAAyE;IACzE,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,sBAAsB,GAC9B,oBAAoB,EAAE,CA2CxB"}
@@ -0,0 +1,43 @@
1
+ import * as path from 'path';
2
+ import { canUpdateAssetContent, resolveAssetFormat, } from './asset-formats.js';
3
+ /**
4
+ * Turn the command line into one upload per file, rejecting anything that
5
+ * could not work before a single request is sent — a batch that fails on its
6
+ * fifth file has already created four assets.
7
+ */
8
+ export function buildAssetUploadPlan(options) {
9
+ const { files, type, name, description, assetId } = options;
10
+ if (files.length === 0) {
11
+ throw new Error('No files to upload.');
12
+ }
13
+ if (files.length > 1 && name != null) {
14
+ throw new Error(`--name names one asset, but ${files.length} files were given. ` +
15
+ `Drop it to name each asset after its file.`);
16
+ }
17
+ if (files.length > 1 && assetId != null) {
18
+ throw new Error(`--asset-id replaces one asset, but ${files.length} files were given.`);
19
+ }
20
+ if (assetId != null && (!Number.isSafeInteger(assetId) || assetId < 1)) {
21
+ throw new Error('--asset-id must be a positive integer.');
22
+ }
23
+ return files.map((filePath) => {
24
+ const { assetType, contentType } = resolveAssetFormat(filePath, type);
25
+ if (assetId != null && !canUpdateAssetContent(assetType)) {
26
+ throw new Error(`Cannot replace asset ${assetId} with "${filePath}": the Assets API ` +
27
+ `only replaces the content of a Model. Upload the ${assetType} ` +
28
+ `without --asset-id to create a new asset instead.`);
29
+ }
30
+ const displayName = name ?? path.basename(filePath, path.extname(filePath));
31
+ return {
32
+ filePath,
33
+ assetType,
34
+ contentType,
35
+ displayName,
36
+ // The API requires a description on create, so an omitted one falls back
37
+ // to the name rather than to text nobody chose.
38
+ description: description ?? displayName,
39
+ assetId,
40
+ };
41
+ });
42
+ }
43
+ //# sourceMappingURL=asset-upload-plan.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"asset-upload-plan.js","sourceRoot":"","sources":["../../../src/utils/assets/asset-upload-plan.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,EACL,qBAAqB,EACrB,kBAAkB,GAEnB,MAAM,oBAAoB,CAAC;AAuB5B;;;;GAIG;AACH,MAAM,UAAU,oBAAoB,CAClC,OAA+B;IAE/B,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC;IAE5D,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvB,MAAM,IAAI,KAAK,CAAC,qBAAqB,CAAC,CAAC;IACzC,CAAC;IACD,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,IAAI,IAAI,IAAI,IAAI,EAAE,CAAC;QACrC,MAAM,IAAI,KAAK,CACb,+BAA+B,KAAK,CAAC,MAAM,qBAAqB;YAC9D,4CAA4C,CAC/C,CAAC;IACJ,CAAC;IACD,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,IAAI,OAAO,IAAI,IAAI,EAAE,CAAC;QACxC,MAAM,IAAI,KAAK,CACb,sCAAsC,KAAK,CAAC,MAAM,oBAAoB,CACvE,CAAC;IACJ,CAAC;IACD,IAAI,OAAO,IAAI,IAAI,IAAI,CAAC,CAAC,MAAM,CAAC,aAAa,CAAC,OAAO,CAAC,IAAI,OAAO,GAAG,CAAC,CAAC,EAAE,CAAC;QACvE,MAAM,IAAI,KAAK,CAAC,wCAAwC,CAAC,CAAC;IAC5D,CAAC;IAED,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE;QAC5B,MAAM,EAAE,SAAS,EAAE,WAAW,EAAE,GAAG,kBAAkB,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;QACtE,IAAI,OAAO,IAAI,IAAI,IAAI,CAAC,qBAAqB,CAAC,SAAS,CAAC,EAAE,CAAC;YACzD,MAAM,IAAI,KAAK,CACb,wBAAwB,OAAO,UAAU,QAAQ,oBAAoB;gBACnE,oDAAoD,SAAS,GAAG;gBAChE,mDAAmD,CACtD,CAAC;QACJ,CAAC;QAED,MAAM,WAAW,GAAG,IAAI,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC;QAC5E,OAAO;YACL,QAAQ;YACR,SAAS;YACT,WAAW;YACX,WAAW;YACX,yEAAyE;YACzE,gDAAgD;YAChD,WAAW,EAAE,WAAW,IAAI,WAAW;YACvC,OAAO;SACR,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=asset-upload-plan.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"asset-upload-plan.test.d.ts","sourceRoot":"","sources":["../../../src/utils/assets/asset-upload-plan.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,57 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { buildAssetUploadPlan } from './asset-upload-plan.js';
3
+ describe('buildAssetUploadPlan', () => {
4
+ it('names each asset after its file, and describes it by its name', () => {
5
+ expect(buildAssetUploadPlan({ files: ['art/icons_1.png', 'models/City.fbx'] })).toEqual([
6
+ {
7
+ filePath: 'art/icons_1.png',
8
+ assetType: 'Image',
9
+ contentType: 'image/png',
10
+ displayName: 'icons_1',
11
+ description: 'icons_1',
12
+ assetId: undefined,
13
+ },
14
+ {
15
+ filePath: 'models/City.fbx',
16
+ assetType: 'Model',
17
+ contentType: 'model/fbx',
18
+ displayName: 'City',
19
+ description: 'City',
20
+ assetId: undefined,
21
+ },
22
+ ]);
23
+ });
24
+ it('takes an explicit name and description for a single file', () => {
25
+ const [entry] = buildAssetUploadPlan({
26
+ files: ['City.fbx'],
27
+ name: 'Openfront City',
28
+ description: 'Unit model',
29
+ });
30
+ expect(entry?.displayName).toBe('Openfront City');
31
+ expect(entry?.description).toBe('Unit model');
32
+ });
33
+ it('refuses one name for several files', () => {
34
+ expect(() => buildAssetUploadPlan({ files: ['a.png', 'b.png'], name: 'Icon' })).toThrowError(/--name names one asset, but 2 files were given/);
35
+ });
36
+ it('plans a replacement when given the id of an existing model', () => {
37
+ const [entry] = buildAssetUploadPlan({
38
+ files: ['City.fbx'],
39
+ assetId: 123,
40
+ });
41
+ expect(entry?.assetId).toBe(123);
42
+ });
43
+ it('refuses to replace anything but a model', () => {
44
+ // The API has no in-place update for these, so letting the request through
45
+ // would only trade a clear message for whatever the server says instead.
46
+ expect(() => buildAssetUploadPlan({ files: ['icon.png'], assetId: 123 })).toThrowError(/only replaces the content of a Model/);
47
+ });
48
+ it('refuses one asset id for several files', () => {
49
+ expect(() => buildAssetUploadPlan({ files: ['a.fbx', 'b.fbx'], assetId: 123 })).toThrowError(/--asset-id replaces one asset, but 2 files were given/);
50
+ });
51
+ it('rejects the whole batch when one file cannot be uploaded', () => {
52
+ // Nothing is uploaded until every file is known to be uploadable: a batch
53
+ // that fails partway has already created assets that cannot be taken back.
54
+ expect(() => buildAssetUploadPlan({ files: ['a.png', 'notes.txt'] })).toThrowError(/"\.txt" is not an asset format/);
55
+ });
56
+ });
57
+ //# sourceMappingURL=asset-upload-plan.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"asset-upload-plan.test.js","sourceRoot":"","sources":["../../../src/utils/assets/asset-upload-plan.test.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"upload.d.ts","sourceRoot":"","sources":["../../../src/utils/build/upload.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,cAAc,EACpB,MAAM,+BAA+B,CAAC;AACvC,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,EAAE,eAAe,EAAE,MAAM,oCAAoC,CAAC;AACrE,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,EAAE,KAAK,QAAQ,EAAE,MAAM,sCAAsC,CAAC;AAErE,MAAM,WAAW,kBAAkB;IACjC,UAAU,EAAE,UAAU,CAAC;IACvB,IAAI,EAAE,cAAc,GAAG;QAAE,OAAO,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC;IAC7C,MAAM,EAAE,eAAe,CAAC;IACxB,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,eAAe,CAAC;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,YAAY,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;GAGG;AACH,wBAAsB,gBAAgB,CACpC,OAAO,EAAE,kBAAkB,GAC1B,OAAO,CAAC,iBAAiB,CAAC,CA6B5B"}
1
+ {"version":3,"file":"upload.d.ts","sourceRoot":"","sources":["../../../src/utils/build/upload.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,cAAc,EACpB,MAAM,+BAA+B,CAAC;AACvC,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,EAAE,eAAe,EAAE,MAAM,oCAAoC,CAAC;AAErE,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,EAAE,KAAK,QAAQ,EAAE,MAAM,sCAAsC,CAAC;AAErE,MAAM,WAAW,kBAAkB;IACjC,UAAU,EAAE,UAAU,CAAC;IACvB,IAAI,EAAE,cAAc,GAAG;QAAE,OAAO,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC;IAC7C,MAAM,EAAE,eAAe,CAAC;IACxB,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,eAAe,CAAC;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,YAAY,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;GAGG;AACH,wBAAsB,gBAAgB,CACpC,OAAO,EAAE,kBAAkB,GAC1B,OAAO,CAAC,iBAAiB,CAAC,CAgC5B"}
@@ -1,4 +1,5 @@
1
1
  import { getApiKeyAsync, } from '@quenty/nevermore-cli-helpers';
2
+ import { reportRateLimitWait } from '../open-cloud/rate-limiter.js';
2
3
  /**
3
4
  * Upload a previously-built .rbxl file to Roblox via Open Cloud.
4
5
  * Creates an OpenCloudClient if one is not provided.
@@ -18,7 +19,9 @@ export async function uploadPlaceAsync(options) {
18
19
  });
19
20
  }
20
21
  : undefined;
21
- const version = await client.uploadPlaceAsync(target.universeId, target.placeId, rbxlPath, args.publish, onProgress);
22
+ const version = await client.uploadPlaceAsync(target.universeId, target.placeId, rbxlPath, args.publish, onProgress, reporter && packageName
23
+ ? reportRateLimitWait(reporter, packageName)
24
+ : undefined);
22
25
  return { client, apiKey, target, version };
23
26
  }
24
27
  //# sourceMappingURL=upload.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"upload.js","sourceRoot":"","sources":["../../../src/utils/build/upload.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,GAEf,MAAM,+BAA+B,CAAC;AAqBvC;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,OAA2B;IAE3B,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,GAAG,OAAO,CAAC;IAC5D,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC;IACzB,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,UAAU,CAAC;IAExC,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC,IAAI,CAAC,CAAC;IAE1C,QAAQ,EAAE,oBAAoB,CAAC,WAAW,IAAI,EAAE,EAAE,WAAW,CAAC,CAAC;IAE/D,MAAM,UAAU,GACd,QAAQ,IAAI,WAAW;QACrB,CAAC,CAAC,CAAC,WAAmB,EAAE,KAAa,EAAE,EAAE;YACrC,QAAQ,CAAC,uBAAuB,CAAC,WAAW,EAAE;gBAC5C,IAAI,EAAE,OAAO;gBACb,gBAAgB,EAAE,WAAW;gBAC7B,UAAU,EAAE,KAAK;aAClB,CAAC,CAAC;QACL,CAAC;QACH,CAAC,CAAC,SAAS,CAAC;IAEhB,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,gBAAgB,CAC3C,MAAM,CAAC,UAAU,EACjB,MAAM,CAAC,OAAO,EACd,QAAQ,EACR,IAAI,CAAC,OAAO,EACZ,UAAU,CACX,CAAC;IAEF,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC;AAC7C,CAAC"}
1
+ {"version":3,"file":"upload.js","sourceRoot":"","sources":["../../../src/utils/build/upload.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,GAEf,MAAM,+BAA+B,CAAC;AAGvC,OAAO,EAAE,mBAAmB,EAAE,MAAM,+BAA+B,CAAC;AAmBpE;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,OAA2B;IAE3B,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,GAAG,OAAO,CAAC;IAC5D,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC;IACzB,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,UAAU,CAAC;IAExC,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC,IAAI,CAAC,CAAC;IAE1C,QAAQ,EAAE,oBAAoB,CAAC,WAAW,IAAI,EAAE,EAAE,WAAW,CAAC,CAAC;IAE/D,MAAM,UAAU,GACd,QAAQ,IAAI,WAAW;QACrB,CAAC,CAAC,CAAC,WAAmB,EAAE,KAAa,EAAE,EAAE;YACrC,QAAQ,CAAC,uBAAuB,CAAC,WAAW,EAAE;gBAC5C,IAAI,EAAE,OAAO;gBACb,gBAAgB,EAAE,WAAW;gBAC7B,UAAU,EAAE,KAAK;aAClB,CAAC,CAAC;QACL,CAAC;QACH,CAAC,CAAC,SAAS,CAAC;IAEhB,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,gBAAgB,CAC3C,MAAM,CAAC,UAAU,EACjB,MAAM,CAAC,OAAO,EACd,QAAQ,EACR,IAAI,CAAC,OAAO,EACZ,UAAU,EACV,QAAQ,IAAI,WAAW;QACrB,CAAC,CAAC,mBAAmB,CAAC,QAAQ,EAAE,WAAW,CAAC;QAC5C,CAAC,CAAC,SAAS,CACd,CAAC;IAEF,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC;AAC7C,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"cloud-job-context.d.ts","sourceRoot":"","sources":["../../../src/utils/job-context/cloud-job-context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,QAAQ,EAAE,MAAM,sCAAsC,CAAC;AACrE,OAAO,EAGL,KAAK,eAAe,EACrB,MAAM,oCAAoC,CAAC;AAG5C,OAAO,EACL,KAAK,UAAU,EACf,KAAK,kBAAkB,EACvB,KAAK,OAAO,EACZ,KAAK,gBAAgB,EACrB,KAAK,eAAe,EACrB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,KAAK,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAClE,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAkBvD,qBAAa,eAAgB,SAAQ,cAAc;gBAE/C,QAAQ,EAAE,QAAQ,EAClB,eAAe,EAAE,eAAe,EAChC,iBAAiB,CAAC,EAAE,iBAAiB;IAKjC,qBAAqB,CACzB,OAAO,EAAE,kBAAkB,GAC1B,OAAO,CAAC,UAAU,CAAC;IAgChB,cAAc,CAClB,UAAU,EAAE,UAAU,EACtB,OAAO,EAAE,gBAAgB,GACxB,OAAO,CAAC,eAAe,CAAC;IA8DrB,YAAY,CAAC,UAAU,EAAE,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC;IAuBtD,YAAY,CAAC,WAAW,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAIpD,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC;CAGpC"}
1
+ {"version":3,"file":"cloud-job-context.d.ts","sourceRoot":"","sources":["../../../src/utils/job-context/cloud-job-context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,QAAQ,EAAE,MAAM,sCAAsC,CAAC;AACrE,OAAO,EAGL,KAAK,eAAe,EACrB,MAAM,oCAAoC,CAAC;AAI5C,OAAO,EACL,KAAK,UAAU,EACf,KAAK,kBAAkB,EACvB,KAAK,OAAO,EACZ,KAAK,gBAAgB,EACrB,KAAK,eAAe,EACrB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,KAAK,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAClE,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAkBvD,qBAAa,eAAgB,SAAQ,cAAc;gBAE/C,QAAQ,EAAE,QAAQ,EAClB,eAAe,EAAE,eAAe,EAChC,iBAAiB,CAAC,EAAE,iBAAiB;IAKjC,qBAAqB,CACzB,OAAO,EAAE,kBAAkB,GAC1B,OAAO,CAAC,UAAU,CAAC;IAiChB,cAAc,CAClB,UAAU,EAAE,UAAU,EACtB,OAAO,EAAE,gBAAgB,GACxB,OAAO,CAAC,eAAe,CAAC;IAqErB,YAAY,CAAC,UAAU,EAAE,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC;IAuBtD,YAAY,CAAC,WAAW,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAIpD,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC;CAGpC"}
@@ -1,4 +1,5 @@
1
1
  import { getTaskReturnValues, } from '../open-cloud/open-cloud-client.js';
2
+ import { reportRateLimitWait } from '../open-cloud/rate-limiter.js';
2
3
  import { tryRenamePlaceAsync } from '@quenty/nevermore-cli-helpers';
3
4
  import { buildPlaceNameAsync, timeoutAsync } from '../nevermore-cli-utils.js';
4
5
  import { BaseJobContext } from './base-job-context.js';
@@ -29,7 +30,7 @@ export class CloudJobContext extends BaseJobContext {
29
30
  transferredBytes: transferred,
30
31
  totalBytes: total,
31
32
  });
32
- });
33
+ }, reportRateLimitWait(this._reporter, packageName));
33
34
  // Eagerly release build artifacts after upload (disposeAsync is safety net)
34
35
  await this.releaseBuiltPlaceAsync(builtPlace);
35
36
  // Best-effort rename to reflect current package + commit
@@ -42,8 +43,9 @@ export class CloudJobContext extends BaseJobContext {
42
43
  async runScriptAsync(deployment, options) {
43
44
  const cloudDeployment = deployment;
44
45
  const { scriptContent, packageName, timeoutMs = 120_000 } = options;
46
+ const onRateLimitWait = reportRateLimitWait(this._reporter, packageName);
45
47
  this._reporter.onPackagePhaseChange(packageName, 'scheduling');
46
- const task = await this._openCloudClient.createExecutionTaskAsync(cloudDeployment.universeId, cloudDeployment.placeId, cloudDeployment.version, scriptContent, timeoutMs);
48
+ const task = await this._openCloudClient.createExecutionTaskAsync(cloudDeployment.universeId, cloudDeployment.placeId, cloudDeployment.version, scriptContent, timeoutMs, onRateLimitWait);
47
49
  // Give the server-side timeout a head start so we observe the cancelled
48
50
  // task state instead of bailing out on the client first.
49
51
  const CLIENT_TIMEOUT_GRACE_MS = 30_000;
@@ -61,7 +63,7 @@ export class CloudJobContext extends BaseJobContext {
61
63
  total: 0,
62
64
  label,
63
65
  });
64
- }),
66
+ }, onRateLimitWait),
65
67
  timeoutAsync(timeoutMs + CLIENT_TIMEOUT_GRACE_MS, `Test timed out after ${timeoutMs / 1000}s`),
66
68
  ]);
67
69
  cloudDeployment.taskPath = task.path;
@@ -1 +1 @@
1
- {"version":3,"file":"cloud-job-context.js","sourceRoot":"","sources":["../../../src/utils/job-context/cloud-job-context.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cloud-job-context.js","sourceRoot":"","sources":["../../../src/utils/job-context/cloud-job-context.ts"],"names":[],"mappings":"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"}