@spinnaker/docker 2026.2.3 → 2026.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.
@@ -1,2 +1,31 @@
1
- export const DOCKER_PIPELINE_STAGES_BAKE_DOCKERBAKESTAGE: "spinnaker.docker.pipeline.stage.bakeStage";
2
- export const name: "spinnaker.docker.pipeline.stage.bakeStage";
1
+ import React from 'react';
2
+ import type { IExecutionDetailsSectionProps, IStage, IStageConfigProps } from '@spinnaker/core';
3
+ interface IBaseOsOption {
4
+ id: string;
5
+ shortDescription?: string;
6
+ detailedDescription?: string;
7
+ isImageFamily?: boolean;
8
+ displayName?: string;
9
+ }
10
+ interface IDockerBakeStageDefaults {
11
+ user: string;
12
+ baseOsOptions: IBaseOsOption[];
13
+ baseLabelOptions: string[];
14
+ }
15
+ interface IDockerBakeStageConfigState {
16
+ baseLabelOptions: string[];
17
+ baseOsOptions: IBaseOsOption[];
18
+ loadError: boolean;
19
+ loading: boolean;
20
+ }
21
+ export declare function applyDockerBakeStageDefaults(stage: IStage, defaults: IDockerBakeStageDefaults): IStage;
22
+ export declare class DockerBakeStageConfig extends React.Component<IStageConfigProps, IDockerBakeStageConfigState> {
23
+ private mounted;
24
+ state: IDockerBakeStageConfigState;
25
+ componentDidMount(): void;
26
+ componentWillUnmount(): void;
27
+ render(): JSX.Element;
28
+ }
29
+ export declare function DockerBakeExecutionDetails(props: IExecutionDetailsSectionProps): JSX.Element;
30
+ export declare const DOCKER_BAKE_STAGE_CONFIG: any;
31
+ export {};
@@ -11,7 +11,8 @@ export interface IDockerTriggerTemplateState {
11
11
  export declare class DockerTriggerTemplate extends React.Component<ITriggerTemplateComponentProps, IDockerTriggerTemplateState> {
12
12
  private queryStream;
13
13
  private subscription;
14
- static formatLabel(trigger: IDockerTrigger): PromiseLike<string>;
14
+ private tagRequest;
15
+ static formatLabel(trigger: IDockerTrigger): Promise<string>;
15
16
  constructor(props: ITriggerTemplateComponentProps);
16
17
  private handleQuery;
17
18
  private lookupTypeChanged;
package/package.json CHANGED
@@ -5,7 +5,7 @@
5
5
  "url": "https://github.com/spinnaker/spinnaker.git"
6
6
  },
7
7
  "license": "Apache-2.0",
8
- "version": "2026.2.3",
8
+ "version": "2026.3.0",
9
9
  "module": "dist/index.js",
10
10
  "typings": "dist/index.d.ts",
11
11
  "publishConfig": {
@@ -22,12 +22,9 @@
22
22
  },
23
23
  "dependencies": {
24
24
  "@spinnaker/core": "^0.29.1",
25
- "@uirouter/angularjs": "1.0.26",
26
- "angular": "1.8.3",
27
25
  "date-fns": "2.21.1",
28
26
  "formik": "1.5.1",
29
27
  "lodash": "4.18.1",
30
- "ngimport": "0.6.1",
31
28
  "react": "16.14.0",
32
29
  "react-select": "1.2.1",
33
30
  "rxjs": "6.6.7"
@@ -35,12 +32,11 @@
35
32
  "devDependencies": {
36
33
  "@spinnaker/eslint-plugin": "^3.0.2",
37
34
  "@spinnaker/scripts": "^0.4.0",
38
- "@types/angular": "1.6.26",
39
35
  "@types/lodash": "4.14.64",
40
36
  "@types/react": "16.14.10",
41
37
  "@types/react-select": "1.3.4",
42
38
  "shx": "0.3.3",
43
39
  "typescript": "5.0.4"
44
40
  },
45
- "gitHead": "a4e60ac0d767ffea0a41057a8bd9b0df110dfaa4"
41
+ "gitHead": "0f7d75f5d4b42c1675e2ecc69a53f8eb73090eb9"
46
42
  }
@@ -1,7 +1,2 @@
1
- import { module } from 'angular';
2
-
3
- import { DOCKER_PIPELINE_STAGES_BAKE_DOCKERBAKESTAGE } from './pipeline/stages/bake/dockerBakeStage';
1
+ import './pipeline/stages/bake/dockerBakeStage';
4
2
  import './pipeline/trigger/DockerTrigger';
5
-
6
- export const DOCKER_MODULE = 'spinnaker.docker';
7
- module(DOCKER_MODULE, [DOCKER_PIPELINE_STAGES_BAKE_DOCKERBAKESTAGE]);
@@ -71,6 +71,7 @@ export class DockerChartAndTagSelector extends React.Component<
71
71
  };
