hereya-cli 0.56.0 → 0.57.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.
@@ -71,21 +71,50 @@ export default class Down extends Command {
71
71
  },
72
72
  {
73
73
  async task(ctx) {
74
- let packages = Object.keys(ctx.configOutput.config.packages ?? {});
74
+ // Get packages with their versions from config
75
+ const configPackages = ctx.configOutput.config.packages ?? {};
76
+ let packagesWithVersions = Object.entries(configPackages).map(([name, info]) => ({
77
+ name,
78
+ packageSpec: info.version ? `${name}@${info.version}` : name,
79
+ version: info.version || ''
80
+ }));
75
81
  const backend = await getBackend();
76
82
  const savedStateOutput = await backend.getState({
77
83
  project: ctx.configOutput.config.project,
78
84
  workspace: ctx.workspace,
79
85
  });
80
- let removedPackages = [];
86
+ let removedPackagesWithVersions = [];
81
87
  if (savedStateOutput.found) {
82
- const savedPackages = Object.keys(savedStateOutput.config.packages ?? {});
83
- removedPackages = savedPackages.filter((packageName) => !packages.includes(packageName));
88
+ const savedPackages = savedStateOutput.config.packages ?? {};
89
+ removedPackagesWithVersions = Object.entries(savedPackages)
90
+ .filter(([name]) => !configPackages[name])
91
+ .map(([name, info]) => ({
92
+ name,
93
+ packageSpec: info.version ? `${name}@${info.version}` : name,
94
+ version: info.version || ''
95
+ }));
84
96
  }
97
+ // Handle --select flag with version validation
85
98
  if (flags.select.length > 0) {
86
- packages = packages.filter((packageName) => flags.select.includes(packageName));
99
+ const selectedPackages = [];
100
+ for (const selectedPkg of flags.select) {
101
+ // Parse the selected package to extract name and version
102
+ const [selectedName, selectedVersion] = selectedPkg.split('@');
103
+ // Find the package in the config
104
+ const configPkg = packagesWithVersions.find(pkg => pkg.name === selectedName);
105
+ if (!configPkg) {
106
+ throw new Error(`Package ${selectedName} not found in project`);
107
+ }
108
+ // If user specified a version, validate it matches the installed version
109
+ if (selectedVersion && selectedVersion !== configPkg.version) {
110
+ throw new Error(`Package ${selectedName} version mismatch: installed version is ${configPkg.version || 'unspecified'}, but you specified ${selectedVersion}. ` +
111
+ `Please use 'hereya down -s ${selectedName}' to use the installed version.`);
112
+ }
113
+ selectedPackages.push(configPkg);
114
+ }
115
+ packagesWithVersions = selectedPackages;
87
116
  }
88
- ctx.packages = [...packages, ...removedPackages];
117
+ ctx.packages = [...packagesWithVersions, ...removedPackagesWithVersions];
89
118
  await delay(500);
90
119
  },
91
120
  title: 'Identifying packages to destroy',
@@ -96,7 +125,7 @@ export default class Down extends Command {
96
125
  if (!ctx.packages || ctx.packages.length === 0) {
97
126
  return;
98
127
  }
99
- return task.newListr(ctx.packages.map((packageName) => ({
128
+ return task.newListr(ctx.packages.map((pkg) => ({
100
129
  rendererOptions: {
101
130
  persistentOutput: isDebug(),
102
131
  },
@@ -105,7 +134,7 @@ export default class Down extends Command {
105
134
  const backend = await getBackend();
106
135
  const profile = await getProfileFromWorkspace(backend, ctx.workspace, ctx.configOutput.config.project);
107
136
  const { parameters } = await parameterManager.getPackageParameters({
108
- package: packageName,
137
+ package: pkg.name,
109
138
  profile,
110
139
  projectRootDir,
111
140
  });
@@ -117,7 +146,7 @@ export default class Down extends Command {
117
146
  const destroyOutput = await executor.destroy({
118
147
  isDeploying: flags.deploy,
119
148
  logger: getLogger(task),
120
- package: packageName,
149
+ package: pkg.packageSpec,
121
150
  parameters,
122
151
  project: ctx.configOutput.config.project,
123
152
  projectRootDir,
@@ -128,10 +157,10 @@ export default class Down extends Command {
128
157
  }
129
158
  const { env, metadata } = destroyOutput;
130
159
  const output = ctx.destroyed || [];
131
- output.push({ env, metadata, packageName });
160
+ output.push({ env, metadata, packageName: pkg.name });
132
161
  ctx.destroyed = output;
133
162
  },
134
- title: `Destroying ${packageName}`,
163
+ title: `Destroying ${pkg.name}`,
135
164
  })), { concurrent: true, rendererOptions: { collapseSubtasks: !isDebug() } });
136
165
  },
137
166
  title: `Destroying packages`,
@@ -135,8 +135,9 @@ export default class Import extends Command {
135
135
  const configManager = getConfigManager();
136
136
  await configManager.addPackage({
137
137
  metadata: ctx.importOutput.metadata,
138
- package: ctx.package,
138
+ package: ctx.importOutput.pkgName,
139
139
  projectRootDir,
140
+ version: ctx.importOutput.version,
140
141
  });
141
142
  await delay(500);
142
143
  },
@@ -68,9 +68,21 @@ export default class Remove extends Command {
68
68
  throw new Error(validation.message);
69
69
  }
70
70
  const { config } = loadConfigOutput;
71
- if (!(ctx.package in (config.packages ?? {})) && !(ctx.package in (config.deploy ?? {}))) {
72
- throw new Error(`Package ${ctx.package} not found in the project.`);
71
+ // Parse package name to extract name and version
72
+ const [packageNameWithoutVersion, userSpecifiedVersion] = ctx.package.split('@');
73
+ // Check if package exists in config (using clean name without version)
74
+ const packageInfo = config.packages?.[packageNameWithoutVersion] || config.deploy?.[packageNameWithoutVersion];
75
+ if (!packageInfo) {
76
+ throw new Error(`Package ${packageNameWithoutVersion} not found in the project.`);
73
77
  }
78
+ // Get the installed version from config
79
+ const installedVersion = packageInfo.version || '';
80
+ // If user specified a version, validate it matches the installed version
81
+ if (userSpecifiedVersion && userSpecifiedVersion !== installedVersion) {
82
+ throw new Error(`Package ${packageNameWithoutVersion} version mismatch: installed version is ${installedVersion || 'unspecified'}, but you specified ${userSpecifiedVersion}. ` +
83
+ `Please use 'hereya remove ${packageNameWithoutVersion}' to remove the installed version.`);
84
+ }
85
+ ctx.packageWithInstalledVersion = installedVersion ? `${packageNameWithoutVersion}@${installedVersion}` : packageNameWithoutVersion;
74
86
  await delay(500);
75
87
  },
76
88
  title: 'Loading project config',
@@ -102,7 +114,7 @@ export default class Remove extends Command {
102
114
  const { executor } = executor$;
103
115
  const destroyOutput = await executor.destroy({
104
116
  logger: getLogger(task),
105
- package: ctx.package,
117
+ package: ctx.packageWithInstalledVersion,
106
118
  parameters: ctx.parametersOutput.parameters,
107
119
  project: ctx.configOutput.config.project,
108
120
  projectRootDir,
@@ -134,7 +146,7 @@ export default class Remove extends Command {
134
146
  const configManager = getConfigManager();
135
147
  await configManager.removePackage({
136
148
  metadata: ctx.destroyOutput.metadata,
137
- package: ctx.package,
149
+ package: ctx.destroyOutput.pkgName,
138
150
  projectRootDir,
139
151
  });
140
152
  await delay(500);
@@ -98,14 +98,42 @@ export default class Undeploy extends Command {
98
98
  },
99
99
  {
100
100
  async task(ctx) {
101
- const deployPackages = Object.keys(ctx.configOutput.config.deploy ?? {});
102
- const savedDeployPackages = Object.keys(ctx.savedStateOutput?.config.deploy ?? {});
103
- const removedDeployPackages = savedDeployPackages.filter((packageName) => !deployPackages.includes(packageName));
104
- ctx.deployPackages = [...removedDeployPackages, ...deployPackages];
105
- const packages = Object.keys(ctx.configOutput.config.packages ?? {});
106
- const savedPackages = Object.keys(ctx.savedStateOutput?.config.packages ?? {});
107
- const removedPackages = savedPackages.filter((packageName) => !packages.includes(packageName));
108
- ctx.packages = [...removedPackages, ...packages];
101
+ // Get deploy packages with versions from config
102
+ const configDeployPackages = ctx.configOutput.config.deploy ?? {};
103
+ const deployPackagesWithVersions = Object.entries(configDeployPackages).map(([name, info]) => ({
104
+ name,
105
+ packageSpec: info.version ? `${name}@${info.version}` : name,
106
+ version: info.version || ''
107
+ }));
108
+ // Get removed deploy packages with versions from saved state
109
+ const savedDeployPackages = ctx.savedStateOutput?.config.deploy ?? {};
110
+ const currentDeployPackageNames = Object.keys(configDeployPackages);
111
+ const removedDeployPackages = Object.entries(savedDeployPackages)
112
+ .filter(([name]) => !currentDeployPackageNames.includes(name))
113
+ .map(([name, info]) => ({
114
+ name,
115
+ packageSpec: info.version ? `${name}@${info.version}` : name,
116
+ version: info.version || ''
117
+ }));
118
+ ctx.deployPackages = [...removedDeployPackages, ...deployPackagesWithVersions];
119
+ // Get regular packages with versions from config
120
+ const configPackages = ctx.configOutput.config.packages ?? {};
121
+ const packagesWithVersions = Object.entries(configPackages).map(([name, info]) => ({
122
+ name,
123
+ packageSpec: info.version ? `${name}@${info.version}` : name,
124
+ version: info.version || ''
125
+ }));
126
+ // Get removed packages with versions from saved state
127
+ const savedPackages = ctx.savedStateOutput?.config.packages ?? {};
128
+ const currentPackageNames = Object.keys(configPackages);
129
+ const removedPackages = Object.entries(savedPackages)
130
+ .filter(([name]) => !currentPackageNames.includes(name))
131
+ .map(([name, info]) => ({
132
+ name,
133
+ packageSpec: info.version ? `${name}@${info.version}` : name,
134
+ version: info.version || ''
135
+ }));
136
+ ctx.packages = [...removedPackages, ...packagesWithVersions];
109
137
  await delay(500);
110
138
  },
111
139
  title: 'Identifying removed packages',
@@ -113,7 +141,7 @@ export default class Undeploy extends Command {
113
141
  {
114
142
  skip: (ctx) => ctx.deployPackages.length === 0,
115
143
  async task(ctx, task) {
116
- return task.newListr(ctx.deployPackages.map((packageName) => ({
144
+ return task.newListr(ctx.deployPackages.map((pkg) => ({
117
145
  rendererOptions: {
118
146
  persistentOutput: isDebug(),
119
147
  },
@@ -122,7 +150,7 @@ export default class Undeploy extends Command {
122
150
  const backend = await getBackend();
123
151
  const profile = await getProfileFromWorkspace(backend, ctx.workspace, ctx.configOutput.config.project);
124
152
  const { parameters } = await parameterManager.getPackageParameters({
125
- package: packageName,
153
+ package: pkg.name,
126
154
  profile,
127
155
  projectRootDir,
128
156
  });
@@ -134,7 +162,7 @@ export default class Undeploy extends Command {
134
162
  const destroyOutput = await executor.destroy({
135
163
  isDeploying: true,
136
164
  logger: getLogger(task),
137
- package: packageName,
165
+ package: pkg.packageSpec,
138
166
  parameters,
139
167
  project: ctx.configOutput.config.project,
140
168
  projectEnv: ctx.projectEnv,
@@ -145,7 +173,7 @@ export default class Undeploy extends Command {
145
173
  throw new Error(destroyOutput.reason);
146
174
  }
147
175
  },
148
- title: `Destroying package ${packageName}`,
176
+ title: `Destroying package ${pkg.name}`,
149
177
  })), { concurrent: false, rendererOptions: { collapseSubtasks: !isDebug() } });
150
178
  },
151
179
  title: 'Destroying deployment packages',
@@ -153,7 +181,7 @@ export default class Undeploy extends Command {
153
181
  {
154
182
  skip: (ctx) => !ctx.packages || ctx.packages.length === 0,
155
183
  async task(ctx, task) {
156
- return task.newListr(ctx.packages.map((packageName) => ({
184
+ return task.newListr(ctx.packages.map((pkg) => ({
157
185
  rendererOptions: {
158
186
  persistentOutput: isDebug(),
159
187
  },
@@ -162,7 +190,7 @@ export default class Undeploy extends Command {
162
190
  const backend = await getBackend();
163
191
  const profile = await getProfileFromWorkspace(backend, ctx.workspace, ctx.configOutput.config.project);
164
192
  const { parameters } = await parameterManager.getPackageParameters({
165
- package: packageName,
193
+ package: pkg.name,
166
194
  profile,
167
195
  projectRootDir,
168
196
  });
@@ -174,7 +202,7 @@ export default class Undeploy extends Command {
174
202
  const destroyOutput = await executor.destroy({
175
203
  isDeploying: true,
176
204
  logger: getLogger(task),
177
- package: packageName,
205
+ package: pkg.packageSpec,
178
206
  parameters,
179
207
  project: ctx.configOutput.config.project,
180
208
  projectRootDir,
@@ -185,10 +213,10 @@ export default class Undeploy extends Command {
185
213
  }
186
214
  const { env, metadata } = destroyOutput;
187
215
  const output = ctx.destroyed || [];
188
- output.push({ env, metadata, packageName });
216
+ output.push({ env, metadata, packageName: pkg.name });
189
217
  ctx.destroyed = output;
190
218
  },
191
- title: `Destroying ${packageName}`,
219
+ title: `Destroying ${pkg.name}`,
192
220
  })), { concurrent: true, rendererOptions: { collapseSubtasks: !isDebug() } });
193
221
  },
194
222
  title: `Destroying packages`,
@@ -85,14 +85,39 @@ export default class Up extends Command {
85
85
  },
86
86
  {
87
87
  async task(ctx) {
88
- const packages = Object.keys(ctx.configOutput.config.packages ?? {});
88
+ // Get packages with their versions from config
89
+ const configPackages = ctx.configOutput.config.packages ?? {};
90
+ const packagesWithVersions = Object.entries(configPackages).map(([name, info]) => ({
91
+ name,
92
+ packageSpec: info.version ? `${name}@${info.version}` : name,
93
+ version: info.version || ''
94
+ }));
89
95
  const savedPackages = Object.keys(ctx.savedStateOutput?.config?.packages ?? {});
90
- const removedPackages = savedPackages.filter((packageName) => !packages.includes(packageName));
96
+ const removedPackages = savedPackages.filter((packageName) => !configPackages[packageName]);
91
97
  ctx.removedPackages = removedPackages;
92
- ctx.packages =
93
- flags.select.length > 0
94
- ? packages.filter((packageName) => flags.select.includes(packageName))
95
- : packages;
98
+ // Handle --select flag with version validation
99
+ if (flags.select.length > 0) {
100
+ const selectedPackages = [];
101
+ for (const selectedPkg of flags.select) {
102
+ // Parse the selected package to extract name and version
103
+ const [selectedName, selectedVersion] = selectedPkg.split('@');
104
+ // Find the package in the config
105
+ const configPkg = packagesWithVersions.find(pkg => pkg.name === selectedName);
106
+ if (!configPkg) {
107
+ throw new Error(`Package ${selectedName} not found in project`);
108
+ }
109
+ // If user specified a version, validate it matches the installed version
110
+ if (selectedVersion && selectedVersion !== configPkg.version) {
111
+ throw new Error(`Package ${selectedName} version mismatch: installed version is ${configPkg.version || 'unspecified'}, but you specified ${selectedVersion}. ` +
112
+ `Please use 'hereya up -s ${selectedName}' to use the installed version, or update the package to version ${selectedVersion} first.`);
113
+ }
114
+ selectedPackages.push(configPkg);
115
+ }
116
+ ctx.packages = selectedPackages;
117
+ }
118
+ else {
119
+ ctx.packages = packagesWithVersions;
120
+ }
96
121
  await delay(500);
97
122
  },
98
123
  title: 'Searching for removed packages',
@@ -150,7 +175,7 @@ export default class Up extends Command {
150
175
  if (!ctx.packages || ctx.packages.length === 0) {
151
176
  return;
152
177
  }
153
- return task.newListr(ctx.packages.map((packageName) => ({
178
+ return task.newListr(ctx.packages.map((pkg) => ({
154
179
  rendererOptions: {
155
180
  persistentOutput: isDebug(),
156
181
  },
@@ -159,7 +184,7 @@ export default class Up extends Command {
159
184
  const backend = await getBackend();
160
185
  const profile = await getProfileFromWorkspace(backend, ctx.workspace, ctx.configOutput.config.project);
161
186
  const { parameters } = await parameterManager.getPackageParameters({
162
- package: packageName,
187
+ package: pkg.name,
163
188
  profile,
164
189
  projectRootDir,
165
190
  });
@@ -171,7 +196,7 @@ export default class Up extends Command {
171
196
  const provisionOutput = await executor.provision({
172
197
  isDeploying: flags.deploy,
173
198
  logger: getLogger(task),
174
- package: packageName,
199
+ package: pkg.packageSpec,
175
200
  parameters,
176
201
  project: ctx.configOutput.config.project,
177
202
  projectRootDir,
@@ -182,10 +207,10 @@ export default class Up extends Command {
182
207
  }
183
208
  const { env, metadata } = provisionOutput;
184
209
  const output = ctx.added || [];
185
- output.push({ env, metadata, packageName });
210
+ output.push({ env, metadata, packageName: pkg.name });
186
211
  ctx.added = output;
187
212
  },
188
- title: `Provisioning ${packageName}`,
213
+ title: `Provisioning ${pkg.name}`,
189
214
  })), { concurrent: true, rendererOptions: { collapseSubtasks: !isDebug() } });
190
215
  },
191
216
  title: `Provisioning packages`,
@@ -106,7 +106,7 @@ export default class WorkspaceInstall extends Command {
106
106
  const output = await backend.addPackageToWorkspace({
107
107
  env,
108
108
  infra: metadata.infra,
109
- package: args.package,
109
+ package: ctx.provisionOutput.pkgName,
110
110
  parameters: ctx.parameters,
111
111
  workspace: flags.workspace,
112
112
  });
@@ -54,9 +54,20 @@ export default class WorkspaceUninstall extends Command {
54
54
  if (loadWorkspaceOutput.workspace.mirrorOf) {
55
55
  throw new Error(`Workspace ${flags.workspace} is a mirror of ${loadWorkspaceOutput.workspace.mirrorOf}`);
56
56
  }
57
- if (!(args.package in (loadWorkspaceOutput.workspace.packages ?? {}))) {
58
- throw new Error(`Package ${args.package} not found in workspace ${flags.workspace}`);
57
+ // Parse package name to extract name and version
58
+ const [packageNameWithoutVersion, userSpecifiedVersion] = args.package.split('@');
59
+ const packageInfo = loadWorkspaceOutput.workspace.packages?.[packageNameWithoutVersion];
60
+ if (!packageInfo) {
61
+ throw new Error(`Package ${packageNameWithoutVersion} not found in workspace ${flags.workspace}`);
59
62
  }
63
+ // Get the installed version from workspace
64
+ const installedVersion = packageInfo.version || '';
65
+ // If user specified a version, validate it matches the installed version
66
+ if (userSpecifiedVersion && userSpecifiedVersion !== installedVersion) {
67
+ throw new Error(`Package ${packageNameWithoutVersion} version mismatch: installed version is ${installedVersion || 'unspecified'}, but you specified ${userSpecifiedVersion}. ` +
68
+ `Please use 'hereya workspace uninstall ${packageNameWithoutVersion} -w ${flags.workspace}' to uninstall the installed version.`);
69
+ }
70
+ ctx.packageWithInstalledVersion = installedVersion ? `${packageNameWithoutVersion}@${installedVersion}` : packageNameWithoutVersion;
60
71
  ctx.workspace = loadWorkspaceOutput;
61
72
  await delay(500);
62
73
  },
@@ -73,8 +84,10 @@ export default class WorkspaceUninstall extends Command {
73
84
  }
74
85
  parametersFromFile = data;
75
86
  }
87
+ // Use the clean package name to get stored parameters
88
+ const packageNameWithoutVersion = args.package.split('@')[0];
76
89
  const parameters = {
77
- ...ctx.workspace.workspace.packages?.[args.package].parameters,
90
+ ...ctx.workspace.workspace.packages?.[packageNameWithoutVersion].parameters,
78
91
  ...parametersFromFile,
79
92
  ...parametersInCmdline,
80
93
  };
@@ -95,7 +108,7 @@ export default class WorkspaceUninstall extends Command {
95
108
  const { executor } = executor$;
96
109
  const destroyOutput = await executor.destroy({
97
110
  logger: getLogger(task),
98
- package: args.package,
111
+ package: ctx.packageWithInstalledVersion,
99
112
  parameters: ctx.parameters,
100
113
  workspace: flags.workspace,
101
114
  });
@@ -113,7 +126,7 @@ export default class WorkspaceUninstall extends Command {
113
126
  const output = await backend.removePackageFromWorkspace({
114
127
  env,
115
128
  infra: metadata.infra,
116
- package: args.package,
129
+ package: ctx.destroyOutput.pkgName,
117
130
  workspace: flags.workspace,
118
131
  });
119
132
  if (!output.success) {
@@ -21,7 +21,9 @@ export type ExecutorProvisionOutput = {
21
21
  [key: string]: string;
22
22
  };
23
23
  metadata: IPackageMetadata;
24
+ pkgName: string;
24
25
  success: true;
26
+ version?: string;
25
27
  } | {
26
28
  reason: string;
27
29
  success: false;
@@ -61,6 +63,7 @@ export type ExecutorUnsetEnvVarInput = {
61
63
  workspace: string;
62
64
  };
63
65
  export type ExecutorImportInput = {
66
+ logger?: Logger;
64
67
  package: string;
65
68
  project: string;
66
69
  projectRootDir?: string;
@@ -69,7 +72,9 @@ export type ExecutorImportInput = {
69
72
  };
70
73
  export type ExecutorImportOutput = {
71
74
  metadata: IPackageMetadata;
75
+ pkgName: string;
72
76
  success: true;
77
+ version?: string;
73
78
  } | {
74
79
  reason: string;
75
80
  success: false;
@@ -17,11 +17,11 @@ export class LocalExecutor {
17
17
  });
18
18
  }
19
19
  async import(input) {
20
- const resolvePackageOutput = await resolvePackage({ package: input.package, projectRootDir: input.projectRootDir });
20
+ const resolvePackageOutput = await resolvePackage({ logger: input.logger, package: input.package, projectRootDir: input.projectRootDir });
21
21
  if (!resolvePackageOutput.found) {
22
22
  return { reason: resolvePackageOutput.reason, success: false };
23
23
  }
24
- const { canonicalName, metadata, pkgName } = resolvePackageOutput;
24
+ const { canonicalName, metadata, pkgName, version } = resolvePackageOutput;
25
25
  const backend = await getBackend();
26
26
  const id$ = await backend.getProvisioningId({
27
27
  logicalId: getProvisioningLogicalId({ pkg: pkgName, project: input.project, workspace: input.workspace }),
@@ -46,7 +46,7 @@ export class LocalExecutor {
46
46
  if (!uploadStateFileOutput.success) {
47
47
  return { reason: uploadStateFileOutput.reason, success: false };
48
48
  }
49
- return { metadata, success: true };
49
+ return { metadata, pkgName, success: true, version };
50
50
  }
51
51
  async provision(input) {
52
52
  const getWorkspaceEnvOutput = await this.getWorkspaceEnv({
@@ -39,7 +39,9 @@ export type ProvisionPackageOutput = {
39
39
  [key: string]: string;
40
40
  };
41
41
  metadata: z.infer<typeof PackageMetadata>;
42
+ pkgName: string;
42
43
  success: true;
44
+ version?: string;
43
45
  } | {
44
46
  reason: string;
45
47
  success: false;
@@ -29,17 +29,17 @@ export function getInfrastructure(input) {
29
29
  }
30
30
  }
31
31
  export async function destroyPackage(input) {
32
- const resolvePackageOutput = await resolvePackage({ isDeploying: input.isDeploying, package: input.package, projectRootDir: input.projectRootDir });
32
+ const resolvePackageOutput = await resolvePackage({ isDeploying: input.isDeploying, logger: input.logger, package: input.package, projectRootDir: input.projectRootDir });
33
33
  if (!resolvePackageOutput.found) {
34
34
  return { reason: resolvePackageOutput.reason, success: false };
35
35
  }
36
- const { canonicalName, metadata, packageUri, pkgName } = resolvePackageOutput;
36
+ const { canonicalName, metadata, packageUri, pkgName, version } = resolvePackageOutput;
37
37
  const infrastructure$ = getInfrastructure({ type: metadata.infra });
38
38
  if (!infrastructure$.supported) {
39
39
  return { reason: infrastructure$.reason, success: false };
40
40
  }
41
41
  if (metadata.deploy && input.skipDeploy) {
42
- return { env: {}, metadata, success: true };
42
+ return { env: {}, metadata, pkgName, success: true, version: version || '' };
43
43
  }
44
44
  const { infrastructure } = infrastructure$;
45
45
  const backend = await getBackend();
@@ -92,20 +92,20 @@ export async function destroyPackage(input) {
92
92
  success: false,
93
93
  };
94
94
  }
95
- return { env: destroyOutput.env, metadata, success: true };
95
+ return { env: destroyOutput.env, metadata, pkgName, success: true, version: version || '' };
96
96
  }
97
97
  export async function provisionPackage(input) {
98
- const resolvePackageOutput = await resolvePackage({ isDeploying: input.isDeploying, package: input.package, projectRootDir: input.projectRootDir });
98
+ const resolvePackageOutput = await resolvePackage({ isDeploying: input.isDeploying, logger: input.logger, package: input.package, projectRootDir: input.projectRootDir });
99
99
  if (!resolvePackageOutput.found) {
100
100
  return { reason: resolvePackageOutput.reason, success: false };
101
101
  }
102
- const { canonicalName, metadata, packageUri, pkgName } = resolvePackageOutput;
102
+ const { canonicalName, metadata, packageUri, pkgName, version } = resolvePackageOutput;
103
103
  const infrastructure$ = getInfrastructure({ type: metadata.infra });
104
104
  if (!infrastructure$.supported) {
105
105
  return { reason: infrastructure$.reason, success: false };
106
106
  }
107
107
  if (metadata.deploy && input.skipDeploy) {
108
- return { env: {}, metadata, success: true };
108
+ return { env: {}, metadata, pkgName, success: true, version: version || '' };
109
109
  }
110
110
  const dependencies = metadata.dependencies ?? {};
111
111
  const depsOutput = await Promise.all(Object.entries(dependencies).map(async ([depName]) => provisionPackage({
@@ -167,7 +167,7 @@ export async function provisionPackage(input) {
167
167
  if (!provisionOutput.success) {
168
168
  return { reason: provisionOutput.reason, success: false };
169
169
  }
170
- return { env: provisionOutput.env, metadata, success: true };
170
+ return { env: provisionOutput.env, metadata, pkgName, success: true, version: version || '' };
171
171
  }
172
172
  export function getProvisioningLogicalId({ pkg, project, workspace }) {
173
173
  const projectName = project ? stripOrgPrefix(project) : project;
@@ -37,5 +37,6 @@ export type AddPackageInput = {
37
37
  metadata: IPackageMetadata;
38
38
  package: string;
39
39
  projectRootDir?: string;
40
+ version?: string;
40
41
  };
41
42
  export type RemovePackageInput = AddPackageInput;
@@ -11,7 +11,7 @@ export class SimpleConfigManager {
11
11
  deploy: {
12
12
  ...config.deploy,
13
13
  [input.package]: {
14
- version: '',
14
+ version: input.version || '',
15
15
  },
16
16
  },
17
17
  }
@@ -19,7 +19,7 @@ export class SimpleConfigManager {
19
19
  packages: {
20
20
  ...config.packages,
21
21
  [input.package]: {
22
- version: '',
22
+ version: input.version || '',
23
23
  ...(input.metadata.onDeploy
24
24
  ? {
25
25
  onDeploy: {
@@ -0,0 +1,19 @@
1
+ import type { Backend, RegistryPackage } from '../../backend/common.js';
2
+ import type { Logger } from '../log.js';
3
+ import type { GetRepoContentInput, GetRepoContentOutput, PackageManager } from './common.js';
4
+ export interface CloudPackageInfo {
5
+ name: string;
6
+ registryPackage: RegistryPackage;
7
+ version: string;
8
+ }
9
+ export declare class CloudPackageManager implements PackageManager {
10
+ private readonly backend;
11
+ private readonly logger?;
12
+ constructor(backend: Backend, logger?: Logger | undefined);
13
+ downloadAndValidatePackage(registryPackage: RegistryPackage, destPath: string): Promise<string>;
14
+ downloadPackage(pkgUrl: string, destPath: string): Promise<string>;
15
+ getFileFromRepository(repoUrl: string, commit: string | undefined, filePath: string, sha256?: string): Promise<GetRepoContentOutput>;
16
+ getRepoContent({ owner, path: filePath, repo, version }: GetRepoContentInput): Promise<GetRepoContentOutput>;
17
+ resolvePackage(packageSpec: string): Promise<CloudPackageInfo | null>;
18
+ private parsePackageSpec;
19
+ }