diff --git a/messages/cache.md b/messages/cache.md index 69dd16b8..bd891752 100644 --- a/messages/cache.md +++ b/messages/cache.md @@ -5,3 +5,7 @@ No job found for ID: %s. # error.NoRecentJobId There are no recent job IDs available. + +# error.NoMatchingJobId + +No matching job found in cache for ID: %s. diff --git a/messages/deploy.metadata.quick.md b/messages/deploy.metadata.quick.md index 8767e89c..c818c3ea 100644 --- a/messages/deploy.metadata.quick.md +++ b/messages/deploy.metadata.quick.md @@ -84,6 +84,10 @@ Job ID can't be used for quick deployment. Possible reasons include the deployme Deployment %s exited with status code: %s. +# error.NoTargetOrg + +No target org found in cache, from a flag, or in the environment. + # info.QuickDeploySuccess Successfully deployed (%s). diff --git a/src/commands/project/deploy/cancel.ts b/src/commands/project/deploy/cancel.ts index 20af243f..0dfc39af 100644 --- a/src/commands/project/deploy/cancel.ts +++ b/src/commands/project/deploy/cancel.ts @@ -63,7 +63,7 @@ export default class DeployMetadataCancel extends SfCommand { const jobId = cache.resolveLatest(flags['use-most-recent'], flags['job-id']); // cancel don't care about your tracking conflicts - const deployOpts = { ...cache.get(jobId), 'ignore-conflicts': true }; + const deployOpts = { ...cache.maybeGet(jobId), 'ignore-conflicts': true }; // we may already know the job finished if ( deployOpts.status && @@ -80,7 +80,7 @@ export default class DeployMetadataCancel extends SfCommand { if (!this.jsonEnabled()) formatter.display(); return formatter.getJson(); } else { - const wait = flags.wait ?? Duration.minutes(deployOpts.wait); + const wait = flags.wait ?? Duration.minutes(deployOpts.wait ?? 33); const result = await cancelDeploy({ ...deployOpts, wait }, jobId); const formatter = new DeployCancelResultFormatter(result); if (!this.jsonEnabled()) formatter.display(); diff --git a/src/commands/project/deploy/quick.ts b/src/commands/project/deploy/quick.ts index 6877259b..9656f61f 100644 --- a/src/commands/project/deploy/quick.ts +++ b/src/commands/project/deploy/quick.ts @@ -10,7 +10,7 @@ import { Messages, Org } from '@salesforce/core'; import { SfCommand, toHelpSection, Flags } from '@salesforce/sf-plugins-core'; import { MetadataApiDeploy, RequestStatus } from '@salesforce/source-deploy-retrieve'; import { Duration } from '@salesforce/kit'; -import { DeployOptions, determineExitCode, resolveApi } from '../../../utils/deploy.js'; +import { determineExitCode, resolveApi } from '../../../utils/deploy.js'; import { DeployCache } from '../../../utils/deployCache.js'; import { DEPLOY_STATUS_CODES_DESCRIPTIONS } from '../../../utils/errorCodes.js'; import { AsyncDeployResultFormatter } from '../../../formatters/asyncDeployResultFormatter.js'; @@ -84,12 +84,10 @@ export default class DeployMetadataQuick extends SfCommand { const [{ flags }, cache] = await Promise.all([this.parse(DeployMetadataQuick), DeployCache.create()]); // This is the ID of the validation request - const jobId = cache.resolveLatest(flags['use-most-recent'], flags['job-id'], false); - - const deployOpts = cache.get(jobId) ?? ({} as DeployOptions); - const org = flags['target-org'] ?? (await Org.create({ aliasOrUsername: deployOpts['target-org'] })); + const jobId = resolveJobId(cache, flags['use-most-recent'], flags['job-id']); + const targetOrg = await resolveTargetOrg(cache, jobId, flags['target-org']); const api = await resolveApi(this.configAggregator); - const connection = org.getConnection(flags['api-version']); + const connection = targetOrg.getConnection(flags['api-version']); // This is the ID of the deploy (of the validated metadata) const deployId = await connection.metadata.deployRecentValidation({ @@ -145,3 +143,28 @@ export default class DeployMetadataQuick extends SfCommand { return super.catch(error); } } + +/** Resolve a job ID for a validated deploy using cache, most recent, or a job ID flag. */ +const resolveJobId = (cache: DeployCache, useMostRecentFlag: boolean, jobIdFlag?: string): string => { + try { + return cache.resolveLatest(useMostRecentFlag, jobIdFlag, true); + } catch (e) { + if (e instanceof Error && e.name === 'NoMatchingJobIdError' && jobIdFlag) { + return jobIdFlag; // Use the specified 15 char job ID + } + throw e; + } +}; + +/** Resolve a target org using job ID in cache, or a target org flag. */ +const resolveTargetOrg = async (cache: DeployCache, jobId: string, targetOrgFlag: Org): Promise => { + const orgFromCache = cache.maybeGet(jobId)?.['target-org']; + const targetOrg = orgFromCache ? await Org.create({ aliasOrUsername: orgFromCache }) : targetOrgFlag; + + // If we don't have a target org at this point, throw. + if (!targetOrg) { + throw messages.createError('error.NoTargetOrg'); + } + + return targetOrg; +}; diff --git a/src/commands/project/deploy/report.ts b/src/commands/project/deploy/report.ts index d0689611..cde43b68 100644 --- a/src/commands/project/deploy/report.ts +++ b/src/commands/project/deploy/report.ts @@ -5,8 +5,6 @@ * For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause */ - - import { Messages, Org, SfProject } from '@salesforce/core'; import { SfCommand, Flags } from '@salesforce/sf-plugins-core'; import { ComponentSet, DeployResult, MetadataApiDeploy } from '@salesforce/source-deploy-retrieve'; @@ -17,7 +15,7 @@ import { DeployReportResultFormatter } from '../../../formatters/deployReportRes import { API, DeployResultJson } from '../../../utils/types.js'; import { coverageFormattersFlag } from '../../../utils/flags.js'; -Messages.importMessagesDirectoryFromMetaUrl(import.meta.url) +Messages.importMessagesDirectoryFromMetaUrl(import.meta.url); const messages = Messages.loadMessages('@salesforce/plugin-deploy-retrieve', 'deploy.metadata.report'); const deployMessages = Messages.loadMessages('@salesforce/plugin-deploy-retrieve', 'deploy.metadata'); const testFlags = 'Test'; @@ -75,14 +73,16 @@ export default class DeployMetadataReport extends SfCommand { const [{ flags }, cache] = await Promise.all([this.parse(DeployMetadataReport), DeployCache.create()]); const jobId = cache.resolveLatest(flags['use-most-recent'], flags['job-id'], false); - const deployOpts = cache.get(jobId) ?? {}; + const deployOpts = cache.maybeGet(jobId); const wait = flags['wait']; - const org = flags['target-org'] ?? (await Org.create({ aliasOrUsername: deployOpts['target-org'] })); + const org = deployOpts?.['target-org'] + ? await Org.create({ aliasOrUsername: deployOpts['target-org'] }) + : flags['target-org']; // if we're using mdapi we won't have a component set let componentSet = new ComponentSet(); - if (!deployOpts.isMdapi) { - if (!cache.get(jobId)) { + if (!deployOpts?.isMdapi) { + if (!cache.maybeGet(jobId)) { // If the cache file isn't there, use the project package directories for the CompSet try { this.project = await SfProject.resolve(); @@ -102,7 +102,7 @@ export default class DeployMetadataReport extends SfCommand { id: jobId, components: componentSet, apiOptions: { - rest: deployOpts.api === API['REST'], + rest: deployOpts?.api === API['REST'], }, }); diff --git a/src/commands/project/deploy/resume.ts b/src/commands/project/deploy/resume.ts index d4c1c147..d8557af1 100644 --- a/src/commands/project/deploy/resume.ts +++ b/src/commands/project/deploy/resume.ts @@ -5,8 +5,6 @@ * For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause */ - - import chalk from 'chalk'; import { EnvironmentVariable, Messages, Org, SfError } from '@salesforce/core'; import { SfCommand, toHelpSection, Flags } from '@salesforce/sf-plugins-core'; @@ -20,7 +18,7 @@ import { DeployCache } from '../../../utils/deployCache.js'; import { DEPLOY_STATUS_CODES_DESCRIPTIONS } from '../../../utils/errorCodes.js'; import { coverageFormattersFlag } from '../../../utils/flags.js'; -Messages.importMessagesDirectoryFromMetaUrl(import.meta.url) +Messages.importMessagesDirectoryFromMetaUrl(import.meta.url); const messages = Messages.loadMessages('@salesforce/plugin-deploy-retrieve', 'deploy.metadata.resume'); const testFlags = 'Test'; @@ -83,10 +81,10 @@ export default class DeployMetadataResume extends SfCommand { public async run(): Promise { const [{ flags }, cache] = await Promise.all([this.parse(DeployMetadataResume), DeployCache.create()]); - const jobId = cache.resolveLatest(flags['use-most-recent'], flags['job-id']); + const jobId = cache.resolveLatest(flags['use-most-recent'], flags['job-id'], true); // if it was async before, then it should not be async now. - const deployOpts = { ...cache.get(jobId), async: false }; + const deployOpts = { ...cache.maybeGet(jobId), async: false }; let result: DeployResult; @@ -108,7 +106,7 @@ export default class DeployMetadataResume extends SfCommand { const deployStatus = await mdapiDeploy.checkStatus(); result = new DeployResult(deployStatus, componentSet); } else { - const wait = flags.wait ?? Duration.minutes(deployOpts.wait); + const wait = flags.wait ?? Duration.minutes(deployOpts.wait ?? 33); const { deploy } = await executeDeploy( // there will always be conflicts on a resume if anything deployed--the changes on the server are not synced to local { @@ -134,6 +132,7 @@ export default class DeployMetadataResume extends SfCommand { if (!deploy.id) { throw new SfError('The deploy id is not available.'); } + cache.update(deploy.id, { status: result.response.status }); await cache.write(); } diff --git a/src/utils/deployCache.ts b/src/utils/deployCache.ts index d7446abd..b6f149cd 100644 --- a/src/utils/deployCache.ts +++ b/src/utils/deployCache.ts @@ -41,44 +41,82 @@ export class DeployCache extends TTLConfig { public static async unset(key: string): Promise { const cache = await DeployCache.create(); - cache.unset(key); + cache.unset(ensure18(key, cache)); await Promise.all([cache.write(), maybeDestroyManifest(key)]); } public static async update(key: string, obj: JsonMap): Promise { const cache = await DeployCache.create(); - cache.update(key, obj); + cache.update(ensure18(key, cache), obj); await cache.write(); } - public resolveLatest(useMostRecent: boolean, key: string | undefined, throwOnNotFound = true): string { - const keyFromLatest = useMostRecent ? this.getLatestKey() : key; - if (!keyFromLatest) throw cacheMessages.createError('error.NoRecentJobId'); + public update(key: string, obj: JsonMap): void { + super.update(ensure18(key, this), obj); + } + + /** will return an 18 character ID if throwOnNotFound is true (because the cache can be used to shift 15 to 18) */ + public resolveLatest(useMostRecent: boolean, key: string | undefined, throwOnNotFound?: boolean): string { + const resolvedKey = useMostRecent ? this.getLatestKey() : key; + if (!resolvedKey) throw cacheMessages.createError('error.NoRecentJobId'); - const jobId = this.resolveLongId(keyFromLatest); + const match = this.maybeGet(resolvedKey); - if (throwOnNotFound && !this.has(jobId)) { - throw cacheMessages.createError('error.InvalidJobId', [jobId]); + if (throwOnNotFound === true && !match) { + throw cacheMessages.createError('error.NoMatchingJobId', [resolvedKey]); } - return jobId; + return throwOnNotFound ? ensure18(resolvedKey, this) : resolvedKey; } + /** + * @deprecated. Use maybeGet to handle both 15 and 18 char IDs + * returns 18-char ID unmodified, regardless of whether it's in cache or not + * returns 15-char ID if it matches a key in the cache, otherwise throws + */ public resolveLongId(jobId: string): string { - if (jobId.length === 18) { - return jobId; - } else if (jobId.length === 15) { - const match = this.keys().find((k) => k.startsWith(jobId)); - if (match) { - return match; - } - throw cacheMessages.createError('error.InvalidJobId', [jobId]); - } else { - throw cacheMessages.createError('error.InvalidJobId', [jobId]); - } + return ensure18(jobId, this); } + /** + * + * @deprecated. Use maybeGet because the typings are wrong in sfdx-core + */ public get(jobId: string): TTLConfig.Entry { return super.get(this.resolveLongId(jobId)); } + + /** + * works with 18 and 15-character IDs. + * Prefer 18 as that's how the cache is keyed. + * Returns undefined if no match is found. + */ + public maybeGet(jobId: string): TTLConfig.Entry | undefined { + if (jobId.length === 18) { + return super.get(jobId); + } + if (jobId.length === 15) { + const match = this.keys().find((k) => k.startsWith(jobId)); + return match ? super.get(match) : undefined; + } + throw cacheMessages.createError('error.InvalidJobId', [jobId]); + } } + +/** + * if the jobId is 15 characters, use the cache to convert to 18 + * will throw if the value is not in the cache + */ +const ensure18 = (jobId: string, cache: DeployCache): string => { + if (jobId.length === 18) { + return jobId; + } else if (jobId.length === 15) { + const match = cache.keys().find((k) => k.startsWith(jobId)); + if (match) { + return match; + } + throw cacheMessages.createError('error.NoMatchingJobId', [jobId]); + } else { + throw cacheMessages.createError('error.InvalidJobId', [jobId]); + } +}; diff --git a/test/commands/deploy/metadata/quick.nut.ts b/test/commands/deploy/metadata/quick.nut.ts index 56d2b97f..aa748f04 100644 --- a/test/commands/deploy/metadata/quick.nut.ts +++ b/test/commands/deploy/metadata/quick.nut.ts @@ -6,10 +6,13 @@ */ import { fileURLToPath } from 'node:url'; +import fs from 'node:fs'; +import path from 'node:path'; import { SourceTestkit } from '@salesforce/source-testkit'; import { assert, config } from 'chai'; import { execCmd } from '@salesforce/cli-plugins-testkit'; import { DeployResultJson } from '../../../../src/utils/types.js'; + config.truncateThreshold = 0; describe('deploy metadata quick NUTs', () => { @@ -81,59 +84,160 @@ describe('deploy metadata quick NUTs', () => { }); }); - describe('--job-id', () => { - it('should deploy previously validated deployment (async)', async () => { - const validation = await testkit.execute('project:deploy:validate', { - args: '--source-dir force-app', - json: true, - exitCode: 0, + describe('using cache', () => { + describe('--job-id 18', () => { + it('should deploy previously validated deployment (async)', async () => { + const validation = await testkit.execute('project:deploy:validate', { + args: '--source-dir force-app', + json: true, + exitCode: 0, + }); + assert(validation); + await testkit.expect.filesToBeDeployed(['force-app/**/*'], ['force-app/test/**/*']); + + const deploy = await testkit.execute('project:deploy:quick', { + args: `--job-id ${validation.result.id}`, + json: true, + exitCode: 0, + }); + assert(deploy); + assert(deploy.result.id !== validation.result.id, 'deploy result ID should not be the validation ID'); + await testkit.expect.filesToBeDeployed(['force-app/**/*'], ['force-app/test/**/*']); }); - assert(validation); - await testkit.expect.filesToBeDeployed(['force-app/**/*'], ['force-app/test/**/*']); - const deploy = await testkit.execute('project:deploy:quick', { - args: `--job-id ${validation.result.id}`, - json: true, - exitCode: 0, + it('should deploy previously validated deployment (poll)', async () => { + const validation = await testkit.execute('project:deploy:validate', { + args: '--source-dir force-app', + json: true, + exitCode: 0, + }); + assert(validation); + await testkit.expect.filesToBeDeployed(['force-app/**/*'], ['force-app/test/**/*']); + + const deploy = await testkit.execute('project:deploy:quick', { + args: `--job-id ${validation.result.id} --wait 20`, + json: true, + exitCode: 0, + }); + assert(deploy); + assert(deploy.result.id !== validation.result.id, 'deploy result ID should not be the validation ID'); + await testkit.expect.filesToBeDeployed(['force-app/**/*'], ['force-app/test/**/*']); }); - assert(deploy); - assert(deploy.result.id !== validation.result.id, 'deploy result ID should not be the validation ID'); - await testkit.expect.filesToBeDeployed(['force-app/**/*'], ['force-app/test/**/*']); - }); - it('should deploy previously validated deployment (poll)', async () => { - const validation = await testkit.execute('project:deploy:validate', { - args: '--source-dir force-app', - json: true, - exitCode: 0, + it('should fail to deploy previously deployed deployment', async () => { + const first = await testkit.execute('deploy:metadata', { + args: '--source-dir force-app', + json: true, + exitCode: 0, + }); + assert(first); + const deploy = await testkit.execute('project:deploy:quick', { + args: `--job-id ${first.result.id}`, + json: true, + exitCode: 1, + }); + assert(deploy); + testkit.expect.errorToHaveName(deploy, 'CannotQuickDeployError'); }); - assert(validation); - await testkit.expect.filesToBeDeployed(['force-app/**/*'], ['force-app/test/**/*']); + }); - const deploy = await testkit.execute('project:deploy:quick', { - args: `--job-id ${validation.result.id} --wait 20`, - json: true, - exitCode: 0, + describe('--job-id 15', () => { + it('should deploy previously validated deployment (async)', async () => { + const validation = await testkit.execute('project:deploy:validate', { + args: '--source-dir force-app', + json: true, + exitCode: 0, + }); + assert(validation); + await testkit.expect.filesToBeDeployed(['force-app/**/*'], ['force-app/test/**/*']); + + const deploy = await testkit.execute('project:deploy:quick', { + args: `--job-id ${validation.result.id?.slice(0, 15)}`, + json: true, + exitCode: 0, + }); + assert(deploy); + assert(deploy.result.id !== validation.result.id, 'deploy result ID should not be the validation ID'); + await testkit.expect.filesToBeDeployed(['force-app/**/*'], ['force-app/test/**/*']); }); - assert(deploy); - assert(deploy.result.id !== validation.result.id, 'deploy result ID should not be the validation ID'); - await testkit.expect.filesToBeDeployed(['force-app/**/*'], ['force-app/test/**/*']); }); + }); - it('should fail to deploy previously deployed deployment', async () => { - const first = await testkit.execute('deploy:metadata', { - args: '--source-dir force-app', - json: true, - exitCode: 0, + describe('no cache using default org', () => { + describe('--job-id 18', () => { + it('should deploy previously validated deployment (async)', async () => { + const validation = await testkit.execute('project:deploy:validate', { + args: '--source-dir force-app', + json: true, + exitCode: 0, + }); + assert(validation); + await testkit.expect.filesToBeDeployed(['force-app/**/*'], ['force-app/test/**/*']); + + await fs.promises.rm(path.join(testkit.projectDir, '..', '.sf', 'deploy-cache.json'), { + recursive: true, + force: true, + }); + + const deploy = await testkit.execute('project:deploy:quick', { + args: `--job-id ${validation.result.id}`, + json: true, + exitCode: 0, + }); + assert(deploy); + assert(deploy.result.id !== validation.result.id, 'deploy result ID should not be the validation ID'); + await testkit.expect.filesToBeDeployed(['force-app/**/*'], ['force-app/test/**/*']); }); - assert(first); - const deploy = await testkit.execute('project:deploy:quick', { - args: `--job-id ${first.result.id}`, - json: true, - exitCode: 1, + + it('should deploy previously validated deployment (poll)', async () => { + const validation = await testkit.execute('project:deploy:validate', { + args: '--source-dir force-app', + json: true, + exitCode: 0, + }); + assert(validation); + await testkit.expect.filesToBeDeployed(['force-app/**/*'], ['force-app/test/**/*']); + + await fs.promises.rm(path.join(testkit.projectDir, '..', '.sf', 'deploy-cache.json'), { + recursive: true, + force: true, + }); + + const deploy = await testkit.execute('project:deploy:quick', { + args: `--job-id ${validation.result.id} --wait 20`, + json: true, + exitCode: 0, + }); + assert(deploy); + assert(deploy.result.id !== validation.result.id, 'deploy result ID should not be the validation ID'); + await testkit.expect.filesToBeDeployed(['force-app/**/*'], ['force-app/test/**/*']); + }); + }); + + describe('--job-id 15', () => { + it('should deploy previously validated deployment (async)', async () => { + const validation = await testkit.execute('project:deploy:validate', { + args: '--source-dir force-app', + json: true, + exitCode: 0, + }); + assert(validation); + await testkit.expect.filesToBeDeployed(['force-app/**/*'], ['force-app/test/**/*']); + + await fs.promises.rm(path.join(testkit.projectDir, '..', '.sf', 'deploy-cache.json'), { + recursive: true, + force: true, + }); + + const deploy = await testkit.execute('project:deploy:quick', { + args: `--job-id ${validation.result.id?.slice(0, 15)}`, + json: true, + exitCode: 0, + }); + assert(deploy); + assert(deploy.result.id !== validation.result.id, 'deploy result ID should not be the validation ID'); + await testkit.expect.filesToBeDeployed(['force-app/**/*'], ['force-app/test/**/*']); }); - assert(deploy); - testkit.expect.errorToHaveName(deploy, 'CannotQuickDeployError'); }); }); }); diff --git a/yarn.lock b/yarn.lock index fb0ece42..d545db0a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -574,7 +574,7 @@ "@smithy/util-utf8" "^2.1.1" tslib "^2.5.0" -"@aws-sdk/types@3.496.0": +"@aws-sdk/types@3.496.0", "@aws-sdk/types@^3.222.0": version "3.496.0" resolved "https://registry.yarnpkg.com/@aws-sdk/types/-/types-3.496.0.tgz#cdde44a94a57cf8f97cf05e4d0bdce2f56ce4eeb" integrity sha512-umkGadK4QuNQaMoDICMm7NKRI/mYSXiyPjcn3d53BhsuArYU/52CebGQKdt4At7SwwsiVJZw9RNBHyN5Mm0HVw== @@ -582,14 +582,6 @@ "@smithy/types" "^2.9.1" tslib "^2.5.0" -"@aws-sdk/types@^3.222.0": - version "3.489.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/types/-/types-3.489.0.tgz#0fa29adaace3e407ac15428524aa67e9bd229f65" - integrity sha512-kcDtLfKog/p0tC4gAeqJqWxAiEzfe2LRPnKamvSG2Mjbthx4R/alE2dxyIq/wW+nvRv0fqR3OD5kD1+eVfdr/w== - dependencies: - "@smithy/types" "^2.8.0" - tslib "^2.5.0" - "@aws-sdk/util-arn-parser@3.495.0": version "3.495.0" resolved "https://registry.yarnpkg.com/@aws-sdk/util-arn-parser/-/util-arn-parser-3.495.0.tgz#539f2d6dfef343a80324348f1f9a1b7eed2390f3" @@ -1830,22 +1822,7 @@ shelljs "^0.8.4" sinon "^10.0.0" -"@salesforce/source-tracking@^5.0.0": - version "5.1.5" - resolved "https://registry.yarnpkg.com/@salesforce/source-tracking/-/source-tracking-5.1.5.tgz#a8ff65d738ed12ce585540d3efe4a8a4a65afafc" - integrity sha512-4uQGz6Vg213CLDCGVI8VIxsFVguShEMDV535YHV3YPK/Q3ls4z4eOBk8vOrFpItlHuKpfYYmAKKy16AFJMgk2w== - dependencies: - "@oclif/core" "^3.18.1" - "@salesforce/core" "^6.4.7" - "@salesforce/kit" "^3.0.15" - "@salesforce/source-deploy-retrieve" "^10.2.11" - "@salesforce/ts-types" "^2.0.9" - fast-xml-parser "^4.2.5" - graceful-fs "^4.2.11" - isomorphic-git "1.23.0" - ts-retry-promise "^0.7.0" - -"@salesforce/source-tracking@^5.1.7": +"@salesforce/source-tracking@^5.0.0", "@salesforce/source-tracking@^5.1.7": version "5.1.7" resolved "https://registry.yarnpkg.com/@salesforce/source-tracking/-/source-tracking-5.1.7.tgz#2bfc3e6c9bf0aabd7ba5644a69977dfd1fef84c3" integrity sha512-kkXWt4X+wxmYsLqG1OIWKgo3aFEg1f+1X6MBIHIrmjEmfMXIRiGX0dRyY+IjFl54w+CnOffNDQNsGSmnPImEYg== @@ -2300,13 +2277,6 @@ "@smithy/util-stream" "^2.1.1" tslib "^2.5.0" -"@smithy/types@^2.8.0": - version "2.8.0" - resolved "https://registry.yarnpkg.com/@smithy/types/-/types-2.8.0.tgz#bdbaa0a54c9c3538d6c763c6f32d3e4f76fe0df9" - integrity sha512-h9sz24cFgt/W1Re22OlhQKmUZkNh244ApgRsUDYinqF8R+QgcsBIX344u2j61TPshsTz3CvL6HYU1DnQdsSrHA== - dependencies: - tslib "^2.5.0" - "@smithy/types@^2.9.1": version "2.9.1" resolved "https://registry.yarnpkg.com/@smithy/types/-/types-2.9.1.tgz#ed04d4144eed3b8bd26d20fc85aae8d6e357ebb9" @@ -9074,7 +9044,7 @@ ts-node@^10.8.1, ts-node@^10.9.2: v8-compile-cache-lib "^3.0.1" yn "3.1.1" -ts-retry-promise@^0.7.0, ts-retry-promise@^0.7.1: +ts-retry-promise@^0.7.1: version "0.7.1" resolved "https://registry.yarnpkg.com/ts-retry-promise/-/ts-retry-promise-0.7.1.tgz#176d6eee6415f07b6c7c286d3657355e284a6906" integrity sha512-NhHOCZ2AQORvH42hOPO5UZxShlcuiRtm7P2jIq2L2RY3PBxw2mLnUsEdHrIslVBFya1v5aZmrR55lWkzo13LrQ==