@enspirit/emb 0.0.8 → 0.1.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.
Files changed (125) hide show
  1. package/README.md +50 -27
  2. package/dist/src/cli/abstract/BaseCommand.d.ts +6 -0
  3. package/dist/src/cli/abstract/BaseCommand.js +33 -0
  4. package/dist/src/cli/abstract/FlavouredCommand.d.ts +2 -1
  5. package/dist/src/cli/abstract/FlavouredCommand.js +4 -3
  6. package/dist/src/cli/abstract/index.d.ts +1 -0
  7. package/dist/src/cli/abstract/index.js +1 -0
  8. package/dist/src/cli/commands/clean.d.ts +2 -2
  9. package/dist/src/cli/commands/clean.js +7 -6
  10. package/dist/src/cli/commands/components/index.d.ts +5 -4
  11. package/dist/src/cli/commands/components/index.js +13 -15
  12. package/dist/src/cli/commands/config/print.d.ts +2 -2
  13. package/dist/src/cli/commands/containers/index.d.ts +2 -2
  14. package/dist/src/cli/commands/containers/index.js +3 -3
  15. package/dist/src/cli/commands/containers/prune.d.ts +2 -2
  16. package/dist/src/cli/commands/containers/prune.js +2 -2
  17. package/dist/src/cli/commands/images/delete.d.ts +2 -2
  18. package/dist/src/cli/commands/images/delete.js +3 -2
  19. package/dist/src/cli/commands/images/index.d.ts +2 -2
  20. package/dist/src/cli/commands/images/index.js +3 -3
  21. package/dist/src/cli/commands/images/prune.d.ts +2 -2
  22. package/dist/src/cli/commands/images/prune.js +3 -2
  23. package/dist/src/cli/commands/{components → resources}/build.d.ts +4 -3
  24. package/dist/src/cli/commands/resources/build.js +42 -0
  25. package/dist/src/cli/commands/resources/index.d.ts +9 -0
  26. package/dist/src/cli/commands/resources/index.js +28 -0
  27. package/dist/src/cli/commands/tasks/index.d.ts +2 -2
  28. package/dist/src/cli/commands/tasks/index.js +4 -4
  29. package/dist/src/cli/commands/tasks/run.d.ts +2 -2
  30. package/dist/src/cli/commands/tasks/run.js +12 -5
  31. package/dist/src/cli/commands/up.js +5 -4
  32. package/dist/src/cli/hooks/init.js +1 -26
  33. package/dist/src/cli/utils.d.ts +1 -0
  34. package/dist/src/cli/utils.js +26 -0
  35. package/dist/src/config/convert.d.ts +2 -4
  36. package/dist/src/config/convert.js +12 -35
  37. package/dist/src/config/index.d.ts +3 -4
  38. package/dist/src/config/index.js +2 -3
  39. package/dist/src/config/schema.d.ts +69 -48
  40. package/dist/src/config/schema.json +185 -99
  41. package/dist/src/config/types.d.ts +13 -46
  42. package/dist/src/config/types.js +1 -1
  43. package/dist/src/config/validation.d.ts +3 -3
  44. package/dist/src/config/validation.js +9 -9
  45. package/dist/src/context.d.ts +1 -1
  46. package/dist/src/context.js +1 -0
  47. package/dist/src/docker/compose/operations/ComposeUpOperation.js +13 -12
  48. package/dist/src/docker/images/index.d.ts +0 -1
  49. package/dist/src/docker/images/index.js +0 -1
  50. package/dist/src/docker/index.d.ts +1 -1
  51. package/dist/src/docker/index.js +1 -1
  52. package/dist/src/docker/operations/containers/ExecContainerOperation.js +2 -1
  53. package/dist/src/docker/operations/images/BuildImageOperation.d.ts +7 -8
  54. package/dist/src/docker/operations/images/BuildImageOperation.js +17 -11
  55. package/dist/src/docker/resources/DockerImageResource.js +56 -0
  56. package/dist/src/docker/resources/index.d.ts +1 -0
  57. package/dist/src/docker/resources/index.js +1 -0
  58. package/dist/src/docker/utils.d.ts +1 -7
  59. package/dist/src/docker/utils.js +3 -7
  60. package/dist/src/errors.d.ts +9 -6
  61. package/dist/src/errors.js +15 -9
  62. package/dist/src/index.d.ts +2 -0
  63. package/dist/src/index.js +2 -0
  64. package/dist/src/monorepo/component.d.ts +14 -19
  65. package/dist/src/monorepo/component.js +42 -58
  66. package/dist/src/monorepo/config.d.ts +13 -15
  67. package/dist/src/monorepo/config.js +15 -46
  68. package/dist/src/monorepo/index.d.ts +1 -0
  69. package/dist/src/monorepo/index.js +1 -0
  70. package/dist/src/monorepo/monorepo.d.ts +13 -10
  71. package/dist/src/monorepo/monorepo.js +78 -19
  72. package/dist/src/monorepo/operations/components/index.d.ts +0 -1
  73. package/dist/src/monorepo/operations/components/index.js +0 -1
  74. package/dist/src/monorepo/operations/fs/CreateFileOperation.d.ts +11 -0
  75. package/dist/src/monorepo/operations/fs/CreateFileOperation.js +31 -0
  76. package/dist/src/monorepo/operations/fs/index.d.ts +1 -0
  77. package/dist/src/monorepo/operations/fs/index.js +1 -0
  78. package/dist/src/monorepo/operations/index.d.ts +1 -0
  79. package/dist/src/monorepo/operations/index.js +1 -0
  80. package/dist/src/monorepo/operations/resources/BuildResourcesOperation.d.ts +27 -0
  81. package/dist/src/monorepo/operations/resources/BuildResourcesOperation.js +146 -0
  82. package/dist/src/monorepo/operations/tasks/RunTasksOperation.js +5 -13
  83. package/dist/src/monorepo/plugins/{ComponentDiscoverPlugin.d.ts → AutoDockerPlugin.d.ts} +4 -4
  84. package/dist/src/monorepo/plugins/AutoDockerPlugin.js +46 -0
  85. package/dist/src/monorepo/plugins/EmbfileLoaderPlugin.js +9 -2
  86. package/dist/src/monorepo/plugins/index.d.ts +1 -1
  87. package/dist/src/monorepo/plugins/index.js +3 -3
  88. package/dist/src/monorepo/resources/FileResource.d.ts +1 -0
  89. package/dist/src/monorepo/resources/FileResource.js +13 -0
  90. package/dist/src/monorepo/resources/ResourceFactory.d.ts +23 -0
  91. package/dist/src/monorepo/resources/ResourceFactory.js +16 -0
  92. package/dist/src/monorepo/resources/index.d.ts +1 -0
  93. package/dist/src/monorepo/resources/index.js +1 -0
  94. package/dist/src/monorepo/store/index.d.ts +1 -1
  95. package/dist/src/monorepo/store/index.js +10 -2
  96. package/dist/src/monorepo/taskManagerFactory.d.ts +2 -2
  97. package/dist/src/monorepo/taskManagerFactory.js +2 -2
  98. package/dist/src/monorepo/types.d.ts +18 -5
  99. package/dist/src/monorepo/utils/{findRunOrder.d.ts → EMBCollection.d.ts} +3 -9
  100. package/dist/src/monorepo/utils/EMBCollection.js +101 -0
  101. package/dist/src/monorepo/utils/graph.d.ts +15 -0
  102. package/dist/src/monorepo/utils/graph.js +84 -0
  103. package/dist/src/monorepo/utils/index.d.ts +7 -1
  104. package/dist/src/monorepo/utils/index.js +14 -1
  105. package/dist/src/monorepo/utils/types.d.ts +2 -0
  106. package/dist/src/monorepo/utils/types.js +1 -0
  107. package/dist/src/operations/abstract/AbstractOperation.d.ts +3 -1
  108. package/dist/src/operations/abstract/AbstractOperation.js +3 -0
  109. package/dist/src/operations/types.d.ts +1 -1
  110. package/dist/src/prerequisites/GitPrerequisitePlugin.js +2 -2
  111. package/dist/src/utils/TemplateExpander.d.ts +2 -1
  112. package/dist/src/utils/TemplateExpander.js +3 -1
  113. package/oclif.manifest.json +157 -112
  114. package/package.json +7 -2
  115. package/dist/src/cli/commands/components/build.js +0 -34
  116. package/dist/src/docker/images/buildImage.d.ts +0 -19
  117. package/dist/src/docker/images/buildImage.js +0 -64
  118. package/dist/src/docker/types.d.ts +0 -14
  119. package/dist/src/monorepo/operations/components/BuildComponentsOperation.d.ts +0 -21
  120. package/dist/src/monorepo/operations/components/BuildComponentsOperation.js +0 -135
  121. package/dist/src/monorepo/plugins/ComponentDiscoverPlugin.js +0 -44
  122. package/dist/src/monorepo/project.d.ts +0 -6
  123. package/dist/src/monorepo/project.js +0 -8
  124. package/dist/src/monorepo/utils/findRunOrder.js +0 -165
  125. /package/dist/src/docker/{types.js → resources/DockerImageResource.d.ts} +0 -0
