@servicetitan/restrict-imports 18.0.0 → 19.2.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.
@@ -1,7 +1,10 @@
1
1
  import { Config, RawConfig } from './config';
2
2
  /**
3
- * Config describes import restrictions between modules. E.g.
4
- * ```
3
+ * @param {string} base an absolute path
4
+ * @param {Array<string>} modules
5
+ * @param {Object} [config] describes import restrictions between modules
6
+ *
7
+ * @example
5
8
  * [
6
9
  * // 'common' is self-containing, imports from other modules is restricted
7
10
  * { name: 'common' },
@@ -22,33 +25,20 @@ import { Config, RawConfig } from './config';
22
25
  * // 'settings' can import from every module
23
26
  * { name: 'settings', allow: '*' },
24
27
  * ]
25
- * ```
26
- *
27
- * Config should follow the next rules:
28
28
  *
29
+ * @description Config should follow the next rules:
29
30
  * 1. The only available mask for both `name` and `allow` fields is '*'
30
- *
31
- * 2. Order of entries is important.
32
- * To avoid circular dependencies between modules, module's dependency should be described *above* the module description.
33
- * In the example, the 'common' module should be described *above* other modules.
34
- * This rule also applies to the '*' mask, it should be described *before* it is using in other config entries
31
+ * 2. Order of entries is important to avoid circular dependencies between modules, module's dependency should be described *above* the module description. In the example, the 'common' module should be described *above* other modules. This rule also applies to the '*' mask, it should be described *before* it is using in other config entries.
35
32
  */
36
33
  export declare function restrictImports(base: string, modules: string[], config?: RawConfig): RestrictionZone[];
37
34
  export declare function restrictImports_(base: string, modules: string[], config: Config): RestrictionZone[];
38
35
  export declare function getAllow(c: Config): (name: string) => import("./config").Allow;
39
36
  export declare function getDisallow(c: Config, name: string): string[];
40
- /**
41
- * allowZone('./app/', 'awesome', ['common'])
42
- * // => { target: './app/awesome', from: './app/(?!(awesome|common)/).*' }
43
- */
44
37
  export declare function allowZone(base: string, dirName: string, allow?: string[]): RestrictionZone;
45
- /**
46
- * disallowZone('./app/', 'amazing', ['layout', 'header'])
47
- * // => { target: './app/amazing', from: './app/(header|layout)/.*' }
48
- */
49
38
  export declare function disallowZone(base: string, dirName: string, disallow: string[]): RestrictionZone;
50
39
  export interface RestrictionZone {
51
40
  target: string;
52
41
  from: string;
42
+ except?: string[];
53
43
  }
54
44
  //# sourceMappingURL=restrict-imports.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"restrict-imports.d.ts","sourceRoot":"","sources":["../src/restrict-imports.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsB,MAAM,EAAE,SAAS,EAAqB,MAAM,UAAU,CAAC;AAEpF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAEH,wBAAgB,eAAe,CAC3B,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EAAE,EACjB,MAAM,CAAC,EAAE,SAAS,GACnB,eAAe,EAAE,CAOnB;AAID,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,MAAM,qBAiB/E;AAED,wBAAgB,QAAQ,CAAC,CAAC,EAAE,MAAM,UAGhB,MAAM,8BACvB;AAED,wBAAgB,WAAW,CAAC,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,YAKlD;AAED;;;GAGG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,GAAE,MAAM,EAAO,GAAG,eAAe,CAO9F;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,eAAe,CAK/F;AAED,MAAM,WAAW,eAAe;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;CAChB"}
