@cloud-copilot/iam-expand 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (84) hide show
  1. package/LICENSE.txt +674 -0
  2. package/README.md +269 -0
  3. package/dist/cjs/cli.d.ts +3 -0
  4. package/dist/cjs/cli.d.ts.map +1 -0
  5. package/dist/cjs/cli.js +76 -0
  6. package/dist/cjs/cli.js.map +1 -0
  7. package/dist/cjs/cli_utils.d.ts +27 -0
  8. package/dist/cjs/cli_utils.d.ts.map +1 -0
  9. package/dist/cjs/cli_utils.js +69 -0
  10. package/dist/cjs/cli_utils.js.map +1 -0
  11. package/dist/cjs/expand.d.ts +69 -0
  12. package/dist/cjs/expand.d.ts.map +1 -0
  13. package/dist/cjs/expand.js +118 -0
  14. package/dist/cjs/expand.js.map +1 -0
  15. package/dist/cjs/index.d.ts +2 -0
  16. package/dist/cjs/index.d.ts.map +1 -0
  17. package/dist/cjs/index.js +18 -0
  18. package/dist/cjs/index.js.map +1 -0
  19. package/dist/cjs/package.json +3 -0
  20. package/dist/cjs/stdin.d.ts +7 -0
  21. package/dist/cjs/stdin.d.ts.map +1 -0
  22. package/dist/cjs/stdin.js +34 -0
  23. package/dist/cjs/stdin.js.map +1 -0
  24. package/dist/cli.d.ts +3 -0
  25. package/dist/cli.d.ts.map +1 -0
  26. package/dist/cli.js +67 -0
  27. package/dist/cli.js.map +1 -0
  28. package/dist/cli_utils.d.ts +27 -0
  29. package/dist/cli_utils.d.ts.map +1 -0
  30. package/dist/cli_utils.js +57 -0
  31. package/dist/cli_utils.js.map +1 -0
  32. package/dist/cli_utils.test.d.ts +2 -0
  33. package/dist/cli_utils.test.d.ts.map +1 -0
  34. package/dist/cli_utils.test.js +90 -0
  35. package/dist/cli_utils.test.js.map +1 -0
  36. package/dist/esm/cli.d.ts +3 -0
  37. package/dist/esm/cli.d.ts.map +1 -0
  38. package/dist/esm/cli.js +74 -0
  39. package/dist/esm/cli.js.map +1 -0
  40. package/dist/esm/cli_utils.d.ts +27 -0
  41. package/dist/esm/cli_utils.d.ts.map +1 -0
  42. package/dist/esm/cli_utils.js +63 -0
  43. package/dist/esm/cli_utils.js.map +1 -0
  44. package/dist/esm/expand.d.ts +69 -0
  45. package/dist/esm/expand.d.ts.map +1 -0
  46. package/dist/esm/expand.js +114 -0
  47. package/dist/esm/expand.js.map +1 -0
  48. package/dist/esm/index.d.ts +2 -0
  49. package/dist/esm/index.d.ts.map +1 -0
  50. package/dist/esm/index.js +2 -0
  51. package/dist/esm/index.js.map +1 -0
  52. package/dist/esm/package.json +3 -0
  53. package/dist/esm/stdin.d.ts +7 -0
  54. package/dist/esm/stdin.d.ts.map +1 -0
  55. package/dist/esm/stdin.js +31 -0
  56. package/dist/esm/stdin.js.map +1 -0
  57. package/dist/expand.d.ts +55 -0
  58. package/dist/expand.d.ts.map +1 -0
  59. package/dist/expand.js +94 -0
  60. package/dist/expand.js.map +1 -0
  61. package/dist/expand.test.d.ts +2 -0
  62. package/dist/expand.test.d.ts.map +1 -0
  63. package/dist/expand.test.js +382 -0
  64. package/dist/expand.test.js.map +1 -0
  65. package/dist/index.d.ts +2 -0
  66. package/dist/index.d.ts.map +1 -0
  67. package/dist/index.js +18 -0
  68. package/dist/index.js.map +1 -0
  69. package/dist/stdin.d.ts +7 -0
  70. package/dist/stdin.d.ts.map +1 -0
  71. package/dist/stdin.js +35 -0
  72. package/dist/stdin.js.map +1 -0
  73. package/package.json +33 -0
  74. package/postbuild.sh +13 -0
  75. package/src/cli.ts +82 -0
  76. package/src/cli_utils.test.ts +131 -0
  77. package/src/cli_utils.ts +78 -0
  78. package/src/expand.test.ts +523 -0
  79. package/src/expand.ts +185 -0
  80. package/src/index.ts +1 -0
  81. package/src/stdin.ts +34 -0
  82. package/tsconfig.cjs.json +11 -0
  83. package/tsconfig.esm.json +14 -0
  84. package/tsconfig.json +22 -0
