@ubiquity-os/plugin-sdk 3.6.3 → 3.8.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.
@@ -2,7 +2,7 @@ import { Value } from '@sinclair/typebox/value';
2
2
  import YAML from 'js-yaml';
3
3
  import * as _sinclair_typebox from '@sinclair/typebox';
4
4
  import { StaticDecode, TLiteral } from '@sinclair/typebox';
5
- import { C as Context } from './context-sqbr2o6i.mjs';
5
+ import { C as Context } from './context-Dwl3aRX-.mjs';
6
6
  import { Manifest } from './manifest.mjs';
7
7
  import '@octokit/webhooks';
8
8
  import '@ubiquity-os/ubiquity-os-logger';
@@ -43,6 +43,7 @@ type Location = {
43
43
  owner: string;
44
44
  repo: string;
45
45
  };
46
+ type OctokitFactory = (location: Location) => Promise<Context["octokit"] | null>;
46
47
  interface LoggerInterface {
47
48
  debug(message: string, metadata?: Record<string, unknown>): void;
48
49
  error(message: string, metadata?: Record<string, unknown>): void;
@@ -61,7 +62,10 @@ declare class ConfigurationHandler {
61
62
  private readonly _environment;
62
63
  private _manifestCache;
63
64
  private _manifestPromiseCache;
64
- constructor(_logger: LoggerInterface, _octokit: Context["octokit"], _environment?: "development" | "production" | null);
65
+ private readonly _octokitFactory?;
66
+ constructor(_logger: LoggerInterface, _octokit: Context["octokit"], _environment?: string | null, options?: {
67
+ octokitFactory?: OctokitFactory;
68
+ });
65
69
  /**
66
70
  * Retrieves the configuration for the current plugin based on its manifest.
67
71
  * @param manifest - The plugin manifest containing the `short_name` identifier
@@ -78,8 +82,8 @@ declare class ConfigurationHandler {
78
82
  imports?: string[] | undefined;
79
83
  plugins: {
80
84
  [x: string]: {
81
- skipBotEvents?: boolean | undefined;
82
85
  runsOn?: ("branch_protection_configuration" | "branch_protection_configuration.disabled" | "branch_protection_configuration.enabled" | "branch_protection_rule" | "branch_protection_rule.created" | "branch_protection_rule.deleted" | "branch_protection_rule.edited" | "check_run" | "check_run.completed" | "check_run.created" | "check_run.requested_action" | "check_run.rerequested" | "check_suite" | "check_suite.completed" | "check_suite.requested" | "check_suite.rerequested" | "code_scanning_alert" | "code_scanning_alert.appeared_in_branch" | "code_scanning_alert.closed_by_user" | "code_scanning_alert.created" | "code_scanning_alert.fixed" | "code_scanning_alert.reopened" | "code_scanning_alert.reopened_by_user" | "commit_comment" | "commit_comment.created" | "create" | "custom_property" | "custom_property.created" | "custom_property.deleted" | "custom_property.promote_to_enterprise" | "custom_property.updated" | "custom_property_values" | "custom_property_values.updated" | "delete" | "dependabot_alert" | "dependabot_alert.auto_dismissed" | "dependabot_alert.auto_reopened" | "dependabot_alert.created" | "dependabot_alert.dismissed" | "dependabot_alert.fixed" | "dependabot_alert.reintroduced" | "dependabot_alert.reopened" | "deploy_key" | "deploy_key.created" | "deploy_key.deleted" | "deployment" | "deployment.created" | "deployment_protection_rule" | "deployment_protection_rule.requested" | "deployment_review" | "deployment_review.approved" | "deployment_review.rejected" | "deployment_review.requested" | "deployment_status" | "deployment_status.created" | "discussion" | "discussion.answered" | "discussion.category_changed" | "discussion.closed" | "discussion.created" | "discussion.deleted" | "discussion.edited" | "discussion.labeled" | "discussion.locked" | "discussion.pinned" | "discussion.reopened" | "discussion.transferred" | "discussion.unanswered" | "discussion.unlabeled" | "discussion.unlocked" | "discussion.unpinned" | "discussion_comment" | "discussion_comment.created" | "discussion_comment.deleted" | "discussion_comment.edited" | "fork" | "github_app_authorization" | "github_app_authorization.revoked" | "gollum" | "installation" | "installation.created" | "installation.deleted" | "installation.new_permissions_accepted" | "installation.suspend" | "installation.unsuspend" | "installation_repositories" | "installation_repositories.added" | "installation_repositories.removed" | "installation_target" | "installation_target.renamed" | "issue_comment" | "issue_comment.created" | "issue_comment.deleted" | "issue_comment.edited" | "issues" | "issues.assigned" | "issues.closed" | "issues.deleted" | "issues.demilestoned" | "issues.edited" | "issues.labeled" | "issues.locked" | "issues.milestoned" | "issues.opened" | "issues.pinned" | "issues.reopened" | "issues.transferred" | "issues.typed" | "issues.unassigned" | "issues.unlabeled" | "issues.unlocked" | "issues.unpinned" | "issues.untyped" | "label" | "label.created" | "label.deleted" | "label.edited" | "marketplace_purchase" | "marketplace_purchase.cancelled" | "marketplace_purchase.changed" | "marketplace_purchase.pending_change" | "marketplace_purchase.pending_change_cancelled" | "marketplace_purchase.purchased" | "member" | "member.added" | "member.edited" | "member.removed" | "membership" | "membership.added" | "membership.removed" | "merge_group" | "merge_group.checks_requested" | "merge_group.destroyed" | "meta" | "meta.deleted" | "milestone" | "milestone.closed" | "milestone.created" | "milestone.deleted" | "milestone.edited" | "milestone.opened" | "org_block" | "org_block.blocked" | "org_block.unblocked" | "organization" | "organization.deleted" | "organization.member_added" | "organization.member_invited" | "organization.member_removed" | "organization.renamed" | "package" | "package.published" | "package.updated" | "page_build" | "personal_access_token_request" | "personal_access_token_request.approved" | "personal_access_token_request.cancelled" | "personal_access_token_request.created" | "personal_access_token_request.denied" | "ping" | "project" | "project.closed" | "project.created" | "project.deleted" | "project.edited" | "project.reopened" | "project_card" | "project_card.converted" | "project_card.created" | "project_card.deleted" | "project_card.edited" | "project_card.moved" | "project_column" | "project_column.created" | "project_column.deleted" | "project_column.edited" | "project_column.moved" | "projects_v2" | "projects_v2.closed" | "projects_v2.created" | "projects_v2.deleted" | "projects_v2.edited" | "projects_v2.reopened" | "projects_v2_item" | "projects_v2_item.archived" | "projects_v2_item.converted" | "projects_v2_item.created" | "projects_v2_item.deleted" | "projects_v2_item.edited" | "projects_v2_item.reordered" | "projects_v2_item.restored" | "projects_v2_status_update" | "projects_v2_status_update.created" | "projects_v2_status_update.deleted" | "projects_v2_status_update.edited" | "public" | "pull_request" | "pull_request.assigned" | "pull_request.auto_merge_disabled" | "pull_request.auto_merge_enabled" | "pull_request.closed" | "pull_request.converted_to_draft" | "pull_request.demilestoned" | "pull_request.dequeued" | "pull_request.edited" | "pull_request.enqueued" | "pull_request.labeled" | "pull_request.locked" | "pull_request.milestoned" | "pull_request.opened" | "pull_request.ready_for_review" | "pull_request.reopened" | "pull_request.review_request_removed" | "pull_request.review_requested" | "pull_request.synchronize" | "pull_request.unassigned" | "pull_request.unlabeled" | "pull_request.unlocked" | "pull_request_review" | "pull_request_review.dismissed" | "pull_request_review.edited" | "pull_request_review.submitted" | "pull_request_review_comment" | "pull_request_review_comment.created" | "pull_request_review_comment.deleted" | "pull_request_review_comment.edited" | "pull_request_review_thread" | "pull_request_review_thread.resolved" | "pull_request_review_thread.unresolved" | "push" | "registry_package" | "registry_package.published" | "registry_package.updated" | "release" | "release.created" | "release.deleted" | "release.edited" | "release.prereleased" | "release.published" | "release.released" | "release.unpublished" | "repository" | "repository.archived" | "repository.created" | "repository.deleted" | "repository.edited" | "repository.privatized" | "repository.publicized" | "repository.renamed" | "repository.transferred" | "repository.unarchived" | "repository_advisory" | "repository_advisory.published" | "repository_advisory.reported" | "repository_dispatch" | "repository_dispatch.sample.collected" | "repository_import" | "repository_ruleset" | "repository_ruleset.created" | "repository_ruleset.deleted" | "repository_ruleset.edited" | "repository_vulnerability_alert" | "repository_vulnerability_alert.create" | "repository_vulnerability_alert.dismiss" | "repository_vulnerability_alert.reopen" | "repository_vulnerability_alert.resolve" | "secret_scanning_alert" | "secret_scanning_alert.created" | "secret_scanning_alert.publicly_leaked" | "secret_scanning_alert.reopened" | "secret_scanning_alert.resolved" | "secret_scanning_alert.validated" | "secret_scanning_alert_location" | "secret_scanning_alert_location.created" | "secret_scanning_scan" | "secret_scanning_scan.completed" | "security_advisory" | "security_advisory.published" | "security_advisory.updated" | "security_advisory.withdrawn" | "security_and_analysis" | "sponsorship" | "sponsorship.cancelled" | "sponsorship.created" | "sponsorship.edited" | "sponsorship.pending_cancellation" | "sponsorship.pending_tier_change" | "sponsorship.tier_changed" | "star" | "star.created" | "star.deleted" | "status" | "sub_issues" | "sub_issues.parent_issue_added" | "sub_issues.parent_issue_removed" | "sub_issues.sub_issue_added" | "sub_issues.sub_issue_removed" | "team" | "team.added_to_repository" | "team.created" | "team.deleted" | "team.edited" | "team.removed_from_repository" | "team_add" | "watch" | "watch.started" | "workflow_dispatch" | "workflow_job" | "workflow_job.completed" | "workflow_job.in_progress" | "workflow_job.queued" | "workflow_job.waiting" | "workflow_run" | "workflow_run.completed" | "workflow_run.in_progress" | "workflow_run.requested")[] | undefined;
86
+ skipBotEvents?: boolean | undefined;
83
87
  with: {
84
88
  [x: string]: unknown;
85
89
  };
@@ -101,26 +105,28 @@ declare class ConfigurationHandler {
101
105
  imports?: string[] | undefined;
102
106
  plugins: {
103
107
  [x: string]: {
104
- skipBotEvents?: boolean | undefined;
105
108
  runsOn?: ("branch_protection_configuration" | "branch_protection_configuration.disabled" | "branch_protection_configuration.enabled" | "branch_protection_rule" | "branch_protection_rule.created" | "branch_protection_rule.deleted" | "branch_protection_rule.edited" | "check_run" | "check_run.completed" | "check_run.created" | "check_run.requested_action" | "check_run.rerequested" | "check_suite" | "check_suite.completed" | "check_suite.requested" | "check_suite.rerequested" | "code_scanning_alert" | "code_scanning_alert.appeared_in_branch" | "code_scanning_alert.closed_by_user" | "code_scanning_alert.created" | "code_scanning_alert.fixed" | "code_scanning_alert.reopened" | "code_scanning_alert.reopened_by_user" | "commit_comment" | "commit_comment.created" | "create" | "custom_property" | "custom_property.created" | "custom_property.deleted" | "custom_property.promote_to_enterprise" | "custom_property.updated" | "custom_property_values" | "custom_property_values.updated" | "delete" | "dependabot_alert" | "dependabot_alert.auto_dismissed" | "dependabot_alert.auto_reopened" | "dependabot_alert.created" | "dependabot_alert.dismissed" | "dependabot_alert.fixed" | "dependabot_alert.reintroduced" | "dependabot_alert.reopened" | "deploy_key" | "deploy_key.created" | "deploy_key.deleted" | "deployment" | "deployment.created" | "deployment_protection_rule" | "deployment_protection_rule.requested" | "deployment_review" | "deployment_review.approved" | "deployment_review.rejected" | "deployment_review.requested" | "deployment_status" | "deployment_status.created" | "discussion" | "discussion.answered" | "discussion.category_changed" | "discussion.closed" | "discussion.created" | "discussion.deleted" | "discussion.edited" | "discussion.labeled" | "discussion.locked" | "discussion.pinned" | "discussion.reopened" | "discussion.transferred" | "discussion.unanswered" | "discussion.unlabeled" | "discussion.unlocked" | "discussion.unpinned" | "discussion_comment" | "discussion_comment.created" | "discussion_comment.deleted" | "discussion_comment.edited" | "fork" | "github_app_authorization" | "github_app_authorization.revoked" | "gollum" | "installation" | "installation.created" | "installation.deleted" | "installation.new_permissions_accepted" | "installation.suspend" | "installation.unsuspend" | "installation_repositories" | "installation_repositories.added" | "installation_repositories.removed" | "installation_target" | "installation_target.renamed" | "issue_comment" | "issue_comment.created" | "issue_comment.deleted" | "issue_comment.edited" | "issues" | "issues.assigned" | "issues.closed" | "issues.deleted" | "issues.demilestoned" | "issues.edited" | "issues.labeled" | "issues.locked" | "issues.milestoned" | "issues.opened" | "issues.pinned" | "issues.reopened" | "issues.transferred" | "issues.typed" | "issues.unassigned" | "issues.unlabeled" | "issues.unlocked" | "issues.unpinned" | "issues.untyped" | "label" | "label.created" | "label.deleted" | "label.edited" | "marketplace_purchase" | "marketplace_purchase.cancelled" | "marketplace_purchase.changed" | "marketplace_purchase.pending_change" | "marketplace_purchase.pending_change_cancelled" | "marketplace_purchase.purchased" | "member" | "member.added" | "member.edited" | "member.removed" | "membership" | "membership.added" | "membership.removed" | "merge_group" | "merge_group.checks_requested" | "merge_group.destroyed" | "meta" | "meta.deleted" | "milestone" | "milestone.closed" | "milestone.created" | "milestone.deleted" | "milestone.edited" | "milestone.opened" | "org_block" | "org_block.blocked" | "org_block.unblocked" | "organization" | "organization.deleted" | "organization.member_added" | "organization.member_invited" | "organization.member_removed" | "organization.renamed" | "package" | "package.published" | "package.updated" | "page_build" | "personal_access_token_request" | "personal_access_token_request.approved" | "personal_access_token_request.cancelled" | "personal_access_token_request.created" | "personal_access_token_request.denied" | "ping" | "project" | "project.closed" | "project.created" | "project.deleted" | "project.edited" | "project.reopened" | "project_card" | "project_card.converted" | "project_card.created" | "project_card.deleted" | "project_card.edited" | "project_card.moved" | "project_column" | "project_column.created" | "project_column.deleted" | "project_column.edited" | "project_column.moved" | "projects_v2" | "projects_v2.closed" | "projects_v2.created" | "projects_v2.deleted" | "projects_v2.edited" | "projects_v2.reopened" | "projects_v2_item" | "projects_v2_item.archived" | "projects_v2_item.converted" | "projects_v2_item.created" | "projects_v2_item.deleted" | "projects_v2_item.edited" | "projects_v2_item.reordered" | "projects_v2_item.restored" | "projects_v2_status_update" | "projects_v2_status_update.created" | "projects_v2_status_update.deleted" | "projects_v2_status_update.edited" | "public" | "pull_request" | "pull_request.assigned" | "pull_request.auto_merge_disabled" | "pull_request.auto_merge_enabled" | "pull_request.closed" | "pull_request.converted_to_draft" | "pull_request.demilestoned" | "pull_request.dequeued" | "pull_request.edited" | "pull_request.enqueued" | "pull_request.labeled" | "pull_request.locked" | "pull_request.milestoned" | "pull_request.opened" | "pull_request.ready_for_review" | "pull_request.reopened" | "pull_request.review_request_removed" | "pull_request.review_requested" | "pull_request.synchronize" | "pull_request.unassigned" | "pull_request.unlabeled" | "pull_request.unlocked" | "pull_request_review" | "pull_request_review.dismissed" | "pull_request_review.edited" | "pull_request_review.submitted" | "pull_request_review_comment" | "pull_request_review_comment.created" | "pull_request_review_comment.deleted" | "pull_request_review_comment.edited" | "pull_request_review_thread" | "pull_request_review_thread.resolved" | "pull_request_review_thread.unresolved" | "push" | "registry_package" | "registry_package.published" | "registry_package.updated" | "release" | "release.created" | "release.deleted" | "release.edited" | "release.prereleased" | "release.published" | "release.released" | "release.unpublished" | "repository" | "repository.archived" | "repository.created" | "repository.deleted" | "repository.edited" | "repository.privatized" | "repository.publicized" | "repository.renamed" | "repository.transferred" | "repository.unarchived" | "repository_advisory" | "repository_advisory.published" | "repository_advisory.reported" | "repository_dispatch" | "repository_dispatch.sample.collected" | "repository_import" | "repository_ruleset" | "repository_ruleset.created" | "repository_ruleset.deleted" | "repository_ruleset.edited" | "repository_vulnerability_alert" | "repository_vulnerability_alert.create" | "repository_vulnerability_alert.dismiss" | "repository_vulnerability_alert.reopen" | "repository_vulnerability_alert.resolve" | "secret_scanning_alert" | "secret_scanning_alert.created" | "secret_scanning_alert.publicly_leaked" | "secret_scanning_alert.reopened" | "secret_scanning_alert.resolved" | "secret_scanning_alert.validated" | "secret_scanning_alert_location" | "secret_scanning_alert_location.created" | "secret_scanning_scan" | "secret_scanning_scan.completed" | "security_advisory" | "security_advisory.published" | "security_advisory.updated" | "security_advisory.withdrawn" | "security_and_analysis" | "sponsorship" | "sponsorship.cancelled" | "sponsorship.created" | "sponsorship.edited" | "sponsorship.pending_cancellation" | "sponsorship.pending_tier_change" | "sponsorship.tier_changed" | "star" | "star.created" | "star.deleted" | "status" | "sub_issues" | "sub_issues.parent_issue_added" | "sub_issues.parent_issue_removed" | "sub_issues.sub_issue_added" | "sub_issues.sub_issue_removed" | "team" | "team.added_to_repository" | "team.created" | "team.deleted" | "team.edited" | "team.removed_from_repository" | "team_add" | "watch" | "watch.started" | "workflow_dispatch" | "workflow_job" | "workflow_job.completed" | "workflow_job.in_progress" | "workflow_job.queued" | "workflow_job.waiting" | "workflow_run" | "workflow_run.completed" | "workflow_run.in_progress" | "workflow_run.requested")[] | undefined;
109
+ skipBotEvents?: boolean | undefined;
106
110
  with: {
107
111
  [x: string]: unknown;
108
112
  };
109
113
  } | null;
110
114
  };
111
- };
112
- errors: Value.ValueErrorIterator | null;
113
- rawData: string;
114
- } | {
115
- config: null;
116
- errors: YAML.YAMLException[] | null;
115
+ } | null;
116
+ errors: YAML.YAMLException[] | Value.ValueErrorIterator | null;
117
117
  rawData: string;
118
118
  }>;
119
+ private _createImportState;
120
+ private _getOctokitForLocation;
121
+ private _loadConfigSource;
122
+ private _decodeConfiguration;
123
+ private _resolveImportedConfiguration;
119
124
  private _download;
120
125
  private _parseYaml;
121
126
  protected mergeConfigurations(configuration1: PluginConfiguration, configuration2: PluginConfiguration): PluginConfiguration;
122
127
  getManifest(plugin: GithubPlugin): Promise<{
123
128
  description?: string | undefined;
129
+ skipBotEvents?: boolean | undefined;
124
130
  commands?: {
125
131
  [x: string]: {
126
132
  parameters?: {
@@ -146,7 +152,6 @@ declare class ConfigurationHandler {
146
152
  configuration?: {
147
153
  [x: string]: any;
148
154
  } | undefined;
149
- skipBotEvents?: boolean | undefined;
150
155
  homepage_url?: string | undefined;
151
156
  name: string;
152
157
  short_name: string;
@@ -2,7 +2,7 @@ import { Value } from '@sinclair/typebox/value';
2
2
  import YAML from 'js-yaml';
3
3
  import * as _sinclair_typebox from '@sinclair/typebox';
4
4
  import { StaticDecode, TLiteral } from '@sinclair/typebox';
5
- import { C as Context } from './context-BbEmsEct.js';
5
+ import { C as Context } from './context-zLHgu52i.js';
6
6
  import { Manifest } from './manifest.js';
7
7
  import '@octokit/webhooks';
8
8
  import '@ubiquity-os/ubiquity-os-logger';
@@ -43,6 +43,7 @@ type Location = {
43
43
  owner: string;
44
44
  repo: string;
45
45
  };
46
+ type OctokitFactory = (location: Location) => Promise<Context["octokit"] | null>;
46
47
  interface LoggerInterface {
47
48
  debug(message: string, metadata?: Record<string, unknown>): void;
48
49
  error(message: string, metadata?: Record<string, unknown>): void;
@@ -61,7 +62,10 @@ declare class ConfigurationHandler {
61
62
  private readonly _environment;
62
63
  private _manifestCache;
63
64
  private _manifestPromiseCache;
64
- constructor(_logger: LoggerInterface, _octokit: Context["octokit"], _environment?: "development" | "production" | null);
65
+ private readonly _octokitFactory?;
66
+ constructor(_logger: LoggerInterface, _octokit: Context["octokit"], _environment?: string | null, options?: {
67
+ octokitFactory?: OctokitFactory;
68
+ });
65
69
  /**
66
70
  * Retrieves the configuration for the current plugin based on its manifest.
67
71
  * @param manifest - The plugin manifest containing the `short_name` identifier
@@ -78,8 +82,8 @@ declare class ConfigurationHandler {
78
82
  imports?: string[] | undefined;
79
83
  plugins: {
80
84
  [x: string]: {
81
- skipBotEvents?: boolean | undefined;
82
85
  runsOn?: ("branch_protection_configuration" | "branch_protection_configuration.disabled" | "branch_protection_configuration.enabled" | "branch_protection_rule" | "branch_protection_rule.created" | "branch_protection_rule.deleted" | "branch_protection_rule.edited" | "check_run" | "check_run.completed" | "check_run.created" | "check_run.requested_action" | "check_run.rerequested" | "check_suite" | "check_suite.completed" | "check_suite.requested" | "check_suite.rerequested" | "code_scanning_alert" | "code_scanning_alert.appeared_in_branch" | "code_scanning_alert.closed_by_user" | "code_scanning_alert.created" | "code_scanning_alert.fixed" | "code_scanning_alert.reopened" | "code_scanning_alert.reopened_by_user" | "commit_comment" | "commit_comment.created" | "create" | "custom_property" | "custom_property.created" | "custom_property.deleted" | "custom_property.promote_to_enterprise" | "custom_property.updated" | "custom_property_values" | "custom_property_values.updated" | "delete" | "dependabot_alert" | "dependabot_alert.auto_dismissed" | "dependabot_alert.auto_reopened" | "dependabot_alert.created" | "dependabot_alert.dismissed" | "dependabot_alert.fixed" | "dependabot_alert.reintroduced" | "dependabot_alert.reopened" | "deploy_key" | "deploy_key.created" | "deploy_key.deleted" | "deployment" | "deployment.created" | "deployment_protection_rule" | "deployment_protection_rule.requested" | "deployment_review" | "deployment_review.approved" | "deployment_review.rejected" | "deployment_review.requested" | "deployment_status" | "deployment_status.created" | "discussion" | "discussion.answered" | "discussion.category_changed" | "discussion.closed" | "discussion.created" | "discussion.deleted" | "discussion.edited" | "discussion.labeled" | "discussion.locked" | "discussion.pinned" | "discussion.reopened" | "discussion.transferred" | "discussion.unanswered" | "discussion.unlabeled" | "discussion.unlocked" | "discussion.unpinned" | "discussion_comment" | "discussion_comment.created" | "discussion_comment.deleted" | "discussion_comment.edited" | "fork" | "github_app_authorization" | "github_app_authorization.revoked" | "gollum" | "installation" | "installation.created" | "installation.deleted" | "installation.new_permissions_accepted" | "installation.suspend" | "installation.unsuspend" | "installation_repositories" | "installation_repositories.added" | "installation_repositories.removed" | "installation_target" | "installation_target.renamed" | "issue_comment" | "issue_comment.created" | "issue_comment.deleted" | "issue_comment.edited" | "issues" | "issues.assigned" | "issues.closed" | "issues.deleted" | "issues.demilestoned" | "issues.edited" | "issues.labeled" | "issues.locked" | "issues.milestoned" | "issues.opened" | "issues.pinned" | "issues.reopened" | "issues.transferred" | "issues.typed" | "issues.unassigned" | "issues.unlabeled" | "issues.unlocked" | "issues.unpinned" | "issues.untyped" | "label" | "label.created" | "label.deleted" | "label.edited" | "marketplace_purchase" | "marketplace_purchase.cancelled" | "marketplace_purchase.changed" | "marketplace_purchase.pending_change" | "marketplace_purchase.pending_change_cancelled" | "marketplace_purchase.purchased" | "member" | "member.added" | "member.edited" | "member.removed" | "membership" | "membership.added" | "membership.removed" | "merge_group" | "merge_group.checks_requested" | "merge_group.destroyed" | "meta" | "meta.deleted" | "milestone" | "milestone.closed" | "milestone.created" | "milestone.deleted" | "milestone.edited" | "milestone.opened" | "org_block" | "org_block.blocked" | "org_block.unblocked" | "organization" | "organization.deleted" | "organization.member_added" | "organization.member_invited" | "organization.member_removed" | "organization.renamed" | "package" | "package.published" | "package.updated" | "page_build" | "personal_access_token_request" | "personal_access_token_request.approved" | "personal_access_token_request.cancelled" | "personal_access_token_request.created" | "personal_access_token_request.denied" | "ping" | "project" | "project.closed" | "project.created" | "project.deleted" | "project.edited" | "project.reopened" | "project_card" | "project_card.converted" | "project_card.created" | "project_card.deleted" | "project_card.edited" | "project_card.moved" | "project_column" | "project_column.created" | "project_column.deleted" | "project_column.edited" | "project_column.moved" | "projects_v2" | "projects_v2.closed" | "projects_v2.created" | "projects_v2.deleted" | "projects_v2.edited" | "projects_v2.reopened" | "projects_v2_item" | "projects_v2_item.archived" | "projects_v2_item.converted" | "projects_v2_item.created" | "projects_v2_item.deleted" | "projects_v2_item.edited" | "projects_v2_item.reordered" | "projects_v2_item.restored" | "projects_v2_status_update" | "projects_v2_status_update.created" | "projects_v2_status_update.deleted" | "projects_v2_status_update.edited" | "public" | "pull_request" | "pull_request.assigned" | "pull_request.auto_merge_disabled" | "pull_request.auto_merge_enabled" | "pull_request.closed" | "pull_request.converted_to_draft" | "pull_request.demilestoned" | "pull_request.dequeued" | "pull_request.edited" | "pull_request.enqueued" | "pull_request.labeled" | "pull_request.locked" | "pull_request.milestoned" | "pull_request.opened" | "pull_request.ready_for_review" | "pull_request.reopened" | "pull_request.review_request_removed" | "pull_request.review_requested" | "pull_request.synchronize" | "pull_request.unassigned" | "pull_request.unlabeled" | "pull_request.unlocked" | "pull_request_review" | "pull_request_review.dismissed" | "pull_request_review.edited" | "pull_request_review.submitted" | "pull_request_review_comment" | "pull_request_review_comment.created" | "pull_request_review_comment.deleted" | "pull_request_review_comment.edited" | "pull_request_review_thread" | "pull_request_review_thread.resolved" | "pull_request_review_thread.unresolved" | "push" | "registry_package" | "registry_package.published" | "registry_package.updated" | "release" | "release.created" | "release.deleted" | "release.edited" | "release.prereleased" | "release.published" | "release.released" | "release.unpublished" | "repository" | "repository.archived" | "repository.created" | "repository.deleted" | "repository.edited" | "repository.privatized" | "repository.publicized" | "repository.renamed" | "repository.transferred" | "repository.unarchived" | "repository_advisory" | "repository_advisory.published" | "repository_advisory.reported" | "repository_dispatch" | "repository_dispatch.sample.collected" | "repository_import" | "repository_ruleset" | "repository_ruleset.created" | "repository_ruleset.deleted" | "repository_ruleset.edited" | "repository_vulnerability_alert" | "repository_vulnerability_alert.create" | "repository_vulnerability_alert.dismiss" | "repository_vulnerability_alert.reopen" | "repository_vulnerability_alert.resolve" | "secret_scanning_alert" | "secret_scanning_alert.created" | "secret_scanning_alert.publicly_leaked" | "secret_scanning_alert.reopened" | "secret_scanning_alert.resolved" | "secret_scanning_alert.validated" | "secret_scanning_alert_location" | "secret_scanning_alert_location.created" | "secret_scanning_scan" | "secret_scanning_scan.completed" | "security_advisory" | "security_advisory.published" | "security_advisory.updated" | "security_advisory.withdrawn" | "security_and_analysis" | "sponsorship" | "sponsorship.cancelled" | "sponsorship.created" | "sponsorship.edited" | "sponsorship.pending_cancellation" | "sponsorship.pending_tier_change" | "sponsorship.tier_changed" | "star" | "star.created" | "star.deleted" | "status" | "sub_issues" | "sub_issues.parent_issue_added" | "sub_issues.parent_issue_removed" | "sub_issues.sub_issue_added" | "sub_issues.sub_issue_removed" | "team" | "team.added_to_repository" | "team.created" | "team.deleted" | "team.edited" | "team.removed_from_repository" | "team_add" | "watch" | "watch.started" | "workflow_dispatch" | "workflow_job" | "workflow_job.completed" | "workflow_job.in_progress" | "workflow_job.queued" | "workflow_job.waiting" | "workflow_run" | "workflow_run.completed" | "workflow_run.in_progress" | "workflow_run.requested")[] | undefined;
86
+ skipBotEvents?: boolean | undefined;
83
87
  with: {
84
88
  [x: string]: unknown;
85
89
  };
@@ -101,26 +105,28 @@ declare class ConfigurationHandler {
101
105
  imports?: string[] | undefined;
102
106
  plugins: {
103
107
  [x: string]: {
104
- skipBotEvents?: boolean | undefined;
105
108
  runsOn?: ("branch_protection_configuration" | "branch_protection_configuration.disabled" | "branch_protection_configuration.enabled" | "branch_protection_rule" | "branch_protection_rule.created" | "branch_protection_rule.deleted" | "branch_protection_rule.edited" | "check_run" | "check_run.completed" | "check_run.created" | "check_run.requested_action" | "check_run.rerequested" | "check_suite" | "check_suite.completed" | "check_suite.requested" | "check_suite.rerequested" | "code_scanning_alert" | "code_scanning_alert.appeared_in_branch" | "code_scanning_alert.closed_by_user" | "code_scanning_alert.created" | "code_scanning_alert.fixed" | "code_scanning_alert.reopened" | "code_scanning_alert.reopened_by_user" | "commit_comment" | "commit_comment.created" | "create" | "custom_property" | "custom_property.created" | "custom_property.deleted" | "custom_property.promote_to_enterprise" | "custom_property.updated" | "custom_property_values" | "custom_property_values.updated" | "delete" | "dependabot_alert" | "dependabot_alert.auto_dismissed" | "dependabot_alert.auto_reopened" | "dependabot_alert.created" | "dependabot_alert.dismissed" | "dependabot_alert.fixed" | "dependabot_alert.reintroduced" | "dependabot_alert.reopened" | "deploy_key" | "deploy_key.created" | "deploy_key.deleted" | "deployment" | "deployment.created" | "deployment_protection_rule" | "deployment_protection_rule.requested" | "deployment_review" | "deployment_review.approved" | "deployment_review.rejected" | "deployment_review.requested" | "deployment_status" | "deployment_status.created" | "discussion" | "discussion.answered" | "discussion.category_changed" | "discussion.closed" | "discussion.created" | "discussion.deleted" | "discussion.edited" | "discussion.labeled" | "discussion.locked" | "discussion.pinned" | "discussion.reopened" | "discussion.transferred" | "discussion.unanswered" | "discussion.unlabeled" | "discussion.unlocked" | "discussion.unpinned" | "discussion_comment" | "discussion_comment.created" | "discussion_comment.deleted" | "discussion_comment.edited" | "fork" | "github_app_authorization" | "github_app_authorization.revoked" | "gollum" | "installation" | "installation.created" | "installation.deleted" | "installation.new_permissions_accepted" | "installation.suspend" | "installation.unsuspend" | "installation_repositories" | "installation_repositories.added" | "installation_repositories.removed" | "installation_target" | "installation_target.renamed" | "issue_comment" | "issue_comment.created" | "issue_comment.deleted" | "issue_comment.edited" | "issues" | "issues.assigned" | "issues.closed" | "issues.deleted" | "issues.demilestoned" | "issues.edited" | "issues.labeled" | "issues.locked" | "issues.milestoned" | "issues.opened" | "issues.pinned" | "issues.reopened" | "issues.transferred" | "issues.typed" | "issues.unassigned" | "issues.unlabeled" | "issues.unlocked" | "issues.unpinned" | "issues.untyped" | "label" | "label.created" | "label.deleted" | "label.edited" | "marketplace_purchase" | "marketplace_purchase.cancelled" | "marketplace_purchase.changed" | "marketplace_purchase.pending_change" | "marketplace_purchase.pending_change_cancelled" | "marketplace_purchase.purchased" | "member" | "member.added" | "member.edited" | "member.removed" | "membership" | "membership.added" | "membership.removed" | "merge_group" | "merge_group.checks_requested" | "merge_group.destroyed" | "meta" | "meta.deleted" | "milestone" | "milestone.closed" | "milestone.created" | "milestone.deleted" | "milestone.edited" | "milestone.opened" | "org_block" | "org_block.blocked" | "org_block.unblocked" | "organization" | "organization.deleted" | "organization.member_added" | "organization.member_invited" | "organization.member_removed" | "organization.renamed" | "package" | "package.published" | "package.updated" | "page_build" | "personal_access_token_request" | "personal_access_token_request.approved" | "personal_access_token_request.cancelled" | "personal_access_token_request.created" | "personal_access_token_request.denied" | "ping" | "project" | "project.closed" | "project.created" | "project.deleted" | "project.edited" | "project.reopened" | "project_card" | "project_card.converted" | "project_card.created" | "project_card.deleted" | "project_card.edited" | "project_card.moved" | "project_column" | "project_column.created" | "project_column.deleted" | "project_column.edited" | "project_column.moved" | "projects_v2" | "projects_v2.closed" | "projects_v2.created" | "projects_v2.deleted" | "projects_v2.edited" | "projects_v2.reopened" | "projects_v2_item" | "projects_v2_item.archived" | "projects_v2_item.converted" | "projects_v2_item.created" | "projects_v2_item.deleted" | "projects_v2_item.edited" | "projects_v2_item.reordered" | "projects_v2_item.restored" | "projects_v2_status_update" | "projects_v2_status_update.created" | "projects_v2_status_update.deleted" | "projects_v2_status_update.edited" | "public" | "pull_request" | "pull_request.assigned" | "pull_request.auto_merge_disabled" | "pull_request.auto_merge_enabled" | "pull_request.closed" | "pull_request.converted_to_draft" | "pull_request.demilestoned" | "pull_request.dequeued" | "pull_request.edited" | "pull_request.enqueued" | "pull_request.labeled" | "pull_request.locked" | "pull_request.milestoned" | "pull_request.opened" | "pull_request.ready_for_review" | "pull_request.reopened" | "pull_request.review_request_removed" | "pull_request.review_requested" | "pull_request.synchronize" | "pull_request.unassigned" | "pull_request.unlabeled" | "pull_request.unlocked" | "pull_request_review" | "pull_request_review.dismissed" | "pull_request_review.edited" | "pull_request_review.submitted" | "pull_request_review_comment" | "pull_request_review_comment.created" | "pull_request_review_comment.deleted" | "pull_request_review_comment.edited" | "pull_request_review_thread" | "pull_request_review_thread.resolved" | "pull_request_review_thread.unresolved" | "push" | "registry_package" | "registry_package.published" | "registry_package.updated" | "release" | "release.created" | "release.deleted" | "release.edited" | "release.prereleased" | "release.published" | "release.released" | "release.unpublished" | "repository" | "repository.archived" | "repository.created" | "repository.deleted" | "repository.edited" | "repository.privatized" | "repository.publicized" | "repository.renamed" | "repository.transferred" | "repository.unarchived" | "repository_advisory" | "repository_advisory.published" | "repository_advisory.reported" | "repository_dispatch" | "repository_dispatch.sample.collected" | "repository_import" | "repository_ruleset" | "repository_ruleset.created" | "repository_ruleset.deleted" | "repository_ruleset.edited" | "repository_vulnerability_alert" | "repository_vulnerability_alert.create" | "repository_vulnerability_alert.dismiss" | "repository_vulnerability_alert.reopen" | "repository_vulnerability_alert.resolve" | "secret_scanning_alert" | "secret_scanning_alert.created" | "secret_scanning_alert.publicly_leaked" | "secret_scanning_alert.reopened" | "secret_scanning_alert.resolved" | "secret_scanning_alert.validated" | "secret_scanning_alert_location" | "secret_scanning_alert_location.created" | "secret_scanning_scan" | "secret_scanning_scan.completed" | "security_advisory" | "security_advisory.published" | "security_advisory.updated" | "security_advisory.withdrawn" | "security_and_analysis" | "sponsorship" | "sponsorship.cancelled" | "sponsorship.created" | "sponsorship.edited" | "sponsorship.pending_cancellation" | "sponsorship.pending_tier_change" | "sponsorship.tier_changed" | "star" | "star.created" | "star.deleted" | "status" | "sub_issues" | "sub_issues.parent_issue_added" | "sub_issues.parent_issue_removed" | "sub_issues.sub_issue_added" | "sub_issues.sub_issue_removed" | "team" | "team.added_to_repository" | "team.created" | "team.deleted" | "team.edited" | "team.removed_from_repository" | "team_add" | "watch" | "watch.started" | "workflow_dispatch" | "workflow_job" | "workflow_job.completed" | "workflow_job.in_progress" | "workflow_job.queued" | "workflow_job.waiting" | "workflow_run" | "workflow_run.completed" | "workflow_run.in_progress" | "workflow_run.requested")[] | undefined;
109
+ skipBotEvents?: boolean | undefined;
106
110
  with: {
107
111
  [x: string]: unknown;
108
112
  };
109
113
  } | null;
110
114
  };
111
- };
112
- errors: Value.ValueErrorIterator | null;
113
- rawData: string;
114
- } | {
115
- config: null;
116
- errors: YAML.YAMLException[] | null;
115
+ } | null;
116
+ errors: YAML.YAMLException[] | Value.ValueErrorIterator | null;
117
117
  rawData: string;
118
118
  }>;
119
+ private _createImportState;
120
+ private _getOctokitForLocation;
121
+ private _loadConfigSource;
122
+ private _decodeConfiguration;
123
+ private _resolveImportedConfiguration;
119
124
  private _download;
120
125
  private _parseYaml;
121
126
  protected mergeConfigurations(configuration1: PluginConfiguration, configuration2: PluginConfiguration): PluginConfiguration;
122
127
  getManifest(plugin: GithubPlugin): Promise<{
123
128
  description?: string | undefined;
129
+ skipBotEvents?: boolean | undefined;
124
130
  commands?: {
125
131
  [x: string]: {
126
132
  parameters?: {
@@ -146,7 +152,6 @@ declare class ConfigurationHandler {
146
152
  configuration?: {
147
153
  [x: string]: any;
148
154
  } | undefined;
149
- skipBotEvents?: boolean | undefined;
150
155
  homepage_url?: string | undefined;
151
156
  name: string;
152
157
  short_name: string;
@@ -2734,14 +2734,101 @@ var manifestSchema = import_typebox2.Type.Object({
2734
2734
  var CONFIG_PROD_FULL_PATH = ".github/.ubiquity-os.config.yml";
2735
2735
  var CONFIG_DEV_FULL_PATH = ".github/.ubiquity-os.config.dev.yml";
2736
2736
  var CONFIG_ORG_REPO = ".ubiquity-os";
2737
+ var ENVIRONMENT_TO_CONFIG_SUFFIX = {
2738
+ development: "dev"
2739
+ };
2740
+ var VALID_CONFIG_SUFFIX = /^[a-z0-9][a-z0-9_-]*$/i;
2741
+ var MAX_IMPORT_DEPTH = 6;
2742
+ function normalizeEnvironmentName(environment) {
2743
+ return String(environment ?? "").trim().toLowerCase();
2744
+ }
2745
+ function getConfigPathCandidatesForEnvironment(environment) {
2746
+ const normalized = normalizeEnvironmentName(environment);
2747
+ if (!normalized) {
2748
+ return [CONFIG_PROD_FULL_PATH, CONFIG_DEV_FULL_PATH];
2749
+ }
2750
+ if (normalized === "production" || normalized === "prod") {
2751
+ return [CONFIG_PROD_FULL_PATH];
2752
+ }
2753
+ const suffix = ENVIRONMENT_TO_CONFIG_SUFFIX[normalized] ?? normalized;
2754
+ if (suffix === "dev") {
2755
+ return [CONFIG_DEV_FULL_PATH];
2756
+ }
2757
+ if (!VALID_CONFIG_SUFFIX.test(suffix)) {
2758
+ return [CONFIG_DEV_FULL_PATH];
2759
+ }
2760
+ return [`.github/.ubiquity-os.config.${suffix}.yml`, CONFIG_PROD_FULL_PATH];
2761
+ }
2762
+ function normalizeImportKey(location) {
2763
+ return `${location.owner}`.trim().toLowerCase() + "/" + `${location.repo}`.trim().toLowerCase();
2764
+ }
2765
+ function parseImportSpec(value) {
2766
+ const trimmed = value.trim();
2767
+ if (!trimmed) return null;
2768
+ const parts = trimmed.split("/");
2769
+ if (parts.length !== 2) return null;
2770
+ const [owner, repo] = parts;
2771
+ if (!owner || !repo) return null;
2772
+ return { owner, repo };
2773
+ }
2774
+ function readImports(logger, value, source) {
2775
+ if (!value) return [];
2776
+ if (!Array.isArray(value)) {
2777
+ logger.warn("Invalid imports; expected a list of strings.", { source });
2778
+ return [];
2779
+ }
2780
+ const seen = /* @__PURE__ */ new Set();
2781
+ const imports = [];
2782
+ for (const entry of value) {
2783
+ if (typeof entry !== "string") {
2784
+ logger.warn("Ignoring invalid import entry; expected string.", { source, entry });
2785
+ continue;
2786
+ }
2787
+ const parsed = parseImportSpec(entry);
2788
+ if (!parsed) {
2789
+ logger.warn("Ignoring invalid import entry; expected owner/repo.", { source, entry });
2790
+ continue;
2791
+ }
2792
+ const key = normalizeImportKey(parsed);
2793
+ if (seen.has(key)) continue;
2794
+ seen.add(key);
2795
+ imports.push(parsed);
2796
+ }
2797
+ return imports;
2798
+ }
2799
+ function stripImports(config) {
2800
+ if (!config || typeof config !== "object") return config;
2801
+ const { imports: _imports, ...rest } = config;
2802
+ return rest;
2803
+ }
2804
+ function mergeImportedConfigs(imported, base) {
2805
+ if (!imported.length) {
2806
+ return base;
2807
+ }
2808
+ let merged = imported[0];
2809
+ for (let i = 1; i < imported.length; i++) {
2810
+ merged = {
2811
+ ...merged,
2812
+ ...imported[i],
2813
+ plugins: { ...merged.plugins, ...imported[i].plugins }
2814
+ };
2815
+ }
2816
+ return base ? {
2817
+ ...merged,
2818
+ ...base,
2819
+ plugins: { ...merged.plugins, ...base.plugins }
2820
+ } : merged;
2821
+ }
2737
2822
  var ConfigurationHandler = class {
2738
- constructor(_logger, _octokit, _environment = null) {
2823
+ constructor(_logger, _octokit, _environment = null, options) {
2739
2824
  this._logger = _logger;
2740
2825
  this._octokit = _octokit;
2741
2826
  this._environment = _environment;
2827
+ this._octokitFactory = options?.octokitFactory;
2742
2828
  }
2743
2829
  _manifestCache = {};
2744
2830
  _manifestPromiseCache = {};
2831
+ _octokitFactory;
2745
2832
  /**
2746
2833
  * Retrieves the configuration for the current plugin based on its manifest.
2747
2834
  * @param manifest - The plugin manifest containing the `short_name` identifier
@@ -2760,7 +2847,7 @@ var ConfigurationHandler = class {
2760
2847
  * @returns The merged plugin configuration with resolved plugin settings.
2761
2848
  */
2762
2849
  async getConfiguration(location) {
2763
- const defaultConfiguration = import_value.Value.Decode(configSchema, import_value.Value.Default(configSchema, {}));
2850
+ const defaultConfiguration = stripImports(import_value.Value.Decode(configSchema, import_value.Value.Default(configSchema, {})));
2764
2851
  if (!location) {
2765
2852
  this._logger.info("No location was provided, using the default configuration");
2766
2853
  return defaultConfiguration;
@@ -2821,57 +2908,153 @@ var ConfigurationHandler = class {
2821
2908
  * @param repository The repository name
2822
2909
  */
2823
2910
  async getConfigurationFromRepo(owner, repository) {
2911
+ const location = { owner, repo: repository };
2912
+ const state = this._createImportState();
2913
+ const octokit = await this._getOctokitForLocation(location, state);
2914
+ if (!octokit) {
2915
+ this._logger.warn("No Octokit available for configuration load", { owner, repository });
2916
+ return { config: null, errors: null, rawData: null };
2917
+ }
2918
+ const { config, imports, errors, rawData } = await this._loadConfigSource(location, octokit);
2919
+ if (!rawData) {
2920
+ return { config: null, errors: null, rawData: null };
2921
+ }
2922
+ if (errors && errors.length) {
2923
+ this._logger.warn("YAML could not be decoded", { owner, repository, errors });
2924
+ return { config: null, errors, rawData };
2925
+ }
2926
+ if (!config) {
2927
+ this._logger.warn("YAML could not be decoded", { owner, repository });
2928
+ return { config: null, errors, rawData };
2929
+ }
2930
+ const importedConfigs = [];
2931
+ for (const next of imports) {
2932
+ const resolved = await this._resolveImportedConfiguration(next, state, 1);
2933
+ if (resolved) importedConfigs.push(resolved);
2934
+ }
2935
+ const mergedConfig = mergeImportedConfigs(importedConfigs, config);
2936
+ if (!mergedConfig) {
2937
+ return { config: null, errors: null, rawData };
2938
+ }
2939
+ const decoded = this._decodeConfiguration(location, mergedConfig);
2940
+ return { config: decoded.config, errors: decoded.errors, rawData };
2941
+ }
2942
+ _createImportState() {
2943
+ return {
2944
+ cache: /* @__PURE__ */ new Map(),
2945
+ inFlight: /* @__PURE__ */ new Set(),
2946
+ octokitByLocation: /* @__PURE__ */ new Map()
2947
+ };
2948
+ }
2949
+ async _getOctokitForLocation(location, state) {
2950
+ const key = normalizeImportKey(location);
2951
+ if (state.octokitByLocation.has(key)) {
2952
+ return state.octokitByLocation.get(key) ?? null;
2953
+ }
2954
+ if (this._octokitFactory) {
2955
+ const resolved = await this._octokitFactory(location);
2956
+ if (resolved) {
2957
+ state.octokitByLocation.set(key, resolved);
2958
+ return resolved;
2959
+ }
2960
+ }
2961
+ state.octokitByLocation.set(key, this._octokit);
2962
+ return this._octokit;
2963
+ }
2964
+ async _loadConfigSource(location, octokit) {
2824
2965
  const rawData = await this._download({
2825
- repository,
2826
- owner
2966
+ repository: location.repo,
2967
+ owner: location.owner,
2968
+ octokit
2827
2969
  });
2828
- this._logger.ok("Downloaded configuration file", { owner, repository });
2970
+ this._logger.ok("Downloaded configuration file", { owner: location.owner, repository: location.repo });
2829
2971
  if (!rawData) {
2830
- this._logger.warn("No raw configuration data", { owner, repository });
2831
- return { config: null, errors: null, rawData: null };
2972
+ this._logger.warn("No raw configuration data", { owner: location.owner, repository: location.repo });
2973
+ return { config: null, imports: [], errors: null, rawData: null };
2832
2974
  }
2833
2975
  const { yaml, errors } = this._parseYaml(rawData);
2976
+ const imports = readImports(this._logger, yaml?.imports, location);
2977
+ if (yaml && typeof yaml === "object" && !Array.isArray(yaml) && "imports" in yaml) {
2978
+ delete yaml.imports;
2979
+ }
2834
2980
  const targetRepoConfiguration = yaml;
2835
- this._logger.info("Decoding configuration", { owner, repository });
2836
- if (targetRepoConfiguration) {
2837
- try {
2838
- const configSchemaWithDefaults = import_value.Value.Default(configSchema, targetRepoConfiguration);
2839
- const errors2 = import_value.Value.Errors(configSchema, configSchemaWithDefaults);
2840
- if (errors2.First()) {
2841
- for (const error of errors2) {
2842
- this._logger.warn("Configuration validation error", { err: error });
2843
- }
2981
+ return { config: targetRepoConfiguration, imports, errors, rawData };
2982
+ }
2983
+ _decodeConfiguration(location, config) {
2984
+ this._logger.info("Decoding configuration", { owner: location.owner, repository: location.repo });
2985
+ try {
2986
+ const configSchemaWithDefaults = import_value.Value.Default(configSchema, config);
2987
+ const errors = import_value.Value.Errors(configSchema, configSchemaWithDefaults);
2988
+ if (errors.First()) {
2989
+ for (const error of errors) {
2990
+ this._logger.warn("Configuration validation error", { err: error });
2844
2991
  }
2845
- const decodedConfig = import_value.Value.Decode(configSchema, configSchemaWithDefaults);
2846
- return { config: decodedConfig, errors: errors2.First() ? errors2 : null, rawData };
2847
- } catch (error) {
2848
- this._logger.warn("Error decoding configuration; Will ignore.", { err: error, owner, repository });
2849
- return { config: null, errors: [error instanceof import_value.TransformDecodeCheckError ? error.error : error], rawData };
2850
2992
  }
2993
+ const decodedConfig = import_value.Value.Decode(configSchema, configSchemaWithDefaults);
2994
+ return { config: stripImports(decodedConfig), errors: errors.First() ? errors : null };
2995
+ } catch (error) {
2996
+ this._logger.warn("Error decoding configuration; Will ignore.", { err: error, owner: location.owner, repository: location.repo });
2997
+ return { config: null, errors: [error instanceof import_value.TransformDecodeCheckError ? error.error : error] };
2851
2998
  }
2852
- this._logger.warn("YAML could not be decoded", { owner, repository, errors });
2853
- return { config: null, errors, rawData };
2854
2999
  }
2855
- async _download({ repository, owner }) {
3000
+ async _resolveImportedConfiguration(location, state, depth) {
3001
+ const key = normalizeImportKey(location);
3002
+ if (state.cache.has(key)) {
3003
+ return state.cache.get(key) ?? null;
3004
+ }
3005
+ if (state.inFlight.has(key)) {
3006
+ this._logger.warn("Skipping import due to circular reference.", { location });
3007
+ return null;
3008
+ }
3009
+ if (depth > MAX_IMPORT_DEPTH) {
3010
+ this._logger.warn("Skipping import; maximum depth exceeded.", { location, depth });
3011
+ return null;
3012
+ }
3013
+ state.inFlight.add(key);
3014
+ let resolved = null;
3015
+ try {
3016
+ const octokit = await this._getOctokitForLocation(location, state);
3017
+ if (!octokit) {
3018
+ this._logger.warn("Skipping import; no authorized Octokit for owner.", { location });
3019
+ return null;
3020
+ }
3021
+ const { config, imports, errors } = await this._loadConfigSource(location, octokit);
3022
+ if (errors && errors.length) {
3023
+ this._logger.warn("Skipping import due to YAML parsing errors.", { location, errors });
3024
+ return null;
3025
+ }
3026
+ if (!config) {
3027
+ return null;
3028
+ }
3029
+ const importedConfigs = [];
3030
+ for (const next of imports) {
3031
+ const nested = await this._resolveImportedConfiguration(next, state, depth + 1);
3032
+ if (nested) importedConfigs.push(nested);
3033
+ }
3034
+ const mergedConfig = mergeImportedConfigs(importedConfigs, config);
3035
+ if (!mergedConfig) return null;
3036
+ const decoded = this._decodeConfiguration(location, mergedConfig);
3037
+ resolved = decoded.config;
3038
+ } finally {
3039
+ state.inFlight.delete(key);
3040
+ state.cache.set(key, resolved);
3041
+ }
3042
+ return resolved;
3043
+ }
3044
+ async _download({
3045
+ repository,
3046
+ owner,
3047
+ octokit
3048
+ }) {
2856
3049
  if (!repository || !owner) {
2857
3050
  this._logger.warn("Repo or owner is not defined, cannot download the requested file");
2858
3051
  return null;
2859
3052
  }
2860
- let pathList;
2861
- switch (this._environment) {
2862
- case "development":
2863
- pathList = [CONFIG_DEV_FULL_PATH];
2864
- break;
2865
- case "production":
2866
- pathList = [CONFIG_PROD_FULL_PATH];
2867
- break;
2868
- default:
2869
- pathList = [CONFIG_PROD_FULL_PATH, CONFIG_DEV_FULL_PATH];
2870
- }
3053
+ const pathList = getConfigPathCandidatesForEnvironment(this._environment);
2871
3054
  for (const filePath of pathList) {
2872
3055
  try {
2873
3056
  this._logger.info("Attempting to fetch configuration", { owner, repository, filePath });
2874
- const { data, headers } = await this._octokit.rest.repos.getContent({
3057
+ const { data, headers } = await octokit.rest.repos.getContent({
2875
3058
  owner,
2876
3059
  repo: repository,
2877
3060
  path: filePath,