1
+ {"version":3,"file":"restrict-imports.d.ts","sourceRoot":"","sources":["../src/restrict-imports.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsB,MAAM,EAAE,SAAS,EAAqB,MAAM,UAAU,CAAC;AAEpF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAEH,wBAAgB,eAAe,CAC3B,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EAAE,EACjB,MAAM,CAAC,EAAE,SAAS,GACnB,eAAe,EAAE,CAOnB;AAID,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,MAAM,qBAiB/E;AAED,wBAAgB,QAAQ,CAAC,CAAC,EAAE,MAAM,UAGhB,MAAM,8BACvB;AAED,wBAAgB,WAAW,CAAC,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,YAKlD;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,GAAE,MAAM,EAAO,GAAG,eAAe,CAM9F;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,eAAe,CAK/F;AAgBD,MAAM,WAAW,eAAe;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;CACrB"}
@@ -3,8 +3,11 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.disallowZone = exports.allowZone = exports.getDisallow = exports.getAllow = exports.restrictImports_ = exports.restrictImports = void 0;
4
4
  const config_1 = require("./config");
5
5
  /**
6
- * Config describes import restrictions between modules. E.g.
7
- * ```
6
+ * @param {string} base an absolute path
7
+ * @param {Array<string>} modules
8
+ * @param {Object} [config] describes import restrictions between modules
9
+ *
10
+ * @example
8
11
  * [
9
12
  * // 'common' is self-containing, imports from other modules is restricted
10
13
  * { name: 'common' },
@@ -25,16 +28,10 @@ const config_1 = require("./config");
25
28
  * // 'settings' can import from every module
26
29
  * { name: 'settings', allow: '*' },
27
30
  * ]
28
- * ```
29
- *
30
- * Config should follow the next rules:
31
31
  *
32
+ * @description Config should follow the next rules:
32
33
  * 1. The only available mask for both `name` and `allow` fields is '*'
33
- *
34
- * 2. Order of entries is important.
35
- * To avoid circular dependencies between modules, module's dependency should be described *above* the module description.
36
- * In the example, the 'common' module should be described *above* other modules.
37
- * This rule also applies to the '*' mask, it should be described *before* it is using in other config entries
34
+ * 2. Order of entries is important to avoid circular dependencies between modules, module's dependency should be described *above* the module description. In the example, the 'common' module should be described *above* other modules. This rule also applies to the '*' mask, it should be described *before* it is using in other config entries.
38
35
  */
39
36
  function restrictImports(base, modules, config) {
40
37
  const validationError = (0, config_1.validateRawConfig)(config);
@@ -73,27 +70,29 @@ function getDisallow(c, name) {
73
70
  return names.slice(index + 1);
74
71
  }
75
72
  exports.getDisallow = getDisallow;
76
- /**
77
- * allowZone('./app/', 'awesome', ['common'])
78
- * // => { target: './app/awesome', from: './app/(?!(awesome|common)/).*' }
79
- */
80
73
  function allowZone(base, dirName, allow = []) {
81
- const allowedImports = [dirName, ...allow];
82
74
  return {
83
75
  target: base + dirName,
84
- from: `${base}(?!(${allowedImports.join('|')})/).*`,
76
+ from: `${base}**/*`,
77
+ except: [`${base}${toGlobList([dirName, ...allow])}/**/*`],
85
78
  };
86
79
  }
87
80
  exports.allowZone = allowZone;
88
- /**
89
- * disallowZone('./app/', 'amazing', ['layout', 'header'])
90
- * // => { target: './app/amazing', from: './app/(header|layout)/.*' }
91
- */
92
81
  function disallowZone(base, dirName, disallow) {
93
82
  return {
94
83
  target: base + dirName,
95
- from: `${base}(${disallow.join('|')})/.*`,
84
+ from: `${base}${toGlobList(disallow)}/**/*`,
96
85
  };
97
86
  }
98
87
  exports.disallowZone = disallowZone;
88
+ const toGlobList = (items) => {
89
+ if (!items.length) {
90
+ return '';
91
+ }
92
+ const uniqueItems = Array.from(new Set(items));
93
+ if (uniqueItems.length === 1) {
94
+ return uniqueItems[0];
95
+ }
96
+ return `{${uniqueItems.join(',')}}`;
97
+ };
99
98
  //# sourceMappingURL=restrict-imports.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"restrict-imports.js","sourceRoot":"","sources":["../src/restrict-imports.ts"],"names":[],"mappings":";;;AAAA,qCAAoF;AAEpF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAEH,SAAgB,eAAe,CAC3B,IAAY,EACZ,OAAiB,EACjB,MAAkB;IAElB,MAAM,eAAe,GAAG,IAAA,0BAAiB,EAAC,MAAM,CAAC,CAAC;IAClD,IAAI,eAAe,EAAE;QACjB,MAAM,IAAI,KAAK,CAAC,eAAe,CAAC,CAAC;KACpC;IAED,OAAO,gBAAgB,CAAC,IAAI,EAAE,OAAO,EAAE,IAAA,2BAAkB,EAAC,MAAM,CAAC,CAAC,CAAC;AACvE,CAAC;AAXD,0CAWC;AAED,4CAA4C;AAC5C,gEAAgE;AAChE,SAAgB,gBAAgB,CAAC,IAAY,EAAE,OAAiB,EAAE,MAAc;IAC5E,gEAAgE;IAChE,MAAM,SAAS,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC;IAEnC,OAAO,OAAO,CAAC,MAAM,CAAoB,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE;QACnD,MAAM,KAAK,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;QAC9B,IAAI,KAAK,KAAK,GAAG,EAAE;YACf,OAAO,CAAC,GAAG,GAAG,EAAE,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC;SACjD;QAED,MAAM,QAAQ,GAAG,WAAW,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QAC3C,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE;YACrB,OAAO,CAAC,GAAG,GAAG,EAAE,YAAY,CAAC,IAAI,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC;SACvD;QAED,OAAO,GAAG,CAAC;IACf,CAAC,EAAE,EAAE,CAAC,CAAC;AACX,CAAC;AAjBD,4CAiBC;AAED,SAAgB,QAAQ,CAAC,CAAS;IAC9B,MAAM,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAEjD,OAAO,CAAC,IAAY,EAAE,EAAE,eAAC,OAAA,MAAA,MAAA,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,mCAAI,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,mCAAI,EAAE,CAAA,EAAA,CAAC;AAC7D,CAAC;AAJD,4BAIC;AAED,SAAgB,WAAW,CAAC,CAAS,EAAE,IAAY;IAC/C,MAAM,KAAK,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IACjC,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAElC,OAAO,KAAK,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;AAClC,CAAC;AALD,kCAKC;AAED;;;GAGG;AACH,SAAgB,SAAS,CAAC,IAAY,EAAE,OAAe,EAAE,QAAkB,EAAE;IACzE,MAAM,cAAc,GAAG,CAAC,OAAO,EAAE,GAAG,KAAK,CAAC,CAAC;IAE3C,OAAO;QACH,MAAM,EAAE,IAAI,GAAG,OAAO;QACtB,IAAI,EAAE,GAAG,IAAI,OAAO,cAAc,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO;KACtD,CAAC;AACN,CAAC;AAPD,8BAOC;AAED;;;GAGG;AACH,SAAgB,YAAY,CAAC,IAAY,EAAE,OAAe,EAAE,QAAkB;IAC1E,OAAO;QACH,MAAM,EAAE,IAAI,GAAG,OAAO;QACtB,IAAI,EAAE,GAAG,IAAI,IAAI,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM;KAC5C,CAAC;AACN,CAAC;AALD,oCAKC"}
1
+ {"version":3,"file":"restrict-imports.js","sourceRoot":"","sources":["../src/restrict-imports.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@servicetitan/restrict-imports",
3
- "version": "18.0.0",
3
+ "version": "19.2.0",
4
4
  "description": "",
5
5
  "repository": {
6
6
  "type": "git",
@@ -19,5 +19,5 @@
19
19
  "cli": {
20
20
  "webpack": false
21
21
  },
22
- "gitHead": "53a1be9461fbc72760e5f134fd0c324c269d286f"
22
+ "gitHead": "62c48deffc4ed9aba58325fbad1b256ecbfae553"
23
23
  }
@@ -8,7 +8,7 @@ import {
8
8
  } from '../restrict-imports';
9
9
 
10
10
  describe('restrictImports()', () => {
11
- const base = './app/modules/';
11
+ const base = '/app/modules/';
12
12
  const modules = [
13
13
  'amazing',
14
14
  'awesome',
@@ -31,32 +31,38 @@ describe('restrictImports()', () => {
31
31
 
32
32
  expect(restrictImports(base, modules, config)).toEqual([
33
33
  {
34
- target: './app/modules/amazing',
35
- from: './app/modules/(?!(amazing|awesome)/).*',
34
+ target: '/app/modules/amazing',
35
+ from: '/app/modules/**/*',
36
+ except: ['/app/modules/{amazing,awesome}/**/*'],
36
37
  },
37
38
  {
38
- target: './app/modules/awesome',
39
- from: './app/modules/(?!(awesome)/).*',
39
+ target: '/app/modules/awesome',
40
+ from: '/app/modules/**/*',
41
+ except: ['/app/modules/awesome/**/*'],
40
42
  },
41
43
  {
42
- target: './app/modules/brilliant',
43
- from: './app/modules/(?!(brilliant|awesome|amazing)/).*',
44
+ target: '/app/modules/brilliant',
45
+ from: '/app/modules/**/*',
46
+ except: ['/app/modules/{brilliant,awesome,amazing}/**/*'],
44
47
  },
45
48
  {
46
- target: './app/modules/incredible',
47
- from: './app/modules/(surprising)/.*',
49
+ target: '/app/modules/incredible',
50
+ from: '/app/modules/surprising/**/*',
48
51
  },
49
52
  {
50
- target: './app/modules/marvelous',
51
- from: './app/modules/(?!(marvelous|awesome|amazing)/).*',
53
+ target: '/app/modules/marvelous',
54
+ from: '/app/modules/**/*',
55
+ except: ['/app/modules/{marvelous,awesome,amazing}/**/*'],
52
56
  },
53
57
  {
54
- target: './app/modules/unbelievable',
55
- from: './app/modules/(?!(unbelievable|awesome|amazing)/).*',
58
+ target: '/app/modules/unbelievable',
59
+ from: '/app/modules/**/*',
60
+ except: ['/app/modules/{unbelievable,awesome,amazing}/**/*'],
56
61
  },
57
62
  {
58
- target: './app/modules/wonderful',
59
- from: './app/modules/(?!(wonderful|awesome|amazing)/).*',
63
+ target: '/app/modules/wonderful',
64
+ from: '/app/modules/**/*',
65
+ except: ['/app/modules/{wonderful,awesome,amazing}/**/*'],
60
66
  },
61
67
  ]);
62
68
  });
@@ -64,36 +70,44 @@ describe('restrictImports()', () => {
64
70
  test('an empty config will restrict imports between all modules', () => {
65
71
  expect(restrictImports(base, modules)).toEqual([
66
72
  {
67
- target: './app/modules/amazing',
68
- from: './app/modules/(?!(amazing)/).*',
73
+ target: '/app/modules/amazing',
74
+ from: '/app/modules/**/*',
75
+ except: ['/app/modules/amazing/**/*'],
69
76
  },
70
77
  {
71
- target: './app/modules/awesome',
72
- from: './app/modules/(?!(awesome)/).*',
78
+ target: '/app/modules/awesome',
79
+ from: '/app/modules/**/*',
80
+ except: ['/app/modules/awesome/**/*'],
73
81
  },
74
82
  {
75
- target: './app/modules/brilliant',
76
- from: './app/modules/(?!(brilliant)/).*',
83
+ target: '/app/modules/brilliant',
84
+ from: '/app/modules/**/*',
85
+ except: ['/app/modules/brilliant/**/*'],
77
86
  },
78
87
  {
79
- target: './app/modules/incredible',
80
- from: './app/modules/(?!(incredible)/).*',
88
+ target: '/app/modules/incredible',
89
+ from: '/app/modules/**/*',
90
+ except: ['/app/modules/incredible/**/*'],
81
91
  },
82
92
  {
83
- target: './app/modules/marvelous',
84
- from: './app/modules/(?!(marvelous)/).*',
93
+ target: '/app/modules/marvelous',
94
+ from: '/app/modules/**/*',
95
+ except: ['/app/modules/marvelous/**/*'],
85
96
  },
86
97
  {
87
- target: './app/modules/surprising',
88
- from: './app/modules/(?!(surprising)/).*',
98
+ target: '/app/modules/surprising',
99
+ from: '/app/modules/**/*',
100
+ except: ['/app/modules/surprising/**/*'],
89
101
  },
90
102
  {
91
- target: './app/modules/unbelievable',
92
- from: './app/modules/(?!(unbelievable)/).*',
103
+ target: '/app/modules/unbelievable',
104
+ from: '/app/modules/**/*',
105
+ except: ['/app/modules/unbelievable/**/*'],
93
106
  },
94
107
  {
95
- target: './app/modules/wonderful',
96
- from: './app/modules/(?!(wonderful)/).*',
108
+ target: '/app/modules/wonderful',
109
+ from: '/app/modules/**/*',
110
+ except: ['/app/modules/wonderful/**/*'],
97
111
  },
98
112
  ]);
99
113
  });
@@ -147,16 +161,18 @@ describe('getDisallow()', () => {
147
161
 
148
162
  describe('allowZone()', () => {
149
163
  test('`./packages/admin` can import from itself only', () => {
150
- expect(allowZone('./packages/', 'admin')).toEqual({
151
- target: './packages/admin',
152
- from: './packages/(?!(admin)/).*',
164
+ expect(allowZone('/packages/', 'admin')).toEqual({
165
+ target: '/packages/admin',
166
+ from: '/packages/**/*',
167
+ except: ['/packages/admin/**/*'],
153
168
  });
154
169
  });
155
170
 
156
171
  test('`./app/awesome` can import from `common` and itself', () => {
157
- expect(allowZone('./app/', 'awesome', ['common'])).toEqual({
158
- target: './app/awesome',
159
- from: './app/(?!(awesome|common)/).*',
172
+ expect(allowZone('/app/', 'awesome', ['common'])).toEqual({
173
+ target: '/app/awesome',
174
+ from: '/app/**/*',
175
+ except: ['/app/{awesome,common}/**/*'],
160
176
  });
161
177
  });
162
178
  });
@@ -165,7 +181,7 @@ describe('disallowZone()', () => {
165
181
  test('`./app/awesome` can import from any module, except for `common`', () => {
166
182
  expect(disallowZone('./app/', 'awesome', ['common'])).toEqual({
167
183
  target: './app/awesome',
168
- from: './app/(common)/.*',
184
+ from: './app/common/**/*',
169
185
  });
170
186
  });
171
187
  });
@@ -1,8 +1,11 @@
1
1
  import { canonicalizeConfig, Config, RawConfig, validateRawConfig } from './config';
2
2
 
3
3
  /**
4
- * Config describes import restrictions between modules. E.g.
5
- * ```
4
+ * @param {string} base an absolute path
5
+ * @param {Array<string>} modules
6
+ * @param {Object} [config] describes import restrictions between modules
7
+ *
8
+ * @example
6
9
  * [
7
10
  * // 'common' is self-containing, imports from other modules is restricted
8
11
  * { name: 'common' },
@@ -23,16 +26,10 @@ import { canonicalizeConfig, Config, RawConfig, validateRawConfig } from './conf
23
26
  * // 'settings' can import from every module
24
27
  * { name: 'settings', allow: '*' },
25
28
  * ]
26
- * ```
27
- *
28
- * Config should follow the next rules:
29
29
  *
30
+ * @description Config should follow the next rules:
30
31
  * 1. The only available mask for both `name` and `allow` fields is '*'
31
- *
32
- * 2. Order of entries is important.
33
- * To avoid circular dependencies between modules, module's dependency should be described *above* the module description.
34
- * In the example, the 'common' module should be described *above* other modules.
35
- * This rule also applies to the '*' mask, it should be described *before* it is using in other config entries
32
+ * 2. Order of entries is important to avoid circular dependencies between modules, module's dependency should be described *above* the module description. In the example, the 'common' module should be described *above* other modules. This rule also applies to the '*' mask, it should be described *before* it is using in other config entries.
36
33
  */
37
34
 
38
35
  export function restrictImports(
@@ -82,31 +79,37 @@ export function getDisallow(c: Config, name: string) {
82
79
  return names.slice(index + 1);
83
80
  }
84
81
 
85
- /**
86
- * allowZone('./app/', 'awesome', ['common'])
87
- * // => { target: './app/awesome', from: './app/(?!(awesome|common)/).*' }
88
- */
89
82
  export function allowZone(base: string, dirName: string, allow: string[] = []): RestrictionZone {
90
- const allowedImports = [dirName, ...allow];
91
-
92
83
  return {
93
84
  target: base + dirName,
94
- from: `${base}(?!(${allowedImports.join('|')})/).*`,
85
+ from: `${base}**/*`,
86
+ except: [`${base}${toGlobList([dirName, ...allow])}/**/*`],
95
87
  };
96
88
  }
97
89
 
98
- /**
99
- * disallowZone('./app/', 'amazing', ['layout', 'header'])
100
- * // => { target: './app/amazing', from: './app/(header|layout)/.*' }
101
- */
102
90
  export function disallowZone(base: string, dirName: string, disallow: string[]): RestrictionZone {
103
91
  return {
104
92
  target: base + dirName,
105
- from: `${base}(${disallow.join('|')})/.*`,
93
+ from: `${base}${toGlobList(disallow)}/**/*`,
106
94
  };
107
95
  }
108
96
 
97
+ const toGlobList = (items: string[]) => {
98
+ if (!items.length) {
99
+ return '';
100
+ }
101
+
102
+ const uniqueItems = Array.from(new Set(items));
103
+
104
+ if (uniqueItems.length === 1) {
105
+ return uniqueItems[0];
106
+ }
107
+
108
+ return `{${uniqueItems.join(',')}}`;
109
+ };
110
+
109
111
  export interface RestrictionZone {
110
112
  target: string;
111
113
  from: string;
114
+ except?: string[];
112
115
  }