@@ -0,0 +1,114 @@
1
+ import { iamActionExists, iamActionsForService, iamServiceExists, iamServiceKeys } from '@cloud-copilot/iam-data';
2
+ export var InvalidActionBehavior;
3
+ (function (InvalidActionBehavior) {
4
+ InvalidActionBehavior["Remove"] = "Remove";
5
+ InvalidActionBehavior["Error"] = "Error";
6
+ InvalidActionBehavior["Include"] = "Include";
7
+ })(InvalidActionBehavior || (InvalidActionBehavior = {}));
8
+ const defaultOptions = {
9
+ expandAsterik: false,
10
+ expandServiceAsterik: false,
11
+ errorOnInvalidFormat: false,
12
+ errorOnMissingService: false,
13
+ invalidActionBehavior: InvalidActionBehavior.Remove,
14
+ distinct: false,
15
+ sort: false
16
+ };
17
+ const allAsteriksPattern = /^\*+$/i;
18
+ /**
19
+ * Expands an IAM action string that contains wildcards.
20
+ * If the action string contains no wildcards, it is returned as is.
21
+ * @see {@link ExpandIamActionsOptions} for options to customize behavior
22
+ *
23
+ * If any options are set to throw an error, the function will throw an error if validation fails for a single value.
24
+ *
25
+ * @param actionStringOrStrings An IAM action or array IAM action(s) that may contain wildcards
26
+ * @param overrideOptions Options to override the default behavior
27
+ * @returns An array of expanded action strings flattend to a single array
28
+ */
29
+ export function expandIamActions(actionStringOrStrings, overrideOptions) {
30
+ const options = { ...defaultOptions, ...overrideOptions };
31
+ if (!actionStringOrStrings) {
32
+ //Just in case the user passes in null or undefined
33
+ return [];
34
+ }
35
+ if (Array.isArray(actionStringOrStrings)) {
36
+ let allMatches = actionStringOrStrings.flatMap(actionString => expandIamActions(actionString, options));
37
+ if (options.distinct) {
38
+ const aSet = new Set();
39
+ allMatches = allMatches.filter((value) => {
40
+ if (aSet.has(value)) {
41
+ return false;
42
+ }
43
+ aSet.add(value);
44
+ return true;
45
+ });
46
+ }
47
+ if (options.sort) {
48
+ allMatches.sort();
49
+ }
50
+ return allMatches;
51
+ }
52
+ const actionString = actionStringOrStrings.trim();
53
+ if (actionString.match(allAsteriksPattern)) {
54
+ if (options.expandAsterik) {
55
+ //If that's really what you want...
56
+ return iamServiceKeys().flatMap(service => iamActionsForService(service).map(action => `${service}:${action}`));
57
+ }
58
+ return ['*'];
59
+ }
60
+ if (!actionString.includes(':')) {
61
+ if (options.errorOnInvalidFormat) {
62
+ throw new Error(`Invalid action format: ${actionString}`);
63
+ }
64
+ return [];
65
+ }
66
+ const parts = actionString.split(':');
67
+ if (parts.length !== 2) {
68
+ if (options.errorOnInvalidFormat) {
69
+ throw new Error(`Invalid action format: ${actionString}`);
70
+ }
71
+ return [];
72
+ }
73
+ const [service, wildcardActions] = parts.map(part => part.toLowerCase());
74
+ if (!iamServiceExists(service)) {
75
+ if (options.errorOnMissingService) {
76
+ throw new Error(`Service not found: ${service}`);
77
+ }
78
+ return [];
79
+ }
80
+ if (wildcardActions.match(allAsteriksPattern)) {
81
+ if (options.expandServiceAsterik) {
82
+ return iamActionsForService(service).map(action => `${service}:${action}`);
83
+ }
84
+ return [`${service}:*`];
85
+ }
86
+ if (!actionString.includes('*')) {
87
+ const actionExists = iamActionExists(service, wildcardActions);
88
+ if (actionExists) {
89
+ return [actionString];
90
+ }
91
+ if (options.invalidActionBehavior === InvalidActionBehavior.Remove) {
92
+ return [];
93
+ }
94
+ else if (options.invalidActionBehavior === InvalidActionBehavior.Include) {
95
+ return [actionString];
96
+ }
97
+ else if (options.invalidActionBehavior === InvalidActionBehavior.Error) {
98
+ throw new Error(`Invalid action: ${actionString}`);
99
+ }
100
+ else {
101
+ //This should never happen
102
+ throw new Error(`Invalid invalidActionBehavior: ${options.invalidActionBehavior}`);
103
+ }
104
+ }
105
+ const allActions = iamActionsForService(service);
106
+ const pattern = "^" + wildcardActions.replace(/\*/g, '.*?') + "$";
107
+ const regex = new RegExp(pattern, 'i');
108
+ const matchingActions = allActions.filter(action => regex.test(action)).map(action => `${service}:${action}`);
109
+ if (options.sort) {
110
+ matchingActions.sort();
111
+ }
112
+ return matchingActions;
113
+ }
114
+ //# sourceMappingURL=expand.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"expand.js","sourceRoot":"","sources":["../../src/expand.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export * from './expand.js';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC"}
@@ -0,0 +1,2 @@
1
+ export * from './expand.js';
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC"}
@@ -0,0 +1,3 @@
1
+ {
2
+ "type": "module"
3
+ }
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Read from stdin until the stream ends, timeout, or an error occurs
3
+ *
4
+ * @returns the string input from stdin
5
+ */
6
+ export declare function readStdin(readWait: number | undefined): Promise<string>;
7
+ //# sourceMappingURL=stdin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stdin.d.ts","sourceRoot":"","sources":["../../src/stdin.ts"],"names":[],"mappings":"AACA;;;;GAIG;AACH,wBAAsB,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC,CA2B7E"}
@@ -0,0 +1,31 @@
1
+ import { stdin } from 'process';
2
+ /**
3
+ * Read from stdin until the stream ends, timeout, or an error occurs
4
+ *
5
+ * @returns the string input from stdin
6
+ */
7
+ export async function readStdin(readWait) {
8
+ return new Promise((resolve, reject) => {
9
+ // If the input is not a TTY, we are most likely receiving data from a pipe.
10
+ const definitelyReceivingData = !process.stdin.isTTY;
11
+ if (!readWait || readWait <= 0) {
12
+ readWait = definitelyReceivingData ? 10000 : 20;
13
+ }
14
+ let data = '';
15
+ setTimeout(() => {
16
+ if (data.length === 0) {
17
+ resolve(data);
18
+ }
19
+ }, readWait);
20
+ stdin.on('data', (chunk) => {
21
+ data += chunk;
22
+ });
23
+ stdin.on('end', () => {
24
+ resolve(data);
25
+ });
26
+ stdin.on('error', (err) => {
27
+ reject(err);
28
+ });
29
+ });
30
+ }
31
+ //# sourceMappingURL=stdin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stdin.js","sourceRoot":"","sources":["../../src/stdin.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,QAA4B;IAC1D,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,4EAA4E;QAC5E,MAAM,uBAAuB,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAA;QACpD,IAAG,CAAC,QAAQ,IAAI,QAAQ,IAAI,CAAC,EAAE,CAAC;YAC9B,QAAQ,GAAG,uBAAuB,CAAC,CAAC,CAAC,KAAM,CAAC,CAAC,CAAC,EAAE,CAAA;QAClD,CAAC;QAED,IAAI,IAAI,GAAG,EAAE,CAAC;QACd,UAAU,CAAC,GAAG,EAAE;YACd,IAAG,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACrB,OAAO,CAAC,IAAI,CAAC,CAAA;YACf,CAAC;QACH,CAAC,EAAE,QAAQ,CAAC,CAAA;QAEZ,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,EAAE;YACzB,IAAI,IAAI,KAAK,CAAC;QAChB,CAAC,CAAC,CAAC;QAEH,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE;YACnB,OAAO,CAAC,IAAI,CAAC,CAAC;QAChB,CAAC,CAAC,CAAC;QAEH,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE;YACxB,MAAM,CAAC,GAAG,CAAC,CAAC;QACd,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,55 @@
1
+ /**
2
+ * Options for the expand function
3
+ *
4
+ */
5
+ export interface ExpandIamActionsOptions {
6
+ /**
7
+ * If true, a single `*` will be expanded to all actions for all services
8
+ * If false, a single `*` will be returned as is
9
+ * Default: false
10
+ */
11
+ expandAsterik: boolean;
12
+ /**
13
+ * If true, `service:*` will be expanded to all actions for that service
14
+ * If false, `service:*` will be returned as is
15
+ * Default: false
16
+ */
17
+ expandServiceAsterik: boolean;
18
+ /**
19
+ * If true, an error will be thrown if the action string is not in the correct format
20
+ * If false, an empty array will be returned
21
+ * Default: false
22
+ */
23
+ errorOnInvalidFormat: boolean;
24
+ /**
25
+ * If true, an error will be thrown if the service in the action string does not exist
26
+ * If false, an empty array will be returned
27
+ * Default: false
28
+ */
29
+ errorOnMissingService: boolean;
30
+ /**
31
+ * If true, only unique values will be returned, while maintaining order
32
+ * If false, all values will be returned, even if they are duplicates
33
+ * Default: false
34
+ */
35
+ distinct: boolean;
36
+ /**
37
+ * If true, the returned array will be sorted
38
+ * If false, the returned array will be in the order they were expanded
39
+ * Default: false
40
+ */
41
+ sort: boolean;
42
+ }
43
+ /**
44
+ * Expands an IAM action string that contains wildcards.
45
+ * If the action string contains no wildcards, it is returned as is.
46
+ * @see {@link ExpandIamActionsOptions} for options to customize behavior
47
+ *
48
+ * If any options are set to throw an error, the function will throw an error if validation fails for a single value.
49
+ *
50
+ * @param actionStringOrStrings An IAM action or array IAM action(s) that may contain wildcards
51
+ * @param overrideOptions Options to override the default behavior
52
+ * @returns An array of expanded action strings flattend to a single array
53
+ */
54
+ export declare function expandIamActions(actionStringOrStrings: string | string[], overrideOptions?: Partial<ExpandIamActionsOptions>): string[];
55
+ //# sourceMappingURL=expand.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"expand.d.ts","sourceRoot":"","sources":["../src/expand.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,MAAM,WAAW,uBAAuB;IACtC;;;;OAIG;IACH,aAAa,EAAE,OAAO,CAAA;IAEtB;;;;OAIG;IACH,oBAAoB,EAAE,OAAO,CAAA;IAE7B;;;;OAIG;IACH,oBAAoB,EAAE,OAAO,CAAA;IAE7B;;;;OAIG;IACH,qBAAqB,EAAE,OAAO,CAAA;IAE9B;;;;OAIG;IACH,QAAQ,EAAE,OAAO,CAAA;IAEjB;;;;OAIG;IACH,IAAI,EAAE,OAAO,CAAA;CACd;AAWD;;;;;;;;;;GAUG;AACH,wBAAgB,gBAAgB,CAAC,qBAAqB,EAAE,MAAM,GAAG,MAAM,EAAE,EAAE,eAAe,CAAC,EAAE,OAAO,CAAC,uBAAuB,CAAC,GAAG,MAAM,EAAE,CAkFvI"}
package/dist/expand.js ADDED
@@ -0,0 +1,94 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.expandIamActions = expandIamActions;
4
+ const iam_data_1 = require("@cloud-copilot/iam-data");
5
+ const defaultOptions = {
6
+ expandAsterik: false,
7
+ expandServiceAsterik: false,
8
+ errorOnInvalidFormat: false,
9
+ errorOnMissingService: false,
10
+ distinct: false,
11
+ sort: false
12
+ };
13
+ /**
14
+ * Expands an IAM action string that contains wildcards.
15
+ * If the action string contains no wildcards, it is returned as is.
16
+ * @see {@link ExpandIamActionsOptions} for options to customize behavior
17
+ *
18
+ * If any options are set to throw an error, the function will throw an error if validation fails for a single value.
19
+ *
20
+ * @param actionStringOrStrings An IAM action or array IAM action(s) that may contain wildcards
21
+ * @param overrideOptions Options to override the default behavior
22
+ * @returns An array of expanded action strings flattend to a single array
23
+ */
24
+ function expandIamActions(actionStringOrStrings, overrideOptions) {
25
+ const options = { ...defaultOptions, ...overrideOptions };
26
+ if (!actionStringOrStrings) {
27
+ //Just in case the user passes in null or undefined
28
+ return [];
29
+ }
30
+ if (Array.isArray(actionStringOrStrings)) {
31
+ let allMatches = actionStringOrStrings.flatMap(actionString => expandIamActions(actionString, options));
32
+ if (options.distinct) {
33
+ const aSet = new Set();
34
+ allMatches = allMatches.filter((value) => {
35
+ if (aSet.has(value)) {
36
+ return false;
37
+ }
38
+ aSet.add(value);
39
+ return true;
40
+ });
41
+ }
42
+ if (options.sort) {
43
+ allMatches.sort();
44
+ }
45
+ return allMatches;
46
+ }
47
+ const actionString = actionStringOrStrings.trim();
48
+ if (actionString === '*') {
49
+ if (options.expandAsterik) {
50
+ //If that's really what you want...
51
+ return (0, iam_data_1.allServiceKeys)().flatMap(service => (0, iam_data_1.getActionsForService)(service).map(action => `${service}:${action}`));
52
+ }
53
+ return ['*'];
54
+ }
55
+ if (!actionString.includes(':')) {
56
+ if (options.errorOnInvalidFormat) {
57
+ throw new Error(`Invalid action format: ${actionString}`);
58
+ }
59
+ return [];
60
+ }
61
+ const parts = actionString.split(':');
62
+ if (parts.length !== 2) {
63
+ if (options.errorOnInvalidFormat) {
64
+ throw new Error(`Invalid action format: ${actionString}`);
65
+ }
66
+ return [];
67
+ }
68
+ const [service, wildcardActions] = parts.map(part => part.toLowerCase());
69
+ if (!(0, iam_data_1.serviceExists)(service)) {
70
+ if (options.errorOnMissingService) {
71
+ throw new Error(`Service not found: ${service}`);
72
+ }
73
+ return [];
74
+ }
75
+ if (!actionString.includes('*')) {
76
+ //No wildcards, just return the action string
77
+ return [actionString];
78
+ }
79
+ if (wildcardActions === '*') {
80
+ if (options.expandServiceAsterik) {
81
+ return (0, iam_data_1.getActionsForService)(service).map(action => `${service}:${action}`);
82
+ }
83
+ return [actionString];
84
+ }
85
+ const allActions = (0, iam_data_1.getActionsForService)(service);
86
+ const pattern = "^" + wildcardActions.replace(/\*/g, '.*?') + "$";
87
+ const regex = new RegExp(pattern, 'i');
88
+ const matchingActions = allActions.filter(action => regex.test(action)).map(action => `${service}:${action}`);
89
+ if (options.sort) {
90
+ matchingActions.sort();
91
+ }
92
+ return matchingActions;
93
+ }
94
+ //# sourceMappingURL=expand.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"expand.js","sourceRoot":"","sources":["../src/expand.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=expand.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"expand.test.d.ts","sourceRoot":"","sources":["../src/expand.test.ts"],"names":[],"mappings":""}