72
72
 
73
73
  private unmounted = false;
74
+ private imageRequest: AbortController;
74
75
  private images: IDockerImage[];
75
76
  private accounts: string[];
76
77
 
@@ -109,7 +110,7 @@ export class DockerChartAndTagSelector extends React.Component<
109
110
 
110
111
  private getAccountMap(images: IDockerImage[]): { [key: string]: string[] } {
111
112
  const groupedImages = groupBy(
112
- images.filter((image) => image.account),
113
+ images.filter((image) => image.account && image.repository),
113
114
  'account',
114
115
  );
115
116
  return reduce<IDockerImage[], { [key: string]: string[] }>(
@@ -192,11 +193,12 @@ export class DockerChartAndTagSelector extends React.Component<
192
193
  }
193
194
 
194
195
  public componentWillReceiveProps(nextProps: IDockerChartAndTagSelectorProps) {
196
+ const requestAccount = this.props.showRegistry ? this.props.account : this.props.registry;
197
+ const nextRequestAccount = nextProps.showRegistry ? nextProps.account : nextProps.registry;
195
198
  if (
196
- !this.images ||
197
- ['account', 'showRegistry'].some(
198
- (key: keyof IDockerChartAndTagSelectorProps) => this.props[key] !== nextProps[key],
199
- )
199
+ (!this.images && !this.imageRequest) ||
200
+ this.props.showRegistry !== nextProps.showRegistry ||
201
+ requestAccount !== nextRequestAccount
200
202
  ) {
201
203
  this.refreshImages(nextProps);
202
204
  } else if (
@@ -214,6 +216,7 @@ export class DockerChartAndTagSelector extends React.Component<
214
216
 
215
217
  componentWillUnmount() {
216
218
  this.unmounted = true;
219
+ this.imageRequest?.abort();
217
220
  }
218
221
 
219
222
  private synchronizeChanges(values: IDockerImageParts, registry: string) {
@@ -315,10 +318,14 @@ export class DockerChartAndTagSelector extends React.Component<
315
318
  }
316
319
 
317
320
  private initializeImages(props: IDockerChartAndTagSelectorProps) {
318
- if (this.state.imagesLoading) {
321
+ if (this.unmounted) {
319
322
  return;
320
323
  }
321
324
 
325
+ this.imageRequest?.abort();
326
+ const imageRequest = new AbortController();
327
+ this.imageRequest = imageRequest;
328
+
322
329
  const { showRegistry, account, registry } = props;
323
330
 
324
331
  const imageConfig: IFindImageParams = {
@@ -327,8 +334,11 @@ export class DockerChartAndTagSelector extends React.Component<
327
334
  };
328
335
 
329
336
  this.setState({ imagesLoading: true });
330
- DockerChartImageReader.findImages(imageConfig)
337
+ DockerChartImageReader.findImages(imageConfig, imageRequest.signal)
331
338
  .then((images: IDockerImage[]) => {
339
+ if (imageRequest.signal.aborted || this.unmounted) {
340
+ return;
341
+ }
332
342
  this.images = images;
333
343
  this.registryMap = this.getRegistryMap(this.images);
334
344
  this.accountMap = this.getAccountMap(this.images);
@@ -337,10 +347,11 @@ export class DockerChartAndTagSelector extends React.Component<
337
347
  this.organizationMap = this.getOrganizationMap(this.images);
338
348
  this.repositoryMap = this.getRepositoryMap(this.images);
339
349
  this.organizations = this.getOrganizationsList(this.accountMap);
340
- this.updateThings(props, true);
350
+ this.updateThings(this.props, true);
341
351
  })
342
352
  .finally(() => {
343
- if (!this.unmounted) {
353
+ if (!this.unmounted && this.imageRequest === imageRequest) {
354
+ this.imageRequest = null;
344
355
  this.setState({ imagesLoading: false });
345
356
  }
346
357
  });
@@ -354,9 +365,10 @@ export class DockerChartAndTagSelector extends React.Component<
354
365
  this.initializeImages(props);
355
366
  }
356
367
 
357
- private initializeAccounts(props: IDockerChartAndTagSelectorProps) {
358
- let { account } = props;
368
+ private initializeAccounts() {
359
369
  AccountService.listAccounts('dockerRegistry').then((allAccounts: IAccount[]) => {
370
+ const props = this.props;
371
+ let { account } = props;
360
372
  const accounts = allAccounts.map((a: IAccount) => a.name);
361
373
  if (this.props.showRegistry && !account) {
362
374
  account = accounts[0];
@@ -373,7 +385,7 @@ export class DockerChartAndTagSelector extends React.Component<
373
385
 
374
386
  public componentDidMount() {
375
387
  if (!this.props.deferInitialization && (this.props.registry || this.isNew())) {
376
- this.initializeAccounts(this.props);
388
+ this.initializeAccounts();
377
389
  }
378
390
  }
379
391
 
@@ -0,0 +1,159 @@
1
+ import { DockerChartAndTagSelector } from './DockerChartAndTagSelector';
2
+ import { DockerImageAndTagSelector } from './DockerImageAndTagSelector';
3
+ import { DockerChartImageReader, DockerImageReader } from './DockerImageReader';
4
+ import { AccountService } from '@spinnaker/core';
5
+
6
+ interface IDeferred<T> {
7
+ promise: Promise<T>;
8
+ resolve: (value: T) => void;
9
+ }
10
+
11
+ function deferred<T>(): IDeferred<T> {
12
+ let resolve: (value: T) => void;
13
+ const promise = new Promise<T>((promiseResolve) => (resolve = promiseResolve));
14
+ return { promise, resolve };
15
+ }
16
+
17
+ describe('Docker image selectors', () => {
18
+ const props = {
19
+ specifyTagByRegex: false,
20
+ imageId: '',
21
+ organization: '',
22
+ registry: '',
23
+ repository: '',
24
+ tag: '',
25
+ digest: '',
26
+ account: '',
27
+ onChange: () => undefined,
28
+ };
29
+
30
+ it('ignores image records without repositories when grouping account organizations', () => {
31
+ const images = [
32
+ { account: 'test', registry: 'registry.example', repository: undefined },
33
+ { account: 'test', registry: 'registry.example', repository: 'spinnaker/deck', tag: 'latest' },
34
+ ];
35
+
36
+ expect((new DockerImageAndTagSelector(props) as any).getAccountMap(images)).toEqual({ test: ['spinnaker'] });
37
+ expect((new DockerChartAndTagSelector(props) as any).getAccountMap(images)).toEqual({ test: ['spinnaker'] });
38
+ });
39
+
40
+ it('ignores non-Docker image records when no repositories are present', () => {
41
+ const images = [
42
+ { account: 'gce', imageName: 'ubuntu-1804-bionic-v20181003' },
43
+ { account: 'compute-engine', imageName: 'ubuntu-1804-bionic-v20181003' },
44
+ ];
45
+
46
+ expect((new DockerImageAndTagSelector(props) as any).getAccountMap(images)).toEqual({});
47
+ expect((new DockerChartAndTagSelector(props) as any).getAccountMap(images)).toEqual({});
48
+ });
49
+
50
+ [
51
+ { name: 'image', Selector: DockerImageAndTagSelector, Reader: DockerImageReader },
52
+ { name: 'chart', Selector: DockerChartAndTagSelector, Reader: DockerChartImageReader },
53
+ ].forEach(({ name, Selector, Reader }) => {
54
+ it(`aborts replaced and unmounted ${name} loads without applying late state`, async () => {
55
+ const firstRequest = deferred<any[]>();
56
+ const secondRequest = deferred<any[]>();
57
+ const findImages = spyOn(Reader, 'findImages').and.returnValues(firstRequest.promise, secondRequest.promise);
58
+ const component = new Selector(props);
59
+ const setState = spyOn(component, 'setState');
60
+
61
+ component.refreshImages(props);
62
+ component.refreshImages({ ...props, account: 'replacement' });
63
+ const firstSignal = findImages.calls.argsFor(0)[1] as AbortSignal;
64
+ const secondSignal = findImages.calls.argsFor(1)[1] as AbortSignal;
65
+
66
+ expect(firstSignal.aborted).toBe(true);
67
+ expect(secondSignal.aborted).toBe(false);
68
+ component.componentWillUnmount();
69
+ expect(secondSignal.aborted).toBe(true);
70
+
71
+ firstRequest.resolve([]);
72
+ secondRequest.resolve([]);
73
+ await Promise.all([firstRequest.promise, secondRequest.promise]);
74
+ await Promise.resolve();
75
+
76
+ expect(setState.calls.allArgs()).toEqual([[{ imagesLoading: true }], [{ imagesLoading: true }]]);
77
+ });
78
+
79
+ it(`preserves a pending ${name} load across unrelated prop updates`, async () => {
80
+ const request = deferred<any[]>();
81
+ const findImages = spyOn(Reader, 'findImages').and.returnValue(request.promise);
82
+ const component = new Selector(props);
83
+ spyOn(component, 'setState');
84
+ const updateThings = spyOn(component as any, 'updateThings').and.callThrough();
85
+ const replacementProps = { ...props, repository: 'replacement' };
86
+
87
+ component.refreshImages(props);
88
+ component.componentWillReceiveProps(replacementProps);
89
+ (component as any).props = replacementProps;
90
+ const signal = findImages.calls.argsFor(0)[1] as AbortSignal;
91
+
92
+ expect(findImages).toHaveBeenCalledTimes(1);
93
+ expect(signal.aborted).toBe(false);
94
+
95
+ updateThings.calls.reset();
96
+ request.resolve([]);
97
+ await request.promise;
98
+ await Promise.resolve();
99
+
100
+ expect(updateThings).toHaveBeenCalledOnceWith(replacementProps, true);
101
+ component.componentWillUnmount();
102
+ });
103
+
104
+ it(`replaces a pending ${name} load when its effective registry account changes`, async () => {
105
+ const firstRequest = deferred<any[]>();
106
+ const secondRequest = deferred<any[]>();
107
+ const findImages = spyOn(Reader, 'findImages').and.returnValues(firstRequest.promise, secondRequest.promise);
108
+ const initialProps = { ...props, registry: 'initial', showRegistry: false };
109
+ const replacementProps = { ...initialProps, registry: 'replacement' };
110
+ const component = new Selector(initialProps);
111
+ spyOn(component, 'setState');
112
+
113
+ component.refreshImages(initialProps);
114
+ component.componentWillReceiveProps(replacementProps);
115
+ (component as any).props = replacementProps;
116
+ const firstSignal = findImages.calls.argsFor(0)[1] as AbortSignal;
117
+ const secondSignal = findImages.calls.argsFor(1)[1] as AbortSignal;
118
+
119
+ expect(findImages.calls.argsFor(1)[0].account).toBe('replacement');
120
+ expect(firstSignal.aborted).toBe(true);
121
+ expect(secondSignal.aborted).toBe(false);
122
+
123
+ component.componentWillUnmount();
124
+ firstRequest.resolve([]);
125
+ secondRequest.resolve([]);
126
+ await Promise.all([firstRequest.promise, secondRequest.promise]);
127
+ });
128
+
129
+ it(`uses current props when delayed account initialization refreshes ${name} loads`, async () => {
130
+ const accountsRequest = deferred<any[]>();
131
+ const firstImageRequest = deferred<any[]>();
132
+ const secondImageRequest = deferred<any[]>();
133
+ spyOn(AccountService, 'listAccounts').and.returnValue(accountsRequest.promise);
134
+ const findImages = spyOn(Reader, 'findImages').and.returnValues(
135
+ firstImageRequest.promise,
136
+ secondImageRequest.promise,
137
+ );
138
+ const initialProps = { ...props, account: 'initial', showRegistry: true };
139
+ const replacementProps = { ...initialProps, account: 'replacement' };
140
+ const component = new Selector(initialProps);
141
+ spyOn(component, 'setState');
142
+
143
+ (component as any).initializeAccounts(initialProps);
144
+ (component as any).props = replacementProps;
145
+ component.refreshImages(replacementProps);
146
+ accountsRequest.resolve([{ name: 'default' }]);
147
+ await accountsRequest.promise;
148
+ await Promise.resolve();
149
+
150
+ expect(findImages.calls.argsFor(0)[0].account).toBe('replacement');
151
+ expect(findImages.calls.argsFor(1)[0].account).toBe('replacement');
152
+
153
+ component.componentWillUnmount();
154
+ firstImageRequest.resolve([]);
155
+ secondImageRequest.resolve([]);
156
+ await Promise.all([firstImageRequest.promise, secondImageRequest.promise]);
157
+ });
158
+ });
159
+ });
@@ -71,6 +71,7 @@ export class DockerImageAndTagSelector extends React.Component<
71
71
  };
72
72
 
73
73
  private unmounted = false;
74
+ private imageRequest: AbortController;
74
75
  private images: IDockerImage[];
75
76
  private accounts: string[];
76
77
 
@@ -109,7 +110,7 @@ export class DockerImageAndTagSelector extends React.Component<
109
110
 
110
111
  private getAccountMap(images: IDockerImage[]): { [key: string]: string[] } {
111
112
  const groupedImages = groupBy(
112
- images.filter((image) => image.account),
113
+ images.filter((image) => image.account && image.repository),
113
114
  'account',
114
115
  );
115
116
  return reduce<IDockerImage[], { [key: string]: string[] }>(
@@ -192,11 +193,12 @@ export class DockerImageAndTagSelector extends React.Component<
192
193
  }
193
194
 
194
195
  public componentWillReceiveProps(nextProps: IDockerImageAndTagSelectorProps) {
196
+ const requestAccount = this.props.showRegistry ? this.props.account : this.props.registry;
197
+ const nextRequestAccount = nextProps.showRegistry ? nextProps.account : nextProps.registry;
195
198
  if (
196
- !this.images ||
197
- ['account', 'showRegistry'].some(
198
- (key: keyof IDockerImageAndTagSelectorProps) => this.props[key] !== nextProps[key],
199
- )
199
+ (!this.images && !this.imageRequest) ||
200
+ this.props.showRegistry !== nextProps.showRegistry ||
201
+ requestAccount !== nextRequestAccount
200
202
  ) {
201
203
  this.refreshImages(nextProps);
202
204
  } else if (
@@ -214,6 +216,7 @@ export class DockerImageAndTagSelector extends React.Component<
214
216
 
215
217
  componentWillUnmount() {
216
218
  this.unmounted = true;
219
+ this.imageRequest?.abort();
217
220
  }
218
221
 
219
222
  private synchronizeChanges(values: IDockerImageParts, registry: string) {
@@ -315,10 +318,14 @@ export class DockerImageAndTagSelector extends React.Component<
315
318
  }
316
319
 
317
320
  private initializeImages(props: IDockerImageAndTagSelectorProps) {
318
- if (this.state.imagesLoading) {
321
+ if (this.unmounted) {
319
322
  return;
320
323
  }
321
324
 
325
+ this.imageRequest?.abort();
326
+ const imageRequest = new AbortController();
327
+ this.imageRequest = imageRequest;
328
+
322
329
  const { showRegistry, account, registry } = props;
323
330
 
324
331
  const imageConfig: IFindImageParams = {
@@ -327,8 +334,11 @@ export class DockerImageAndTagSelector extends React.Component<
327
334
  };
328
335
 
329
336
  this.setState({ imagesLoading: true });
330
- DockerImageReader.findImages(imageConfig)
337
+ DockerImageReader.findImages(imageConfig, imageRequest.signal)
331
338
  .then((images: IDockerImage[]) => {
339
+ if (imageRequest.signal.aborted || this.unmounted) {
340
+ return;
341
+ }
332
342
  this.images = images;
333
343
  this.registryMap = this.getRegistryMap(this.images);
334
344
  this.accountMap = this.getAccountMap(this.images);
@@ -337,10 +347,11 @@ export class DockerImageAndTagSelector extends React.Component<
337
347
  this.organizationMap = this.getOrganizationMap(this.images);
338
348
  this.repositoryMap = this.getRepositoryMap(this.images);
339
349
  this.organizations = this.getOrganizationsList(this.accountMap);
340
- this.updateThings(props, true);
350
+ this.updateThings(this.props, true);
341
351
  })
342
352
  .finally(() => {
343
- if (!this.unmounted) {
353
+ if (!this.unmounted && this.imageRequest === imageRequest) {
354
+ this.imageRequest = null;
344
355
  this.setState({ imagesLoading: false });
345
356
  }
346
357
  });
@@ -354,9 +365,10 @@ export class DockerImageAndTagSelector extends React.Component<
354
365
  this.initializeImages(props);
355
366
  }
356
367
 
357
- private initializeAccounts(props: IDockerImageAndTagSelectorProps) {
358
- let { account } = props;
368
+ private initializeAccounts() {
359
369
  AccountService.listAccounts('dockerRegistry').then((allAccounts: IAccount[]) => {
370
+ const props = this.props;
371
+ let { account } = props;
360
372
  const accounts = allAccounts.map((a: IAccount) => a.name);
361
373
  if (this.props.showRegistry && !account) {
362
374
  account = accounts[0];
@@ -373,7 +385,7 @@ export class DockerImageAndTagSelector extends React.Component<
373
385
 
374
386
  public componentDidMount() {
375
387
  if (!this.props.deferInitialization && (this.props.registry || this.isNew())) {
376
- this.initializeAccounts(this.props);
388
+ this.initializeAccounts();
377
389
  }
378
390
  }
379
391
 
@@ -0,0 +1,21 @@
1
+ import { RetryService } from '@spinnaker/core';
2
+
3
+ import { DockerChartImageReader, DockerImageReader } from './DockerImageReader';
4
+
5
+ describe('Docker image readers', () => {
6
+ it('passes owner signals through all image and tag retry sequences', async () => {
7
+ const retry = spyOn(RetryService, 'buildRetrySequence').and.returnValue(Promise.resolve([]));
8
+ const signal = new AbortController().signal;
9
+ const imageParams = { provider: 'dockerRegistry', account: 'registry.example' };
10
+ const tagParams = { ...imageParams, repository: 'example/service' };
11
+
12
+ await Promise.all([
13
+ DockerImageReader.findImages(imageParams, signal),
14
+ DockerImageReader.findTags(tagParams, signal),
15
+ DockerChartImageReader.findImages(imageParams, signal),
16
+ DockerChartImageReader.findTags(tagParams, signal),
17
+ ]);
18
+
19
+ expect(retry.calls.allArgs().map((args) => args[4])).toEqual([signal, signal, signal, signal]);
20
+ });
21
+ });
@@ -9,7 +9,7 @@ export interface IDockerImage extends IImage {
9
9
  }
10
10
 
11
11
  export class DockerImageReader {
12
- public static getImage(imageName: string, region: string, credentials: string): PromiseLike<IDockerImage> {
12
+ public static getImage(imageName: string, region: string, credentials: string): Promise<IDockerImage> {
13
13
  return REST('/images')
14
14
  .path(credentials, region, imageName)
15
15
  .query({ provider: 'docker' })
@@ -18,23 +18,25 @@ export class DockerImageReader {
18
18
  .catch((): IDockerImage => null);
19
19
  }
20
20
 
21
- public static findImages(params: IFindImageParams): PromiseLike<IDockerImage[]> {
21
+ public static findImages(params: IFindImageParams, signal?: AbortSignal): Promise<IDockerImage[]> {
22
22
  return RetryService.buildRetrySequence<IDockerImage[]>(
23
23
  () => REST('/images/find').query(params).get(),
24
24
  (results: IDockerImage[]) => results.length > 0,
25
25
  10,
26
26
  1000,
27
+ signal,
27
28
  )
28
29
  .then((results: IDockerImage[]) => results)
29
30
  .catch((): IDockerImage[] => []);
30
31
  }
31
32
 
32
- public static findTags(params: IFindTagsParams): PromiseLike<string[]> {
33
+ public static findTags(params: IFindTagsParams, signal?: AbortSignal): Promise<string[]> {
33
34
  return RetryService.buildRetrySequence<string[]>(
34
35
  () => REST('/images/tags').query(params).get(),
35
36
  (results: string[]) => results.length > 0,
36
37
  10,
37
38
  1000,
39
+ signal,
38
40
  )
39
41
  .then((results: string[]) => results)
40
42
  .catch((): string[] => []);
@@ -42,7 +44,7 @@ export class DockerImageReader {
42
44
  }
43
45
 
44
46
  export class DockerChartImageReader {
45
- public static getImage(imageName: string, region: string, credentials: string): PromiseLike<IDockerImage> {
47
+ public static getImage(imageName: string, region: string, credentials: string): Promise<IDockerImage> {
46
48
  return REST('/charts')
47
49
  .path(credentials, region, imageName)
48
50
  .query({ provider: 'docker' })
@@ -51,23 +53,25 @@ export class DockerChartImageReader {
51
53
  .catch((): IDockerImage => null);
52
54
  }
53
55
 
54
- public static findImages(params: IFindImageParams): PromiseLike<IDockerImage[]> {
56
+ public static findImages(params: IFindImageParams, signal?: AbortSignal): Promise<IDockerImage[]> {
55
57
  return RetryService.buildRetrySequence<IDockerImage[]>(
56
58
  () => REST('/charts/find').query(params).get(),
57
59
  (results: IDockerImage[]) => results.length > 0,
58
60
  10,
59
61
  1000,
62
+ signal,
60
63
  )
61
64
  .then((results: IDockerImage[]) => results)
62
65
  .catch((): IDockerImage[] => []);
63
66
  }
64
67
 
65
- public static findTags(params: IFindTagsParams): PromiseLike<string[]> {
68
+ public static findTags(params: IFindTagsParams, signal?: AbortSignal): Promise<string[]> {
66
69
  return RetryService.buildRetrySequence<string[]>(
67
70
  () => REST('/charts/tags').query(params).get(),
68
71
  (results: string[]) => results.length > 0,
69
72
  10,
70
73
  1000,
74
+ signal,
71
75
  )
72
76
  .then((results: string[]) => results)
73
77
  .catch((): string[] => []);
package/src/index.ts CHANGED
@@ -1,2 +1,3 @@
1
+ import './docker.module';
2
+
1
3
  export * from './image';
2
- export * from './docker.module';