@jcoreio/aws-ecr-utils 1.2.0 → 1.3.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.
@@ -0,0 +1,58 @@
1
+ import z from 'zod';
2
+ export declare const ImageManifestSchema: z.ZodObject<{
3
+ schemaVersion: z.ZodLiteral<2>;
4
+ mediaType: z.ZodString;
5
+ config: z.ZodObject<{
6
+ mediaType: z.ZodString;
7
+ size: z.ZodNumber;
8
+ digest: z.ZodString;
9
+ }, "strip", z.ZodTypeAny, {
10
+ mediaType: string;
11
+ size: number;
12
+ digest: string;
13
+ }, {
14
+ mediaType: string;
15
+ size: number;
16
+ digest: string;
17
+ }>;
18
+ layers: z.ZodArray<z.ZodObject<{
19
+ mediaType: z.ZodString;
20
+ size: z.ZodNumber;
21
+ digest: z.ZodString;
22
+ }, "strip", z.ZodTypeAny, {
23
+ mediaType: string;
24
+ size: number;
25
+ digest: string;
26
+ }, {
27
+ mediaType: string;
28
+ size: number;
29
+ digest: string;
30
+ }>, "many">;
31
+ }, "strip", z.ZodTypeAny, {
32
+ mediaType: string;
33
+ schemaVersion: 2;
34
+ config: {
35
+ mediaType: string;
36
+ size: number;
37
+ digest: string;
38
+ };
39
+ layers: {
40
+ mediaType: string;
41
+ size: number;
42
+ digest: string;
43
+ }[];
44
+ }, {
45
+ mediaType: string;
46
+ schemaVersion: 2;
47
+ config: {
48
+ mediaType: string;
49
+ size: number;
50
+ digest: string;
51
+ };
52
+ layers: {
53
+ mediaType: string;
54
+ size: number;
55
+ digest: string;
56
+ }[];
57
+ }>;
58
+ export type ImageManifestSchema = z.infer<typeof ImageManifestSchema>;
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.ImageManifestSchema = void 0;
8
+ var _zod = _interopRequireDefault(require("zod"));
9
+ var MediaType = _zod["default"].string().min(1);
10
+ var Size = _zod["default"].number()["int"]().nonnegative();
11
+ var Digest = _zod["default"].string().min(32);
12
+ var LayerSchema = _zod["default"].object({
13
+ mediaType: MediaType,
14
+ size: Size,
15
+ digest: Digest
16
+ });
17
+ var ImageManifestSchema = exports.ImageManifestSchema = _zod["default"].object({
18
+ schemaVersion: _zod["default"].literal(2),
19
+ mediaType: _zod["default"].string(),
20
+ config: LayerSchema,
21
+ layers: _zod["default"].array(LayerSchema)
22
+ });
@@ -0,0 +1,15 @@
1
+ import z from 'zod';
2
+ const MediaType = z.string().min(1);
3
+ const Size = z.number().int().nonnegative();
4
+ const Digest = z.string().min(32);
5
+ const LayerSchema = z.object({
6
+ mediaType: MediaType,
7
+ size: Size,
8
+ digest: Digest
9
+ });
10
+ export const ImageManifestSchema = z.object({
11
+ schemaVersion: z.literal(2),
12
+ mediaType: z.string(),
13
+ config: LayerSchema,
14
+ layers: z.array(LayerSchema)
15
+ });
@@ -0,0 +1,18 @@
1
+ import AWS from 'aws-sdk';
2
+ export default function checkECRImageAccess({ ecr, awsConfig, repoAccountAwsConfig, imageUri, log, }: {
3
+ ecr?: AWS.ECR;
4
+ awsConfig?: AWS.ConfigurationOptions;
5
+ /**
6
+ * Config for the AWS account containing the ECR repository.
7
+ * Optional; if given, will prompt to add/update the policy on the
8
+ * ECR repository, if access checks failed and the terminal is
9
+ * interactive.
10
+ */
11
+ repoAccountAwsConfig?: AWS.ConfigurationOptions;
12
+ imageUri: string;
13
+ log?: {
14
+ info: (...args: any[]) => void;
15
+ warn: (...args: any[]) => void;
16
+ error: (...args: any[]) => void;
17
+ };
18
+ }): Promise<boolean>;
@@ -0,0 +1,180 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports["default"] = checkECRImageAccess;
8
+ var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
9
+ var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
10
+ var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
11
+ var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
12
+ var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
13
+ var _awsSdk = _interopRequireDefault(require("aws-sdk"));
14
+ var _parseECRImageUri2 = _interopRequireDefault(require("./parseECRImageUri.js"));
15
+ var _ImageManifestSchema = require("./ImageManifestSchema.js");
16
+ var _isInteractive = _interopRequireDefault(require("is-interactive"));
17
+ var _inquirer = _interopRequireDefault(require("inquirer"));
18
+ var _formatECRRepositoryHostname = _interopRequireDefault(require("./formatECRRepositoryHostname.js"));
19
+ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
20
+ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2["default"])(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
21
+ function checkECRImageAccess(_x) {
22
+ return _checkECRImageAccess.apply(this, arguments);
23
+ }
24
+ function _checkECRImageAccess() {
25
+ _checkECRImageAccess = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee(_ref) {
26
+ var ecr, awsConfig, repoAccountAwsConfig, imageUri, _ref$log, log, _parseECRImageUri, registryId, region, repositoryName, imageTag, _yield$ecr$batchGetIm, _yield$ecr$batchGetIm2, _yield$ecr$batchGetIm3, _yield$ecr$batchGetIm4, image, imageManifest, _ImageManifestSchema$, config, layers, Action, _yield$AWS$STS$getCal, Account, _yield$inquirer$promp, update, srcEcr, _yield$srcEcr$getRepo, policyText, policy;
27
+ return _regenerator["default"].wrap(function _callee$(_context) {
28
+ while (1) switch (_context.prev = _context.next) {
29
+ case 0:
30
+ ecr = _ref.ecr, awsConfig = _ref.awsConfig, repoAccountAwsConfig = _ref.repoAccountAwsConfig, imageUri = _ref.imageUri, _ref$log = _ref.log, log = _ref$log === void 0 ? console : _ref$log;
31
+ log.error('checking access to ECR image:', imageUri, '...');
32
+ _parseECRImageUri = (0, _parseECRImageUri2["default"])(imageUri), registryId = _parseECRImageUri.registryId, region = _parseECRImageUri.region, repositoryName = _parseECRImageUri.repositoryName, imageTag = _parseECRImageUri.imageTag;
33
+ if (!ecr) ecr = new _awsSdk["default"].ECR(_objectSpread(_objectSpread({}, awsConfig), {}, {
34
+ region: region
35
+ }));
36
+ _context.prev = 4;
37
+ _context.next = 7;
38
+ return ecr.batchGetImage({
39
+ registryId: registryId,
40
+ repositoryName: repositoryName,
41
+ imageIds: [{
42
+ imageTag: imageTag
43
+ }]
44
+ }).promise();
45
+ case 7:
46
+ _yield$ecr$batchGetIm = _context.sent;
47
+ _yield$ecr$batchGetIm2 = _yield$ecr$batchGetIm.images;
48
+ _yield$ecr$batchGetIm3 = _yield$ecr$batchGetIm2 === void 0 ? [] : _yield$ecr$batchGetIm2;
49
+ _yield$ecr$batchGetIm4 = (0, _slicedToArray2["default"])(_yield$ecr$batchGetIm3, 1);
50
+ image = _yield$ecr$batchGetIm4[0];
51
+ imageManifest = image === null || image === void 0 ? void 0 : image.imageManifest;
52
+ if (imageManifest) {
53
+ _context.next = 15;
54
+ break;
55
+ }
56
+ throw new Error("imageManifest not found for: ".concat(imageUri));
57
+ case 15:
58
+ _ImageManifestSchema$ = _ImageManifestSchema.ImageManifestSchema.parse(JSON.parse(imageManifest)), config = _ImageManifestSchema$.config, layers = _ImageManifestSchema$.layers;
59
+ _context.next = 18;
60
+ return ecr.batchCheckLayerAvailability({
61
+ registryId: registryId,
62
+ repositoryName: repositoryName,
63
+ layerDigests: [config.digest].concat((0, _toConsumableArray2["default"])(layers.map(function (l) {
64
+ return l.digest;
65
+ })))
66
+ }).promise();
67
+ case 18:
68
+ _context.next = 20;
69
+ return ecr.getDownloadUrlForLayer({
70
+ registryId: registryId,
71
+ repositoryName: repositoryName,
72
+ layerDigest: layers[0].digest
73
+ }).promise();
74
+ case 20:
75
+ log.error("ECR image is accessible: ".concat(imageUri));
76
+ return _context.abrupt("return", true);
77
+ case 24:
78
+ _context.prev = 24;
79
+ _context.t0 = _context["catch"](4);
80
+ if (!(!(_context.t0 instanceof Error) || _context.t0.name !== 'AccessDeniedException')) {
81
+ _context.next = 28;
82
+ break;
83
+ }
84
+ throw _context.t0;
85
+ case 28:
86
+ log.error("Unable to access ECR image: ".concat(imageUri));
87
+ Action = ['ecr:GetDownloadUrlForLayer', 'ecr:BatchCheckLayerAvailability', 'ecr:BatchGetImage'];
88
+ log.error("You may need to add a policy to the ECR repository to allow this account.\n\nThe policy should include:\n\n ".concat(JSON.stringify({
89
+ Version: '2012-10-17',
90
+ Statement: [{
91
+ Effect: 'Allow',
92
+ Principal: {
93
+ AWS: ['XXXXXXXXXXXX']
94
+ },
95
+ Action: Action
96
+ }]
97
+ }, null, 2).replace(/\n/gm, '\n '), "\n"));
98
+ if (!(repoAccountAwsConfig && (0, _isInteractive["default"])())) {
99
+ _context.next = 55;
100
+ break;
101
+ }
102
+ _context.next = 34;
103
+ return new _awsSdk["default"].STS({
104
+ credentials: ecr.config.credentials,
105
+ region: region
106
+ }).getCallerIdentity().promise();
107
+ case 34:
108
+ _yield$AWS$STS$getCal = _context.sent;
109
+ Account = _yield$AWS$STS$getCal.Account;
110
+ if (Account) {
111
+ _context.next = 39;
112
+ break;
113
+ }
114
+ log.error("failed to determine AWS account");
115
+ return _context.abrupt("return", false);
116
+ case 39:
117
+ _context.next = 41;
118
+ return _inquirer["default"].prompt([{
119
+ name: 'update',
120
+ message: 'Do you want to add/update the policy?',
121
+ type: 'confirm',
122
+ "default": false
123
+ }]);
124
+ case 41:
125
+ _yield$inquirer$promp = _context.sent;
126
+ update = _yield$inquirer$promp.update;
127
+ if (update) {
128
+ _context.next = 45;
129
+ break;
130
+ }
131
+ return _context.abrupt("return", false);
132
+ case 45:
133
+ srcEcr = new _awsSdk["default"].ECR(_objectSpread(_objectSpread({}, repoAccountAwsConfig), {}, {
134
+ region: region
135
+ }));
136
+ _context.next = 48;
137
+ return srcEcr.getRepositoryPolicy({
138
+ registryId: registryId,
139
+ repositoryName: repositoryName
140
+ }).promise()["catch"](function (error) {
141
+ if (error.name === 'RepositoryPolicyNotFoundException') return {};
142
+ throw error;
143
+ });
144
+ case 48:
145
+ _yield$srcEcr$getRepo = _context.sent;
146
+ policyText = _yield$srcEcr$getRepo.policyText;
147
+ policy = JSON.parse(policyText || '{}');
148
+ _context.next = 53;
149
+ return srcEcr.setRepositoryPolicy({
150
+ repositoryName: repositoryName,
151
+ policyText: JSON.stringify(_objectSpread(_objectSpread({
152
+ Version: '2012-10-17'
153
+ }, policy), {}, {
154
+ Statement: [].concat((0, _toConsumableArray2["default"])(policy.Statement || []), [{
155
+ Effect: 'Allow',
156
+ Principal: {
157
+ AWS: [Account]
158
+ },
159
+ Action: Action
160
+ }])
161
+ }), null, 2)
162
+ }).promise();
163
+ case 53:
164
+ log.info("updated policy on ECR repository ".concat((0, _formatECRRepositoryHostname["default"])({
165
+ registryId: registryId,
166
+ region: region,
167
+ repositoryName: repositoryName
168
+ })));
169
+ return _context.abrupt("return", true);
170
+ case 55:
171
+ return _context.abrupt("return", false);
172
+ case 56:
173
+ case "end":
174
+ return _context.stop();
175
+ }
176
+ }, _callee, null, [[4, 24]]);
177
+ }));
178
+ return _checkECRImageAccess.apply(this, arguments);
179
+ }
180
+ module.exports = exports.default;
@@ -0,0 +1,133 @@
1
+ import AWS from 'aws-sdk';
2
+ import parseECRImageUri from "./parseECRImageUri.mjs";
3
+ import { ImageManifestSchema } from "./ImageManifestSchema.mjs";
4
+ import isInteractive from 'is-interactive';
5
+ import inquirer from 'inquirer';
6
+ import formatECRRepositoryHostname from "./formatECRRepositoryHostname.mjs";
7
+ export default async function checkECRImageAccess({
8
+ ecr,
9
+ awsConfig,
10
+ repoAccountAwsConfig,
11
+ imageUri,
12
+ log = console
13
+ }) {
14
+ log.error('checking access to ECR image:', imageUri, '...');
15
+ const {
16
+ registryId,
17
+ region,
18
+ repositoryName,
19
+ imageTag
20
+ } = parseECRImageUri(imageUri);
21
+ if (!ecr) ecr = new AWS.ECR({
22
+ ...awsConfig,
23
+ region
24
+ });
25
+ try {
26
+ const {
27
+ images: [image] = []
28
+ } = await ecr.batchGetImage({
29
+ registryId,
30
+ repositoryName,
31
+ imageIds: [{
32
+ imageTag
33
+ }]
34
+ }).promise();
35
+ const imageManifest = image === null || image === void 0 ? void 0 : image.imageManifest;
36
+ if (!imageManifest) {
37
+ throw new Error(`imageManifest not found for: ${imageUri}`);
38
+ }
39
+ const {
40
+ config,
41
+ layers
42
+ } = ImageManifestSchema.parse(JSON.parse(imageManifest));
43
+ await ecr.batchCheckLayerAvailability({
44
+ registryId,
45
+ repositoryName,
46
+ layerDigests: [config.digest, ...layers.map(l => l.digest)]
47
+ }).promise();
48
+ await ecr.getDownloadUrlForLayer({
49
+ registryId,
50
+ repositoryName,
51
+ layerDigest: layers[0].digest
52
+ }).promise();
53
+ log.error(`ECR image is accessible: ${imageUri}`);
54
+ return true;
55
+ } catch (error) {
56
+ if (!(error instanceof Error) || error.name !== 'AccessDeniedException') {
57
+ throw error;
58
+ }
59
+ }
60
+ log.error(`Unable to access ECR image: ${imageUri}`);
61
+ const Action = ['ecr:GetDownloadUrlForLayer', 'ecr:BatchCheckLayerAvailability', 'ecr:BatchGetImage'];
62
+ log.error(`You may need to add a policy to the ECR repository to allow this account.
63
+
64
+ The policy should include:
65
+
66
+ ${JSON.stringify({
67
+ Version: '2012-10-17',
68
+ Statement: [{
69
+ Effect: 'Allow',
70
+ Principal: {
71
+ AWS: ['XXXXXXXXXXXX']
72
+ },
73
+ Action
74
+ }]
75
+ }, null, 2).replace(/\n/gm, '\n ')}
76
+ `);
77
+ if (repoAccountAwsConfig && isInteractive()) {
78
+ const {
79
+ Account
80
+ } = await new AWS.STS({
81
+ credentials: ecr.config.credentials,
82
+ region
83
+ }).getCallerIdentity().promise();
84
+ if (!Account) {
85
+ log.error(`failed to determine AWS account`);
86
+ return false;
87
+ }
88
+ const {
89
+ update
90
+ } = await inquirer.prompt([{
91
+ name: 'update',
92
+ message: 'Do you want to add/update the policy?',
93
+ type: 'confirm',
94
+ default: false
95
+ }]);
96
+ if (!update) return false;
97
+ const srcEcr = new AWS.ECR({
98
+ ...repoAccountAwsConfig,
99
+ region
100
+ });
101
+ const {
102
+ policyText
103
+ } = await srcEcr.getRepositoryPolicy({
104
+ registryId,
105
+ repositoryName
106
+ }).promise().catch(error => {
107
+ if (error.name === 'RepositoryPolicyNotFoundException') return {};
108
+ throw error;
109
+ });
110
+ const policy = JSON.parse(policyText || '{}');
111
+ await srcEcr.setRepositoryPolicy({
112
+ repositoryName,
113
+ policyText: JSON.stringify({
114
+ Version: '2012-10-17',
115
+ ...policy,
116
+ Statement: [...(policy.Statement || []), {
117
+ Effect: 'Allow',
118
+ Principal: {
119
+ AWS: [Account]
120
+ },
121
+ Action
122
+ }]
123
+ }, null, 2)
124
+ }).promise();
125
+ log.info(`updated policy on ECR repository ${formatECRRepositoryHostname({
126
+ registryId,
127
+ region,
128
+ repositoryName
129
+ })}`);
130
+ return true;
131
+ }
132
+ return false;
133
+ }
@@ -0,0 +1,6 @@
1
+ export default function formatECRImageUri({ registryId, region, repositoryName, imageTag, }: {
2
+ registryId: AWS.ECR.RegistryId;
3
+ region: string;
4
+ repositoryName: AWS.ECR.RepositoryName;
5
+ imageTag: AWS.ECR.ImageTag;
6
+ }): string;
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports["default"] = formatECRImageUri;
8
+ var _formatECRRepositoryHostname = _interopRequireDefault(require("./formatECRRepositoryHostname.js"));
9
+ function formatECRImageUri(_ref) {
10
+ var registryId = _ref.registryId,
11
+ region = _ref.region,
12
+ repositoryName = _ref.repositoryName,
13
+ imageTag = _ref.imageTag;
14
+ return "".concat((0, _formatECRRepositoryHostname["default"])({
15
+ registryId: registryId,
16
+ region: region,
17
+ repositoryName: repositoryName
18
+ }), ":").concat(imageTag);
19
+ }
20
+ module.exports = exports.default;
@@ -0,0 +1,13 @@
1
+ import formatECRRepositoryHostname from "./formatECRRepositoryHostname.mjs";
2
+ export default function formatECRImageUri({
3
+ registryId,
4
+ region,
5
+ repositoryName,
6
+ imageTag
7
+ }) {
8
+ return `${formatECRRepositoryHostname({
9
+ registryId,
10
+ region,
11
+ repositoryName
12
+ })}:${imageTag}`;
13
+ }
@@ -0,0 +1,5 @@
1
+ export default function formatECRRepositoryHostname({ registryId, region, repositoryName, }: {
2
+ registryId: AWS.ECR.RegistryId;
3
+ region: string;
4
+ repositoryName: AWS.ECR.RepositoryName;
5
+ }): string;
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports["default"] = formatECRRepositoryHostname;
7
+ function formatECRRepositoryHostname(_ref) {
8
+ var registryId = _ref.registryId,
9
+ region = _ref.region,
10
+ repositoryName = _ref.repositoryName;
11
+ return "".concat(registryId, ".dkr.ecr.").concat(region, ".amazonaws.com/").concat(repositoryName);
12
+ }
13
+ module.exports = exports.default;
@@ -0,0 +1,7 @@
1
+ export default function formatECRRepositoryHostname({
2
+ registryId,
3
+ region,
4
+ repositoryName
5
+ }) {
6
+ return `${registryId}.dkr.ecr.${region}.amazonaws.com/${repositoryName}`;
7
+ }
package/index.d.ts CHANGED
@@ -6,3 +6,6 @@ export { default as parseECRImageUri } from './parseECRImageUri';
6
6
  export { default as parseECRRepositoryHostname } from './parseECRRepositoryHostname';
