@hot-updater/plugin-core 0.36.7 → 1.0.0-rc.0

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 (161) hide show
  1. package/dist/assetStorageLayout.cjs +36 -18
  2. package/dist/assetStorageLayout.d.cts +21 -6
  3. package/dist/assetStorageLayout.d.mts +21 -6
  4. package/dist/assetStorageLayout.mjs +36 -18
  5. package/dist/bundleStorageLayout.cjs +2 -3
  6. package/dist/bundleStorageLayout.mjs +2 -3
  7. package/dist/contentAddressedAssets.cjs +5 -0
  8. package/dist/contentAddressedAssets.d.cts +2 -1
  9. package/dist/contentAddressedAssets.d.mts +2 -1
  10. package/dist/contentAddressedAssets.mjs +5 -1
  11. package/dist/createDatabasePlugin.cjs +775 -284
  12. package/dist/createDatabasePlugin.d.cts +20 -64
  13. package/dist/createDatabasePlugin.d.mts +20 -64
  14. package/dist/createDatabasePlugin.mjs +773 -284
  15. package/dist/createStorageKeyBuilder.cjs +9 -2
  16. package/dist/createStorageKeyBuilder.mjs +9 -2
  17. package/dist/createStoragePlugin.cjs +6 -145
  18. package/dist/createStoragePlugin.d.cts +7 -52
  19. package/dist/createStoragePlugin.d.mts +7 -52
  20. package/dist/createStoragePlugin.mjs +5 -143
  21. package/dist/databaseClient.cjs +112 -0
  22. package/dist/databaseClient.d.cts +33 -0
  23. package/dist/databaseClient.d.mts +33 -0
  24. package/dist/databaseClient.mjs +110 -0
  25. package/dist/databaseClientReads.cjs +113 -0
  26. package/dist/databaseClientReads.mjs +112 -0
  27. package/dist/databaseClientUpdates.cjs +39 -0
  28. package/dist/databaseClientUpdates.d.cts +11 -0
  29. package/dist/databaseClientUpdates.d.mts +11 -0
  30. package/dist/databaseClientUpdates.mjs +36 -0
  31. package/dist/databaseJsonValue.cjs +37 -0
  32. package/dist/databaseJsonValue.d.cts +5 -0
  33. package/dist/databaseJsonValue.d.mts +5 -0
  34. package/dist/databaseJsonValue.mjs +37 -0
  35. package/dist/databaseMetadata.cjs +13 -0
  36. package/dist/databaseMetadata.mjs +12 -0
  37. package/dist/databasePluginCrud.cjs +86 -0
  38. package/dist/databasePluginCrud.d.cts +1 -0
  39. package/dist/databasePluginCrud.d.mts +1 -0
  40. package/dist/databasePluginCrud.mjs +86 -0
  41. package/dist/databasePluginCrudValidation.d.cts +1 -0
  42. package/dist/databasePluginCrudValidation.d.mts +1 -0
  43. package/dist/databasePluginCrudValidationErrors.cjs +10 -0
  44. package/dist/databasePluginCrudValidationErrors.d.cts +9 -0
  45. package/dist/databasePluginCrudValidationErrors.d.mts +9 -0
  46. package/dist/databasePluginCrudValidationErrors.mjs +10 -0
  47. package/dist/databasePluginCrudValidationFields.cjs +291 -0
  48. package/dist/databasePluginCrudValidationFields.d.cts +1 -0
  49. package/dist/databasePluginCrudValidationFields.d.mts +1 -0
  50. package/dist/databasePluginCrudValidationFields.mjs +281 -0
  51. package/dist/databasePluginCrudValidationMutations.cjs +88 -0
  52. package/dist/databasePluginCrudValidationMutations.d.cts +1 -0
  53. package/dist/databasePluginCrudValidationMutations.d.mts +1 -0
  54. package/dist/databasePluginCrudValidationMutations.mjs +82 -0
  55. package/dist/databasePluginCrudValidationQueries.cjs +103 -0
  56. package/dist/databasePluginCrudValidationQueries.d.cts +1 -0
  57. package/dist/databasePluginCrudValidationQueries.d.mts +1 -0
  58. package/dist/databasePluginCrudValidationQueries.mjs +97 -0
  59. package/dist/databasePluginCrudValidationRows.cjs +55 -0
  60. package/dist/databasePluginCrudValidationRows.d.cts +1 -0
  61. package/dist/databasePluginCrudValidationRows.d.mts +1 -0
  62. package/dist/databasePluginCrudValidationRows.mjs +53 -0
  63. package/dist/databasePluginTransaction.cjs +7 -0
  64. package/dist/databasePluginTransaction.mjs +7 -0
  65. package/dist/databaseRows.cjs +149 -0
  66. package/dist/databaseRows.d.cts +34 -0
  67. package/dist/databaseRows.d.mts +34 -0
  68. package/dist/databaseRows.mjs +141 -0
  69. package/dist/index.cjs +76 -24
  70. package/dist/index.d.cts +22 -12
  71. package/dist/index.d.mts +22 -12
  72. package/dist/index.mjs +21 -14
  73. package/dist/internal.cjs +6 -0
  74. package/dist/internal.d.cts +9 -0
  75. package/dist/internal.d.mts +9 -0
  76. package/dist/internal.mjs +3 -0
  77. package/dist/node_modules/.pnpm/verkit@0.3.2/node_modules/verkit/dist/index.cjs +345 -0
  78. package/dist/node_modules/.pnpm/verkit@0.3.2/node_modules/verkit/dist/index.mjs +341 -0
  79. package/dist/paginateBundles.d.cts +6 -4
  80. package/dist/paginateBundles.d.mts +6 -4
  81. package/dist/parseStorageUri.cjs +46 -30
  82. package/dist/parseStorageUri.d.cts +20 -17
  83. package/dist/parseStorageUri.d.mts +20 -17
  84. package/dist/parseStorageUri.mjs +46 -30
  85. package/dist/queryBundles.cjs +1 -7
  86. package/dist/queryBundles.d.cts +3 -1
  87. package/dist/queryBundles.d.mts +3 -1
  88. package/dist/queryBundles.mjs +1 -7
  89. package/dist/releaseCatalogCompiler.cjs +391 -0
  90. package/dist/releaseCatalogCompiler.d.cts +55 -0
  91. package/dist/releaseCatalogCompiler.d.mts +55 -0
  92. package/dist/releaseCatalogCompiler.mjs +386 -0
  93. package/dist/releaseCatalogMutation.cjs +303 -0
  94. package/dist/releaseCatalogMutation.d.cts +86 -0
  95. package/dist/releaseCatalogMutation.d.mts +86 -0
  96. package/dist/releaseCatalogMutation.mjs +297 -0
  97. package/dist/releaseManagement.cjs +231 -0
  98. package/dist/releaseManagement.d.cts +48 -0
  99. package/dist/releaseManagement.d.mts +48 -0
  100. package/dist/releaseManagement.mjs +224 -0
  101. package/dist/remoteBundleSigning.cjs +296 -0
  102. package/dist/remoteBundleSigning.d.cts +43 -0
  103. package/dist/remoteBundleSigning.d.mts +43 -0
  104. package/dist/remoteBundleSigning.mjs +291 -0
  105. package/dist/requestBundleCache.cjs +22 -0
  106. package/dist/requestBundleCache.d.cts +9 -0
  107. package/dist/requestBundleCache.d.mts +9 -0
  108. package/dist/requestBundleCache.mjs +22 -0
  109. package/dist/semverSatisfies.cjs +3 -4
  110. package/dist/semverSatisfies.mjs +1 -1
  111. package/dist/storageDownloadPath.cjs +48 -0
  112. package/dist/storageDownloadPath.d.cts +15 -0
  113. package/dist/storageDownloadPath.d.mts +15 -0
  114. package/dist/storageDownloadPath.mjs +46 -0
  115. package/dist/types/database.d.cts +4 -0
  116. package/dist/types/database.d.mts +4 -0
  117. package/dist/types/databaseFields.cjs +92 -0
  118. package/dist/types/databaseFields.d.cts +12 -0
  119. package/dist/types/databaseFields.d.mts +12 -0
  120. package/dist/types/databaseFields.mjs +92 -0
  121. package/dist/types/databaseOperations.d.cts +173 -0
  122. package/dist/types/databaseOperations.d.mts +173 -0
  123. package/dist/types/databasePlugin.d.cts +240 -0
  124. package/dist/types/databasePlugin.d.mts +240 -0
  125. package/dist/types/databaseQuery.d.cts +47 -0
  126. package/dist/types/databaseQuery.d.mts +47 -0
  127. package/dist/types/databaseRows.d.cts +120 -0
  128. package/dist/types/databaseRows.d.mts +120 -0
  129. package/dist/types/index.d.cts +120 -162
  130. package/dist/types/index.d.mts +120 -162
  131. package/dist/types/internal.d.cts +7 -0
  132. package/dist/types/internal.d.mts +7 -0
  133. package/dist/types/public.d.cts +3 -0
  134. package/dist/types/public.d.mts +3 -0
  135. package/dist/uuidv7.cjs +9 -0
  136. package/dist/uuidv7.d.cts +4 -1
  137. package/dist/uuidv7.d.mts +4 -1
  138. package/dist/uuidv7.mjs +8 -1
  139. package/package.json +10 -5
  140. package/dist/bundleUnitOfWork.cjs +0 -158
  141. package/dist/bundleUnitOfWork.mjs +0 -158
  142. package/dist/bundleUnitOfWorkStore.cjs +0 -15
  143. package/dist/bundleUnitOfWorkStore.mjs +0 -15
  144. package/dist/createBlobDatabasePlugin.cjs +0 -382
  145. package/dist/createBlobDatabasePlugin.d.cts +0 -29
  146. package/dist/createBlobDatabasePlugin.d.mts +0 -29
  147. package/dist/createBlobDatabasePlugin.mjs +0 -381
  148. package/dist/legacyAssetStorageLayout.cjs +0 -12
  149. package/dist/legacyAssetStorageLayout.mjs +0 -12
  150. package/dist/requestUpdateBundleState.cjs +0 -26
  151. package/dist/requestUpdateBundleState.d.cts +0 -12
  152. package/dist/requestUpdateBundleState.d.mts +0 -12
  153. package/dist/requestUpdateBundleState.mjs +0 -24
  154. package/dist/resolveUpdateInfoFromBundles.cjs +0 -14
  155. package/dist/resolveUpdateInfoFromBundles.d.cts +0 -16
  156. package/dist/resolveUpdateInfoFromBundles.d.mts +0 -16
  157. package/dist/resolveUpdateInfoFromBundles.mjs +0 -13
  158. package/dist/storageProfile.cjs +0 -15
  159. package/dist/storageProfile.d.cts +0 -9
  160. package/dist/storageProfile.d.mts +0 -9
  161. package/dist/storageProfile.mjs +0 -12