@@ -4,29 +4,35 @@ import { AbstractOperation } from '../../../operations/index.js';
4
4
  /**
5
5
  * https://docs.docker.com/reference/api/engine/version/v1.37/#tag/Image/operation/ImageBuild
6
6
  */
7
- const schema = z.object({
8
- buildArgs: z
9
- .record(z.string(), z.string())
10
- .optional()
11
- .describe('Map of string pairs for build-time variables'),
7
+ export const BuildImageOperationInputSchema = z.object({
8
+ //
12
9
  context: z.string().describe('Path to the build context'),
13
10
  dockerfile: z
14
11
  .string()
15
- .describe('Path within the build context to the Dockerfile.'),
16
- labels: z
17
- .record(z.string(), z.string())
18
12
  .optional()
19
- .describe('Arbitrary key/value labels to set on the image, as a JSON map of string pairs.'),
13
+ .default('Dockerfile')
14
+ .describe('Path within the build context to the Dockerfile.'),
20
15
  src: z.array(z.string()),
21
16
  tag: z.z
22
17
  .string()
18
+ .optional()
19
+ .describe('latest')
23
20
  .describe('A name and optional tag to apply to the image in the name:tag'),
21
+ //
22
+ buildArgs: z
23
+ .record(z.string(), z.string())
24
+ .optional()
25
+ .describe('Map of string pairs for build-time variables'),
26
+ labels: z
27
+ .record(z.string(), z.string())
28
+ .optional()
29
+ .describe('Arbitrary key/value labels to set on the image, as a JSON map of string pairs.'),
24
30
  target: z.string().optional().describe('Target build stage'),
25
31
  });
26
32
  export class BuildImageOperation extends AbstractOperation {
27
33
  observer;
28
34
  constructor(observer) {
29
- super(schema);
35
+ super(BuildImageOperationInputSchema);
30
36
  this.observer = observer;
31
37
  }
32
38
  async _run(input) {
@@ -55,7 +61,7 @@ export class BuildImageOperation extends AbstractOperation {
55
61
  try {
56
62
  const { vertexes } = await decodeBuildkitStatusResponse(trace.aux);
57
63
  vertexes.forEach((v) => {
58
- logStream.write(JSON.stringify(v) + '\n');
64
+ // logStream.write(JSON.stringify(v) + '\n');
59
65
  this.observer?.(v.name);
60
66
  });
61
67
  }
@@ -0,0 +1,56 @@
1
+ import { stat } from 'node:fs/promises';
2
+ import { GitPrerequisitePlugin } from '../../prerequisites/index.js';
3
+ import { ResourceFactory, } from '../../monorepo/resources/ResourceFactory.js';
4
+ import { BuildImageOperation } from '../operations/index.js';
5
+ const DockerImageOpFactory = async ({ config, component, monorepo }) => {
6
+ const fromConfig = (config.params || {});
7
+ const plugin = new GitPrerequisitePlugin();
8
+ const sources = await plugin.collect(component);
9
+ const context = fromConfig.context
10
+ ? component.join(fromConfig.context)
11
+ : component.rootDir;
12
+ const buildParams = {
13
+ context,
14
+ dockerfile: fromConfig.dockerfile || 'Dockerfile',
15
+ src: sources.map((s) => s.path),
16
+ buildArgs: fromConfig.buildArgs || {},
17
+ tag: [monorepo.name, fromConfig.tag || component.name].join('/'),
18
+ labels: {
19
+ ...fromConfig.labels,
20
+ 'emb/project': monorepo.name,
21
+ 'emb/component': component.name,
22
+ 'emb/flavor': monorepo.currentFlavor,
23
+ },
24
+ target: fromConfig.target,
25
+ };
26
+ const lastUpdatedInfo = async (sources) => {
27
+ const stats = await Promise.all(sources.map(async (s) => {
28
+ const stats = await stat(component.join(s.path));
29
+ return {
30
+ time: stats.mtime,
31
+ path: s.path,
32
+ };
33
+ }));
34
+ if (stats.length === 0) {
35
+ return 0;
36
+ }
37
+ return stats.reduce((last, entry) => {
38
+ return last.time > entry.time ? last : entry;
39
+ }, stats[0]);
40
+ };
41
+ return {
42
+ async mustBuild(sentinel) {
43
+ const lastUpdated = await lastUpdatedInfo(sources);
44
+ if (!sentinel) {
45
+ return lastUpdated;
46
+ }
47
+ return lastUpdated && lastUpdated.time.getTime() > sentinel.mtime
48
+ ? lastUpdated
49
+ : undefined;
50
+ },
51
+ input: await monorepo.expand(buildParams),
52
+ operation: new BuildImageOperation(),
53
+ };
54
+ };
55
+ // Bring better abstraction and register as part of the plugin initialization
56
+ ResourceFactory.register('docker/image', DockerImageOpFactory);
@@ -0,0 +1 @@
1
+ import './DockerImageResource.js';
@@ -0,0 +1 @@
1
+ import './DockerImageResource.js';
@@ -1,7 +1 @@
1
- import { Component } from '../monorepo/index.js';
2
- export declare const shortId: (id: string) => string;
3
- /**
4
- * This is too naive and will need better logic to ensure
5
- * we take care of flavors etc
6
- */
7
- export declare const getSentinelFile: (component: Component) => string;
1
+ export declare const shortId: (id?: string) => string;
@@ -1,10 +1,6 @@
1
1
  export const shortId = (id) => {
2
+ if (!id) {
3
+ return '';
4
+ }
2
5
  return id.slice(0, 12);
3
6
  };
4
- /**
5
- * This is too naive and will need better logic to ensure
6
- * we take care of flavors etc
7
- */
8
- export const getSentinelFile = (component) => {
9
- return `sentinels/docker/build/${component.name}.built`;
10
- };
@@ -41,17 +41,20 @@ export declare class CliError extends EMBError {
41
41
  */
42
42
  ref?: string | undefined);
43
43
  }
44
- export declare class AmbiguousTaskError extends EMBError {
45
- options: string[];
46
- constructor(msg: string, options: string[]);
44
+ export declare class AmbiguousReferenceError extends EMBError {
45
+ ref: string;
46
+ matches: string[];
47
+ constructor(msg: string, ref: string, matches: string[]);
47
48
  }
48
49
  export declare class UnkownReferenceError extends EMBError {
49
- constructor(msg: string);
50
+ ref: string;
51
+ constructor(msg: string, ref: string);
50
52
  }
51
- export declare class TaskNameCollisionError extends EMBError {
53
+ export declare class ItemCollisionsError extends EMBError {
52
54
  collisions: Array<string>;
53
55
  constructor(msg: string, collisions: Array<string>);
54
56
  }
55
57
  export declare class CircularDependencyError extends EMBError {
56
- constructor(msg: string);
58
+ readonly deps: Array<Array<string>>;
59
+ constructor(msg: string, deps: Array<Array<string>>);
57
60
  }
@@ -40,27 +40,33 @@ export class CliError extends EMBError {
40
40
  this.ref = ref;
41
41
  }
42
42
  }
43
- export class AmbiguousTaskError extends EMBError {
44
- options;
45
- constructor(msg, options) {
46
- super('AMBIG_TASK', msg);
47
- this.options = options;
43
+ export class AmbiguousReferenceError extends EMBError {
44
+ ref;
45
+ matches;
46
+ constructor(msg, ref, matches) {
47
+ super('AMBIGUOUS_TASK', msg);
48
+ this.ref = ref;
49
+ this.matches = matches;
48
50
  }
49
51
  }
50
52
  export class UnkownReferenceError extends EMBError {
51
- constructor(msg) {
53
+ ref;
54
+ constructor(msg, ref) {
52
55
  super('UNKNOWN_REF', msg);
56
+ this.ref = ref;
53
57
  }
54
58
  }
55
- export class TaskNameCollisionError extends EMBError {
59
+ export class ItemCollisionsError extends EMBError {
56
60
  collisions;
57
61
  constructor(msg, collisions) {
58
- super('UNKNOWN_REF', msg);
62
+ super('ITEM_COLLISIONS', msg);
59
63
  this.collisions = collisions;
60
64
  }
61
65
  }
62
66
  export class CircularDependencyError extends EMBError {
63
- constructor(msg) {
67
+ deps;
68
+ constructor(msg, deps) {
64
69
  super('CIRCULAR_DEPS', msg);
70
+ this.deps = deps;
65
71
  }
66
72
  }
@@ -1,4 +1,6 @@
1
1
  export * from './context.js';
2
+ export * from './docker/index.js';
2
3
  export * from './errors.js';
4
+ export * from './monorepo/index.js';
3
5
  export * from './types.js';
4
6
  export { run } from '@oclif/core';
package/dist/src/index.js CHANGED
@@ -1,4 +1,6 @@
1
1
  export * from './context.js';
2
+ export * from './docker/index.js';
2
3
  export * from './errors.js';
4
+ export * from './monorepo/index.js';
3
5
  export * from './types.js';
4
6
  export { run } from '@oclif/core';
@@ -1,24 +1,19 @@
1
- import { ComponentConfig } from '../config/index.js';
2
- import { DockerComponentBuild } from '../docker/index.js';
3
- import { Monorepo, TaskInfo } from './index.js';
1
+ import { ComponentConfig, ComponentFlavorConfig } from '../config/schema.js';
2
+ import { ComponentFlavors, Monorepo, Resources, Tasks } from './index.js';
4
3
  import { FilePrerequisite } from '../prerequisites/index.js';
5
- export declare class Component {
6
- protected _config: ComponentConfig;
4
+ export declare class Component implements ComponentConfig {
5
+ readonly name: string;
6
+ readonly config: ComponentConfig;
7
7
  protected monorepo: Monorepo;
8
- constructor(_config: ComponentConfig, monorepo: Monorepo);
9
- get config(): ComponentConfig;
10
- get context(): string;
11
- get dependencies(): string[];
12
- get imageName(): string;
13
- get imageTag(): string;
14
- get labels(): {
15
- 'emb/component': string;
16
- };
17
- get name(): string;
18
- get rootdir(): string;
19
- get tasks(): Array<TaskInfo>;
20
- cloneWith(config: Partial<ComponentConfig>): Component;
8
+ readonly tasks: Tasks;
9
+ readonly resources: Resources;
10
+ readonly flavors: ComponentFlavors;
11
+ constructor(name: string, config: ComponentConfig, monorepo: Monorepo);
12
+ get rootDir(): string;
13
+ flavor(name: string, mustExist?: boolean): ComponentFlavorConfig;
14
+ cloneWith(config: Partial<ComponentConfig>): ComponentConfig;
15
+ toJSON(): ComponentConfig;
16
+ withFlavor(name: string): Component;
21
17
  getPrerequisites(): Promise<Array<FilePrerequisite>>;
22
18
  join(path: string): string;
23
- toDockerBuild(): Promise<DockerComponentBuild>;
24
19
  }
@@ -1,77 +1,61 @@
1
- import deepmerge from '@fastify/deepmerge';
1
+ import jsonpatch from 'fast-json-patch';
2
2
  import { join } from 'node:path';
3
+ import { toIdentifedHash, } from './index.js';
3
4
  import { GitPrerequisitePlugin } from '../prerequisites/index.js';
4
5
  export class Component {
5
- _config;
6
+ name;
7
+ config;
6
8
  monorepo;
7
- constructor(_config, monorepo) {
8
- this._config = _config;
9
+ tasks;
10
+ resources;
11
+ flavors;
12
+ constructor(name, config, monorepo) {
13
+ this.name = name;
14
+ this.config = config;
9
15
  this.monorepo = monorepo;
10
- }
11
- get config() {
12
- return structuredClone(this._config);
13
- }
14
- get context() {
15
- return this.config.docker?.context || this.name;
16
- }
17
- get dependencies() {
18
- return this.config.docker?.dependencies || [];
19
- }
20
- get imageName() {
21
- return join(this.monorepo.name, this.name);
22
- }
23
- get imageTag() {
24
- return this.monorepo.defaults.docker?.tag || 'latest';
25
- }
26
- get labels() {
27
- return {
28
- 'emb/component': this.name,
29
- ...this._config.docker?.labels,
30
- };
31
- }
32
- get name() {
33
- return this.config.name;
34
- }
35
- get rootdir() {
36
- return this.monorepo.join(this.context || this.name);
37
- }
38
- get tasks() {
39
- return (this.config.tasks || [])?.map((t) => {
40
- return {
41
- ...t,
42
- component: this.name,
43
- id: `${this.name}:${t.name}`,
44
- };
45
- });
16
+ this.tasks = toIdentifedHash(config.tasks || {}, this.name);
17
+ this.resources = toIdentifedHash(
18
+ // Due to the schema.json -> typescript conversion weirdness
19
+ config.resources || {}, this.name);
20
+ this.flavors = toIdentifedHash(config.flavors || {}, this.name);
21
+ }
22
+ get rootDir() {
23
+ return this.monorepo.join(this.name);
24
+ }
25
+ flavor(name, mustExist = true) {
26
+ const flavor = this.flavors[name];
27
+ if (!flavor && mustExist) {
28
+ throw new Error(`Unknown flavor: ${name}`);
29
+ }
30
+ return flavor;
46
31
  }
47
32
  cloneWith(config) {
48
- return new Component({
33
+ return new Component(this.name, {
49
34
  ...this.config,
50
35
  ...config,
51
36
  }, this.monorepo);
52
37
  }
38
+ toJSON() {
39
+ return structuredClone(this.config);
40
+ }
41
+ withFlavor(name) {
42
+ const original = this.toJSON();
43
+ const patches = this.flavor(name).patches || [];
44
+ const errors = jsonpatch.validate(patches, original);
45
+ if (errors) {
46
+ throw new Error('Invalid patch(es) detected');
47
+ }
48
+ const patched = patches.reduce((doc, patch, index) => {
49
+ return jsonpatch.applyReducer(doc, patch, index);
50
+ }, original);
51
+ return new Component(this.name, patched, this.monorepo);
52
+ }
53
53
  async getPrerequisites() {
54
54
  // TODO: move this to config with potential overridzs
55
55
  const plugin = new GitPrerequisitePlugin();
56
56
  return plugin.collect(this);
57
57
  }
58
58
  join(path) {
59
- return this.monorepo.join(this.context || this.name, path);
60
- }
61
- async toDockerBuild() {
62
- return {
63
- buildArgs: await this.monorepo.expand(deepmerge()(this.monorepo.defaults.docker?.buildArgs || {}, this.config.docker?.buildArgs || {})),
64
- context: this.rootdir,
65
- dockerfile: this.config.docker?.dockerfile || 'Dockerfile',
66
- labels: deepmerge()({
67
- ...this.monorepo.defaults.docker?.labels,
68
- }, this.labels),
69
- name: this.imageName,
70
- prerequisites: await this.getPrerequisites(),
71
- tag: this.imageTag
72
- ? await this.monorepo.expand(this.imageTag)
73
- : 'latest',
74
- target: this.config.docker?.target || this.monorepo.defaults?.docker?.target,
75
- };
59
+ return join(this.rootDir, path);
76
60
  }
77
61
  }
@@ -1,19 +1,17 @@
1
- import { ComponentConfig, DefaultSettings, FlavorConfig, IMonorepoConfig, IProjectConfig, PluginConfig, Task } from '../config/index.js';
2
- export declare class MonorepoConfig implements IMonorepoConfig {
3
- currentFlavor: string;
4
- defaults: DefaultSettings;
1
+ import { ProjectFlavors, Tasks } from '../index.js';
2
+ import { ComponentConfig, DefaultsConfig, PluginConfig, ProjectConfig, ProjectFlavorConfig, UserConfig } from '../config/index.js';
3
+ export declare class MonorepoConfig implements UserConfig {
4
+ project: ProjectConfig;
5
+ defaults: DefaultsConfig;
5
6
  env: Record<string, string>;
6
- flavors: Array<FlavorConfig>;
7
+ flavors: ProjectFlavors;
7
8
  plugins: Array<PluginConfig>;
8
- project: IProjectConfig;
9
9
  vars: Record<string, unknown>;
10
- tasks: Array<Task>;
11
- private _components;
12
- constructor(config: IMonorepoConfig);
13
- get components(): ComponentConfig[];
14
- component(name: string): ComponentConfig;
15
- flavor(name: string): FlavorConfig;
16
- toJSON(): IMonorepoConfig;
17
- with(overrides: Partial<IMonorepoConfig>): MonorepoConfig;
18
- withFlavor(name: string): MonorepoConfig;
10
+ tasks: Tasks;
11
+ components: Record<string, ComponentConfig>;
12
+ constructor(config: UserConfig);
13
+ component(id: string): ComponentConfig;
14
+ flavor(name: string): ProjectFlavorConfig;
15
+ toJSON(): Required<UserConfig>;
16
+ with(overrides: Partial<UserConfig>): MonorepoConfig;
19
17
  }
@@ -1,84 +1,53 @@
1
+ import { toIdentifedHash } from '../index.js';
1
2
  import deepMerge from '@fastify/deepmerge';
2
- import { deepMergeArray } from '../utils/index.js';
3
3
  export class MonorepoConfig {
4
- // the flavor we come from
5
- currentFlavor;
6
- //
4
+ project;
7
5
  defaults;
8
6
  env;
9
7
  flavors;
10
8
  plugins;
11
- project;
12
9
  vars;
13
10
  tasks;
14
- _components;
11
+ components;
15
12
  constructor(config) {
16
- this._components = config.components.reduce((map, cmp) => {
17
- map.set(cmp.name, cmp);
18
- return map;
19
- }, new Map());
20
13
  this.defaults = config.defaults || {};
21
14
  this.project = config.project;
22
15
  this.vars = config.vars || {};
23
- this.flavors = config.flavors || [];
16
+ this.flavors = config.flavors || {};
24
17
  this.env = config.env || {};
25
18
  this.plugins = config.plugins || [];
26
- this.tasks = config.tasks || [];
27
- this.currentFlavor = config.currentFlavor || 'default';
19
+ this.tasks = toIdentifedHash(config.tasks || {}, 'global');
20
+ this.components = config.components || {};
28
21
  }
29
- get components() {
30
- return [...this._components.values()];
31
- }
32
- component(name) {
33
- const config = this.components.find((c) => c.name === name);
22
+ component(id) {
23
+ const config = this.components[id];
34
24
  if (!config) {
35
- throw new Error(`Unknown component ${name}`);
25
+ throw new Error(`Unknown component ${id}`);
36
26
  }
37
27
  return config;
38
28
  }
39
29
  flavor(name) {
40
- const flavor = this.flavors.find((f) => f.name === name);
30
+ const flavor = this.flavors[name];
41
31
  if (!flavor) {
42
32
  throw new Error(`Unknown flavor: ${name}`);
43
33
  }
44
34
  return flavor;
45
35
  }
46
36
  toJSON() {
47
- return {
48
- currentFlavor: this.currentFlavor,
37
+ return structuredClone({
49
38
  components: this.components,
50
39
  defaults: this.defaults,
51
40
  env: this.env,
52
41
  flavors: this.flavors,
53
42
  plugins: this.plugins,
54
43
  project: this.project,
55
- vars: this.vars,
56
44
  tasks: this.tasks,
57
- };
45
+ vars: this.vars,
46
+ });
58
47
  }
59
48
  with(overrides) {
60
- const newConfig = {
61
- ...this.toJSON(),
62
- ...overrides,
63
- components: deepMerge({
64
- mergeArray() {
65
- // Merge components by identifying them by name
66
- return (target, source) => deepMergeArray(target, source, (item) => {
67
- return item.name;
68
- });
69
- },
70
- })(this.components, overrides?.components || []),
71
- defaults: deepMerge()(this.defaults || {}, overrides.defaults || {}),
72
- env: deepMerge()(this.env, overrides?.env || {}),
73
- project: deepMerge()(this.project, overrides?.project || {}),
74
- vars: deepMerge()(this.vars, overrides?.vars || {}),
75
- };
49
+ const oldConfig = this.toJSON();
50
+ const newConfig = deepMerge()(oldConfig, overrides);
76
51
  return new MonorepoConfig(newConfig);
77
52
  }
78
- withFlavor(name) {
79
- return this.with({
80
- ...this.flavor(name),
81
- currentFlavor: name,
82
- });
83
- }
84
53
  }
@@ -3,6 +3,7 @@ export * from './config.js';
3
3
  export * from './monorepo.js';
4
4
  export * from './operations/index.js';
5
5
  export * from './plugins/index.js';
6
+ export * from './resources/index.js';
6
7
  export * from './store/index.js';
7
8
  export * from './taskManagerFactory.js';
8
9
  export * from './types.js';
@@ -3,6 +3,7 @@ export * from './config.js';
3
3
  export * from './monorepo.js';
4
4
  export * from './operations/index.js';
5
5
  export * from './plugins/index.js';
6
+ export * from './resources/index.js';
6
7
  export * from './store/index.js';
7
8
  export * from './taskManagerFactory.js';
8
9
  export * from './types.js';
@@ -1,26 +1,29 @@
1
- import { IMonorepoConfig } from '../config/index.js';
1
+ import { UserConfig } from '../config/types.js';
2
2
  import { IOperation } from '../operations/index.js';
3
3
  import { TemplateExpander } from '../utils/index.js';
4
4
  import { Component } from './component.js';
5
5
  import { EMBStore } from './store/index.js';
6
- import { TaskInfo } from './types.js';
6
+ import { ResourceInfo, TaskInfo } from './types.js';
7
7
  export declare class Monorepo {
8
+ private defaultFlavor;
8
9
  private _config;
9
10
  private _store;
10
11
  private initialized;
11
- constructor(config: IMonorepoConfig);
12
- get components(): Component[];
13
- get config(): IMonorepoConfig;
14
- get defaults(): import("../config/index.js").DefaultSettings;
15
- get flavors(): string[];
12
+ constructor(config: UserConfig, defaultFlavor?: string);
13
+ get config(): UserConfig;
14
+ get defaults(): import("../config/types.js").DefaultsConfig;
15
+ get flavors(): import("./types.js").ProjectFlavors;
16
16
  get name(): string;
17
17
  get rootDir(): string;
18
18
  get currentFlavor(): string;
19
19
  get store(): EMBStore;
20
- get tasks(): TaskInfo[];
21
- get vars(): Record<string, unknown>;
20
+ get components(): Component[];
22
21
  component(name: string): Component;
22
+ get tasks(): TaskInfo[];
23
23
  task(nameOrId: string): TaskInfo;
24
+ get resources(): Array<ResourceInfo>;
25
+ resource(nameOrId: string): ResourceInfo;
26
+ get vars(): Record<string, unknown>;
24
27
  expand(str: string, expander?: TemplateExpander): Promise<string>;
25
28
  expand<R extends Record<string, unknown>>(record: R, expander?: TemplateExpander): Promise<R>;
26
29
  private installStore;
@@ -28,5 +31,5 @@ export declare class Monorepo {
28
31
  init(): Promise<Monorepo>;
29
32
  join(...paths: string[]): string;
30
33
  run<I, O>(operation: IOperation<I, O>, args: I): Promise<O>;
31
- withFlavor(name: string): Promise<Monorepo>;
34
+ withFlavor(flavorName: string): Promise<Monorepo>;
32
35
  }