Skip to content

Commit 9f4b5b9

Browse files
authored
Merge pull request #533 from gitKrystan/fix-file-check
Allow 'helpers' and 'adapters' in type config
2 parents e9b82d5 + 4d19293 commit 9f4b5b9

File tree

7 files changed

+55
-39
lines changed

7 files changed

+55
-39
lines changed

.vscode/settings.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
{
22
"editor.formatOnSave": true,
33
"editor.defaultFormatter": "esbenp.prettier-vscode",
4+
"editor.codeActionsOnSave": {
5+
"source.fixAll": true,
6+
"source.organizeImports": true
7+
},
48
"typescript.preferences.importModuleSpecifierEnding": "index",
59
"typescript.suggest.autoImports": true
610
}

README.md

Lines changed: 12 additions & 11 deletions
Large diffs are not rendered by default.

test/options.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@ describe('options', () => {
180180
new RegExp(
181181
makeMultilineMatcher(
182182
'test Config Error',
183-
"[type] Expected 'services', 'routes', 'components', or 'controllers', received 'oops"
183+
"[type] Expected 'adapters', 'components', 'controllers', 'helpers', 'routes', or 'services', received 'oops'"
184184
)
185185
)
186186
);

transforms/ember-object/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ const transformer: Transform = function (
2727
}
2828

2929
if (isTestFile(filePath)) {
30-
logger.info({ filePath, info: 'SKIPPED: test file' });
30+
logger.debug({ filePath, info: 'SKIPPED: test file' });
3131
return; // status: 'skipped'
3232
}
3333

transforms/helpers/options.ts

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import {
77
StringBooleanSchema,
88
StringFalseSchema,
99
} from './schema-helper';
10+
import { defined, twoOrMoreMap } from './util/types';
1011

1112
const DEFAULT_DECORATOR_CONFIG = {
1213
inObjectLiterals: [],
@@ -49,20 +50,30 @@ const QuoteSchema = z.union([z.literal('single'), z.literal('double')], {
4950
},
5051
});
5152

53+
export const TYPES = [
54+
'adapters',
55+
'components',
56+
'controllers',
57+
'helpers',
58+
'routes',
59+
'services',
60+
] as const;
61+
62+
export type Type = (typeof TYPES)[number];
63+
5264
const TypeSchema = z.union(
53-
[
54-
z.literal('services'),
55-
z.literal('routes'),
56-
z.literal('components'),
57-
z.literal('controllers'),
58-
],
65+
twoOrMoreMap(TYPES, (type) => z.literal(type)),
5966
{
6067
errorMap: (issue, ctx) => {
6168
if (issue.code === z.ZodIssueCode.invalid_union) {
69+
const formattedTypes = TYPES.map((type) => `'${type}'`);
70+
const expected = `${formattedTypes
71+
.slice(0, -1)
72+
.join(', ')}, or ${defined(
73+
formattedTypes[formattedTypes.length - 1]
74+
)}`;
6275
return {
63-
message: `Expected 'services', 'routes', 'components', or 'controllers', received ${inspect(
64-
ctx.data
65-
)}`,
76+
message: `Expected ${expected}, received ${inspect(ctx.data)}`,
6677
};
6778
}
6879
return { message: ctx.defaultError };

transforms/helpers/util/types.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,3 +40,14 @@ export function defined<T>(
4040
assert(value !== undefined, message);
4141
return value;
4242
}
43+
44+
/**
45+
* Wraps Array.map in a type-check that the initial array has at least two
46+
* items, then returns an array asserting that it has the same number of items.
47+
*/
48+
export function twoOrMoreMap<T, U>(
49+
array: readonly [T, T, ...T[]],
50+
callbackfn: (value: T, index: number, array: readonly T[]) => U
51+
): [U, U, ...U[]] {
52+
return array.map(callbackfn) as unknown as [U, U, ...U[]];
53+
}
Lines changed: 6 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,9 @@
11
import { minimatch } from 'minimatch';
2-
import type { Options } from './options';
2+
import { TYPES, type Type } from './options';
33

4-
const TYPE_PATTERNS = {
5-
service: '**/services/**/*.js',
6-
services: '**/services/**/*.js',
7-
controller: '**/controllers/**/*.js',
8-
controllers: '**/controllers/**/*.js',
9-
component: '**/components/**/*.js',
10-
components: '**/components/**/*.js',
11-
route: '**/routes/**/*.js',
12-
routes: '**/routes/**/*.js',
13-
} as const;
4+
const TYPE_PATTERNS = Object.fromEntries(
5+
TYPES.map((type) => [type, `**/${type}/**/*.js`] as const)
6+
) as Record<Type, string>;
147

158
const TEST_FILE_PATTERN = '**/*-test.js' as const;
169

@@ -23,10 +16,6 @@ export function isTestFile(file: string): boolean {
2316
* Returns true if the given path matches the type of ember object
2417
* The glob patterns are specified by `TYPE_PATTERNS`
2518
*/
26-
export function isFileOfType(file: string, type: Options['type']): boolean {
27-
return (
28-
// False positive
29-
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
30-
!!type && !!TYPE_PATTERNS[type] && minimatch(file, TYPE_PATTERNS[type])
31-
);
19+
export function isFileOfType(file: string, type: Type): boolean {
20+
return minimatch(file, TYPE_PATTERNS[type]);
3221
}

0 commit comments

Comments
 (0)