@effect-app/eslint-codegen-model 0.7.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.
@@ -0,0 +1,235 @@
1
+ import ts, { SyntaxKind } from "typescript"
2
+
3
+ const sortUnion = (a: string, b: string) => {
4
+ if (a !== "null" && a!== "undefined" && (b === "null" || b === "undefined")) {
5
+ return -1
6
+ }
7
+ if (b !== "null" && b !== "undefined" && (a === "null" || a === "undefined")) {
8
+ return 1
9
+ }
10
+ if(a < b) { return -1; }
11
+ if(a > b) { return 1; }
12
+ return 0;
13
+ }
14
+
15
+ const sortAlpha = (a: string, b: string) => {
16
+ if(a < b) { return -1; }
17
+ if(a > b) { return 1; }
18
+ return 0;
19
+ }
20
+
21
+ // TODO: we don't support string literals with spaces in them currently.
22
+ const rx = /(([^\s\<\>\,\[\(]+)? \| ([^\s\<\>\,\]\)]+))+/
23
+
24
+ function sortIt(str: string) {
25
+ return str.split(" | ").sort(sortUnion).join(" | ")
26
+ }
27
+
28
+ const debug = false // true
29
+
30
+ export function processNode(tc: ts.TypeChecker, root: ts.Node) {
31
+ return (n: ts.Node) => {
32
+ if (/*ts.isClassDeclaration(n) || ts.isTypeAliasDeclaration(n)*/ true) {
33
+ const constructorName = (n as any).name?.escapedText
34
+
35
+ if (!constructorName?.endsWith("Constructor")) {
36
+ //console.log("$$$constructorName doesnt end with Constructor", constructorName)
37
+ return
38
+ }
39
+
40
+ //console.log("$$$ constructorName", constructorName)
41
+
42
+ const t = tc.getTypeAtLocation(n)
43
+
44
+ const result = { encoded: [] as string[], parsed: [] as string[] }
45
+ const unions: Record<string, string> = {}
46
+
47
+ //console.log("$$$ props", t.getProperties().map(x => x.escapedName))
48
+ t.getProperties().forEach((c) => {
49
+ const method = c.name
50
+ if (method === "encoded" || method === "parsed") {
51
+ //console.log("$$$ method", method)
52
+ //console.log(c.members)
53
+ const tt = tc.getTypeOfSymbolAtLocation(c, n)
54
+ // const s = tc.getReturnTypeOfSignature(tt.getCallSignatures()[0])
55
+
56
+ // const type = tc.getReturnTypeOfSignature(s! as any /* TODO */)
57
+
58
+
59
+ tt.getProperties().forEach(p => {
60
+ const isLookup = debug && p.escapedName === "carrier"
61
+
62
+ //kind = 207,
63
+ //arguments[0].escapedText === "HosterRole"
64
+ //console.log("$$$p", p.escapedName)
65
+ //if (p.escapedName === "opposite") {
66
+ //console.log("$$$ a union!", p.declarations?.map(x => x.forEachChild(c => {
67
+
68
+ // TODO: have to find nullable, array, set, map, etc.
69
+ // TODO: "Encoded"
70
+ // but also should find fully custom sets like PurchaseOrderModulesSet - we should be able to just use those directly, incl PurchaseOrderModulesSet.Encoded
71
+ // for now just skip them?
72
+ p.declarations?.map(x => x.forEachChild(c => {
73
+ if (isLookup) {
74
+ console.log("$$$ lookup", c.kind, c)
75
+ }
76
+ if (c.kind === SyntaxKind.CallExpression) { // 207 -- SyntaxKind.ElementAccessExpression) {
77
+ let it = (c as any).arguments[0]
78
+ //const isState = p.escapedName === "state"
79
+ if (isLookup) {
80
+ console.log("$$$ state it", it)
81
+ }
82
+ const isNullable = it.expression?.escapedText === "nullable"
83
+ const isIt = it.arguments && it.arguments[0] //it.expression?.escapedText === "nullable"
84
+ if (isIt) {
85
+ //console.log("$$ nullable", it.arguments[0])
86
+ // TODO: usually the union is on the last input, we need to support all elements individually however
87
+ it = it.arguments[it.arguments.length - 1]
88
+ }
89
+ //console.log("$args", it)
90
+ //tc.getTypeAtLocation(it)
91
+ const tt = tc.getTypeAtLocation(c) //tc.getTypeOfSymbolAtLocation(it.parent, n)
92
+ const typeDecl = tc.typeToString(
93
+ tt,
94
+ root,
95
+ ts.TypeFormatFlags.NoTruncation
96
+ //ts.TypeFormatFlags.None
97
+ //ts.TypeFormatFlags.AddUndefined |
98
+ // | ts.TypeFormatFlags.NoTypeReduction
99
+ // | ts.TypeFormatFlags.MultilineObjectLiterals
100
+ //| ts.TypeFormatFlags.InTypeAlias
101
+ | ts.TypeFormatFlags.UseAliasDefinedOutsideCurrentScope // prevents import(*)
102
+ // | ts.TypeFormatFlags.UseStructuralFallback
103
+ )
104
+ if (isLookup) {
105
+ console.log("$$ type", typeDecl)
106
+ }
107
+ const matches = typeDecl.match(rx)
108
+ if (isLookup) {
109
+ console.log("$$ matches", matches)
110
+ }
111
+ const isOptional = typeDecl.match(/\>, "optional"/)
112
+ if (matches) {
113
+ let replaced = matches[0]!.replace(rx, (match) => sortIt(match))
114
+ replaced = sortIt(isOptional ? isNullable ? replaced.replace(" | null", " | undefined | null") : replaced + " | undefined" : replaced)
115
+ //console.log("$$ replaced", replaced, it.escapedText, matches)
116
+ // if (it.escapedText === "TaskState") {
117
+ // console.log("Help", it)
118
+ // }
119
+ if (isLookup) {
120
+ console.log("$$$ replaced", it.escapedText, replaced)
121
+ }
122
+ if (it.escapedText && !it.escapedText.endsWith("Set") /* skip the "Set" problem */ && replaced.replace(" | null", "").includes("|")) {
123
+ const replacement = it.escapedText + (isNullable ? " | null" : "") + (isOptional ? " | undefined" : "")
124
+ // if (it.escapedText === "TaskState") {
125
+ // console.log("$$$", { replaced, replacement })
126
+ // unions[replaced] = replacement
127
+ // } else {
128
+ unions[replaced] = replacement
129
+ if (isLookup) {
130
+ console.log("$$ repl", { replaced, replacement})
131
+ }
132
+ //}
133
+ } else {
134
+ // if (isIt) {
135
+ // console.log("$$ no name found", it.escapedText)
136
+ // }
137
+ // console.log("$$ no name found??", it)
138
+ }
139
+ }
140
+
141
+ }
142
+ //c.kind === 346 ? console.log(c) : null
143
+ //console.log((c as any).flowNode?.node?.name)
144
+ }))
145
+ //}
146
+ })
147
+
148
+ if (debug && Object.keys(unions).length) {
149
+ console.log("$$$ unions to replace", unions)
150
+ }
151
+
152
+ const typeDecl = tc.typeToString(
153
+ tt,
154
+ root,
155
+ ts.TypeFormatFlags.NoTruncation
156
+ //ts.TypeFormatFlags.None
157
+ //ts.TypeFormatFlags.AddUndefined |
158
+ // | ts.TypeFormatFlags.NoTypeReduction
159
+ // | ts.TypeFormatFlags.MultilineObjectLiterals
160
+ //| ts.TypeFormatFlags.InTypeAlias
161
+ | ts.TypeFormatFlags.UseAliasDefinedOutsideCurrentScope // prevents import(*)
162
+ // | ts.TypeFormatFlags.UseStructuralFallback
163
+ )
164
+ const str = typeDecl === "{}" ? [] :
165
+ // drop leading { and trailing }
166
+ typeDecl.substring(2, typeDecl.length - 2)
167
+ .split(";")
168
+ .map(l => l.trim())
169
+ // todo; skip the first split, as its the property
170
+ .map(l => l.replace(rx, (match) => {
171
+ const rpl = sortIt(match)
172
+ //if (debug) { console.log("Searching for", rpl, { unions}) }
173
+ if (rpl.endsWith(" | undefined")) {
174
+ const sub = unions[rpl.replace(" | undefined", "")]
175
+ return sub ? sub + " | undefined" : unions[rpl] ?? rpl
176
+ }
177
+
178
+ const sub = unions[rpl]
179
+ return (sub ? sub : rpl)
180
+ })
181
+ .replaceAll(" Array<", " ReadonlyArray<") // .replaceAll(/(Array|Set|Map)\</", "ReadonlyArray<") //
182
+ .replaceAll(" Set<", " ROSet<")
183
+ .replaceAll(" Map<", " ROMap<")
184
+ .replaceAll("(Array<", "(ReadonlyArray<") // .replaceAll(/(Array|Set|Map)\</", "ReadonlyArray<") //
185
+ .replaceAll("(Set<", "(ROSet<")
186
+ .replaceAll("(Map<", "(ROMap<")
187
+ .replaceAll(" Array.Array<", " ReadonlyArray<") // .replaceAll(/(Array|Set|Map)\</", "ReadonlyArray<") //
188
+ .replaceAll(" Set.Set<", " ROSet<")
189
+ .replaceAll(" Map.Map<", " ROMap<")
190
+ )
191
+ // we sort for now, because otherwise we have sometimes multiple times changing back and forth between editor and console.
192
+ .sort(sortAlpha)
193
+ // Taken care of by "ts.TypeFormatFlags.UseAliasDefinedOutsideCurrentScope"
194
+ //.replaceAll(/import\("[^"]+"\)\./g, "")
195
+
196
+ result[method] = str
197
+ }
198
+ })
199
+
200
+ if (!("parsed" in result)) {
201
+ throw new Error("No parsed result")
202
+ }
203
+ if (!("encoded" in result)) {
204
+ throw new Error("No encoded result")
205
+ }
206
+
207
+ const modelName = constructorName.replace("Constructor", "")
208
+
209
+ const encoded = result.encoded.filter(x => !!x)
210
+ const parsed = result.parsed.filter(x => !!x)
211
+
212
+ return [
213
+ `export interface ${modelName} {${parsed.length ? "\n" + parsed.map(l => " " + l).join("\n") + "\n" : ""}}`,
214
+ `export namespace ${modelName} {`,
215
+ ` /**`,
216
+ ` * @tsplus type ${modelName}.Encoded`,
217
+ ` */`,
218
+ ` export interface Encoded {${encoded.length ? "\n" + encoded.map(l => " " + l).join("\n") + "\n " : ""}}`,
219
+ ` export const Encoded: EncodedOps = { $: {} }`,
220
+ ` /**`,
221
+ ` * @tsplus type ${modelName}.Encoded/Aspects`,
222
+ ` */`,
223
+ ` export interface EncodedAspects {}`,
224
+ ` /**`,
225
+ ` * @tsplus type ${modelName}.Encoded/Ops`,
226
+ ` */`,
227
+ ` export interface EncodedOps { $: EncodedAspects }`,
228
+ " export interface ConstructorInput",
229
+ ` extends ConstructorInputFromApi<typeof ${modelName}> {}`,
230
+ ` export interface Props extends GetProvidedProps<typeof ${modelName}> {}`,
231
+ "}",
232
+ ]
233
+ }
234
+ }
235
+ }
package/src/index.ts ADDED
@@ -0,0 +1,3 @@
1
+ // codegen:start {preset: barrel, include: ./*/, nodir: false }
2
+ export * from './presets';
3
+ // codegen:end
@@ -0,0 +1,150 @@
1
+ import generate from '@babel/generator';
2
+ import { parse } from '@babel/parser';
3
+ import type { Preset } from 'eslint-plugin-codegen';
4
+ import * as glob from 'glob';
5
+ import { match } from 'io-ts-extra';
6
+ import * as lodash from 'lodash';
7
+ import * as path from 'path';
8
+
9
+ /**
10
+ * Bundle several modules into a single convenient one.
11
+ *
12
+ * @example
13
+ * // codegen:start {preset: barrel, include: some/path/*.ts, exclude: some/path/*util.ts}
14
+ * export * from './some/path/module-a'
15
+ * export * from './some/path/module-b'
16
+ * export * from './some/path/module-c'
17
+ * // codegen:end
18
+ *
19
+ * @param include
20
+ * [optional] If specified, the barrel will only include file paths that match this glob pattern
21
+ * @param exclude
22
+ * [optional] If specified, the barrel will exclude file paths that match these glob patterns
23
+ * @param import
24
+ * [optional] If specified, matching files will be imported and re-exported rather than directly exported
25
+ * with `export * from './xyz'`. Use `import: star` for `import * as xyz from './xyz'` style imports.
26
+ * Use `import: default` for `import xyz from './xyz'` style imports.
27
+ * @param export
28
+ * [optional] Only valid if the import style has been specified (either `import: star` or `import: default`).
29
+ * If specified, matching modules will be bundled into a const or default export based on this name. If set
30
+ * to `{name: someName, keys: path}` the relative file paths will be used as keys. Otherwise the file paths
31
+ * will be camel-cased to make them valid js identifiers.
32
+ */
33
+ export const barrel: Preset<{
34
+ include?: string;
35
+ exclude?: string | string[];
36
+ import?: 'default' | 'star';
37
+ export?:
38
+ | string
39
+ | { name: string; keys: 'path' | 'camelCase' }
40
+ | { as: 'PascalCase', postfix?: string };
41
+ nodir?: boolean;
42
+ }> = ({ meta, options: opts }) => {
43
+ const cwd = path.dirname(meta.filename);
44
+ const nodir = opts.nodir ?? true;
45
+
46
+ const ext = meta.filename.split('.').slice(-1)[0];
47
+ const pattern = opts.include || `*.${ext}`;
48
+
49
+ const relativeFiles = glob
50
+ .sync(pattern, { cwd, ignore: opts.exclude, nodir })
51
+ .filter((f) => path.resolve(cwd, f) !== path.resolve(meta.filename))
52
+ .map((f) => `./${f}`.replace(/(\.\/)+\./g, '.'))
53
+ .filter((file) =>
54
+ nodir
55
+ ? ['.js', '.mjs', '.ts', '.tsx'].includes(path.extname(file))
56
+ : true,
57
+ )
58
+ .map((f) => f.replace(/\.\w+$/, '').replace(/\/$/, ''));
59
+
60
+ function last<T>(list: readonly T[]) {
61
+ return list[list.length - 1]
62
+ }
63
+
64
+ const expectedContent = match(opts.import)
65
+ .case(undefined, () =>
66
+ match(opts.export)
67
+ .case({ as: 'PascalCase' as const }, (v) =>
68
+ lodash
69
+ .chain(relativeFiles)
70
+ .map(
71
+ (f) =>
72
+ `export * as ${lodash
73
+ .startCase(lodash.camelCase(last(f.split("/"))))
74
+ .replace(/ /g, "") // why?
75
+ .replace(/\//, '')}${"postfix" in v ? v.postfix : ''} from '${f}.js'`,
76
+ )
77
+ .value()
78
+ .join('\n'),
79
+ )
80
+ .default(() => {
81
+ return relativeFiles.map((f) => `export * from '${f}.js'`).join('\n');
82
+ })
83
+ .get(),
84
+ )
85
+ .case(String, (s) => {
86
+ const importPrefix = s === 'default' ? '' : '* as ';
87
+ const withIdentifiers = lodash
88
+ .chain(relativeFiles)
89
+ .map((f) => ({
90
+ file: f,
91
+ identifier: lodash
92
+ .camelCase(f)
93
+ .replace(/^([^a-z])/, '_$1')
94
+ .replace(/Index$/, ''),
95
+ }))
96
+ .groupBy((info) => info.identifier)
97
+ .values()
98
+ .flatMap((group) =>
99
+ group.length === 1
100
+ ? group
101
+ : group.map((info, i) => ({
102
+ ...info,
103
+ identifier: `${info.identifier}_${i + 1}`,
104
+ })),
105
+ )
106
+ .value();
107
+
108
+ const imports = withIdentifiers
109
+ .map((i) => `import ${importPrefix}${i.identifier} from '${i.file}.js'`)
110
+ .join('\n');
111
+ const exportProps = match(opts.export)
112
+ .case({ name: String, keys: 'path' }, () =>
113
+ withIdentifiers.map(
114
+ (i) => `${JSON.stringify(i.file)}: ${i.identifier}`,
115
+ ),
116
+ )
117
+ .default(() => withIdentifiers.map((i) => i.identifier))
118
+ .get();
119
+
120
+ const exportPrefix = match(opts.export)
121
+ .case(undefined, () => 'export')
122
+ .case('default', () => 'export default')
123
+ .case({ name: 'default' }, () => 'export default')
124
+ .case(String, (name) => `export const ${name} =`)
125
+ .case({ name: String }, ({ name }) => `export const ${name} =`)
126
+ .default(() => '')
127
+ .get();
128
+
129
+ const exports = exportProps.join(',\n ');
130
+
131
+ return `${imports}\n\n${exportPrefix} {\n ${exports}\n}\n`;
132
+ })
133
+ .get();
134
+
135
+ // ignore stylistic differences. babel generate deals with most
136
+ const normalise = (str: string) =>
137
+ generate(
138
+ parse(str, { sourceType: 'module', plugins: ['typescript'] }) as any,
139
+ )
140
+ .code.replace(/'/g, `"`)
141
+ .replace(/\/index/g, '');
142
+
143
+ try {
144
+ if (normalise(expectedContent) === normalise(meta.existingContent)) {
145
+ return meta.existingContent;
146
+ }
147
+ } catch {}
148
+
149
+ return expectedContent;
150
+ };
@@ -0,0 +1,4 @@
1
+ // codegen:start {preset: barrel, include: ./*.ts}
2
+ export * from './barrel';
3
+ export * from './model';
4
+ // codegen:end
@@ -0,0 +1,114 @@
1
+ import generate from "@babel/generator"
2
+ import { parse } from "@babel/parser"
3
+ import type { Preset } from "eslint-plugin-codegen"
4
+ import * as fs from "fs"
5
+ import { processNode } from "../compiler"
6
+ function normalise(str: string) {
7
+ try {
8
+ return generate(
9
+ parse(str, { sourceType: "module", plugins: ["typescript"] }) as any
10
+ )
11
+ .code
12
+ // .replace(/'/g, `"`)
13
+ // .replace(/\/index/g, "")
14
+ //.replace(/([\n\s]+ \|)/g, " |").replaceAll(": |", ":")
15
+ //.replaceAll(/[\s\n]+\|/g, " |")
16
+ //.replaceAll("\n", ";")
17
+ //.replaceAll(" ", "")
18
+ // TODO: remove all \n and whitespace?
19
+ } catch (e) {
20
+ return str
21
+ }
22
+ }
23
+ // TODO: get shared compiler host...
24
+ import { ESLintUtils } from "@typescript-eslint/utils"
25
+ export const model: Preset<{
26
+ exclude?: string
27
+ }> = ({ meta }, context: any) => {
28
+ if (!context.parserOptions.project) {
29
+ console.warn(`${meta.filename}: Cannot run ESLint Model plugin, because no TS Compiler is enabled`)
30
+ return meta.existingContent
31
+ }
32
+
33
+ try {
34
+ // option to exclude some methods
35
+ //const exclude = (options.exclude || "").split(",")
36
+
37
+ // checks and reads the file
38
+ const sourcePath = meta.filename
39
+ if (!fs.existsSync(sourcePath) || !fs.statSync(sourcePath).isFile()) {
40
+ throw Error(`Source path is not a file: ${sourcePath}`)
41
+ }
42
+ // const cfgFile = ts.findConfigFile(sourcePath, (fn) => fs.existsSync(fn))
43
+ // if (!cfgFile) {
44
+ // throw new Error("No TS config file found")
45
+ // }
46
+
47
+ // const cfg = ts.readConfigFile(cfgFile, (fn) => fs.readFileSync(fn, "utf-8"))
48
+ // const basePath = path.dirname(cfgFile); // equal to "getDirectoryPath" from ts, at least in our case.
49
+ // const parsedConfig = ts.parseJsonConfigFileContent(cfg.config, ts.sys, basePath);
50
+
51
+ // const program = ts.createProgram([sourcePath], parsedConfig.options)
52
+
53
+
54
+ const { program } = ESLintUtils.getParserServices(context);
55
+
56
+ //console.log("$$ processing", sourcePath)
57
+
58
+ // create and parse the AST
59
+ const sourceFile = program.getSourceFile(
60
+ sourcePath,
61
+ )!
62
+
63
+ // collect data-first declarations
64
+ // const dataFirstDeclarations = sourceFile.statements
65
+ // .filter(ts.isFunctionDeclaration)
66
+ // // .filter(
67
+ // // (node) =>
68
+ // // node.modifiers &&
69
+ // // node.modifiers.filter(
70
+ // // (modifier) => modifier.kind === ts.SyntaxKind.ExportKeyword
71
+ // // ).length > 0
72
+ // // )
73
+ // // .filter((node) => !!node.name)
74
+ // // .filter((node) => node.parameters.length >= 2)
75
+ // // .filter((node) => node.name!.getText(sourceFile).endsWith("_"))
76
+ // // .map((node) => ({
77
+ // // functionName: node.name!.getText(sourceFile),
78
+ // // typeParameters: node.typeParameters || ts.factory.createNodeArray(),
79
+ // // parameters: node.parameters || ts.factory.createNodeArray(),
80
+ // // type: node.type!,
81
+ // // implemented: !!node.body,
82
+ // // jsDoc: getJSDoc(node)
83
+ // // }))
84
+ // // .filter((decl) => exclude.indexOf(decl.functionName) === -1)
85
+
86
+ // // create the actual AST nodes
87
+ // const nodes = dataFirstDeclarations.map(createPipeableFunctionDeclaration)
88
+ // const expectedContent = nodes.map((node) => printNode(node, sourceFile)).join("\n")
89
+
90
+ const pn = processNode(program.getTypeChecker(), sourceFile)
91
+ let abc: (string[] | undefined)[] = []
92
+ // TODO: must return void, cannot use getChildren() etc, or it wont work, no idea why!
93
+ sourceFile.forEachChild(c => {abc = abc.concat(pn(c))})
94
+ const expectedContent = [
95
+ "//",
96
+ `/* eslint-disable */`,
97
+ ...abc.filter((x): x is string[] => !!x),
98
+ `/* eslint-enable */`,
99
+ "//"
100
+ ].join("\n")
101
+
102
+ // do not re-emit in a different style, or a loop will occur
103
+ if (normalise(meta.existingContent) === normalise(expectedContent))
104
+ return meta.existingContent
105
+ return expectedContent
106
+ } catch (e) {
107
+ return (
108
+ "/** Got exception: " +
109
+ ("stack" in (e as any) ? (e as any).stack : "") +
110
+ JSON.stringify(e) +
111
+ "*/"
112
+ )
113
+ }
114
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,94 @@
1
+ {
2
+ "compilerOptions": {
3
+ "strict": true,
4
+ "allowUnusedLabels": false,
5
+ "allowUnreachableCode": false,
6
+ "exactOptionalPropertyTypes": false,
7
+ "noFallthroughCasesInSwitch": true,
8
+ "noImplicitOverride": true,
9
+ "noImplicitReturns": false,
10
+ "noPropertyAccessFromIndexSignature": true,
11
+ "noUncheckedIndexedAccess": true,
12
+ "noUnusedLocals": true,
13
+ "noUnusedParameters": true,
14
+ "importsNotUsedAsValues": "error",
15
+ "checkJs": true,
16
+ "esModuleInterop": true,
17
+ "skipLibCheck": true,
18
+ "forceConsistentCasingInFileNames": true,
19
+ "module": "CommonJS",
20
+ "lib": [
21
+ "esnext"
22
+ ],
23
+ "target": "ES2018",
24
+ "inlineSourceMap": true,
25
+ "incremental": true,
26
+ "composite": true,
27
+ "declarationMap": true,
28
+ "experimentalDecorators": true,
29
+ "emitDecoratorMetadata": true,
30
+ "noImplicitAny": true,
31
+ "useUnknownInCatchVariables": true,
32
+ "noImplicitThis": true,
33
+ "outDir": "./dist",
34
+ "resolveJsonModule": true,
35
+ "moduleResolution": "Node16",
36
+ "downlevelIteration": true,
37
+ "noErrorTruncation": true,
38
+ "tsPlusTypes": [
39
+ "./node_modules/@effect-app/core/vendor/effect-ts-tsplus.json",
40
+ "./node_modules/@effect-app/core/vendor/effect-io-tsplus.json",
41
+ "./node_modules/@effect-app/core/vendor/effect-stm-tsplus.json",
42
+ "./node_modules/@effect-app/core/vendor/effect-stream-tsplus.json",
43
+ "./node_modules/@effect-app/core/vendor/fp-ts-data-tsplus.json"
44
+ ],
45
+ "plugins": [
46
+ {
47
+ "name": "@effect/language-service",
48
+ "diagnostics": {
49
+ "1002": "none"
50
+ }
51
+ }
52
+ ],
53
+ "transformers": [
54
+ {
55
+ "name": "@effect/language-service/transformer",
56
+ "trace": {}
57
+ }
58
+ ],
59
+ "baseUrl": ".",
60
+ "tsBuildInfoFile": "./dist/.tsbuildinfo",
61
+ "rootDir": "./src"
62
+ },
63
+ "$schema": "https://json.schemastore.org/tsconfig",
64
+ "display": "Strictest",
65
+ "watchOptions": {
66
+ "watchFile": "useFsEvents",
67
+ "watchDirectory": "useFsEvents",
68
+ "fallbackPolling": "dynamicPriority",
69
+ "excludeDirectories": [
70
+ "**/node_modules",
71
+ "**/dist",
72
+ "**/.build",
73
+ "**/.git",
74
+ "**/.data",
75
+ "**/.logs",
76
+ "**/.*"
77
+ ],
78
+ "excludeFiles": [
79
+ "**/*.tmp",
80
+ "openapi.json",
81
+ "*.json"
82
+ ]
83
+ },
84
+ "include": [
85
+ "src/**/*"
86
+ ],
87
+ "exclude": [
88
+ "**/node_modules",
89
+ "**/build",
90
+ "**/dist",
91
+ "**/.*"
92
+ ],
93
+ "references": []
94
+ }
@@ -0,0 +1,16 @@
1
+ {
2
+ "extends": "../../tsconfig.base.json",
3
+ "compilerOptions": {
4
+ "baseUrl": ".",
5
+ "outDir": "./dist",
6
+ "tsBuildInfoFile": "./dist/.tsbuildinfo",
7
+ "rootDir": "./src",
8
+ "target": "ES2018",
9
+ "module": "CommonJS",
10
+ "emitDecoratorMetadata": true,
11
+ "experimentalDecorators": true
12
+ },
13
+ "include": [
14
+ "src/**/*"
15
+ ]
16
+ }