@@ -1,38 +1,56 @@
1
1
  const require_contentAddressedAssets = require("./contentAddressedAssets.cjs");
2
- const require_legacyAssetStorageLayout = require("./legacyAssetStorageLayout.cjs");
2
+ const require_createStorageKeyBuilder = require("./createStorageKeyBuilder.cjs");
3
+ const require_parseStorageUri = require("./parseStorageUri.cjs");
3
4
  //#region src/assetStorageLayout.ts
4
5
  const isBrotliManifestAssetPath = (assetPath) => /(^|\/)index\.[^/]+\.bundle$/.test(assetPath.replace(/\\/g, "/"));
5
6
  const getManifestAssetDownloadPath = (assetPath) => isBrotliManifestAssetPath(assetPath) ? `${assetPath}.br` : assetPath;
6
7
  const createStorageUriWithRelativePath = ({ baseStorageUri, relativePath }) => {
7
- const storageUrl = new URL(baseStorageUri);
8
- storageUrl.pathname = `${storageUrl.pathname.replace(/\/+$/, "")}/${relativePath.replace(/\\/g, "/").split("/").filter(Boolean).map((segment) => encodeURIComponent(segment)).join("/")}`;
9
- return storageUrl.toString();
10
- };
11
- const getAssetStorageLayout = (assetBaseStorageUri) => {
12
- const pathname = new URL(assetBaseStorageUri).pathname.replace(/\/+$/, "");
13
- return pathname.endsWith("/assets") || pathname === "/assets" ? "content-addressed" : "legacy-files";
8
+ const parsed = require_parseStorageUri.parseStorageUri(baseStorageUri, new URL(baseStorageUri).protocol.replace(":", ""));
9
+ const childKey = require_createStorageKeyBuilder.createStorageKeyBuilder(void 0)(relativePath);
10
+ if (!childKey) throw new Error("Relative storage key must not be empty.");
11
+ return require_parseStorageUri.createStorageUri({
12
+ protocol: parsed.protocol,
13
+ bucket: parsed.bucket,
14
+ key: require_createStorageKeyBuilder.createStorageKeyBuilder(parsed.key)(childKey)
15
+ });
14
16
  };
