sf-plugin-permission-sets 0.1.0 → 0.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.
- package/README.md +65 -42
- package/lib/adapters/connection-org-client.d.ts +17 -0
- package/lib/adapters/connection-org-client.d.ts.map +1 -0
- package/lib/adapters/connection-org-client.js +248 -0
- package/lib/adapters/connection-org-client.js.map +1 -0
- package/lib/commands/ps/apply.d.ts +27 -0
- package/lib/commands/ps/apply.d.ts.map +1 -0
- package/lib/commands/ps/apply.js +124 -0
- package/lib/commands/ps/apply.js.map +1 -0
- package/lib/commands/ps/check.d.ts +2 -1
- package/lib/commands/ps/check.d.ts.map +1 -0
- package/lib/commands/ps/check.js +5 -4
- package/lib/commands/ps/check.js.map +1 -1
- package/lib/commands/ps/export.d.ts +17 -0
- package/lib/commands/ps/export.d.ts.map +1 -0
- package/lib/commands/ps/export.js +28 -0
- package/lib/commands/ps/export.js.map +1 -0
- package/lib/commands/ps/plan.d.ts +22 -0
- package/lib/commands/ps/plan.d.ts.map +1 -0
- package/lib/commands/ps/plan.js +77 -0
- package/lib/commands/ps/plan.js.map +1 -0
- package/lib/commands/ps/validate.d.ts +19 -0
- package/lib/commands/ps/validate.d.ts.map +1 -0
- package/lib/commands/ps/validate.js +47 -0
- package/lib/commands/ps/validate.js.map +1 -0
- package/lib/core/diff.d.ts +10 -0
- package/lib/core/diff.d.ts.map +1 -0
- package/lib/core/diff.js +53 -0
- package/lib/core/diff.js.map +1 -0
- package/lib/core/finding.d.ts +40 -0
- package/lib/core/finding.d.ts.map +1 -0
- package/lib/core/finding.js +68 -0
- package/lib/core/finding.js.map +1 -0
- package/lib/core/load.d.ts +2 -6
- package/lib/core/load.d.ts.map +1 -0
- package/lib/core/load.js +6 -5
- package/lib/core/load.js.map +1 -1
- package/lib/core/model.d.ts +57 -7
- package/lib/core/model.d.ts.map +1 -0
- package/lib/core/normalize.d.ts +6 -1
- package/lib/core/normalize.d.ts.map +1 -0
- package/lib/core/normalize.js +46 -29
- package/lib/core/normalize.js.map +1 -1
- package/lib/core/parse.d.ts +2 -1
- package/lib/core/parse.d.ts.map +1 -0
- package/lib/core/parse.js +4 -9
- package/lib/core/parse.js.map +1 -1
- package/lib/core/report.d.ts +8 -8
- package/lib/core/report.d.ts.map +1 -0
- package/lib/core/report.js +59 -12
- package/lib/core/report.js.map +1 -1
- package/lib/core/resolve.d.ts +20 -0
- package/lib/core/resolve.d.ts.map +1 -0
- package/lib/core/resolve.js +88 -0
- package/lib/core/resolve.js.map +1 -0
- package/lib/core/schema.d.ts +18 -5
- package/lib/core/schema.d.ts.map +1 -0
- package/lib/core/schema.js +19 -10
- package/lib/core/schema.js.map +1 -1
- package/lib/core/serialize.d.ts +9 -0
- package/lib/core/serialize.d.ts.map +1 -0
- package/lib/core/serialize.js +34 -0
- package/lib/core/serialize.js.map +1 -0
- package/lib/index.d.ts +1 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/services/adapters/org-client.d.ts +22 -0
- package/lib/services/adapters/org-client.d.ts.map +1 -0
- package/lib/services/adapters/org-client.js +2 -0
- package/lib/services/adapters/org-client.js.map +1 -0
- package/lib/services/apply.d.ts +40 -0
- package/lib/services/apply.d.ts.map +1 -0
- package/lib/services/apply.js +94 -0
- package/lib/services/apply.js.map +1 -0
- package/lib/services/check.d.ts +9 -6
- package/lib/services/check.d.ts.map +1 -0
- package/lib/services/check.js +21 -13
- package/lib/services/check.js.map +1 -1
- package/lib/services/export.d.ts +14 -0
- package/lib/services/export.d.ts.map +1 -0
- package/lib/services/export.js +25 -0
- package/lib/services/export.js.map +1 -0
- package/lib/services/plan.d.ts +35 -0
- package/lib/services/plan.d.ts.map +1 -0
- package/lib/services/plan.js +47 -0
- package/lib/services/plan.js.map +1 -0
- package/lib/services/resolution.d.ts +17 -0
- package/lib/services/resolution.d.ts.map +1 -0
- package/lib/services/resolution.js +36 -0
- package/lib/services/resolution.js.map +1 -0
- package/lib/services/validate.d.ts +21 -0
- package/lib/services/validate.d.ts.map +1 -0
- package/lib/services/validate.js +43 -0
- package/lib/services/validate.js.map +1 -0
- package/messages/ps.apply.md +81 -0
- package/messages/ps.export.md +25 -0
- package/messages/ps.plan.md +45 -0
- package/messages/ps.validate.md +29 -0
- package/package.json +27 -42
- package/lib/commands/ps/info.d.ts +0 -11
- package/lib/commands/ps/info.js +0 -17
- package/lib/commands/ps/info.js.map +0 -1
- package/messages/ps.info.md +0 -17
- package/oclif.lock +0 -7888
- package/oclif.manifest.json +0 -113
package/lib/core/schema.js
CHANGED
|
@@ -1,9 +1,23 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
-
|
|
2
|
+
import { schemaError } from './finding.js';
|
|
3
|
+
// The permission set name
|
|
4
|
+
const name = z.string().min(1);
|
|
5
|
+
// The permission set expiration date
|
|
6
|
+
const expiration = z.iso.datetime({ offset: true });
|
|
7
|
+
/** An entry is either a bare target name or a name with an expiration. */
|
|
8
|
+
const expiringList = z.array(z.union([
|
|
9
|
+
name,
|
|
10
|
+
z.strictObject({
|
|
11
|
+
name,
|
|
12
|
+
expiration,
|
|
13
|
+
}),
|
|
14
|
+
]));
|
|
15
|
+
/** Licenses cannot expire (PermissionSetLicenseAssign has no ExpirationDate), so names only. */
|
|
16
|
+
const plainList = z.array(name);
|
|
3
17
|
export const userEntrySchema = z.strictObject({
|
|
4
|
-
permissionSets:
|
|
5
|
-
permissionSetGroups:
|
|
6
|
-
permissionSetLicenses:
|
|
18
|
+
permissionSets: expiringList.optional(),
|
|
19
|
+
permissionSetGroups: expiringList.optional(),
|
|
20
|
+
permissionSetLicenses: plainList.optional(),
|
|
7
21
|
});
|
|
8
22
|
export const fileSchema = z.strictObject({
|
|
9
23
|
users: z.record(z.string().min(1), userEntrySchema),
|
|
@@ -15,12 +29,7 @@ export function validateFile(data, file) {
|
|
|
15
29
|
return { data: parsed.data, findings: [] };
|
|
16
30
|
}
|
|
17
31
|
return {
|
|
18
|
-
findings: parsed.error.issues.map((issue) => (
|
|
19
|
-
level: 'error',
|
|
20
|
-
code: 'SCHEMA',
|
|
21
|
-
message: `${issue.path.join('.') || '(root)'}: ${issue.message}`,
|
|
22
|
-
file,
|
|
23
|
-
})),
|
|
32
|
+
findings: parsed.error.issues.map((issue) => schemaError(issue.path.join('.') || '(root)', issue.message, file)),
|
|
24
33
|
};
|
|
25
34
|
}
|
|
26
35
|
//# sourceMappingURL=schema.js.map
|
package/lib/core/schema.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/core/schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/core/schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAW,WAAW,EAAE,MAAM,cAAc,CAAC;AAEpD,0BAA0B;AAC1B,MAAM,IAAI,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;AAE/B,qCAAqC;AACrC,MAAM,UAAU,GAAG,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;AAEpD,0EAA0E;AAC1E,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CACxB,CAAC,CAAC,KAAK,CAAC;IACJ,IAAI;IACJ,CAAC,CAAC,YAAY,CAAC;QACX,IAAI;QACJ,UAAU;KACb,CAAC;CACL,CAAC,CACL,CAAC;AAEF,gGAAgG;AAChG,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;AAEhC,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,CAAC,YAAY,CAAC;IAC1C,cAAc,EAAE,YAAY,CAAC,QAAQ,EAAE;IACvC,mBAAmB,EAAE,YAAY,CAAC,QAAQ,EAAE;IAC5C,qBAAqB,EAAE,SAAS,CAAC,QAAQ,EAAE;CAC9C,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,CAAC,YAAY,CAAC;IACrC,KAAK,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,eAAe,CAAC;CACtD,CAAC,CAAC;AAIH,wFAAwF;AACxF,MAAM,UAAU,YAAY,CAAC,IAAa,EAAE,IAAY;IACpD,MAAM,MAAM,GAAG,UAAU,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IAC1C,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;QACjB,OAAO,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC;IAC/C,CAAC;IACD,OAAO;QACH,QAAQ,EAAE,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CACxC,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,QAAQ,EAAE,KAAK,CAAC,OAAO,EAAE,IAAI,CAAC,CACrE;KACJ,CAAC;AACN,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { DesiredAssignment } from './model.js';
|
|
2
|
+
/**
|
|
3
|
+
* Emit canonical assignments back to a user-keyed YAML document: the inverse of
|
|
4
|
+
* normalize. Usernames and targets are sorted and de-duplicated so the output is
|
|
5
|
+
* deterministic, empty scopes are omitted, and an assignment with an expiration
|
|
6
|
+
* is written as the object form so it round-trips through the schema.
|
|
7
|
+
*/
|
|
8
|
+
export declare function serializeAssignments(assignments: DesiredAssignment[]): string;
|
|
9
|
+
//# sourceMappingURL=serialize.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serialize.d.ts","sourceRoot":"","sources":["../../src/core/serialize.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAS/C;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,iBAAiB,EAAE,GAAG,MAAM,CAiC7E"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { stringify } from 'yaml';
|
|
2
|
+
import { kindKeys } from './normalize.js';
|
|
3
|
+
/**
|
|
4
|
+
* Emit canonical assignments back to a user-keyed YAML document: the inverse of
|
|
5
|
+
* normalize. Usernames and targets are sorted and de-duplicated so the output is
|
|
6
|
+
* deterministic, empty scopes are omitted, and an assignment with an expiration
|
|
7
|
+
* is written as the object form so it round-trips through the schema.
|
|
8
|
+
*/
|
|
9
|
+
export function serializeAssignments(assignments) {
|
|
10
|
+
const usernames = [...new Set(assignments.map((assignment) => assignment.assignee))].sort();
|
|
11
|
+
const users = {};
|
|
12
|
+
for (const username of usernames) {
|
|
13
|
+
const entry = {};
|
|
14
|
+
for (const [kind, key] of kindKeys) {
|
|
15
|
+
const matching = assignments.filter((assignment) => assignment.assignee === username && assignment.kind === kind);
|
|
16
|
+
const expirationByTarget = new Map();
|
|
17
|
+
for (const assignment of matching) {
|
|
18
|
+
if (!expirationByTarget.has(assignment.target)) {
|
|
19
|
+
expirationByTarget.set(assignment.target, assignment.expiration);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
const entries = [...expirationByTarget.keys()].sort().map((target) => {
|
|
23
|
+
const expiration = expirationByTarget.get(target);
|
|
24
|
+
return expiration ? { name: target, expiration } : target;
|
|
25
|
+
});
|
|
26
|
+
if (entries.length > 0) {
|
|
27
|
+
entry[key] = entries;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
users[username] = entry;
|
|
31
|
+
}
|
|
32
|
+
return stringify({ users });
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=serialize.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serialize.js","sourceRoot":"","sources":["../../src/core/serialize.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,MAAM,CAAC;AAEjC,OAAO,EAAE,QAAQ,EAAY,MAAM,gBAAgB,CAAC;AAQpD;;;;;GAKG;AACH,MAAM,UAAU,oBAAoB,CAAC,WAAgC;IACjE,MAAM,SAAS,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IAC5F,MAAM,KAAK,GAAwB,EAAE,CAAC;IAEtC,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;QAC/B,MAAM,KAAK,GAAgC,EAAE,CAAC;QAE9C,KAAK,MAAM,CAAC,IAAI,EAAE,GAAG,CAAC,IAAI,QAAQ,EAAE,CAAC;YACjC,MAAM,QAAQ,GAAG,WAAW,CAAC,MAAM,CAC/B,CAAC,UAAU,EAAE,EAAE,CAAC,UAAU,CAAC,QAAQ,KAAK,QAAQ,IAAI,UAAU,CAAC,IAAI,KAAK,IAAI,CAC/E,CAAC;YAEF,MAAM,kBAAkB,GAAG,IAAI,GAAG,EAA8B,CAAC;YACjE,KAAK,MAAM,UAAU,IAAI,QAAQ,EAAE,CAAC;gBAChC,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;oBAC7C,kBAAkB,CAAC,GAAG,CAAC,UAAU,CAAC,MAAM,EAAE,UAAU,CAAC,UAAU,CAAC,CAAC;gBACrE,CAAC;YACL,CAAC;YAED,MAAM,OAAO,GAAsB,CAAC,GAAG,kBAAkB,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE;gBACpF,MAAM,UAAU,GAAG,kBAAkB,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;gBAClD,OAAO,UAAU,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC;YAC9D,CAAC,CAAC,CAAC;YAEH,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACrB,KAAK,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC;YACzB,CAAC;QACL,CAAC;QAED,KAAK,CAAC,QAAQ,CAAC,GAAG,KAAK,CAAC;IAC5B,CAAC;IAED,OAAO,SAAS,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;AAChC,CAAC"}
|
package/lib/index.d.ts
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA,wBAAkB"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { ActualAssignment, AssignmentOutcome, AssignmentUpdate, DesiredAssignment, Kind, OrgTarget, OrgUser, ResolvedAddition, TargetRef } from '../../core/model.js';
|
|
2
|
+
/**
|
|
3
|
+
* Port: the org operations a service needs, in domain terms. Declared here, by the
|
|
4
|
+
* consumer, so services depend on the abstraction and the adapter implements it.
|
|
5
|
+
*/
|
|
6
|
+
export interface OrgClient {
|
|
7
|
+
/** The users that exist in the org, among the given usernames. */
|
|
8
|
+
findUsers(usernames: string[]): Promise<OrgUser[]>;
|
|
9
|
+
/** The targets (with ids) that exist in the org, among the given names of one kind. */
|
|
10
|
+
findTargets(kind: Kind, names: string[]): Promise<OrgTarget[]>;
|
|
11
|
+
/** Every assignable permission set, group, and license assignment held by active users. */
|
|
12
|
+
listAssignments(): Promise<DesiredAssignment[]>;
|
|
13
|
+
/** The current assignments of the given managed targets, with their record ids. */
|
|
14
|
+
currentAssignments(targets: TargetRef[]): Promise<ActualAssignment[]>;
|
|
15
|
+
/** Insert the given assignments, reporting per-record success or failure. */
|
|
16
|
+
addAssignments(additions: ResolvedAddition[]): Promise<AssignmentOutcome[]>;
|
|
17
|
+
/** Update the expiration of the given assignments, reporting per-record success or failure. */
|
|
18
|
+
updateAssignments(updates: AssignmentUpdate[]): Promise<AssignmentOutcome[]>;
|
|
19
|
+
/** Delete the given assignments by record id, reporting per-record success or failure. */
|
|
20
|
+
removeAssignments(removals: ActualAssignment[]): Promise<AssignmentOutcome[]>;
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=org-client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"org-client.d.ts","sourceRoot":"","sources":["../../../src/services/adapters/org-client.ts"],"names":[],"mappings":"AAAA,OAAO,EACH,gBAAgB,EAChB,iBAAiB,EACjB,gBAAgB,EAChB,iBAAiB,EACjB,IAAI,EACJ,SAAS,EACT,OAAO,EACP,gBAAgB,EAChB,SAAS,EACZ,MAAM,qBAAqB,CAAC;AAE7B;;;GAGG;AACH,MAAM,WAAW,SAAS;IACtB,kEAAkE;IAClE,SAAS,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;IACnD,uFAAuF;IACvF,WAAW,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC;IAC/D,2FAA2F;IAC3F,eAAe,IAAI,OAAO,CAAC,iBAAiB,EAAE,CAAC,CAAC;IAChD,mFAAmF;IACnF,kBAAkB,CAAC,OAAO,EAAE,SAAS,EAAE,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAAC;IACtE,6EAA6E;IAC7E,cAAc,CAAC,SAAS,EAAE,gBAAgB,EAAE,GAAG,OAAO,CAAC,iBAAiB,EAAE,CAAC,CAAC;IAC5E,+FAA+F;IAC/F,iBAAiB,CAAC,OAAO,EAAE,gBAAgB,EAAE,GAAG,OAAO,CAAC,iBAAiB,EAAE,CAAC,CAAC;IAC7E,0FAA0F;IAC1F,iBAAiB,CAAC,QAAQ,EAAE,gBAAgB,EAAE,GAAG,OAAO,CAAC,iBAAiB,EAAE,CAAC,CAAC;CACjF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"org-client.js","sourceRoot":"","sources":["../../../src/services/adapters/org-client.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { AssignmentOutcome, Diff } from '../core/model.js';
|
|
2
|
+
import { Finding } from '../core/finding.js';
|
|
3
|
+
import { OrgClient } from './adapters/org-client.js';
|
|
4
|
+
export type ApplyMode = 'additive' | 'destructive' | 'sync';
|
|
5
|
+
export type ApplyInput = {
|
|
6
|
+
mode: ApplyMode;
|
|
7
|
+
maxDeletes: number;
|
|
8
|
+
dryRun: boolean;
|
|
9
|
+
};
|
|
10
|
+
/** How a run ended, so the command can report and set the exit code. */
|
|
11
|
+
export type ApplyStatus = 'applied' | 'dry-run' | 'declined' | 'max-deletes-exceeded' | 'invalid';
|
|
12
|
+
export type ApplyResult = {
|
|
13
|
+
files: string[];
|
|
14
|
+
findings: Finding[];
|
|
15
|
+
diff: Diff;
|
|
16
|
+
/** What the chosen mode did not act on (surfaced as drift). */
|
|
17
|
+
drift: {
|
|
18
|
+
adds: number;
|
|
19
|
+
updates: number;
|
|
20
|
+
removes: number;
|
|
21
|
+
};
|
|
22
|
+
outcomes: AssignmentOutcome[];
|
|
23
|
+
status: ApplyStatus;
|
|
24
|
+
failed: boolean;
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* Online apply: load the files, resolve every reference to an org id, diff against
|
|
28
|
+
* the org's current state, then add and/or remove per the mode. Deletions are
|
|
29
|
+
* capped by maxDeletes and gated by an injected confirmation.
|
|
30
|
+
*/
|
|
31
|
+
export declare class ApplyService {
|
|
32
|
+
private readonly org;
|
|
33
|
+
private readonly files;
|
|
34
|
+
private readonly input;
|
|
35
|
+
private readonly confirmDeletions;
|
|
36
|
+
constructor(org: OrgClient, files: string[], input: ApplyInput, confirmDeletions: (count: number) => Promise<boolean>);
|
|
37
|
+
run(): Promise<ApplyResult>;
|
|
38
|
+
private execute;
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=apply.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"apply.d.ts","sourceRoot":"","sources":["../../src/services/apply.ts"],"names":[],"mappings":"AAEA,OAAO,EAEH,iBAAiB,EAGjB,IAAI,EAEP,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,OAAO,EAAiB,MAAM,oBAAoB,CAAC;AAC5D,OAAO,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAGrD,MAAM,MAAM,SAAS,GAAG,UAAU,GAAG,aAAa,GAAG,MAAM,CAAC;AAE5D,MAAM,MAAM,UAAU,GAAG;IACrB,IAAI,EAAE,SAAS,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,OAAO,CAAC;CACnB,CAAC;AAEF,wEAAwE;AACxE,MAAM,MAAM,WAAW,GAAG,SAAS,GAAG,SAAS,GAAG,UAAU,GAAG,sBAAsB,GAAG,SAAS,CAAC;AAElG,MAAM,MAAM,WAAW,GAAG;IACtB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,IAAI,EAAE,IAAI,CAAC;IACX,+DAA+D;IAC/D,KAAK,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IAC1D,QAAQ,EAAE,iBAAiB,EAAE,CAAC;IAC9B,MAAM,EAAE,WAAW,CAAC;IACpB,MAAM,EAAE,OAAO,CAAC;CACnB,CAAC;AAiBF;;;;GAIG;AACH,qBAAa,YAAY;IAEjB,OAAO,CAAC,QAAQ,CAAC,GAAG;IACpB,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,gBAAgB;gBAHhB,GAAG,EAAE,SAAS,EACd,KAAK,EAAE,MAAM,EAAE,EACf,KAAK,EAAE,UAAU,EACjB,gBAAgB,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC;IAG7D,GAAG,IAAI,OAAO,CAAC,WAAW,CAAC;YAuD1B,OAAO;CAoBxB"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { loadFiles } from '../core/load.js';
|
|
2
|
+
import { diffAssignments } from '../core/diff.js';
|
|
3
|
+
import { countFindings } from '../core/finding.js';
|
|
4
|
+
import { ResolutionService, managedTargets } from './resolution.js';
|
|
5
|
+
const emptyDiff = { toAdd: [], toUpdate: [], toRemove: [], unchanged: [] };
|
|
6
|
+
/** An aborted-before-any-change result, carrying the findings that explain why. */
|
|
7
|
+
function invalidResult(files, findings) {
|
|
8
|
+
return {
|
|
9
|
+
files,
|
|
10
|
+
findings,
|
|
11
|
+
diff: emptyDiff,
|
|
12
|
+
drift: { adds: 0, updates: 0, removes: 0 },
|
|
13
|
+
outcomes: [],
|
|
14
|
+
status: 'invalid',
|
|
15
|
+
failed: true,
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Online apply: load the files, resolve every reference to an org id, diff against
|
|
20
|
+
* the org's current state, then add and/or remove per the mode. Deletions are
|
|
21
|
+
* capped by maxDeletes and gated by an injected confirmation.
|
|
22
|
+
*/
|
|
23
|
+
export class ApplyService {
|
|
24
|
+
org;
|
|
25
|
+
files;
|
|
26
|
+
input;
|
|
27
|
+
confirmDeletions;
|
|
28
|
+
constructor(org, files, input, confirmDeletions) {
|
|
29
|
+
this.org = org;
|
|
30
|
+
this.files = files;
|
|
31
|
+
this.input = input;
|
|
32
|
+
this.confirmDeletions = confirmDeletions;
|
|
33
|
+
}
|
|
34
|
+
async run() {
|
|
35
|
+
const loaded = await loadFiles(this.files);
|
|
36
|
+
if (countFindings(loaded.findings).errors > 0) {
|
|
37
|
+
return invalidResult(loaded.files, loaded.findings);
|
|
38
|
+
}
|
|
39
|
+
const resolutionService = new ResolutionService(this.org, loaded.assignments);
|
|
40
|
+
const resolution = await resolutionService.run();
|
|
41
|
+
const findings = [...loaded.findings, ...resolution.findings];
|
|
42
|
+
if (countFindings(findings).errors > 0) {
|
|
43
|
+
return invalidResult(loaded.files, findings);
|
|
44
|
+
}
|
|
45
|
+
const actual = await this.org.currentAssignments(managedTargets(resolution));
|
|
46
|
+
const diff = diffAssignments(loaded.assignments, actual);
|
|
47
|
+
const { mode, maxDeletes, dryRun } = this.input;
|
|
48
|
+
const additions = mode === 'destructive' ? [] : diff.toAdd;
|
|
49
|
+
const updates = mode === 'destructive' ? [] : diff.toUpdate;
|
|
50
|
+
const removals = mode === 'additive' ? [] : diff.toRemove;
|
|
51
|
+
const drift = {
|
|
52
|
+
adds: mode === 'destructive' ? diff.toAdd.length : 0,
|
|
53
|
+
updates: mode === 'destructive' ? diff.toUpdate.length : 0,
|
|
54
|
+
removes: mode === 'additive' ? diff.toRemove.length : 0,
|
|
55
|
+
};
|
|
56
|
+
if (removals.length > maxDeletes) {
|
|
57
|
+
return {
|
|
58
|
+
files: loaded.files,
|
|
59
|
+
findings,
|
|
60
|
+
diff,
|
|
61
|
+
drift,
|
|
62
|
+
outcomes: [],
|
|
63
|
+
status: 'max-deletes-exceeded',
|
|
64
|
+
failed: true,
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
if (dryRun) {
|
|
68
|
+
return { files: loaded.files, findings, diff, drift, outcomes: [], status: 'dry-run', failed: false };
|
|
69
|
+
}
|
|
70
|
+
if (removals.length > 0) {
|
|
71
|
+
const confirmed = await this.confirmDeletions(removals.length);
|
|
72
|
+
if (!confirmed) {
|
|
73
|
+
return { files: loaded.files, findings, diff, drift, outcomes: [], status: 'declined', failed: false };
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
const outcomes = await this.execute(additions, updates, removals, resolution);
|
|
77
|
+
const failed = outcomes.some((outcome) => !outcome.success);
|
|
78
|
+
return { files: loaded.files, findings, diff, drift, outcomes, status: 'applied', failed };
|
|
79
|
+
}
|
|
80
|
+
async execute(additions, updates, removals, resolution) {
|
|
81
|
+
const resolved = additions.map((addition) => ({
|
|
82
|
+
...addition,
|
|
83
|
+
assigneeId: resolution.userIds.get(addition.assignee.toLowerCase()) ?? '',
|
|
84
|
+
targetId: resolution.targetIds[addition.kind].get(addition.target.toLowerCase()) ?? '',
|
|
85
|
+
}));
|
|
86
|
+
const [added, updated, removed] = await Promise.all([
|
|
87
|
+
resolved.length > 0 ? this.org.addAssignments(resolved) : Promise.resolve([]),
|
|
88
|
+
updates.length > 0 ? this.org.updateAssignments(updates) : Promise.resolve([]),
|
|
89
|
+
removals.length > 0 ? this.org.removeAssignments(removals) : Promise.resolve([]),
|
|
90
|
+
]);
|
|
91
|
+
return [...added, ...updated, ...removed];
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
//# sourceMappingURL=apply.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"apply.js","sourceRoot":"","sources":["../../src/services/apply.ts"],"names":[],"mappings":"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"}
|
package/lib/services/check.d.ts
CHANGED
|
@@ -1,8 +1,5 @@
|
|
|
1
|
-
import { DesiredAssignment
|
|
2
|
-
|
|
3
|
-
files: string[];
|
|
4
|
-
strict: boolean;
|
|
5
|
-
};
|
|
1
|
+
import { DesiredAssignment } from '../core/model.js';
|
|
2
|
+
import { Finding } from '../core/finding.js';
|
|
6
3
|
export type CheckResult = {
|
|
7
4
|
files: string[];
|
|
8
5
|
assignments: DesiredAssignment[];
|
|
@@ -12,4 +9,10 @@ export type CheckResult = {
|
|
|
12
9
|
failed: boolean;
|
|
13
10
|
};
|
|
14
11
|
/** Offline check: load the files, validate them, and summarize the findings. */
|
|
15
|
-
export declare
|
|
12
|
+
export declare class CheckService {
|
|
13
|
+
private readonly files;
|
|
14
|
+
private readonly strict;
|
|
15
|
+
constructor(files: string[], strict: boolean);
|
|
16
|
+
run(): Promise<CheckResult>;
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=check.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"check.d.ts","sourceRoot":"","sources":["../../src/services/check.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,OAAO,EAAiB,MAAM,oBAAoB,CAAC;AAE5D,MAAM,MAAM,WAAW,GAAG;IACtB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,WAAW,EAAE,iBAAiB,EAAE,CAAC;IACjC,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,OAAO,CAAC;CACnB,CAAC;AAEF,gFAAgF;AAChF,qBAAa,YAAY;IACF,OAAO,CAAC,QAAQ,CAAC,KAAK;IAAY,OAAO,CAAC,QAAQ,CAAC,MAAM;gBAAxC,KAAK,EAAE,MAAM,EAAE,EAAmB,MAAM,EAAE,OAAO;IAExE,GAAG,IAAI,OAAO,CAAC,WAAW,CAAC;CAc3C"}
|
package/lib/services/check.js
CHANGED
|
@@ -1,17 +1,25 @@
|
|
|
1
1
|
import { loadFiles } from '../core/load.js';
|
|
2
|
-
import { countFindings } from '../core/
|
|
2
|
+
import { countFindings } from '../core/finding.js';
|
|
3
3
|
/** Offline check: load the files, validate them, and summarize the findings. */
|
|
4
|
-
export
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
warnings
|
|
14
|
-
failed
|
|
15
|
-
|
|
4
|
+
export class CheckService {
|
|
5
|
+
files;
|
|
6
|
+
strict;
|
|
7
|
+
constructor(files, strict) {
|
|
8
|
+
this.files = files;
|
|
9
|
+
this.strict = strict;
|
|
10
|
+
}
|
|
11
|
+
async run() {
|
|
12
|
+
const loaded = await loadFiles(this.files);
|
|
13
|
+
const { errors, warnings } = countFindings(loaded.findings);
|
|
14
|
+
const failed = errors > 0 || (this.strict && warnings > 0);
|
|
15
|
+
return {
|
|
16
|
+
files: loaded.files,
|
|
17
|
+
assignments: loaded.assignments,
|
|
18
|
+
findings: loaded.findings,
|
|
19
|
+
errors,
|
|
20
|
+
warnings,
|
|
21
|
+
failed,
|
|
22
|
+
};
|
|
23
|
+
}
|
|
16
24
|
}
|
|
17
25
|
//# sourceMappingURL=check.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"check.js","sourceRoot":"","sources":["../../src/services/check.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"check.js","sourceRoot":"","sources":["../../src/services/check.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAE5C,OAAO,EAAW,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAW5D,gFAAgF;AAChF,MAAM,OAAO,YAAY;IACe;IAAkC;IAAtE,YAAoC,KAAe,EAAmB,MAAe;QAAjD,UAAK,GAAL,KAAK,CAAU;QAAmB,WAAM,GAAN,MAAM,CAAS;IAAG,CAAC;IAElF,KAAK,CAAC,GAAG;QACZ,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC3C,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,aAAa,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QAC5D,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,IAAI,QAAQ,GAAG,CAAC,CAAC,CAAC;QAE3D,OAAO;YACH,KAAK,EAAE,MAAM,CAAC,KAAK;YACnB,WAAW,EAAE,MAAM,CAAC,WAAW;YAC/B,QAAQ,EAAE,MAAM,CAAC,QAAQ;YACzB,MAAM;YACN,QAAQ;YACR,MAAM;SACT,CAAC;IACN,CAAC;CACJ"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { OrgClient } from './adapters/org-client.js';
|
|
2
|
+
export type ExportResult = {
|
|
3
|
+
outputFile: string;
|
|
4
|
+
users: number;
|
|
5
|
+
assignments: number;
|
|
6
|
+
};
|
|
7
|
+
/** Online export: read the org's current assignments and write them as a YAML file. */
|
|
8
|
+
export declare class ExportService {
|
|
9
|
+
private readonly org;
|
|
10
|
+
private readonly outputFile;
|
|
11
|
+
constructor(org: OrgClient, outputFile: string);
|
|
12
|
+
run(): Promise<ExportResult>;
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=export.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"export.d.ts","sourceRoot":"","sources":["../../src/services/export.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAErD,MAAM,MAAM,YAAY,GAAG;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;CACvB,CAAC;AAEF,uFAAuF;AACvF,qBAAa,aAAa;IACH,OAAO,CAAC,QAAQ,CAAC,GAAG;IAAa,OAAO,CAAC,QAAQ,CAAC,UAAU;gBAA3C,GAAG,EAAE,SAAS,EAAmB,UAAU,EAAE,MAAM;IAE1E,GAAG,IAAI,OAAO,CAAC,YAAY,CAAC;CAe5C"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { writeFile, mkdir } from 'node:fs/promises';
|
|
2
|
+
import { dirname } from 'node:path';
|
|
3
|
+
import { serializeAssignments } from '../core/serialize.js';
|
|
4
|
+
/** Online export: read the org's current assignments and write them as a YAML file. */
|
|
5
|
+
export class ExportService {
|
|
6
|
+
org;
|
|
7
|
+
outputFile;
|
|
8
|
+
constructor(org, outputFile) {
|
|
9
|
+
this.org = org;
|
|
10
|
+
this.outputFile = outputFile;
|
|
11
|
+
}
|
|
12
|
+
async run() {
|
|
13
|
+
const assignments = await this.org.listAssignments();
|
|
14
|
+
const content = serializeAssignments(assignments);
|
|
15
|
+
await mkdir(dirname(this.outputFile), { recursive: true });
|
|
16
|
+
await writeFile(this.outputFile, content, 'utf8');
|
|
17
|
+
const assignees = new Set(assignments.map((assignment) => assignment.assignee));
|
|
18
|
+
return {
|
|
19
|
+
outputFile: this.outputFile,
|
|
20
|
+
users: assignees.size,
|
|
21
|
+
assignments: assignments.length,
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=export.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"export.js","sourceRoot":"","sources":["../../src/services/export.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAS5D,uFAAuF;AACvF,MAAM,OAAO,aAAa;IACc;IAAiC;IAArE,YAAoC,GAAc,EAAmB,UAAkB;QAAnD,QAAG,GAAH,GAAG,CAAW;QAAmB,eAAU,GAAV,UAAU,CAAQ;IAAG,CAAC;IAEpF,KAAK,CAAC,GAAG;QACZ,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,eAAe,EAAE,CAAC;QACrD,MAAM,OAAO,GAAG,oBAAoB,CAAC,WAAW,CAAC,CAAC;QAElD,MAAM,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC3D,MAAM,SAAS,CAAC,IAAI,CAAC,UAAU,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;QAElD,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC;QAEhF,OAAO;YACH,UAAU,EAAE,IAAI,CAAC,UAAU;YAC3B,KAAK,EAAE,SAAS,CAAC,IAAI;YACrB,WAAW,EAAE,WAAW,CAAC,MAAM;SAClC,CAAC;IACN,CAAC;CACJ"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { Diff } from '../core/model.js';
|
|
2
|
+
import { Finding } from '../core/finding.js';
|
|
3
|
+
import { OrgClient } from './adapters/org-client.js';
|
|
4
|
+
export type PlanMode = 'additive' | 'destructive' | 'sync';
|
|
5
|
+
export type PlanInput = {
|
|
6
|
+
mode: PlanMode;
|
|
7
|
+
};
|
|
8
|
+
/** How a run ended, so the command can report and set the exit code. */
|
|
9
|
+
export type PlanStatus = 'planned' | 'invalid';
|
|
10
|
+
export type PlanResult = {
|
|
11
|
+
files: string[];
|
|
12
|
+
findings: Finding[];
|
|
13
|
+
diff: Diff;
|
|
14
|
+
/** What the chosen mode would not act on (surfaced as drift). */
|
|
15
|
+
drift: {
|
|
16
|
+
adds: number;
|
|
17
|
+
updates: number;
|
|
18
|
+
removes: number;
|
|
19
|
+
};
|
|
20
|
+
status: PlanStatus;
|
|
21
|
+
};
|
|
22
|
+
/**
|
|
23
|
+
* Read-only preview: load the files, resolve every reference to an org id, fetch the
|
|
24
|
+
* current state, and diff. The full diff (adds and would-be removes) is always returned
|
|
25
|
+
* regardless of mode; drift is whatever the chosen mode would not act on. Never changes
|
|
26
|
+
* the org. This is the apply pipeline stopping before any DML.
|
|
27
|
+
*/
|
|
28
|
+
export declare class PlanService {
|
|
29
|
+
private readonly org;
|
|
30
|
+
private readonly files;
|
|
31
|
+
private readonly input;
|
|
32
|
+
constructor(org: OrgClient, files: string[], input: PlanInput);
|
|
33
|
+
run(): Promise<PlanResult>;
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=plan.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plan.d.ts","sourceRoot":"","sources":["../../src/services/plan.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AACxC,OAAO,EAAE,OAAO,EAAiB,MAAM,oBAAoB,CAAC;AAC5D,OAAO,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAGrD,MAAM,MAAM,QAAQ,GAAG,UAAU,GAAG,aAAa,GAAG,MAAM,CAAC;AAE3D,MAAM,MAAM,SAAS,GAAG;IACpB,IAAI,EAAE,QAAQ,CAAC;CAClB,CAAC;AAEF,wEAAwE;AACxE,MAAM,MAAM,UAAU,GAAG,SAAS,GAAG,SAAS,CAAC;AAE/C,MAAM,MAAM,UAAU,GAAG;IACrB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,IAAI,EAAE,IAAI,CAAC;IACX,iEAAiE;IACjE,KAAK,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IAC1D,MAAM,EAAE,UAAU,CAAC;CACtB,CAAC;AASF;;;;;GAKG;AACH,qBAAa,WAAW;IAEhB,OAAO,CAAC,QAAQ,CAAC,GAAG;IACpB,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,KAAK;gBAFL,GAAG,EAAE,SAAS,EACd,KAAK,EAAE,MAAM,EAAE,EACf,KAAK,EAAE,SAAS;IAGxB,GAAG,IAAI,OAAO,CAAC,UAAU,CAAC;CAwB1C"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { loadFiles } from '../core/load.js';
|
|
2
|
+
import { diffAssignments } from '../core/diff.js';
|
|
3
|
+
import { countFindings } from '../core/finding.js';
|
|
4
|
+
import { ResolutionService, managedTargets } from './resolution.js';
|
|
5
|
+
const emptyDiff = { toAdd: [], toUpdate: [], toRemove: [], unchanged: [] };
|
|
6
|
+
/** An aborted-before-the-diff result, carrying the findings that explain why. */
|
|
7
|
+
function invalidResult(files, findings) {
|
|
8
|
+
return { files, findings, diff: emptyDiff, drift: { adds: 0, updates: 0, removes: 0 }, status: 'invalid' };
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Read-only preview: load the files, resolve every reference to an org id, fetch the
|
|
12
|
+
* current state, and diff. The full diff (adds and would-be removes) is always returned
|
|
13
|
+
* regardless of mode; drift is whatever the chosen mode would not act on. Never changes
|
|
14
|
+
* the org. This is the apply pipeline stopping before any DML.
|
|
15
|
+
*/
|
|
16
|
+
export class PlanService {
|
|
17
|
+
org;
|
|
18
|
+
files;
|
|
19
|
+
input;
|
|
20
|
+
constructor(org, files, input) {
|
|
21
|
+
this.org = org;
|
|
22
|
+
this.files = files;
|
|
23
|
+
this.input = input;
|
|
24
|
+
}
|
|
25
|
+
async run() {
|
|
26
|
+
const loaded = await loadFiles(this.files);
|
|
27
|
+
if (countFindings(loaded.findings).errors > 0) {
|
|
28
|
+
return invalidResult(loaded.files, loaded.findings);
|
|
29
|
+
}
|
|
30
|
+
const resolutionService = new ResolutionService(this.org, loaded.assignments);
|
|
31
|
+
const resolution = await resolutionService.run();
|
|
32
|
+
const findings = [...loaded.findings, ...resolution.findings];
|
|
33
|
+
if (countFindings(findings).errors > 0) {
|
|
34
|
+
return invalidResult(loaded.files, findings);
|
|
35
|
+
}
|
|
36
|
+
const actual = await this.org.currentAssignments(managedTargets(resolution));
|
|
37
|
+
const diff = diffAssignments(loaded.assignments, actual);
|
|
38
|
+
const { mode } = this.input;
|
|
39
|
+
const drift = {
|
|
40
|
+
adds: mode === 'destructive' ? diff.toAdd.length : 0,
|
|
41
|
+
updates: mode === 'destructive' ? diff.toUpdate.length : 0,
|
|
42
|
+
removes: mode === 'additive' ? diff.toRemove.length : 0,
|
|
43
|
+
};
|
|
44
|
+
return { files: loaded.files, findings, diff, drift, status: 'planned' };
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=plan.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plan.js","sourceRoot":"","sources":["../../src/services/plan.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAElD,OAAO,EAAW,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAE5D,OAAO,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAoBpE,MAAM,SAAS,GAAS,EAAE,KAAK,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,SAAS,EAAE,EAAE,EAAE,CAAC;AAEjF,iFAAiF;AACjF,SAAS,aAAa,CAAC,KAAe,EAAE,QAAmB;IACvD,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC;AAC/G,CAAC;AAED;;;;;GAKG;AACH,MAAM,OAAO,WAAW;IAEC;IACA;IACA;IAHrB,YACqB,GAAc,EACd,KAAe,EACf,KAAgB;QAFhB,QAAG,GAAH,GAAG,CAAW;QACd,UAAK,GAAL,KAAK,CAAU;QACf,UAAK,GAAL,KAAK,CAAW;IAClC,CAAC;IAEG,KAAK,CAAC,GAAG;QACZ,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC3C,IAAI,aAAa,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC5C,OAAO,aAAa,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC;QACxD,CAAC;QAED,MAAM,iBAAiB,GAAG,IAAI,iBAAiB,CAAC,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC,WAAW,CAAC,CAAC;QAC9E,MAAM,UAAU,GAAG,MAAM,iBAAiB,CAAC,GAAG,EAAE,CAAC;QACjD,MAAM,QAAQ,GAAG,CAAC,GAAG,MAAM,CAAC,QAAQ,EAAE,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC;QAC9D,IAAI,aAAa,CAAC,QAAQ,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACrC,OAAO,aAAa,CAAC,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;QACjD,CAAC;QAED,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,kBAAkB,CAAC,cAAc,CAAC,UAAU,CAAC,CAAC,CAAC;QAC7E,MAAM,IAAI,GAAG,eAAe,CAAC,MAAM,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;QACzD,MAAM,EAAE,IAAI,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC;QAC5B,MAAM,KAAK,GAAG;YACV,IAAI,EAAE,IAAI,KAAK,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;YACpD,OAAO,EAAE,IAAI,KAAK,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;YAC1D,OAAO,EAAE,IAAI,KAAK,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;SAC1D,CAAC;QAEF,OAAO,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC;IAC7E,CAAC;CACJ"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { DesiredAssignment, Kind, TargetRef } from '../core/model.js';
|
|
2
|
+
import { Finding } from '../core/finding.js';
|
|
3
|
+
import { OrgClient } from './adapters/org-client.js';
|
|
4
|
+
export type Resolution = {
|
|
5
|
+
findings: Finding[];
|
|
6
|
+
userIds: Map<string, string>;
|
|
7
|
+
targetIds: Record<Kind, Map<string, string>>;
|
|
8
|
+
};
|
|
9
|
+
export declare function managedTargets(resolution: Resolution): TargetRef[];
|
|
10
|
+
/** Look every declared reference up in the org, returning findings and the resolved id maps. */
|
|
11
|
+
export declare class ResolutionService {
|
|
12
|
+
private readonly org;
|
|
13
|
+
private readonly assignments;
|
|
14
|
+
constructor(org: OrgClient, assignments: DesiredAssignment[]);
|
|
15
|
+
run(): Promise<Resolution>;
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=resolution.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolution.d.ts","sourceRoot":"","sources":["../../src/services/resolution.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,IAAI,EAAsB,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC1F,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAU7C,OAAO,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAErD,MAAM,MAAM,UAAU,GAAG;IACrB,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,SAAS,EAAE,MAAM,CAAC,IAAI,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;CAChD,CAAC;AAEF,wBAAgB,cAAc,CAAC,UAAU,EAAE,UAAU,GAAG,SAAS,EAAE,CAQlE;AAED,gGAAgG;AAChG,qBAAa,iBAAiB;IACP,OAAO,CAAC,QAAQ,CAAC,GAAG;IAAa,OAAO,CAAC,QAAQ,CAAC,WAAW;gBAA5C,GAAG,EAAE,SAAS,EAAmB,WAAW,EAAE,iBAAiB,EAAE;IAExF,GAAG,IAAI,OAAO,CAAC,UAAU,CAAC;CAkC1C"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { kinds, distinctAssignees, distinctTargets, evaluateUsers, evaluateTargets, indexUsersById, indexTargetsById, } from '../core/resolve.js';
|
|
2
|
+
export function managedTargets(resolution) {
|
|
3
|
+
const refs = [];
|
|
4
|
+
for (const kind of kinds) {
|
|
5
|
+
for (const id of resolution.targetIds[kind].values()) {
|
|
6
|
+
refs.push({ kind, id });
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
return refs;
|
|
10
|
+
}
|
|
11
|
+
/** Look every declared reference up in the org, returning findings and the resolved id maps. */
|
|
12
|
+
export class ResolutionService {
|
|
13
|
+
org;
|
|
14
|
+
assignments;
|
|
15
|
+
constructor(org, assignments) {
|
|
16
|
+
this.org = org;
|
|
17
|
+
this.assignments = assignments;
|
|
18
|
+
}
|
|
19
|
+
async run() {
|
|
20
|
+
const usernames = distinctAssignees(this.assignments);
|
|
21
|
+
const targetsByKind = kinds.map((kind) => ({ kind, targets: distinctTargets(this.assignments, kind) }));
|
|
22
|
+
const usersTask = usernames.length > 0 ? this.org.findUsers(usernames) : Promise.resolve([]);
|
|
23
|
+
const targetsTask = Promise.all(targetsByKind.map(({ kind, targets }) => (targets.length > 0 ? this.org.findTargets(kind, targets) : Promise.resolve([])).then((found) => ({ kind, targets, found }))));
|
|
24
|
+
const [foundUsers, perKind] = await Promise.all([usersTask, targetsTask]);
|
|
25
|
+
const findings = [...evaluateUsers(usernames, foundUsers)];
|
|
26
|
+
for (const { kind, targets, found } of perKind) {
|
|
27
|
+
findings.push(...evaluateTargets(kind, targets, found.map((target) => target.name)));
|
|
28
|
+
}
|
|
29
|
+
const targetIds = {};
|
|
30
|
+
for (const { kind, found } of perKind) {
|
|
31
|
+
targetIds[kind] = indexTargetsById(found);
|
|
32
|
+
}
|
|
33
|
+
return { findings, userIds: indexUsersById(foundUsers), targetIds };
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=resolution.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolution.js","sourceRoot":"","sources":["../../src/services/resolution.ts"],"names":[],"mappings":"AAEA,OAAO,EACH,KAAK,EACL,iBAAiB,EACjB,eAAe,EACf,aAAa,EACb,eAAe,EACf,cAAc,EACd,gBAAgB,GACnB,MAAM,oBAAoB,CAAC;AAS5B,MAAM,UAAU,cAAc,CAAC,UAAsB;IACjD,MAAM,IAAI,GAAgB,EAAE,CAAC;IAC7B,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACvB,KAAK,MAAM,EAAE,IAAI,UAAU,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC;YACnD,IAAI,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC;QAC5B,CAAC;IACL,CAAC;IACD,OAAO,IAAI,CAAC;AAChB,CAAC;AAED,gGAAgG;AAChG,MAAM,OAAO,iBAAiB;IACU;IAAiC;IAArE,YAAoC,GAAc,EAAmB,WAAgC;QAAjE,QAAG,GAAH,GAAG,CAAW;QAAmB,gBAAW,GAAX,WAAW,CAAqB;IAAG,CAAC;IAElG,KAAK,CAAC,GAAG;QACZ,MAAM,SAAS,GAAG,iBAAiB,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QACtD,MAAM,aAAa,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,eAAe,CAAC,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;QAExG,MAAM,SAAS,GACX,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QAC/E,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,CAC3B,aAAa,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,CACpC,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,WAAW,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAc,EAAE,CAAC,CAAC,CAAC,IAAI,CAC9F,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CACxC,CACJ,CACJ,CAAC;QAEF,MAAM,CAAC,UAAU,EAAE,OAAO,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC,CAAC;QAE1E,MAAM,QAAQ,GAAc,CAAC,GAAG,aAAa,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC,CAAC;QACtE,KAAK,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,OAAO,EAAE,CAAC;YAC7C,QAAQ,CAAC,IAAI,CACT,GAAG,eAAe,CACd,IAAI,EACJ,OAAO,EACP,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CACrC,CACJ,CAAC;QACN,CAAC;QAED,MAAM,SAAS,GAAG,EAAuC,CAAC;QAC1D,KAAK,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,OAAO,EAAE,CAAC;YACpC,SAAS,CAAC,IAAI,CAAC,GAAG,gBAAgB,CAAC,KAAK,CAAC,CAAC;QAC9C,CAAC;QAED,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,cAAc,CAAC,UAAU,CAAC,EAAE,SAAS,EAAE,CAAC;IACxE,CAAC;CACJ"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { DesiredAssignment } from '../core/model.js';
|
|
2
|
+
import { Finding } from '../core/finding.js';
|
|
3
|
+
import { OrgClient } from './adapters/org-client.js';
|
|
4
|
+
export type ValidateResult = {
|
|
5
|
+
files: string[];
|
|
6
|
+
assignments: DesiredAssignment[];
|
|
7
|
+
findings: Finding[];
|
|
8
|
+
errors: number;
|
|
9
|
+
warnings: number;
|
|
10
|
+
failed: boolean;
|
|
11
|
+
};
|
|
12
|
+
/** Online validate: run the offline load, then resolve every reference against the org. */
|
|
13
|
+
export declare class ValidateService {
|
|
14
|
+
private readonly org;
|
|
15
|
+
private readonly files;
|
|
16
|
+
constructor(org: OrgClient, files: string[]);
|
|
17
|
+
run(): Promise<ValidateResult>;
|
|
18
|
+
/** Look every reference up in the org (in parallel) and evaluate the results. */
|
|
19
|
+
private resolve;
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=validate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../src/services/validate.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,OAAO,EAAiB,MAAM,oBAAoB,CAAC;AAC5D,OAAO,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAErD,MAAM,MAAM,cAAc,GAAG;IACzB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,WAAW,EAAE,iBAAiB,EAAE,CAAC;IACjC,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,OAAO,CAAC;CACnB,CAAC;AAEF,2FAA2F;AAC3F,qBAAa,eAAe;IACL,OAAO,CAAC,QAAQ,CAAC,GAAG;IAAa,OAAO,CAAC,QAAQ,CAAC,KAAK;gBAAtC,GAAG,EAAE,SAAS,EAAmB,KAAK,EAAE,MAAM,EAAE;IAEvE,GAAG,IAAI,OAAO,CAAC,cAAc,CAAC;IAiB3C,iFAAiF;YACnE,OAAO;CA0BxB"}
|