7
7
  export { default as upsertECRRepository } from './upsertECRRepository';
8
8
  export { default as checkECRRepositoryPolicy } from './checkECRRepositoryPolicy';
9
+ export { default as checkECRImageAccess } from './checkECRImageAccess';
10
+ export { default as formatECRRepositoryHostname } from './formatECRRepositoryHostname';
11
+ export { default as formatECRImageUri } from './formatECRImageUri';
package/index.js CHANGED
@@ -4,6 +4,12 @@ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefau
4
4
  Object.defineProperty(exports, "__esModule", {
5
5
  value: true
6
6
  });
7
+ Object.defineProperty(exports, "checkECRImageAccess", {
8
+ enumerable: true,
9
+ get: function get() {
10
+ return _checkECRImageAccess["default"];
11
+ }
12
+ });
7
13
  Object.defineProperty(exports, "checkECRRepositoryPolicy", {
8
14
  enumerable: true,
9
15
  get: function get() {
@@ -22,6 +28,18 @@ Object.defineProperty(exports, "ecrImageExists", {
22
28
  return _ecrImageExists["default"];
23
29
  }
24
30
  });
31
+ Object.defineProperty(exports, "formatECRImageUri", {
32
+ enumerable: true,
33
+ get: function get() {
34
+ return _formatECRImageUri["default"];
35
+ }
36
+ });
37
+ Object.defineProperty(exports, "formatECRRepositoryHostname", {
38
+ enumerable: true,
39
+ get: function get() {
40
+ return _formatECRRepositoryHostname["default"];
41
+ }
42
+ });
25
43
  Object.defineProperty(exports, "loginToECR", {
26
44
  enumerable: true,
27
45
  get: function get() {
@@ -59,4 +77,7 @@ var _tagECRImage = _interopRequireDefault(require("./tagECRImage.js"));
59
77
  var _parseECRImageUri = _interopRequireDefault(require("./parseECRImageUri.js"));
60
78
  var _parseECRRepositoryHostname = _interopRequireDefault(require("./parseECRRepositoryHostname.js"));
61
79
  var _upsertECRRepository = _interopRequireDefault(require("./upsertECRRepository.js"));
62
- var _checkECRRepositoryPolicy = _interopRequireDefault(require("./checkECRRepositoryPolicy.js"));
80
+ var _checkECRRepositoryPolicy = _interopRequireDefault(require("./checkECRRepositoryPolicy.js"));
81
+ var _checkECRImageAccess = _interopRequireDefault(require("./checkECRImageAccess.js"));
82
+ var _formatECRRepositoryHostname = _interopRequireDefault(require("./formatECRRepositoryHostname.js"));
83
+ var _formatECRImageUri = _interopRequireDefault(require("./formatECRImageUri.js"));
package/index.mjs CHANGED
@@ -5,4 +5,7 @@ export { default as tagECRImage } from "./tagECRImage.mjs";
5
5
  export { default as parseECRImageUri } from "./parseECRImageUri.mjs";
6
6
  export { default as parseECRRepositoryHostname } from "./parseECRRepositoryHostname.mjs";
7
7
  export { default as upsertECRRepository } from "./upsertECRRepository.mjs";
8
- export { default as checkECRRepositoryPolicy } from "./checkECRRepositoryPolicy.mjs";
8
+ export { default as checkECRRepositoryPolicy } from "./checkECRRepositoryPolicy.mjs";
9
+ export { default as checkECRImageAccess } from "./checkECRImageAccess.mjs";
10
+ export { default as formatECRRepositoryHostname } from "./formatECRRepositoryHostname.mjs";
11
+ export { default as formatECRImageUri } from "./formatECRImageUri.mjs";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jcoreio/aws-ecr-utils",
3
- "version": "1.2.0",
3
+ "version": "1.3.0",
4
4
  "description": "utilities for working with AWS Elastic Container Registry",
5
5
  "sideEffects": false,
6
6
  "repository": {
@@ -24,7 +24,8 @@
24
24
  "base64-js": "^1.5.1",
25
25
  "inquirer": "^8.2.6",
26
26
  "is-interactive": "^1.0.0",
27
- "promisify-child-process": "^4.1.1"
27
+ "promisify-child-process": "^4.1.1",
28
+ "zod": "^3.22.4"
28
29
  },
29
30
  "main": "index.js",
30
31
  "module": "index.mjs",