15
- const isContentAddressedAssetBaseStorageUri = (assetBaseStorageUri) => getAssetStorageLayout(assetBaseStorageUri) === "content-addressed";
16
- const getManifestAssetStoragePath = ({ assetBaseStorageUri, assetPath, fileHash }) => {
17
- if (getAssetStorageLayout(assetBaseStorageUri) === "content-addressed") return require_contentAddressedAssets.getContentAddressedAssetStoragePath({
18
- assetPath,
19
- fileHash
17
+ const replaceStorageUriKeySuffix = ({ storageUri, keySuffix, replacement }) => {
18
+ const parsed = require_parseStorageUri.parseStorageUri(storageUri, new URL(storageUri).protocol.replace(":", ""));
19
+ const normalizedSuffix = require_createStorageKeyBuilder.createStorageKeyBuilder(void 0)(keySuffix);
20
+ const normalizedReplacement = require_createStorageKeyBuilder.createStorageKeyBuilder(void 0)(replacement);
21
+ if (!normalizedSuffix || !normalizedReplacement) throw new Error("Storage URI key suffix and replacement must not be empty.");
22
+ const keySegments = parsed.key.split("/");
23
+ const suffixSegments = normalizedSuffix.split("/");
24
+ const suffixOffset = keySegments.length - suffixSegments.length;
25
+ if (suffixOffset < 0 || suffixSegments.some((segment, index) => keySegments[suffixOffset + index] !== segment)) throw new Error("Storage URI key does not end with the expected suffix.");
26
+ const prefix = keySegments.slice(0, suffixOffset).join("/");
27
+ return require_parseStorageUri.createStorageUri({
28
+ protocol: parsed.protocol,
29
+ bucket: parsed.bucket,
30
+ key: require_createStorageKeyBuilder.createStorageKeyBuilder(prefix)(normalizedReplacement)
20
31
  });
21
- return require_legacyAssetStorageLayout.getLegacyManifestAssetStoragePath({ assetPath });
22
32
  };
23
- const resolveManifestAssetStorageUri = ({ assetBaseStorageUri, assetPath, fileHash }) => createStorageUriWithRelativePath({
33
+ const resolveManifestAssetStorageFileHash = ({ downloadFileHash, fileHash }) => require_contentAddressedAssets.isContentAddressedAssetFileHash(downloadFileHash) ? downloadFileHash : fileHash;
34
+ const getManifestAssetStoragePath = ({ assetPath, downloadFileHash, fileHash }) => require_contentAddressedAssets.getContentAddressedAssetStoragePath({
35
+ assetPath,
36
+ fileHash: resolveManifestAssetStorageFileHash({
37
+ downloadFileHash,
38
+ fileHash
39
+ })
40
+ });
41
+ const resolveManifestAssetStorageUri = ({ assetBaseStorageUri, assetPath, downloadFileHash, fileHash }) => createStorageUriWithRelativePath({
24
42
  baseStorageUri: assetBaseStorageUri,
25
43
  relativePath: getManifestAssetStoragePath({
26
- assetBaseStorageUri,
27
44
  assetPath,
45
+ downloadFileHash,
28
46
  fileHash
29
47
  })
30
48
  });
31
49
  //#endregion
32
50
  exports.createStorageUriWithRelativePath = createStorageUriWithRelativePath;
33
- exports.getAssetStorageLayout = getAssetStorageLayout;
34
51
  exports.getManifestAssetDownloadPath = getManifestAssetDownloadPath;
35
52
  exports.getManifestAssetStoragePath = getManifestAssetStoragePath;
36
53
  exports.isBrotliManifestAssetPath = isBrotliManifestAssetPath;
37
- exports.isContentAddressedAssetBaseStorageUri = isContentAddressedAssetBaseStorageUri;
54
+ exports.replaceStorageUriKeySuffix = replaceStorageUriKeySuffix;
55
+ exports.resolveManifestAssetStorageFileHash = resolveManifestAssetStorageFileHash;
38
56
  exports.resolveManifestAssetStorageUri = resolveManifestAssetStorageUri;
@@ -1,5 +1,4 @@
1
1
  //#region src/assetStorageLayout.d.ts
2
- type AssetStorageLayout = "content-addressed" | "legacy-files";
3
2
  declare const isBrotliManifestAssetPath: (assetPath: string) => boolean;
4
3
  declare const getManifestAssetDownloadPath: (assetPath: string) => string;
5
4
  declare const createStorageUriWithRelativePath: ({
@@ -9,25 +8,41 @@ declare const createStorageUriWithRelativePath: ({
9
8
  baseStorageUri: string;
10
9
  relativePath: string;
11
10
  }) => string;
12
- declare const getAssetStorageLayout: (assetBaseStorageUri: string) => AssetStorageLayout;
13
- declare const isContentAddressedAssetBaseStorageUri: (assetBaseStorageUri: string) => boolean;
11
+ declare const replaceStorageUriKeySuffix: ({
12
+ storageUri,
13
+ keySuffix,
14
+ replacement
15
+ }: {
16
+ storageUri: string;
17
+ keySuffix: string;
18
+ replacement: string;
19
+ }) => string;
20
+ declare const resolveManifestAssetStorageFileHash: ({
21
+ downloadFileHash,
22
+ fileHash
23
+ }: {
24
+ downloadFileHash?: unknown;
25
+ fileHash: string;
26
+ }) => string;
14
27
  declare const getManifestAssetStoragePath: ({
15
- assetBaseStorageUri,
16
28
  assetPath,
29
+ downloadFileHash,
17
30
  fileHash
18
31
  }: {
19
- assetBaseStorageUri: string;
20
32
  assetPath: string;
33
+ downloadFileHash?: unknown;
21
34
  fileHash: string;
22
35
  }) => string;
23
36
  declare const resolveManifestAssetStorageUri: ({
24
37
  assetBaseStorageUri,
25
38
  assetPath,
39
+ downloadFileHash,
26
40
  fileHash
27
41
  }: {
28
42
  assetBaseStorageUri: string;
29
43
  assetPath: string;
44
+ downloadFileHash?: unknown;
30
45
  fileHash: string;
31
46
  }) => string;
32
47
  //#endregion
33
- export { AssetStorageLayout, createStorageUriWithRelativePath, getAssetStorageLayout, getManifestAssetDownloadPath, getManifestAssetStoragePath, isBrotliManifestAssetPath, isContentAddressedAssetBaseStorageUri, resolveManifestAssetStorageUri };
48
+ export { createStorageUriWithRelativePath, getManifestAssetDownloadPath, getManifestAssetStoragePath, isBrotliManifestAssetPath, replaceStorageUriKeySuffix, resolveManifestAssetStorageFileHash, resolveManifestAssetStorageUri };
@@ -1,5 +1,4 @@
1
1
  //#region src/assetStorageLayout.d.ts
2
- type AssetStorageLayout = "content-addressed" | "legacy-files";
3
2
  declare const isBrotliManifestAssetPath: (assetPath: string) => boolean;
4
3
  declare const getManifestAssetDownloadPath: (assetPath: string) => string;
5
4
  declare const createStorageUriWithRelativePath: ({
@@ -9,25 +8,41 @@ declare const createStorageUriWithRelativePath: ({
9
8
  baseStorageUri: string;
10
9
  relativePath: string;
11
10
  }) => string;
12
- declare const getAssetStorageLayout: (assetBaseStorageUri: string) => AssetStorageLayout;
13
- declare const isContentAddressedAssetBaseStorageUri: (assetBaseStorageUri: string) => boolean;
11
+ declare const replaceStorageUriKeySuffix: ({
12
+ storageUri,
13
+ keySuffix,
14
+ replacement
15
+ }: {
16
+ storageUri: string;
17
+ keySuffix: string;
18
+ replacement: string;
19
+ }) => string;
20
+ declare const resolveManifestAssetStorageFileHash: ({
21
+ downloadFileHash,
22
+ fileHash
23
+ }: {
24
+ downloadFileHash?: unknown;
25
+ fileHash: string;
26
+ }) => string;
14
27
  declare const getManifestAssetStoragePath: ({
15
- assetBaseStorageUri,
16
28
  assetPath,
29
+ downloadFileHash,
17
30
  fileHash
18
31
  }: {
19
- assetBaseStorageUri: string;
20
32
  assetPath: string;
33
+ downloadFileHash?: unknown;
21
34
  fileHash: string;
22
35
  }) => string;
23
36
  declare const resolveManifestAssetStorageUri: ({
24
37
  assetBaseStorageUri,
25
38
  assetPath,
39
+ downloadFileHash,
26
40
  fileHash
27
41
  }: {
28
42
  assetBaseStorageUri: string;
29
43
  assetPath: string;
44
+ downloadFileHash?: unknown;
30
45
  fileHash: string;
31
46
  }) => string;
32
47
  //#endregion
33
- export { AssetStorageLayout, createStorageUriWithRelativePath, getAssetStorageLayout, getManifestAssetDownloadPath, getManifestAssetStoragePath, isBrotliManifestAssetPath, isContentAddressedAssetBaseStorageUri, resolveManifestAssetStorageUri };
48
+ export { createStorageUriWithRelativePath, getManifestAssetDownloadPath, getManifestAssetStoragePath, isBrotliManifestAssetPath, replaceStorageUriKeySuffix, resolveManifestAssetStorageFileHash, resolveManifestAssetStorageUri };
@@ -1,32 +1,50 @@
1
- import { getContentAddressedAssetStoragePath } from "./contentAddressedAssets.mjs";
2
- import { getLegacyManifestAssetStoragePath } from "./legacyAssetStorageLayout.mjs";
1
+ import { getContentAddressedAssetStoragePath, isContentAddressedAssetFileHash } from "./contentAddressedAssets.mjs";
2
+ import { createStorageKeyBuilder } from "./createStorageKeyBuilder.mjs";
3
+ import { createStorageUri, parseStorageUri } from "./parseStorageUri.mjs";
3
4
  //#region src/assetStorageLayout.ts
4
5
  const isBrotliManifestAssetPath = (assetPath) => /(^|\/)index\.[^/]+\.bundle$/.test(assetPath.replace(/\\/g, "/"));
5
6
  const getManifestAssetDownloadPath = (assetPath) => isBrotliManifestAssetPath(assetPath) ? `${assetPath}.br` : assetPath;
6
7
  const createStorageUriWithRelativePath = ({ baseStorageUri, relativePath }) => {
7
- const storageUrl = new URL(baseStorageUri);
8
- storageUrl.pathname = `${storageUrl.pathname.replace(/\/+$/, "")}/${relativePath.replace(/\\/g, "/").split("/").filter(Boolean).map((segment) => encodeURIComponent(segment)).join("/")}`;
9
- return storageUrl.toString();
10
- };
11
- const getAssetStorageLayout = (assetBaseStorageUri) => {
12
- const pathname = new URL(assetBaseStorageUri).pathname.replace(/\/+$/, "");
13
- return pathname.endsWith("/assets") || pathname === "/assets" ? "content-addressed" : "legacy-files";
8
+ const parsed = parseStorageUri(baseStorageUri, new URL(baseStorageUri).protocol.replace(":", ""));
9
+ const childKey = createStorageKeyBuilder(void 0)(relativePath);
10
+ if (!childKey) throw new Error("Relative storage key must not be empty.");
11
+ return createStorageUri({
12
+ protocol: parsed.protocol,
13
+ bucket: parsed.bucket,
14
+ key: createStorageKeyBuilder(parsed.key)(childKey)
15
+ });
14
16
  };
15
- const isContentAddressedAssetBaseStorageUri = (assetBaseStorageUri) => getAssetStorageLayout(assetBaseStorageUri) === "content-addressed";
16
- const getManifestAssetStoragePath = ({ assetBaseStorageUri, assetPath, fileHash }) => {
17
- if (getAssetStorageLayout(assetBaseStorageUri) === "content-addressed") return getContentAddressedAssetStoragePath({
18
- assetPath,
19
- fileHash
17
+ const replaceStorageUriKeySuffix = ({ storageUri, keySuffix, replacement }) => {
18
+ const parsed = parseStorageUri(storageUri, new URL(storageUri).protocol.replace(":", ""));
19
+ const normalizedSuffix = createStorageKeyBuilder(void 0)(keySuffix);
20
+ const normalizedReplacement = createStorageKeyBuilder(void 0)(replacement);
21
+ if (!normalizedSuffix || !normalizedReplacement) throw new Error("Storage URI key suffix and replacement must not be empty.");
22
+ const keySegments = parsed.key.split("/");
23
+ const suffixSegments = normalizedSuffix.split("/");
24
+ const suffixOffset = keySegments.length - suffixSegments.length;
25
+ if (suffixOffset < 0 || suffixSegments.some((segment, index) => keySegments[suffixOffset + index] !== segment)) throw new Error("Storage URI key does not end with the expected suffix.");
26
+ const prefix = keySegments.slice(0, suffixOffset).join("/");
27
+ return createStorageUri({
28
+ protocol: parsed.protocol,
29
+ bucket: parsed.bucket,
30
+ key: createStorageKeyBuilder(prefix)(normalizedReplacement)
20
31
  });
21
- return getLegacyManifestAssetStoragePath({ assetPath });
22
32
  };
23
- const resolveManifestAssetStorageUri = ({ assetBaseStorageUri, assetPath, fileHash }) => createStorageUriWithRelativePath({
33
+ const resolveManifestAssetStorageFileHash = ({ downloadFileHash, fileHash }) => isContentAddressedAssetFileHash(downloadFileHash) ? downloadFileHash : fileHash;
34
+ const getManifestAssetStoragePath = ({ assetPath, downloadFileHash, fileHash }) => getContentAddressedAssetStoragePath({
35
+ assetPath,
36
+ fileHash: resolveManifestAssetStorageFileHash({
37
+ downloadFileHash,
38
+ fileHash
39
+ })
40
+ });
41
+ const resolveManifestAssetStorageUri = ({ assetBaseStorageUri, assetPath, downloadFileHash, fileHash }) => createStorageUriWithRelativePath({
24
42
  baseStorageUri: assetBaseStorageUri,
25
43
  relativePath: getManifestAssetStoragePath({
26
- assetBaseStorageUri,
27
44
  assetPath,
45
+ downloadFileHash,
28
46
  fileHash
29
47
  })
30
48
  });
31
49
  //#endregion
32
- export { createStorageUriWithRelativePath, getAssetStorageLayout, getManifestAssetDownloadPath, getManifestAssetStoragePath, isBrotliManifestAssetPath, isContentAddressedAssetBaseStorageUri, resolveManifestAssetStorageUri };
50
+ export { createStorageUriWithRelativePath, getManifestAssetDownloadPath, getManifestAssetStoragePath, isBrotliManifestAssetPath, replaceStorageUriKeySuffix, resolveManifestAssetStorageFileHash, resolveManifestAssetStorageUri };
@@ -9,9 +9,8 @@ const createStorageRootUriWithPath = (storageUri, bundleId, relativePath) => {
9
9
  const storageUrl = new URL(storageUri);
10
10
  const segments = storageUrl.pathname.split("/").filter(Boolean);
11
11
  const bundleIndex = segments.lastIndexOf(bundleId);
12
- if (bundleIndex < 0) throw new Error(`Storage URI does not contain bundle id: ${bundleId}`);
13
- const rootSegments = segments.slice(0, bundleIndex);
14
- if (rootSegments.at(-1) === "bundles") rootSegments.pop();
12
+ if (bundleIndex < 1 || segments[bundleIndex - 1] !== "bundles") throw new Error(`Storage URI does not contain canonical bundle path: ${BUNDLE_STORAGE_PREFIX}/${bundleId}`);
13
+ const rootSegments = segments.slice(0, bundleIndex - 1);
15
14
  const relativeSegments = relativePath.split("/").filter(Boolean).map((segment) => encodeURIComponent(segment));
16
15
  storageUrl.pathname = `/${[...rootSegments, ...relativeSegments].join("/")}`;
17
16
  return storageUrl.toString();
@@ -9,9 +9,8 @@ const createStorageRootUriWithPath = (storageUri, bundleId, relativePath) => {
9
9
  const storageUrl = new URL(storageUri);
10
10
  const segments = storageUrl.pathname.split("/").filter(Boolean);
11
11
  const bundleIndex = segments.lastIndexOf(bundleId);
12
- if (bundleIndex < 0) throw new Error(`Storage URI does not contain bundle id: ${bundleId}`);
13
- const rootSegments = segments.slice(0, bundleIndex);
14
- if (rootSegments.at(-1) === "bundles") rootSegments.pop();
12
+ if (bundleIndex < 1 || segments[bundleIndex - 1] !== "bundles") throw new Error(`Storage URI does not contain canonical bundle path: ${BUNDLE_STORAGE_PREFIX}/${bundleId}`);
13
+ const rootSegments = segments.slice(0, bundleIndex - 1);
15
14
  const relativeSegments = relativePath.split("/").filter(Boolean).map((segment) => encodeURIComponent(segment));
16
15
  storageUrl.pathname = `/${[...rootSegments, ...relativeSegments].join("/")}`;
17
16
  return storageUrl.toString();
@@ -1,5 +1,9 @@
1
1
  //#region src/contentAddressedAssets.ts
2
2
  const CONTENT_ADDRESSED_ASSET_PREFIX = "assets";
3
+ const SHA256_FILE_HASH_RE = /^[0-9a-f]{64}$/;
4
+ const isContentAddressedAssetFileHash = (value) => {
5
+ return typeof value === "string" && SHA256_FILE_HASH_RE.test(value);
6
+ };
3
7
  const getContentAddressedAssetStoragePath = ({ assetPath, fileHash }) => {
4
8
  const extension = assetPath.endsWith(".br") ? ".br" : assetPath.includes(".") ? `.${assetPath.split(".").pop()}` : "";
5
9
  return `sha256/${fileHash.slice(0, 2)}/${fileHash}${extension}`;
@@ -7,3 +11,4 @@ const getContentAddressedAssetStoragePath = ({ assetPath, fileHash }) => {
7
11
  //#endregion
8
12
  exports.CONTENT_ADDRESSED_ASSET_PREFIX = CONTENT_ADDRESSED_ASSET_PREFIX;
9
13
  exports.getContentAddressedAssetStoragePath = getContentAddressedAssetStoragePath;
14
+ exports.isContentAddressedAssetFileHash = isContentAddressedAssetFileHash;
@@ -1,5 +1,6 @@
1
1
  //#region src/contentAddressedAssets.d.ts
2
2
  declare const CONTENT_ADDRESSED_ASSET_PREFIX = "assets";
3
+ declare const isContentAddressedAssetFileHash: (value: unknown) => value is string;
3
4
  declare const getContentAddressedAssetStoragePath: ({
4
5
  assetPath,
5
6
  fileHash
@@ -8,4 +9,4 @@ declare const getContentAddressedAssetStoragePath: ({
8
9
  fileHash: string;
9
10
  }) => string;
10
11
  //#endregion
11
- export { CONTENT_ADDRESSED_ASSET_PREFIX, getContentAddressedAssetStoragePath };
12
+ export { CONTENT_ADDRESSED_ASSET_PREFIX, getContentAddressedAssetStoragePath, isContentAddressedAssetFileHash };
@@ -1,5 +1,6 @@
1
1
  //#region src/contentAddressedAssets.d.ts
2
2
  declare const CONTENT_ADDRESSED_ASSET_PREFIX = "assets";
3
+ declare const isContentAddressedAssetFileHash: (value: unknown) => value is string;
3
4
  declare const getContentAddressedAssetStoragePath: ({
4
5
  assetPath,
5
6
  fileHash
@@ -8,4 +9,4 @@ declare const getContentAddressedAssetStoragePath: ({
8
9
  fileHash: string;
9
10
  }) => string;
10
11
  //#endregion
11
- export { CONTENT_ADDRESSED_ASSET_PREFIX, getContentAddressedAssetStoragePath };
12
+ export { CONTENT_ADDRESSED_ASSET_PREFIX, getContentAddressedAssetStoragePath, isContentAddressedAssetFileHash };
@@ -1,8 +1,12 @@
1
1
  //#region src/contentAddressedAssets.ts
2
2
  const CONTENT_ADDRESSED_ASSET_PREFIX = "assets";
3
+ const SHA256_FILE_HASH_RE = /^[0-9a-f]{64}$/;
4
+ const isContentAddressedAssetFileHash = (value) => {
5
+ return typeof value === "string" && SHA256_FILE_HASH_RE.test(value);
6
+ };
3
7
  const getContentAddressedAssetStoragePath = ({ assetPath, fileHash }) => {
4
8
  const extension = assetPath.endsWith(".br") ? ".br" : assetPath.includes(".") ? `.${assetPath.split(".").pop()}` : "";
5
9
  return `sha256/${fileHash.slice(0, 2)}/${fileHash}${extension}`;
6
10
  };
7
11
  //#endregion
8
- export { CONTENT_ADDRESSED_ASSET_PREFIX, getContentAddressedAssetStoragePath };
12
+ export { CONTENT_ADDRESSED_ASSET_PREFIX, getContentAddressedAssetStoragePath, isContentAddressedAssetFileHash };