sf-plugin-permission-sets 0.0.0-dev.13 → 0.0.0-dev.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  import { SfCommand, Flags } from '@salesforce/sf-plugins-core';
2
2
  import { Messages } from '@salesforce/core';
3
- import { check } from '../../services/check.js';
3
+ import { CheckService } from '../../services/check.js';
4
4
  import { formatFindings } from '../../core/report.js';
5
5
  Messages.importMessagesDirectoryFromMetaUrl(import.meta.url);
6
6
  const messages = Messages.loadMessages('sf-plugin-permission-sets', 'ps.check');
@@ -21,11 +21,12 @@ export default class Check extends SfCommand {
21
21
  };
22
22
  async run() {
23
23
  const { flags } = await this.parse(Check);
24
- const result = await check({ files: flags.file, strict: flags.strict });
24
+ const service = new CheckService(flags.file, flags.strict);
25
+ const result = await service.run();
25
26
  for (const line of formatFindings(result.findings)) {
26
27
  this.log(line);
27
28
  }
28
- const assignees = new Set(result.assignments.map((a) => a.assignee));
29
+ const assignees = new Set(result.assignments.map((assignment) => assignment.assignee));
29
30
  this.log('');
30
31
  this.log(messages.getMessage('summary.counts', [String(result.errors), String(result.warnings)]));
31
32
  if (result.failed) {
@@ -1 +1 @@
1
- {"version":3,"file":"check.js","sourceRoot":"","sources":["../../../src/commands/ps/check.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,KAAK,EAAE,MAAM,yBAAyB,CAAC;AAChD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAGtD,QAAQ,CAAC,kCAAkC,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC7D,MAAM,QAAQ,GAAG,QAAQ,CAAC,YAAY,CAAC,2BAA2B,EAAE,UAAU,CAAC,CAAC;AAShF,MAAM,CAAC,OAAO,OAAO,KAAM,SAAQ,SAAwB;IAChD,MAAM,CAAU,OAAO,GAAG,QAAQ,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;IACzD,MAAM,CAAU,WAAW,GAAG,QAAQ,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;IACjE,MAAM,CAAU,QAAQ,GAAG,QAAQ,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC;IAE5D,MAAM,CAAU,KAAK,GAAG;QAC3B,IAAI,EAAE,KAAK,CAAC,MAAM,CAAC;YACf,IAAI,EAAE,GAAG;YACT,OAAO,EAAE,QAAQ,CAAC,UAAU,CAAC,oBAAoB,CAAC;YAClD,QAAQ,EAAE,IAAI;YACd,QAAQ,EAAE,IAAI;SACjB,CAAC;QACF,MAAM,EAAE,KAAK,CAAC,OAAO,CAAC;YAClB,OAAO,EAAE,QAAQ,CAAC,UAAU,CAAC,sBAAsB,CAAC;SACvD,CAAC;KACL,CAAC;IAEK,KAAK,CAAC,GAAG;QACZ,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QAC1C,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC;QAExE,KAAK,MAAM,IAAI,IAAI,cAAc,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC;YACjD,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACnB,CAAC;QAED,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC;QACrE,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACb,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,UAAU,CAAC,gBAAgB,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;QAElG,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;YAChB,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;YACrB,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,CAAC;gBACtB,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,UAAU,CAAC,cAAc,CAAC,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC;YACjE,CAAC;QACL,CAAC;QAED,OAAO;YACH,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,MAAM;YAC1B,KAAK,EAAE,SAAS,CAAC,IAAI;YACrB,WAAW,EAAE,MAAM,CAAC,WAAW,CAAC,MAAM;YACtC,QAAQ,EAAE,MAAM,CAAC,QAAQ;SAC5B,CAAC;IACN,CAAC"}
1
+ {"version":3,"file":"check.js","sourceRoot":"","sources":["../../../src/commands/ps/check.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AACvD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAGtD,QAAQ,CAAC,kCAAkC,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC7D,MAAM,QAAQ,GAAG,QAAQ,CAAC,YAAY,CAAC,2BAA2B,EAAE,UAAU,CAAC,CAAC;AAShF,MAAM,CAAC,OAAO,OAAO,KAAM,SAAQ,SAAwB;IAChD,MAAM,CAAU,OAAO,GAAG,QAAQ,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;IACzD,MAAM,CAAU,WAAW,GAAG,QAAQ,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;IACjE,MAAM,CAAU,QAAQ,GAAG,QAAQ,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC;IAE5D,MAAM,CAAU,KAAK,GAAG;QAC3B,IAAI,EAAE,KAAK,CAAC,MAAM,CAAC;YACf,IAAI,EAAE,GAAG;YACT,OAAO,EAAE,QAAQ,CAAC,UAAU,CAAC,oBAAoB,CAAC;YAClD,QAAQ,EAAE,IAAI;YACd,QAAQ,EAAE,IAAI;SACjB,CAAC;QACF,MAAM,EAAE,KAAK,CAAC,OAAO,CAAC;YAClB,OAAO,EAAE,QAAQ,CAAC,UAAU,CAAC,sBAAsB,CAAC;SACvD,CAAC;KACL,CAAC;IAEK,KAAK,CAAC,GAAG;QACZ,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QAE1C,MAAM,OAAO,GAAG,IAAI,YAAY,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;QAC3D,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,GAAG,EAAE,CAAC;QAEnC,KAAK,MAAM,IAAI,IAAI,cAAc,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC;YACjD,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACnB,CAAC;QAED,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC;QAEvF,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACb,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,UAAU,CAAC,gBAAgB,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;QAElG,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;YAChB,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;YACrB,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,CAAC;gBACtB,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,UAAU,CAAC,cAAc,CAAC,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC;YACjE,CAAC;QACL,CAAC;QAED,OAAO;YACH,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,MAAM;YAC1B,KAAK,EAAE,SAAS,CAAC,IAAI;YACrB,WAAW,EAAE,MAAM,CAAC,WAAW,CAAC,MAAM;YACtC,QAAQ,EAAE,MAAM,CAAC,QAAQ;SAC5B,CAAC;IACN,CAAC"}
@@ -0,0 +1,19 @@
1
+ import { SfCommand } from '@salesforce/sf-plugins-core';
2
+ import { Finding } from '../../core/model.js';
3
+ export type PsValidateResult = {
4
+ files: number;
5
+ users: number;
6
+ assignments: number;
7
+ findings: Finding[];
8
+ };
9
+ export default class Validate extends SfCommand<PsValidateResult> {
10
+ static readonly summary: string;
11
+ static readonly description: string;
12
+ static readonly examples: string[];
13
+ static readonly flags: {
14
+ 'target-org': import("@oclif/core/interfaces").OptionFlag<import("@salesforce/core").Org, import("@oclif/core/interfaces").CustomOptions>;
15
+ 'api-version': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
16
+ file: import("@oclif/core/interfaces").OptionFlag<string[], import("@oclif/core/interfaces").CustomOptions>;
17
+ };
18
+ run(): Promise<PsValidateResult>;
19
+ }
@@ -0,0 +1,46 @@
1
+ import { SfCommand, Flags } from '@salesforce/sf-plugins-core';
2
+ import { Messages } from '@salesforce/core';
3
+ import { ValidateService } from '../../services/validate.js';
4
+ import { formatFindings } from '../../core/report.js';
5
+ Messages.importMessagesDirectoryFromMetaUrl(import.meta.url);
6
+ const messages = Messages.loadMessages('sf-plugin-permission-sets', 'ps.validate');
7
+ export default class Validate extends SfCommand {
8
+ static summary = messages.getMessage('summary');
9
+ static description = messages.getMessage('description');
10
+ static examples = messages.getMessages('examples');
11
+ static flags = {
12
+ 'target-org': Flags.requiredOrg(),
13
+ 'api-version': Flags.orgApiVersion(),
14
+ file: Flags.string({
15
+ char: 'f',
16
+ summary: messages.getMessage('flags.file.summary'),
17
+ required: true,
18
+ multiple: true,
19
+ }),
20
+ };
21
+ async run() {
22
+ const { flags } = await this.parse(Validate);
23
+ const connection = flags['target-org'].getConnection(flags['api-version']);
24
+ const service = new ValidateService(connection, flags.file);
25
+ const result = await service.run();
26
+ for (const line of formatFindings(result.findings)) {
27
+ this.log(line);
28
+ }
29
+ const assignees = new Set(result.assignments.map((assignment) => assignment.assignee));
30
+ this.log('');
31
+ this.log(messages.getMessage('summary.counts', [String(result.errors), String(result.warnings)]));
32
+ if (result.failed) {
33
+ process.exitCode = 1;
34
+ if (!this.jsonEnabled()) {
35
+ this.error(messages.getMessage('error.failed'), { exit: 1 });
36
+ }
37
+ }
38
+ return {
39
+ files: result.files.length,
40
+ users: assignees.size,
41
+ assignments: result.assignments.length,
42
+ findings: result.findings,
43
+ };
44
+ }
45
+ }
46
+ //# sourceMappingURL=validate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate.js","sourceRoot":"","sources":["../../../src/commands/ps/validate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAC7D,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAGtD,QAAQ,CAAC,kCAAkC,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC7D,MAAM,QAAQ,GAAG,QAAQ,CAAC,YAAY,CAAC,2BAA2B,EAAE,aAAa,CAAC,CAAC;AASnF,MAAM,CAAC,OAAO,OAAO,QAAS,SAAQ,SAA2B;IACtD,MAAM,CAAU,OAAO,GAAG,QAAQ,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;IACzD,MAAM,CAAU,WAAW,GAAG,QAAQ,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;IACjE,MAAM,CAAU,QAAQ,GAAG,QAAQ,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC;IAE5D,MAAM,CAAU,KAAK,GAAG;QAC3B,YAAY,EAAE,KAAK,CAAC,WAAW,EAAE;QACjC,aAAa,EAAE,KAAK,CAAC,aAAa,EAAE;QACpC,IAAI,EAAE,KAAK,CAAC,MAAM,CAAC;YACf,IAAI,EAAE,GAAG;YACT,OAAO,EAAE,QAAQ,CAAC,UAAU,CAAC,oBAAoB,CAAC;YAClD,QAAQ,EAAE,IAAI;YACd,QAAQ,EAAE,IAAI;SACjB,CAAC;KACL,CAAC;IAEK,KAAK,CAAC,GAAG;QACZ,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;QAE7C,MAAM,UAAU,GAAG,KAAK,CAAC,YAAY,CAAC,CAAC,aAAa,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC;QAC3E,MAAM,OAAO,GAAG,IAAI,eAAe,CAAC,UAAU,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;QAC5D,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,GAAG,EAAE,CAAC;QAEnC,KAAK,MAAM,IAAI,IAAI,cAAc,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC;YACjD,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACnB,CAAC;QAED,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC;QAEvF,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACb,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,UAAU,CAAC,gBAAgB,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;QAElG,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;YAChB,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;YACrB,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,CAAC;gBACtB,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,UAAU,CAAC,cAAc,CAAC,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC;YACjE,CAAC;QACL,CAAC;QAED,OAAO;YACH,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,MAAM;YAC1B,KAAK,EAAE,SAAS,CAAC,IAAI;YACrB,WAAW,EAAE,MAAM,CAAC,WAAW,CAAC,MAAM;YACtC,QAAQ,EAAE,MAAM,CAAC,QAAQ;SAC5B,CAAC;IACN,CAAC"}
@@ -1,8 +1,3 @@
1
- import { DesiredAssignment, Finding, LoadResult } from './model.js';
2
- /** Process one file's text through parse, validate, and normalize. Pure, no disk. */
3
- export declare function checkContent(text: string, file: string): {
4
- assignments: DesiredAssignment[];
5
- findings: Finding[];
6
- };
1
+ import { LoadResult } from './model.js';
7
2
  /** Expand the globs, read every matched file, and merge into one model by union. */
8
3
  export declare function loadFiles(patterns: string[]): Promise<LoadResult>;
package/lib/core/load.js CHANGED
@@ -4,7 +4,7 @@ import { parseFile } from './parse.js';
4
4
  import { validateFile } from './schema.js';
5
5
  import { normalize } from './normalize.js';
6
6
  /** Process one file's text through parse, validate, and normalize. Pure, no disk. */
7
- export function checkContent(text, file) {
7
+ function checkContent(text, file) {
8
8
  const parsed = parseFile(text, file);
9
9
  if (!parsed.data) {
10
10
  return { assignments: [], findings: parsed.findings };
@@ -40,12 +40,12 @@ export async function loadFiles(patterns) {
40
40
  }
41
41
  const seen = new Set();
42
42
  const assignments = [];
43
- for (const a of collected) {
44
- const dedupeKey = `${a.assignee} ${a.kind} ${a.target}`;
43
+ for (const assignment of collected) {
44
+ const dedupeKey = `${assignment.assignee} ${assignment.kind} ${assignment.target}`;
45
45
  if (seen.has(dedupeKey))
46
46
  continue;
47
47
  seen.add(dedupeKey);
48
- assignments.push(a);
48
+ assignments.push(assignment);
49
49
  }
50
50
  return { files, assignments, findings };
51
51
  }
@@ -1 +1 @@
1
- {"version":3,"file":"load.js","sourceRoot":"","sources":["../../src/core/load.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACvC,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAG3C,qFAAqF;AACrF,MAAM,UAAU,YAAY,CAAC,IAAY,EAAE,IAAY;IACnD,MAAM,MAAM,GAAG,SAAS,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IACrC,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;QACf,OAAO,EAAE,WAAW,EAAE,EAAE,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ,EAAE,CAAC;IAC1D,CAAC;IAED,MAAM,SAAS,GAAG,YAAY,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IAClD,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC;QAClB,OAAO,EAAE,WAAW,EAAE,EAAE,EAAE,QAAQ,EAAE,CAAC,GAAG,MAAM,CAAC,QAAQ,EAAE,GAAG,SAAS,CAAC,QAAQ,CAAC,EAAE,CAAC;IACtF,CAAC;IAED,MAAM,UAAU,GAAG,SAAS,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IACnD,OAAO;QACH,WAAW,EAAE,UAAU,CAAC,WAAW;QACnC,QAAQ,EAAE,CAAC,GAAG,MAAM,CAAC,QAAQ,EAAE,GAAG,SAAS,CAAC,QAAQ,EAAE,GAAG,UAAU,CAAC,QAAQ,CAAC;KAChF,CAAC;AACN,CAAC;AAED,oFAAoF;AACpF,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,QAAkB;IAC9C,MAAM,KAAK,GAAG,MAAM,MAAM,CAAC,QAAQ,CAAC,CAAC;IACrC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACrB,OAAO;YACH,KAAK;YACL,WAAW,EAAE,EAAE;YACf,QAAQ,EAAE,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,qBAAqB,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC;SACxG,CAAC;IACN,CAAC;IAED,MAAM,QAAQ,GAAc,EAAE,CAAC;IAC/B,MAAM,SAAS,GAAwB,EAAE,CAAC;IAC1C,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACvB,4CAA4C;QAC5C,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QAC1C,MAAM,GAAG,GAAG,YAAY,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QACrC,QAAQ,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC,QAAQ,CAAC,CAAC;QAC/B,SAAS,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC,WAAW,CAAC,CAAC;IACvC,CAAC;IAED,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,MAAM,WAAW,GAAwB,EAAE,CAAC;IAC5C,KAAK,MAAM,CAAC,IAAI,SAAS,EAAE,CAAC;QACxB,MAAM,SAAS,GAAG,GAAG,CAAC,CAAC,QAAQ,IAAI,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC;QACxD,IAAI,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC;YAAE,SAAS;QAClC,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QACpB,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACxB,CAAC;IAED,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,CAAC;AAC5C,CAAC"}
1
+ {"version":3,"file":"load.js","sourceRoot":"","sources":["../../src/core/load.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACvC,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAG3C,qFAAqF;AACrF,SAAS,YAAY,CAAC,IAAY,EAAE,IAAY;IAC5C,MAAM,MAAM,GAAG,SAAS,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IACrC,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;QACf,OAAO,EAAE,WAAW,EAAE,EAAE,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ,EAAE,CAAC;IAC1D,CAAC;IAED,MAAM,SAAS,GAAG,YAAY,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IAClD,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC;QAClB,OAAO,EAAE,WAAW,EAAE,EAAE,EAAE,QAAQ,EAAE,CAAC,GAAG,MAAM,CAAC,QAAQ,EAAE,GAAG,SAAS,CAAC,QAAQ,CAAC,EAAE,CAAC;IACtF,CAAC;IAED,MAAM,UAAU,GAAG,SAAS,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IACnD,OAAO;QACH,WAAW,EAAE,UAAU,CAAC,WAAW;QACnC,QAAQ,EAAE,CAAC,GAAG,MAAM,CAAC,QAAQ,EAAE,GAAG,SAAS,CAAC,QAAQ,EAAE,GAAG,UAAU,CAAC,QAAQ,CAAC;KAChF,CAAC;AACN,CAAC;AAED,oFAAoF;AACpF,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,QAAkB;IAC9C,MAAM,KAAK,GAAG,MAAM,MAAM,CAAC,QAAQ,CAAC,CAAC;IACrC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACrB,OAAO;YACH,KAAK;YACL,WAAW,EAAE,EAAE;YACf,QAAQ,EAAE,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,qBAAqB,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC;SACxG,CAAC;IACN,CAAC;IAED,MAAM,QAAQ,GAAc,EAAE,CAAC;IAC/B,MAAM,SAAS,GAAwB,EAAE,CAAC;IAC1C,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACvB,4CAA4C;QAC5C,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QAC1C,MAAM,GAAG,GAAG,YAAY,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QACrC,QAAQ,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC,QAAQ,CAAC,CAAC;QAC/B,SAAS,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC,WAAW,CAAC,CAAC;IACvC,CAAC;IAED,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,MAAM,WAAW,GAAwB,EAAE,CAAC;IAE5C,KAAK,MAAM,UAAU,IAAI,SAAS,EAAE,CAAC;QACjC,MAAM,SAAS,GAAG,GAAG,UAAU,CAAC,QAAQ,IAAI,UAAU,CAAC,IAAI,IAAI,UAAU,CAAC,MAAM,EAAE,CAAC;QACnF,IAAI,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC;YAAE,SAAS;QAClC,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QACpB,WAAW,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IACjC,CAAC;IAED,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,CAAC;AAC5C,CAAC"}
@@ -0,0 +1,12 @@
1
+ import { DesiredAssignment, Finding } from './model.js';
2
+ /** A SOQL query paired with the pure function that turns its rows into findings. */
3
+ export type ResolutionStep = {
4
+ soql: string;
5
+ evaluate: (rows: unknown[]) => Finding[];
6
+ };
7
+ /**
8
+ * Plan the org queries needed to resolve these assignments, each paired with the
9
+ * pure evaluator for its rows. The online half of validate, kept free of any org
10
+ * connection: the service runs the SOQL and feeds the rows back to evaluate.
11
+ */
12
+ export declare function planResolution(assignments: DesiredAssignment[]): ResolutionStep[];
@@ -0,0 +1,95 @@
1
+ /** How each declarable target maps to the org object and field that names it. */
2
+ const KIND_RESOLUTION = {
3
+ permissionSet: { sobject: 'PermissionSet', field: 'Name', label: 'permission set' },
4
+ permissionSetGroup: { sobject: 'PermissionSetGroup', field: 'DeveloperName', label: 'permission set group' },
5
+ permissionSetLicense: { sobject: 'PermissionSetLicense', field: 'DeveloperName', label: 'permission set license' },
6
+ };
7
+ /** Escape a value for safe inclusion in a SOQL string literal. */
8
+ function soqlLiteral(value) {
9
+ return value.replace(/\\/g, '\\\\').replace(/'/g, "\\'");
10
+ }
11
+ /** Build a comma-separated, quoted IN list from the values. */
12
+ function inList(values) {
13
+ return values.map((value) => `'${soqlLiteral(value)}'`).join(', ');
14
+ }
15
+ function distinct(values) {
16
+ return [...new Set(values)];
17
+ }
18
+ /** Count how many rows carry each value of a field, keyed case-insensitively (SOQL matches that way). */
19
+ function countByField(rows, field) {
20
+ const counts = new Map();
21
+ for (const row of rows) {
22
+ const value = (row[field] ?? '').toLowerCase();
23
+ counts.set(value, (counts.get(value) ?? 0) + 1);
24
+ }
25
+ return counts;
26
+ }
27
+ /** Every declared user must exist and be active. */
28
+ function evaluateUsers(usernames, rows) {
29
+ const byName = new Map();
30
+ for (const row of rows) {
31
+ byName.set(row.Username.toLowerCase(), row);
32
+ }
33
+ const findings = [];
34
+ for (const username of usernames) {
35
+ const row = byName.get(username.toLowerCase());
36
+ if (!row) {
37
+ findings.push({ level: 'error', code: 'USER_NOT_FOUND', message: `${username}: user not found in org` });
38
+ }
39
+ else if (!row.IsActive) {
40
+ findings.push({ level: 'error', code: 'USER_INACTIVE', message: `${username}: user is inactive` });
41
+ }
42
+ }
43
+ return findings;
44
+ }
45
+ /** Every target of one kind must exist exactly once in the org. */
46
+ function evaluateTargets(kind, targets, rows) {
47
+ const { field, label } = KIND_RESOLUTION[kind];
48
+ const counts = countByField(rows, field);
49
+ const findings = [];
50
+ for (const target of targets) {
51
+ const count = counts.get(target.toLowerCase()) ?? 0;
52
+ if (count === 0) {
53
+ findings.push({
54
+ level: 'error',
55
+ code: 'TARGET_NOT_FOUND',
56
+ message: `${target}: ${label} not found in org`,
57
+ });
58
+ }
59
+ else if (count > 1) {
60
+ findings.push({
61
+ level: 'error',
62
+ code: 'TARGET_AMBIGUOUS',
63
+ message: `${target}: ${label} is not unique in org`,
64
+ });
65
+ }
66
+ }
67
+ return findings;
68
+ }
69
+ /**
70
+ * Plan the org queries needed to resolve these assignments, each paired with the
71
+ * pure evaluator for its rows. The online half of validate, kept free of any org
72
+ * connection: the service runs the SOQL and feeds the rows back to evaluate.
73
+ */
74
+ export function planResolution(assignments) {
75
+ const steps = [];
76
+ const usernames = distinct(assignments.map((assignment) => assignment.assignee));
77
+ if (usernames.length > 0) {
78
+ steps.push({
79
+ soql: `SELECT Username, IsActive FROM User WHERE Username IN (${inList(usernames)})`,
80
+ evaluate: (rows) => evaluateUsers(usernames, rows),
81
+ });
82
+ }
83
+ for (const kind of Object.keys(KIND_RESOLUTION)) {
84
+ const { sobject, field } = KIND_RESOLUTION[kind];
85
+ const targets = distinct(assignments.filter((assignment) => assignment.kind === kind).map((assignment) => assignment.target));
86
+ if (targets.length > 0) {
87
+ steps.push({
88
+ soql: `SELECT ${field} FROM ${sobject} WHERE ${field} IN (${inList(targets)})`,
89
+ evaluate: (rows) => evaluateTargets(kind, targets, rows),
90
+ });
91
+ }
92
+ }
93
+ return steps;
94
+ }
95
+ //# sourceMappingURL=resolve.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolve.js","sourceRoot":"","sources":["../../src/core/resolve.ts"],"names":[],"mappings":"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"}
@@ -1,8 +1,4 @@
1
1
  import { DesiredAssignment, Finding } from '../core/model.js';
2
- export type CheckOptions = {
3
- files: string[];
4
- strict: boolean;
5
- };
6
2
  export type CheckResult = {
7
3
  files: string[];
8
4
  assignments: DesiredAssignment[];
@@ -12,4 +8,9 @@ export type CheckResult = {
12
8
  failed: boolean;
13
9
  };
14
10
  /** Offline check: load the files, validate them, and summarize the findings. */
15
- export declare function check(options: CheckOptions): Promise<CheckResult>;
11
+ export declare class CheckService {
12
+ private readonly files;
13
+ private readonly strict;
14
+ constructor(files: string[], strict: boolean);
15
+ run(): Promise<CheckResult>;
16
+ }
@@ -1,17 +1,25 @@
1
1
  import { loadFiles } from '../core/load.js';
2
2
  import { countFindings } from '../core/report.js';
3
3
  /** Offline check: load the files, validate them, and summarize the findings. */
4
- export async function check(options) {
5
- const loaded = await loadFiles(options.files);
6
- const { errors, warnings } = countFindings(loaded.findings);
7
- const failed = errors > 0 || (options.strict && warnings > 0);
8
- return {
9
- files: loaded.files,
10
- assignments: loaded.assignments,
11
- findings: loaded.findings,
12
- errors,
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;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAiBlD,gFAAgF;AAChF,MAAM,CAAC,KAAK,UAAU,KAAK,CAAC,OAAqB;IAC7C,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IAC9C,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,aAAa,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IAC5D,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,IAAI,QAAQ,GAAG,CAAC,CAAC,CAAC;IAE9D,OAAO;QACH,KAAK,EAAE,MAAM,CAAC,KAAK;QACnB,WAAW,EAAE,MAAM,CAAC,WAAW;QAC/B,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,MAAM;QACN,QAAQ;QACR,MAAM;KACT,CAAC;AACN,CAAC"}
1
+ {"version":3,"file":"check.js","sourceRoot":"","sources":["../../src/services/check.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAYlD,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,17 @@
1
+ import { Connection } from '@salesforce/core';
2
+ import { DesiredAssignment, Finding } from '../core/model.js';
3
+ export type ValidateResult = {
4
+ files: string[];
5
+ assignments: DesiredAssignment[];
6
+ findings: Finding[];
7
+ errors: number;
8
+ warnings: number;
9
+ failed: boolean;
10
+ };
11
+ /** Online validate: run the offline load, then resolve every reference against the org. */
12
+ export declare class ValidateService {
13
+ private readonly connection;
14
+ private readonly files;
15
+ constructor(connection: Connection, files: string[]);
16
+ run(): Promise<ValidateResult>;
17
+ }
@@ -0,0 +1,31 @@
1
+ import { loadFiles } from '../core/load.js';
2
+ import { countFindings } from '../core/report.js';
3
+ import { planResolution } from '../core/resolve.js';
4
+ /** Online validate: run the offline load, then resolve every reference against the org. */
5
+ export class ValidateService {
6
+ connection;
7
+ files;
8
+ constructor(connection, files) {
9
+ this.connection = connection;
10
+ this.files = files;
11
+ }
12
+ async run() {
13
+ const loaded = await loadFiles(this.files);
14
+ const steps = planResolution(loaded.assignments);
15
+ const resolved = await Promise.all(steps.map(async (step) => {
16
+ const result = await this.connection.autoFetchQuery(step.soql);
17
+ return step.evaluate(result.records);
18
+ }));
19
+ const findings = [...loaded.findings, ...resolved.flat()];
20
+ const { errors, warnings } = countFindings(findings);
21
+ return {
22
+ files: loaded.files,
23
+ assignments: loaded.assignments,
24
+ findings,
25
+ errors,
26
+ warnings,
27
+ failed: errors > 0,
28
+ };
29
+ }
30
+ }
31
+ //# sourceMappingURL=validate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate.js","sourceRoot":"","sources":["../../src/services/validate.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAClD,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAYpD,2FAA2F;AAC3F,MAAM,OAAO,eAAe;IACY;IAAyC;IAA7E,YAAoC,UAAsB,EAAmB,KAAe;QAAxD,eAAU,GAAV,UAAU,CAAY;QAAmB,UAAK,GAAL,KAAK,CAAU;IAAG,CAAC;IAEzF,KAAK,CAAC,GAAG;QACZ,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAE3C,MAAM,KAAK,GAAG,cAAc,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;QACjD,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,GAAG,CAC9B,KAAK,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE;YACrB,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC/D,OAAO,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QACzC,CAAC,CAAC,CACL,CAAC;QAEF,MAAM,QAAQ,GAAG,CAAC,GAAG,MAAM,CAAC,QAAQ,EAAE,GAAG,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC;QAC1D,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,aAAa,CAAC,QAAQ,CAAC,CAAC;QAErD,OAAO;YACH,KAAK,EAAE,MAAM,CAAC,KAAK;YACnB,WAAW,EAAE,MAAM,CAAC,WAAW;YAC/B,QAAQ;YACR,MAAM;YACN,QAAQ;YACR,MAAM,EAAE,MAAM,GAAG,CAAC;SACrB,CAAC;IACN,CAAC;CACJ"}
@@ -0,0 +1,29 @@
1
+ # summary
2
+
3
+ Validate permission set assignment files against a target org.
4
+
5
+ # description
6
+
7
+ Run every offline check, then resolve each referenced user, permission set, group, and license against the org. Reports users that are missing or inactive and targets that are missing or not unique. Read-only: it queries the org but never changes it. Run it before plan or apply.
8
+
9
+ # flags.file.summary
10
+
11
+ YAML file or glob to validate. Repeatable.
12
+
13
+ # summary.counts
14
+
15
+ %s errors, %s warnings.
16
+
17
+ # error.failed
18
+
19
+ Validation found problems. See the output above.
20
+
21
+ # examples
22
+
23
+ - Validate every file under permissions against the dev org:
24
+
25
+ <%= config.bin %> <%= command.id %> --file "permissions/\*.yml" --target-org dev
26
+
27
+ - Validate specific files against a named org:
28
+
29
+ <%= config.bin %> <%= command.id %> --file permissions/sales.yml --file permissions/service.yml --target-org prod
@@ -107,7 +107,80 @@
107
107
  "ps:info",
108
108
  "info:ps"
109
109
  ]
110
+ },
111
+ "ps:validate": {
112
+ "aliases": [],
113
+ "args": {},
114
+ "description": "Run every offline check, then resolve each referenced user, permission set, group, and license against the org. Reports users that are missing or inactive and targets that are missing or not unique. Read-only: it queries the org but never changes it. Run it before plan or apply.",
115
+ "examples": [
116
+ "Validate every file under permissions against the dev org:\n<%= config.bin %> <%= command.id %> --file \"permissions/\\*.yml\" --target-org dev",
117
+ "Validate specific files against a named org:\n<%= config.bin %> <%= command.id %> --file permissions/sales.yml --file permissions/service.yml --target-org prod"
118
+ ],
119
+ "flags": {
120
+ "json": {
121
+ "description": "Format output as json.",
122
+ "helpGroup": "GLOBAL",
123
+ "name": "json",
124
+ "allowNo": false,
125
+ "type": "boolean"
126
+ },
127
+ "flags-dir": {
128
+ "helpGroup": "GLOBAL",
129
+ "name": "flags-dir",
130
+ "summary": "Import flag values from a directory.",
131
+ "hasDynamicHelp": false,
132
+ "multiple": false,
133
+ "type": "option"
134
+ },
135
+ "target-org": {
136
+ "char": "o",
137
+ "name": "target-org",
138
+ "noCacheDefault": true,
139
+ "required": true,
140
+ "summary": "Username or alias of the target org. Not required if the `target-org` configuration variable is already set.",
141
+ "hasDynamicHelp": true,
142
+ "multiple": false,
143
+ "type": "option"
144
+ },
145
+ "api-version": {
146
+ "description": "Override the api version used for api requests made by this command",
147
+ "name": "api-version",
148
+ "hasDynamicHelp": false,
149
+ "multiple": false,
150
+ "type": "option"
151
+ },
152
+ "file": {
153
+ "char": "f",
154
+ "name": "file",
155
+ "required": true,
156
+ "summary": "YAML file or glob to validate. Repeatable.",
157
+ "hasDynamicHelp": false,
158
+ "multiple": true,
159
+ "type": "option"
160
+ }
161
+ },
162
+ "hasDynamicHelp": true,
163
+ "hiddenAliases": [],
164
+ "id": "ps:validate",
165
+ "pluginAlias": "sf-plugin-permission-sets",
166
+ "pluginName": "sf-plugin-permission-sets",
167
+ "pluginType": "core",
168
+ "strict": true,
169
+ "summary": "Validate permission set assignment files against a target org.",
170
+ "enableJsonFlag": true,
171
+ "isESM": true,
172
+ "relativePath": [
173
+ "lib",
174
+ "commands",
175
+ "ps",
176
+ "validate.js"
177
+ ],
178
+ "aliasPermutations": [],
179
+ "permutations": [
180
+ "ps:validate",
181
+ "validate:ps"
182
+ ]
110
183
  }
111
184
  },
112
- "version": "0.0.0-dev.13"
185
+ "version": "0.0.0-dev.16"
113
186
  }
package/package.json CHANGED
@@ -1,7 +1,6 @@
1
1
  {
2
2
  "name": "sf-plugin-permission-sets",
3
3
  "description": "",
4
- "version": "0.0.0-dev.13",
5
4
  "repository": {
6
5
  "type": "git",
7
6
  "url": "git+https://github.com/zaclummys/sf-plugin-permission-sets.git"
@@ -133,5 +132,6 @@
133
132
  },
134
133
  "exports": "./lib/index.js",
135
134
  "type": "module",
136
- "author": "Isaac Ferreira"
135
+ "author": "Isaac Ferreira",
136
+ "version": "0.0.0-dev.16"
137
137
  }