@dragonmastery/tamer 0.40.1 → 0.42.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.
- package/README.md +10 -11
- package/dist/{apply-CV4_3Jv4.mjs → apply-Mk9usR-U.mjs} +14 -14
- package/dist/{apply-CV4_3Jv4.mjs.map → apply-Mk9usR-U.mjs.map} +1 -1
- package/dist/{applyTarget-B1YPgkb3.mjs → applyTarget-CJSn9DeJ.mjs} +3 -3
- package/dist/{applyTarget-B1YPgkb3.mjs.map → applyTarget-CJSn9DeJ.mjs.map} +1 -1
- package/dist/{bootstrap-ilkixdmD.mjs → bootstrap-BCy6B-B6.mjs} +3 -3
- package/dist/{bootstrap-ilkixdmD.mjs.map → bootstrap-BCy6B-B6.mjs.map} +1 -1
- package/dist/{cloudflareSnapshot-BAeNVohz.mjs → cloudflareSnapshot-DqP8v_xG.mjs} +4 -4
- package/dist/{cloudflareSnapshot-BAeNVohz.mjs.map → cloudflareSnapshot-DqP8v_xG.mjs.map} +1 -1
- package/dist/{deploy-BEaNADU6.mjs → deploy-DbXBHpCG.mjs} +9 -9
- package/dist/{deploy-BEaNADU6.mjs.map → deploy-DbXBHpCG.mjs.map} +1 -1
- package/dist/{destroy-Krf35oqE.mjs → destroy-CesVkyxf.mjs} +10 -10
- package/dist/{destroy-Krf35oqE.mjs.map → destroy-CesVkyxf.mjs.map} +1 -1
- package/dist/{destroy-tenant-C95ljuon.mjs → destroy-tenant-DMynv_u-.mjs} +1 -1
- package/dist/{destroy-tenant-C95ljuon.mjs.map → destroy-tenant-DMynv_u-.mjs.map} +1 -1
- package/dist/{dev-C__1rLos.mjs → dev-sk6JGKe4.mjs} +7 -7
- package/dist/{dev-C__1rLos.mjs.map → dev-sk6JGKe4.mjs.map} +1 -1
- package/dist/{dns-records.resolve-DwBR_1WI.mjs → dns-records.resolve-SPYGYNHa.mjs} +1 -1
- package/dist/{dns-records.resolve-DwBR_1WI.mjs.map → dns-records.resolve-SPYGYNHa.mjs.map} +1 -1
- package/dist/{dns-records.resolve-C2T0m4NG.mjs → dns-records.resolve-jECsH6N-.mjs} +1 -1
- package/dist/{dns-records.sync-Dfwk76J_.mjs → dns-records.sync-BORRvLky.mjs} +2 -2
- package/dist/{dns-records.sync-Dfwk76J_.mjs.map → dns-records.sync-BORRvLky.mjs.map} +1 -1
- package/dist/{doctor-BIaLEVFR.mjs → doctor-BgqnscIE.mjs} +1 -1
- package/dist/{doctor-BIaLEVFR.mjs.map → doctor-BgqnscIE.mjs.map} +1 -1
- package/dist/{drift-CLsSBorO.mjs → drift-C5r1cKxV.mjs} +6 -6
- package/dist/{drift-CLsSBorO.mjs.map → drift-C5r1cKxV.mjs.map} +1 -1
- package/dist/drift-oOUlh0u8.mjs +8 -0
- package/dist/{emit-Dh68dvo5.mjs → emit-C7KXAVP0.mjs} +2 -2
- package/dist/{emit-Dh68dvo5.mjs.map → emit-C7KXAVP0.mjs.map} +1 -1
- package/dist/{env-gc-0vX5Av4i.mjs → env-gc-DE4EV7j7.mjs} +10 -10
- package/dist/{env-gc-0vX5Av4i.mjs.map → env-gc-DE4EV7j7.mjs.map} +1 -1
- package/dist/{env-list-DYCprcLb.mjs → env-list-DKseThiA.mjs} +1 -1
- package/dist/{env-list-DYCprcLb.mjs.map → env-list-DKseThiA.mjs.map} +1 -1
- package/dist/{events-CnWvxyX_.mjs → events-CqbN9sbT.mjs} +1 -1
- package/dist/{events-CnWvxyX_.mjs.map → events-CqbN9sbT.mjs.map} +1 -1
- package/dist/{generator-DAU5K77L.mjs → generator-CbH3UZ3K.mjs} +2 -2
- package/dist/{generator-DAU5K77L.mjs.map → generator-CbH3UZ3K.mjs.map} +1 -1
- package/dist/{import-BNbHjR9t.mjs → import-leVD9Ryg.mjs} +5 -5
- package/dist/{import-BNbHjR9t.mjs.map → import-leVD9Ryg.mjs.map} +1 -1
- package/dist/loader-B5iVsP6t.mjs +3 -0
- package/dist/{logpush-job-C_6uzGUC.mjs → logpush-job-Dqlt-wEw.mjs} +2 -2
- package/dist/{logpush-job-C_6uzGUC.mjs.map → logpush-job-Dqlt-wEw.mjs.map} +1 -1
- package/dist/{migrate-EVfFlJOM.mjs → migrate-DyrTw9ep.mjs} +5 -5
- package/dist/{migrate-EVfFlJOM.mjs.map → migrate-DyrTw9ep.mjs.map} +1 -1
- package/dist/{plan-tnUWkiM1.mjs → plan-D7UyLznb.mjs} +11 -11
- package/dist/{plan-tnUWkiM1.mjs.map → plan-D7UyLznb.mjs.map} +1 -1
- package/dist/{planFormat-DpA8XhzX.mjs → planFormat-CJw8Kq2s.mjs} +1 -1
- package/dist/{planFormat-DpA8XhzX.mjs.map → planFormat-CJw8Kq2s.mjs.map} +1 -1
- package/dist/{provision-tenant-R6Xa3IUJ.mjs → provision-tenant-BZpqekMK.mjs} +77 -28
- package/dist/provision-tenant-BZpqekMK.mjs.map +1 -0
- package/dist/{r2S3EmptyBucket-CXLmOrYF.mjs → r2S3EmptyBucket-DD81ZWQ7.mjs} +1 -1
- package/dist/{r2S3EmptyBucket-CXLmOrYF.mjs.map → r2S3EmptyBucket-DD81ZWQ7.mjs.map} +1 -1
- package/dist/{registry-X9dlQxG3.mjs → registry-CTerXUza.mjs} +81 -33
- package/dist/registry-CTerXUza.mjs.map +1 -0
- package/dist/{resolveTenantBindings-4grVKHIG.mjs → resolveTenantBindings-86AmRQcW.mjs} +18 -11
- package/dist/resolveTenantBindings-86AmRQcW.mjs.map +1 -0
- package/dist/{stackOutputs-CU2oxjpU.mjs → stackOutputs-BLp-dyzl.mjs} +1 -1
- package/dist/{stackOutputs-CU2oxjpU.mjs.map → stackOutputs-BLp-dyzl.mjs.map} +1 -1
- package/dist/{status-srUxsBIB.mjs → status-CL4MEGbn.mjs} +6 -6
- package/dist/{status-srUxsBIB.mjs.map → status-CL4MEGbn.mjs.map} +1 -1
- package/dist/sync-DSgJGQh1.mjs +7 -0
- package/dist/{sync-DfJGkOME.mjs → sync-Dii9n2nJ.mjs} +5 -5
- package/dist/{sync-DfJGkOME.mjs.map → sync-Dii9n2nJ.mjs.map} +1 -1
- package/dist/tamer.mjs +63 -22
- package/dist/tamer.mjs.map +1 -1
- package/dist/{tamerArtifactsR2-B9myb-IA.mjs → tamerArtifactsR2-B3X21TGV.mjs} +2 -2
- package/dist/{tamerArtifactsR2-B9myb-IA.mjs.map → tamerArtifactsR2-B3X21TGV.mjs.map} +1 -1
- package/dist/{tenant-migrate-BfvYL0HH.mjs → tenant-migrate-CM6cb1zo.mjs} +15 -17
- package/dist/tenant-migrate-CM6cb1zo.mjs.map +1 -0
- package/dist/{types-BPxuutXk.mjs → types-DCL0mEjS.mjs} +5 -5
- package/dist/{types-BPxuutXk.mjs.map → types-DCL0mEjS.mjs.map} +1 -1
- package/dist/{verifyPlanFile-CoAOsD3W.mjs → verifyPlanFile-B9VCcFIJ.mjs} +2 -2
- package/dist/{verifyPlanFile-CoAOsD3W.mjs.map → verifyPlanFile-B9VCcFIJ.mjs.map} +1 -1
- package/dist/{wfp-put-BBitXJep.mjs → wfp-put-Bl5K3snx.mjs} +25 -3
- package/dist/wfp-put-Bl5K3snx.mjs.map +1 -0
- package/dist/{worker-route-CvuUPq1k.mjs → worker-route-BapxsQyX.mjs} +2 -2
- package/dist/{worker-route-CvuUPq1k.mjs.map → worker-route-BapxsQyX.mjs.map} +1 -1
- package/dist/{workers-DSlrKeNL.mjs → workers-D7ow_joN.mjs} +7 -13
- package/dist/{workers-DSlrKeNL.mjs.map → workers-D7ow_joN.mjs.map} +1 -1
- package/dist/wranglerSpawn-CfPkFLP3.mjs +3 -0
- package/dist/{wranglerSpawn-DWdgrsmQ.mjs → wranglerSpawn-VkSL0gZd.mjs} +1 -1
- package/dist/{wranglerSpawn-DWdgrsmQ.mjs.map → wranglerSpawn-VkSL0gZd.mjs.map} +1 -1
- package/dist/{zoneResolver-VoxLHM4N.mjs → zoneResolver-CamXJpSB.mjs} +1 -1
- package/dist/{zoneResolver-VoxLHM4N.mjs.map → zoneResolver-CamXJpSB.mjs.map} +1 -1
- package/package.json +5 -2
- package/dist/buildDispatchUploadForm-D_fM8JaL.mjs +0 -35
- package/dist/buildDispatchUploadForm-D_fM8JaL.mjs.map +0 -1
- package/dist/drift-08k11FV6.mjs +0 -8
- package/dist/provision-tenant-R6Xa3IUJ.mjs.map +0 -1
- package/dist/registry-X9dlQxG3.mjs.map +0 -1
- package/dist/resolveTenantBindings-4grVKHIG.mjs.map +0 -1
- package/dist/sync-CfNyelDN.mjs +0 -7
- package/dist/tenant-migrate-BfvYL0HH.mjs.map +0 -1
- package/dist/wfp-put-BBitXJep.mjs.map +0 -1
- package/dist/wranglerSpawn-aARBLHpA.mjs +0 -3
- /package/dist/{secrets-2Hy5LMHs.mjs → secrets-DJ1yUy01.mjs} +0 -0
- /package/dist/{wranglerOutFile-f08VsoAj.mjs → wranglerOutFile-DDFKeKwO.mjs} +0 -0
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { H as getWorkers } from "./tamer.mjs";
|
|
2
|
-
import {
|
|
3
|
-
import { n as logApplyChange } from "./planFormat-
|
|
2
|
+
import { t as emptyR2BucketViaS3 } from "./r2S3EmptyBucket-DD81ZWQ7.mjs";
|
|
3
|
+
import { n as logApplyChange } from "./planFormat-CJw8Kq2s.mjs";
|
|
4
|
+
import { createHash } from "crypto";
|
|
4
5
|
|
|
5
6
|
//#region src/core/naming/resolveCloudflareName.ts
|
|
6
7
|
function resolveOverride(fn, tenantId, env, ctx) {
|
|
@@ -667,21 +668,71 @@ function r2Drift(allR2, resources, env, state, naming) {
|
|
|
667
668
|
}
|
|
668
669
|
|
|
669
670
|
//#endregion
|
|
670
|
-
//#region src/features/r2/
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
}
|
|
681
|
-
if (!nextCursor) break;
|
|
682
|
-
cursor = nextCursor;
|
|
671
|
+
//#region src/features/r2/r2TempS3Creds.ts
|
|
672
|
+
/**
|
|
673
|
+
* Find the "Workers R2 Storage Bucket Item Write" permission group ID.
|
|
674
|
+
* This is the bucket-scoped permission that maps to S3 operations.
|
|
675
|
+
*/
|
|
676
|
+
async function findR2BucketItemWriteGroupId(api) {
|
|
677
|
+
const groups = await api.accountTokenPermissionGroupsListAll();
|
|
678
|
+
for (const g of groups) {
|
|
679
|
+
const name = g.name.toLowerCase();
|
|
680
|
+
if (/workers r2 storage/i.test(name) && /bucket item/i.test(name) && /write|edit/i.test(name)) return g.id;
|
|
683
681
|
}
|
|
684
|
-
|
|
682
|
+
throw new Error("Could not find 'Workers R2 Storage Bucket Item Write' permission group. Available: " + groups.slice(0, 12).map((g) => g.name).join(", "));
|
|
683
|
+
}
|
|
684
|
+
/**
|
|
685
|
+
* Mint a temporary R2 S3 credential for a specific bucket.
|
|
686
|
+
* Returns S3-compatible credentials + the token ID (for cleanup).
|
|
687
|
+
*
|
|
688
|
+
* Uses the same permission group and resource format as the Cloudflare
|
|
689
|
+
* dashboard when creating R2 API tokens:
|
|
690
|
+
* group: "Workers R2 Storage Bucket Item Write"
|
|
691
|
+
* resource: "com.cloudflare.edge.r2.bucket.{accountId}_default_{bucketName}"
|
|
692
|
+
*/
|
|
693
|
+
async function mintR2S3Credentials(api, accountId, bucketName) {
|
|
694
|
+
const groupId = await findR2BucketItemWriteGroupId(api);
|
|
695
|
+
const bucketResource = `com.cloudflare.edge.r2.bucket.${accountId}_default_${bucketName}`;
|
|
696
|
+
const tokenName = `Tamer R2 cleanup ${bucketName} ${Date.now()}`;
|
|
697
|
+
console.log(`R2: minting S3 token — group=${groupId}, resource=${bucketResource}`);
|
|
698
|
+
const result = await api.accountTokenCreate({
|
|
699
|
+
name: tokenName,
|
|
700
|
+
policies: [{
|
|
701
|
+
effect: "allow",
|
|
702
|
+
permission_groups: [{ id: groupId }],
|
|
703
|
+
resources: { [bucketResource]: "*" }
|
|
704
|
+
}],
|
|
705
|
+
condition: {}
|
|
706
|
+
});
|
|
707
|
+
if (!result.value) {
|
|
708
|
+
try {
|
|
709
|
+
await api.accountTokenDelete(result.id);
|
|
710
|
+
} catch {}
|
|
711
|
+
throw new Error("R2 S3 cleanup: token create succeeded but no value returned. Check that the CF API token has 'API Tokens: Edit' permission.");
|
|
712
|
+
}
|
|
713
|
+
if (!result.policies?.[0]?.id) {
|
|
714
|
+
try {
|
|
715
|
+
await api.accountTokenDelete(result.id);
|
|
716
|
+
} catch {}
|
|
717
|
+
throw new Error("R2 S3 cleanup: token create succeeded but no policy id returned.");
|
|
718
|
+
}
|
|
719
|
+
const policyId = result.policies?.[0]?.id;
|
|
720
|
+
console.log(`R2: token created — id=${result.id}, policyId=${policyId}, valuePrefix=${result.value?.slice(0, 12)}…`);
|
|
721
|
+
const secretAccessKey = createHash("sha256").update(result.value).digest("hex");
|
|
722
|
+
console.log(`R2: derived secret — prefix=${secretAccessKey.slice(0, 16)}…`);
|
|
723
|
+
return {
|
|
724
|
+
accessKeyId: policyId,
|
|
725
|
+
secretAccessKey,
|
|
726
|
+
tokenId: result.id
|
|
727
|
+
};
|
|
728
|
+
}
|
|
729
|
+
/**
|
|
730
|
+
* Delete a previously minted temporary R2 S3 token.
|
|
731
|
+
*/
|
|
732
|
+
async function deleteR2S3Credentials(api, tokenId) {
|
|
733
|
+
try {
|
|
734
|
+
await api.accountTokenDelete(tokenId);
|
|
735
|
+
} catch {}
|
|
685
736
|
}
|
|
686
737
|
|
|
687
738
|
//#endregion
|
|
@@ -691,38 +742,35 @@ async function r2Destroy(_env, state, api, config, baseDir, _force) {
|
|
|
691
742
|
const resources = state.getAll();
|
|
692
743
|
const r2Entries = Object.values(resources).filter((e) => e.type === "r2_bucket");
|
|
693
744
|
const accountId = api.getAccountId();
|
|
694
|
-
const s3creds = r2S3CredentialsFromEnv();
|
|
695
745
|
for (const entry of r2Entries) {
|
|
696
746
|
if (!owned.has(entry.logicalName)) continue;
|
|
697
747
|
const name = entry.derivedName;
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
748
|
+
let creds = null;
|
|
749
|
+
try {
|
|
750
|
+
creds = await mintR2S3Credentials(api, accountId, name);
|
|
751
|
+
} catch {}
|
|
752
|
+
if (creds) try {
|
|
753
|
+
const { uploadsAborted, objectsDeleted } = await emptyR2BucketViaS3(accountId, name, {
|
|
754
|
+
accessKeyId: creds.accessKeyId,
|
|
755
|
+
secretAccessKey: creds.secretAccessKey
|
|
756
|
+
});
|
|
701
757
|
console.log(`R2: bucket "${name}" — aborted ${uploadsAborted} multipart upload(s), deleted ${objectsDeleted} object(s).`);
|
|
702
758
|
} catch (err) {
|
|
703
|
-
console.warn(`R2: S3 empty failed for "${name}"
|
|
704
|
-
await tryEmptyViaCfApi(api, name);
|
|
759
|
+
console.warn(`R2: S3 empty failed for "${name}":`, err instanceof Error ? err.message : err);
|
|
705
760
|
}
|
|
706
|
-
else await tryEmptyViaCfApi(api, name);
|
|
707
761
|
try {
|
|
708
762
|
await api.r2Delete(name);
|
|
709
763
|
state.delete(name);
|
|
764
|
+
console.log(`R2: deleted bucket "${name}".`);
|
|
710
765
|
} catch (err) {
|
|
711
766
|
const msg = err instanceof Error ? err.message : String(err);
|
|
712
767
|
if (/404|not found/i.test(msg)) state.delete(name);
|
|
713
768
|
else throw err;
|
|
769
|
+
} finally {
|
|
770
|
+
if (creds) await deleteR2S3Credentials(api, creds.tokenId);
|
|
714
771
|
}
|
|
715
772
|
}
|
|
716
773
|
}
|
|
717
|
-
async function tryEmptyViaCfApi(api, bucketName) {
|
|
718
|
-
try {
|
|
719
|
-
console.log(`R2: emptying bucket "${bucketName}" via CF API…`);
|
|
720
|
-
const { objectsDeleted } = await emptyR2BucketViaCfApi(api, bucketName);
|
|
721
|
-
console.log(`R2: bucket "${bucketName}" — deleted ${objectsDeleted} object(s) via CF API.`);
|
|
722
|
-
} catch (err) {
|
|
723
|
-
console.warn(`R2: CF API empty failed for "${bucketName}" (bucket may have objects that prevent deletion):`, err instanceof Error ? err.message : err);
|
|
724
|
-
}
|
|
725
|
-
}
|
|
726
774
|
|
|
727
775
|
//#endregion
|
|
728
776
|
//#region src/features/r2/r2.generate.ts
|
|
@@ -3109,4 +3157,4 @@ function getResourceModule(kind) {
|
|
|
3109
3157
|
|
|
3110
3158
|
//#endregion
|
|
3111
3159
|
export { logicalNamesForResourceKind as a, workflowsApply as i, resourceModules as n, d1CloudflareDatabaseName as o, secretsStoreDeriveName as r, d1SkipsProvisionAndMigrate as s, getResourceModule as t };
|
|
3112
|
-
//# sourceMappingURL=registry-
|
|
3160
|
+
//# sourceMappingURL=registry-CTerXUza.mjs.map
|