cvx-kit 0.1.12 → 0.1.14

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 (79) hide show
  1. package/AGENTS.md +47 -0
  2. package/CHANGELOG.md +36 -0
  3. package/README.md +144 -0
  4. package/dist/auth.d.mts +3 -1
  5. package/dist/auth.mjs +1 -1
  6. package/dist/auth.mjs.map +1 -1
  7. package/dist/index.d.mts +5 -2
  8. package/dist/index.mjs +1 -1
  9. package/dist/modules/contracts/binding.d.mts +13 -1
  10. package/dist/modules/contracts/binding.mjs +1 -1
  11. package/dist/modules/contracts/binding.mjs.map +1 -1
  12. package/dist/modules/effect/api-zod.d.mts +1 -1
  13. package/dist/modules/effect/command.d.mts +13 -9
  14. package/dist/modules/effect/command.mjs.map +1 -1
  15. package/dist/modules/effect/domain.d.mts +31 -3
  16. package/dist/modules/effect/domain.mjs.map +1 -1
  17. package/dist/modules/effect/query.d.mts +6 -5
  18. package/dist/modules/effect/query.mjs.map +1 -1
  19. package/dist/modules/foundation/foundation.d.mts +14 -13
  20. package/dist/modules/foundation/foundation.mjs.map +1 -1
  21. package/dist/modules/foundation/operation.d.mts +20 -1
  22. package/dist/modules/foundation/operation.mjs.map +1 -1
  23. package/dist/oxlint/architecture.d.mts +2 -0
  24. package/dist/oxlint/architecture.mjs +1 -1
  25. package/dist/oxlint/architecture.mjs.map +1 -1
  26. package/dist/oxlint/ast.d.mts +10 -1
  27. package/dist/oxlint/ast.mjs +1 -1
  28. package/dist/oxlint/ast.mjs.map +1 -1
  29. package/dist/oxlint.d.mts +1 -1
  30. package/dist/oxlint.mjs +1 -1
  31. package/dist/oxlint.mjs.map +1 -1
  32. package/dist/querying/cursors.d.mts +45 -0
  33. package/dist/querying/cursors.mjs +2 -0
  34. package/dist/querying/cursors.mjs.map +1 -0
  35. package/dist/querying/execution.d.mts +30 -0
  36. package/dist/querying/execution.mjs +2 -0
  37. package/dist/querying/execution.mjs.map +1 -0
  38. package/dist/querying/filters.d.mts +136 -0
  39. package/dist/querying/filters.mjs +2 -0
  40. package/dist/querying/filters.mjs.map +1 -0
  41. package/dist/querying/planner.d.mts +50 -0
  42. package/dist/querying/planner.mjs +2 -0
  43. package/dist/querying/planner.mjs.map +1 -0
  44. package/dist/querying/relationships.d.mts +41 -0
  45. package/dist/querying/relationships.mjs +2 -0
  46. package/dist/querying/relationships.mjs.map +1 -0
  47. package/dist/querying/security.d.mts +107 -0
  48. package/dist/querying/security.mjs +2 -0
  49. package/dist/querying/security.mjs.map +1 -0
  50. package/dist/querying.d.mts +39 -0
  51. package/dist/querying.mjs +2 -0
  52. package/dist/querying.mjs.map +1 -0
  53. package/dist/relations-public.d.mts +2 -0
  54. package/dist/relations-public.mjs +1 -0
  55. package/dist/relations.d.mts +155 -0
  56. package/dist/relations.mjs +2 -0
  57. package/dist/relations.mjs.map +1 -0
  58. package/dist/zod-convex.d.mts +10 -0
  59. package/dist/zod-convex.mjs +2 -0
  60. package/dist/zod-convex.mjs.map +1 -0
  61. package/dist/zod-registration.d.mts +10 -0
  62. package/dist/zod-registration.mjs +2 -0
  63. package/dist/zod-registration.mjs.map +1 -0
  64. package/dist/zod-table.d.mts +63 -8
  65. package/dist/zod-table.mjs +1 -1
  66. package/dist/zod-table.mjs.map +1 -1
  67. package/docs/conventions.md +12 -0
  68. package/docs/domain-contracts.md +42 -9
  69. package/docs/llms.md +15 -5
  70. package/docs/oxlint.md +129 -25
  71. package/docs/querying.md +293 -0
  72. package/docs/zod-table.md +93 -13
  73. package/package.json +11 -1
  74. package/scripts/owned-process.mjs +140 -0
  75. package/scripts/owned-process.test.mjs +107 -0
  76. package/scripts/smoke-packed-querying.mjs +296 -0
  77. package/scripts/test-packed-effect.mjs +10 -1
  78. package/scripts/test-packed-oxlint.mjs +5 -1
  79. package/scripts/test-packed-querying.mjs +185 -0
@@ -1,6 +1,7 @@
1
1
  import { ContractInput, ContractOutput, NeutralSchema } from "../contracts/contract.mjs";
2
2
  import { AuditEntryInput } from "../../components/foundation/client.mjs";
3
3
  import { DomainOperationContract, ExactOperationKeys } from "../contracts/domain.mjs";
4
+ import { DeclaredSchemas } from "../contracts/binding.mjs";
4
5
  //#region src/modules/foundation/operation.d.ts
5
6
  type Supported<A> = A | PromiseLike<A>;
6
7
  export type Audit = Omit<AuditEntryInput, 'classification'> | null;
@@ -81,7 +82,25 @@ type Forbidden = {
81
82
  replayResult?: never;
82
83
  wire?: never;
83
84
  };
84
- export type DomainFactory<Context, Entries extends Readonly<Record<string, NormalEntry>>, Command extends boolean, Required extends boolean> = { [Kind in Command extends true ? 'command' : 'query']: { [Key in keyof Entries]: <const Implementation extends object>(implementation: Implementation & Definition<Context, Entries[Key]> & Forbidden & CommandRules<Context, Entries[Key], Command, Required>) => CheckedDefinition<Context, Entries[Key] & Implementation, Key>; }; };
85
+ type HandlerOptions<Context, Input extends NeutralSchema, Result extends NeutralSchema, Command extends boolean, Required extends boolean> = Omit<Definition<Context, {
86
+ input: Input;
87
+ result: Result;
88
+ }>, 'handler'> & Forbidden & {
89
+ handler?: never;
90
+ } & CommandRules<Context, {
91
+ input: Input;
92
+ result: Result;
93
+ }, Command, Required>;
94
+ type HandlerArguments<Options, Required extends boolean> = Required extends true ? [options: Options] : [options?: Options];
95
+ export type DomainFactory<Context, Entries extends Readonly<Record<string, NormalEntry>>, Command extends boolean, Required extends boolean> = { [Kind in Command extends true ? 'command' : 'query']: { [Key in keyof Entries]: <const Implementation extends object>(implementation: Implementation & Definition<Context, Entries[Key]> & Forbidden & CommandRules<Context, Entries[Key], Command, Required>) => DeclaredSchemas<Pick<Entries[Key], 'input' | 'result'>> & CheckedDefinition<Context, Entries[Key] & Implementation, Key>; } & {
96
+ handler: <const Input extends NeutralSchema, const Result extends NeutralSchema, Key extends keyof Entries, Handler extends Supported<ContractInput<Result>>, const Implementation extends object = Record<never, never>>(handler: (input: ContractOutput<Input>, context: Context) => Handler, ...options: HandlerArguments<Implementation & HandlerOptions<Context, Input, Result, Command, Required>, Command extends true ? Required : false>) => DeclaredSchemas<{
97
+ input: Input;
98
+ result: Result;
99
+ }> & CheckedDefinition<Context, NoInfer<Implementation> & {
100
+ handler: (input: ContractOutput<Input>, context: Context) => Handler;
101
+ }, Key>;
102
+ }; };
103
+ export type DomainImplementations<Context, Entries extends Readonly<Record<string, NormalEntry>>, Command extends boolean, Required extends boolean> = { [Key in keyof Entries]: DeclaredSchemas<Pick<Entries[Key], 'input' | 'result'>> & CheckedDefinition<Context, Definition<Context, Entries[Key]> & CommandRules<Context, Entries[Key], Command, Required>, Key>; };
85
104
  export declare function domainFactory<Context, Entries extends Readonly<Record<string, NormalEntry>>, Command extends boolean, Required extends boolean>(entries: Entries, command: Command): DomainFactory<Context, Entries, Command, Required>;
86
105
  export declare function operationFactory<Context, Required extends boolean = true>(): {
87
106
  command: <const Input extends NeutralSchema, const Result extends NeutralSchema, const Wire extends NeutralSchema, const Replay extends NeutralSchema, const Implementation extends object>(implementation: Implementation & {
@@ -1 +1 @@
1
- {"version":3,"file":"operation.mjs","names":["domainFactory","helpers","domainHelpers","entries","command","operationFactory","implementation","query"],"sources":["../../../src/modules/foundation/operation.ts"],"sourcesContent":["/* oxlint-disable anti-slop/no-object-parameters -- Internal helper storage is heterogeneous; the exported mapped signatures validate the schema-paired implementation. */\nimport type { AuditEntryInput } from '../../components/foundation/client'\nimport type { ContractInput, ContractOutput, NeutralSchema } from '../contracts/contract'\nimport type { DomainOperationContract, ExactOperationKeys } from '../contracts/domain'\nimport { domainHelpers } from '../contracts/binding'\n\ntype Supported<A> = A | PromiseLike<A>\nexport type Audit = Omit<AuditEntryInput, 'classification'> | null\nexport type NormalEntry = DomainOperationContract & {\n\tinput: NeutralSchema\n\tresult: NeutralSchema\n\treplayResult?: NeutralSchema\n\twire?: { schema: NeutralSchema; project: Function }\n}\ndeclare const checkedOperation: unique symbol\nexport type CheckedDefinition<Context, Definition, Key = unknown> = NoInfer<Definition> & {\n\treadonly [checkedOperation]: {\n\t\tcontext: (context: Context) => void\n\t\tdefinition: Definition\n\t\tkey: Key\n\t}\n}\nexport type CheckedOperation<Context> = {\n\treadonly [checkedOperation]: {\n\t\tcontext: (context: Context) => void\n\t\tdefinition: unknown\n\t\tkey: unknown\n\t}\n}\nexport type ValidatedOperations<Operations> = {\n\t[Key in keyof Operations]: Operations[Key] extends {\n\t\treadonly [checkedOperation]: { definition: infer Definition }\n\t}\n\t\t? Operations[Key] extends Definition\n\t\t\t? Operations[Key]\n\t\t\t: never\n\t\t: never\n}\nexport type ExactOperations<Operations, Entries> = ExactOperationKeys<Operations, Entries> & {\n\t[Key in keyof Operations]: Operations[Key] extends { readonly [checkedOperation]: { key: Key } }\n\t\t? Operations[Key]\n\t\t: never\n}\ntype Definition<Context, Entry extends NormalEntry> = {\n\thandler: (\n\t\tinput: ContractOutput<Entry['input']>,\n\t\tcontext: Context,\n\t) => Supported<ContractInput<Entry['result']>>\n\tpermission?: string\n\tmetadata?: object\n\taggregates?: readonly string[]\n\tguard?: (context: Context, input: ContractOutput<Entry['input']>) => Supported<void>\n\tprepare?: (\n\t\tcontext: Context,\n\t\tinput: ContractOutput<Entry['input']>,\n\t) => Supported<\n\t\t| { kind: 'replay'; result: unknown }\n\t\t| { kind: 'execute'; complete?: (result: ContractOutput<Entry['result']>) => Supported<void> }\n\t>\n\taudit?: (\n\t\tresolution: {\n\t\t\tcommand: ContractOutput<Entry['input']>\n\t\t\tresult: ContractOutput<Entry['result']>\n\t\t},\n\t\tcontext: Context,\n\t) => Supported<Audit>\n\tmiddleware?: (input: {\n\t\toperation: string\n\t\tinput: ContractOutput<Entry['input']>\n\t\tcommand: ContractOutput<Entry['input']>\n\t\tcontext: Context\n\t\tmetadata: object\n\t\tnext: (options?: { context?: object }) => Promise<ContractInput<Entry['result']>>\n\t}) => Supported<ContractInput<Entry['result']>>\n}\ntype CommandRules<\n\tContext,\n\tEntry extends NormalEntry,\n\tCommand extends boolean,\n\tRequired extends boolean,\n> = Command extends false\n\t? { audit?: never; prepare?: never; aggregates?: never; replayResult?: never }\n\t: Required extends true\n\t\t? { audit: NonNullable<Definition<Context, Entry>['audit']> }\n\t\t: {}\ntype Forbidden = {\n\tinput?: never\n\tresult?: never\n\tclassification?: never\n\treplayResult?: never\n\twire?: never\n}\nexport type DomainFactory<\n\tContext,\n\tEntries extends Readonly<Record<string, NormalEntry>>,\n\tCommand extends boolean,\n\tRequired extends boolean,\n> = {\n\t[Kind in Command extends true ? 'command' : 'query']: {\n\t\t[Key in keyof Entries]: <const Implementation extends object>(\n\t\t\timplementation: Implementation &\n\t\t\t\tDefinition<Context, Entries[Key]> &\n\t\t\t\tForbidden &\n\t\t\t\tCommandRules<Context, Entries[Key], Command, Required>,\n\t\t) => CheckedDefinition<Context, Entries[Key] & Implementation, Key>\n\t}\n}\nexport function domainFactory<\n\tContext,\n\tEntries extends Readonly<Record<string, NormalEntry>>,\n\tCommand extends boolean,\n\tRequired extends boolean,\n>(entries: Entries, command: Command): DomainFactory<Context, Entries, Command, Required> {\n\tconst helpers = domainHelpers(entries)\n\t// SAFETY: paired schemas and callbacks are checked by the named helper signatures.\n\treturn { [command ? 'command' : 'query']: helpers } as DomainFactory<\n\t\tContext,\n\t\tEntries,\n\t\tCommand,\n\t\tRequired\n\t>\n}\nexport function operationFactory<Context, Required extends boolean = true>() {\n\tfunction command<\n\t\tconst Input extends NeutralSchema,\n\t\tconst Result extends NeutralSchema,\n\t\tconst Wire extends NeutralSchema,\n\t\tconst Replay extends NeutralSchema,\n\t\tconst Implementation extends object,\n\t>(\n\t\timplementation: Implementation & {\n\t\t\tinput: Input\n\t\t\tresult: Result\n\t\t\tclassification: string\n\t\t\treplayResult?: Replay &\n\t\t\t\t(ContractOutput<Replay> extends ContractOutput<Result> ? unknown : never)\n\t\t\twire?: { schema: Wire; project: (result: ContractOutput<Result>) => ContractInput<Wire> }\n\t\t} & Definition<Context, { input: Input; result: Result }> &\n\t\t\tCommandRules<Context, { input: Input; result: Result }, true, Required>,\n\t) {\n\t\t// SAFETY: this type-only evidence records the complete helper-checked definition.\n\t\treturn implementation as CheckedDefinition<Context, typeof implementation>\n\t}\n\tfunction query<\n\t\tconst Input extends NeutralSchema,\n\t\tconst Result extends NeutralSchema,\n\t\tconst Wire extends NeutralSchema,\n\t\tconst Implementation extends object,\n\t>(\n\t\timplementation: Implementation & {\n\t\t\tinput: Input\n\t\t\tresult: Result\n\t\t\tclassification?: string\n\t\t\twire?: { schema: Wire; project: (result: ContractOutput<Result>) => ContractInput<Wire> }\n\t\t} & Definition<Context, { input: Input; result: Result }> &\n\t\t\tCommandRules<Context, { input: Input; result: Result }, false, true>,\n\t) {\n\t\t// SAFETY: this type-only evidence records the complete helper-checked definition.\n\t\treturn implementation as CheckedDefinition<Context, typeof implementation>\n\t}\n\treturn { command, query }\n}\nexport type InlineFactory<Context, Required extends boolean> = ReturnType<\n\ttypeof operationFactory<Context, Required>\n>\n"],"mappings":"yDA2GA,SAAgBA,EAKd,EAAkB,EAAsE,CACzF,IAAMC,EAAUC,EAAcC,CAAO,EAErC,MAAO,EAAGC,EAAU,UAAY,SAAUH,CAAQ,CAMnD,CACA,SAAgBI,GAA6D,CAC5E,SAASD,EAOR,EASC,CAED,OAAOE,CACR,CACA,SAASC,EAMR,EAOC,CAED,OAAOD,CACR,CACA,MAAO,CAAE,UAAS,OAAM,CACzB"}
1
+ {"version":3,"file":"operation.mjs","names":["domainFactory","helpers","domainHelpers","entries","command","operationFactory","implementation","query"],"sources":["../../../src/modules/foundation/operation.ts"],"sourcesContent":["/* oxlint-disable anti-slop/no-object-parameters -- Internal helper storage is heterogeneous; the exported mapped signatures validate the schema-paired implementation. */\nimport type { AuditEntryInput } from '../../components/foundation/client'\nimport type { ContractInput, ContractOutput, NeutralSchema } from '../contracts/contract'\nimport type { DomainOperationContract, ExactOperationKeys } from '../contracts/domain'\nimport { domainHelpers, type DeclaredSchemas } from '../contracts/binding'\n\ntype Supported<A> = A | PromiseLike<A>\nexport type Audit = Omit<AuditEntryInput, 'classification'> | null\nexport type NormalEntry = DomainOperationContract & {\n\tinput: NeutralSchema\n\tresult: NeutralSchema\n\treplayResult?: NeutralSchema\n\twire?: { schema: NeutralSchema; project: Function }\n}\ndeclare const checkedOperation: unique symbol\nexport type CheckedDefinition<Context, Definition, Key = unknown> = NoInfer<Definition> & {\n\treadonly [checkedOperation]: {\n\t\tcontext: (context: Context) => void\n\t\tdefinition: Definition\n\t\tkey: Key\n\t}\n}\nexport type CheckedOperation<Context> = {\n\treadonly [checkedOperation]: {\n\t\tcontext: (context: Context) => void\n\t\tdefinition: unknown\n\t\tkey: unknown\n\t}\n}\nexport type ValidatedOperations<Operations> = {\n\t[Key in keyof Operations]: Operations[Key] extends {\n\t\treadonly [checkedOperation]: { definition: infer Definition }\n\t}\n\t\t? Operations[Key] extends Definition\n\t\t\t? Operations[Key]\n\t\t\t: never\n\t\t: never\n}\nexport type ExactOperations<Operations, Entries> = ExactOperationKeys<Operations, Entries> & {\n\t[Key in keyof Operations]: Operations[Key] extends { readonly [checkedOperation]: { key: Key } }\n\t\t? Operations[Key]\n\t\t: never\n}\ntype Definition<Context, Entry extends NormalEntry> = {\n\thandler: (\n\t\tinput: ContractOutput<Entry['input']>,\n\t\tcontext: Context,\n\t) => Supported<ContractInput<Entry['result']>>\n\tpermission?: string\n\tmetadata?: object\n\taggregates?: readonly string[]\n\tguard?: (context: Context, input: ContractOutput<Entry['input']>) => Supported<void>\n\tprepare?: (\n\t\tcontext: Context,\n\t\tinput: ContractOutput<Entry['input']>,\n\t) => Supported<\n\t\t| { kind: 'replay'; result: unknown }\n\t\t| { kind: 'execute'; complete?: (result: ContractOutput<Entry['result']>) => Supported<void> }\n\t>\n\taudit?: (\n\t\tresolution: {\n\t\t\tcommand: ContractOutput<Entry['input']>\n\t\t\tresult: ContractOutput<Entry['result']>\n\t\t},\n\t\tcontext: Context,\n\t) => Supported<Audit>\n\tmiddleware?: (input: {\n\t\toperation: string\n\t\tinput: ContractOutput<Entry['input']>\n\t\tcommand: ContractOutput<Entry['input']>\n\t\tcontext: Context\n\t\tmetadata: object\n\t\tnext: (options?: { context?: object }) => Promise<ContractInput<Entry['result']>>\n\t}) => Supported<ContractInput<Entry['result']>>\n}\ntype CommandRules<\n\tContext,\n\tEntry extends NormalEntry,\n\tCommand extends boolean,\n\tRequired extends boolean,\n> = Command extends false\n\t? { audit?: never; prepare?: never; aggregates?: never; replayResult?: never }\n\t: Required extends true\n\t\t? { audit: NonNullable<Definition<Context, Entry>['audit']> }\n\t\t: {}\ntype Forbidden = {\n\tinput?: never\n\tresult?: never\n\tclassification?: never\n\treplayResult?: never\n\twire?: never\n}\ntype HandlerOptions<\n\tContext,\n\tInput extends NeutralSchema,\n\tResult extends NeutralSchema,\n\tCommand extends boolean,\n\tRequired extends boolean,\n> = Omit<Definition<Context, { input: Input; result: Result }>, 'handler'> &\n\tForbidden & { handler?: never } & CommandRules<\n\t\tContext,\n\t\t{ input: Input; result: Result },\n\t\tCommand,\n\t\tRequired\n\t>\ntype HandlerArguments<Options, Required extends boolean> = Required extends true\n\t? [options: Options]\n\t: [options?: Options]\n\nexport type DomainFactory<\n\tContext,\n\tEntries extends Readonly<Record<string, NormalEntry>>,\n\tCommand extends boolean,\n\tRequired extends boolean,\n> = {\n\t[Kind in Command extends true ? 'command' : 'query']: {\n\t\t[Key in keyof Entries]: <const Implementation extends object>(\n\t\t\timplementation: Implementation &\n\t\t\t\tDefinition<Context, Entries[Key]> &\n\t\t\t\tForbidden &\n\t\t\t\tCommandRules<Context, Entries[Key], Command, Required>,\n\t\t) => DeclaredSchemas<Pick<Entries[Key], 'input' | 'result'>> &\n\t\t\tCheckedDefinition<Context, Entries[Key] & Implementation, Key>\n\t} & {\n\t\thandler: <\n\t\t\tconst Input extends NeutralSchema,\n\t\t\tconst Result extends NeutralSchema,\n\t\t\tKey extends keyof Entries,\n\t\t\tHandler extends Supported<ContractInput<Result>>,\n\t\t\tconst Implementation extends object = Record<never, never>,\n\t\t>(\n\t\t\thandler: (input: ContractOutput<Input>, context: Context) => Handler,\n\t\t\t...options: HandlerArguments<\n\t\t\t\tImplementation & HandlerOptions<Context, Input, Result, Command, Required>,\n\t\t\t\tCommand extends true ? Required : false\n\t\t\t>\n\t\t) => DeclaredSchemas<{ input: Input; result: Result }> &\n\t\t\tCheckedDefinition<\n\t\t\t\tContext,\n\t\t\t\tNoInfer<Implementation> & {\n\t\t\t\t\thandler: (input: ContractOutput<Input>, context: Context) => Handler\n\t\t\t\t},\n\t\t\t\tKey\n\t\t\t>\n\t}\n}\nexport type DomainImplementations<\n\tContext,\n\tEntries extends Readonly<Record<string, NormalEntry>>,\n\tCommand extends boolean,\n\tRequired extends boolean,\n> = {\n\t[Key in keyof Entries]: DeclaredSchemas<Pick<Entries[Key], 'input' | 'result'>> &\n\t\tCheckedDefinition<\n\t\t\tContext,\n\t\t\tDefinition<Context, Entries[Key]> & CommandRules<Context, Entries[Key], Command, Required>,\n\t\t\tKey\n\t\t>\n}\nexport function domainFactory<\n\tContext,\n\tEntries extends Readonly<Record<string, NormalEntry>>,\n\tCommand extends boolean,\n\tRequired extends boolean,\n>(entries: Entries, command: Command): DomainFactory<Context, Entries, Command, Required> {\n\tconst helpers = domainHelpers(entries)\n\t// SAFETY: helper signatures check callbacks; registration pairs drafts with their declarations.\n\treturn { [command ? 'command' : 'query']: helpers } as DomainFactory<\n\t\tContext,\n\t\tEntries,\n\t\tCommand,\n\t\tRequired\n\t>\n}\nexport function operationFactory<Context, Required extends boolean = true>() {\n\tfunction command<\n\t\tconst Input extends NeutralSchema,\n\t\tconst Result extends NeutralSchema,\n\t\tconst Wire extends NeutralSchema,\n\t\tconst Replay extends NeutralSchema,\n\t\tconst Implementation extends object,\n\t>(\n\t\timplementation: Implementation & {\n\t\t\tinput: Input\n\t\t\tresult: Result\n\t\t\tclassification: string\n\t\t\treplayResult?: Replay &\n\t\t\t\t(ContractOutput<Replay> extends ContractOutput<Result> ? unknown : never)\n\t\t\twire?: { schema: Wire; project: (result: ContractOutput<Result>) => ContractInput<Wire> }\n\t\t} & Definition<Context, { input: Input; result: Result }> &\n\t\t\tCommandRules<Context, { input: Input; result: Result }, true, Required>,\n\t) {\n\t\t// SAFETY: this type-only evidence records the complete helper-checked definition.\n\t\treturn implementation as CheckedDefinition<Context, typeof implementation>\n\t}\n\tfunction query<\n\t\tconst Input extends NeutralSchema,\n\t\tconst Result extends NeutralSchema,\n\t\tconst Wire extends NeutralSchema,\n\t\tconst Implementation extends object,\n\t>(\n\t\timplementation: Implementation & {\n\t\t\tinput: Input\n\t\t\tresult: Result\n\t\t\tclassification?: string\n\t\t\twire?: { schema: Wire; project: (result: ContractOutput<Result>) => ContractInput<Wire> }\n\t\t} & Definition<Context, { input: Input; result: Result }> &\n\t\t\tCommandRules<Context, { input: Input; result: Result }, false, true>,\n\t) {\n\t\t// SAFETY: this type-only evidence records the complete helper-checked definition.\n\t\treturn implementation as CheckedDefinition<Context, typeof implementation>\n\t}\n\treturn { command, query }\n}\nexport type InlineFactory<Context, Required extends boolean> = ReturnType<\n\ttypeof operationFactory<Context, Required>\n>\n"],"mappings":"yDA+JA,SAAgBA,EAKd,EAAkB,EAAsE,CACzF,IAAMC,EAAUC,EAAcC,CAAO,EAErC,MAAO,EAAGC,EAAU,UAAY,SAAUH,CAAQ,CAMnD,CACA,SAAgBI,GAA6D,CAC5E,SAASD,EAOR,EASC,CAED,OAAOE,CACR,CACA,SAASC,EAMR,EAOC,CAED,OAAOD,CACR,CACA,MAAO,CAAE,UAAS,OAAM,CACzB"}
@@ -15,5 +15,7 @@ export declare function createResolver(): ResolverFactory;
15
15
  export declare function resolveImport(resolver: ResolverFactory, filename: string, source: string): string | null;
16
16
  /** The lint rule runs the project scan on one deterministic source file. */
17
17
  export declare function architectureAnchor(root: string): string | null;
18
+ /** Only these two factory declarations may omit root business ownership. */
19
+ export declare function narrowRootDeclaration(file: string, source: string): boolean;
18
20
  //#endregion
19
21
  //# sourceMappingURL=architecture.d.mts.map
@@ -1,2 +1,2 @@
1
- import{dirname as e,relative as t,resolve as n,sep as r}from"node:path";import{existsSync as i,readFileSync as a,readdirSync as o,realpathSync as s}from"node:fs";import{Visitor as c,parseSync as l}from"oxc-parser";import{ResolverFactory as u}from"oxc-resolver";function d(o={}){let c=n(o.cwd??process.cwd(),o.convexDir??`convex`),u=i(c)?s(c):c,d=[];if(!i(u))return[{code:`missing-root`,file:`.`,message:`Convex directory does not exist: ${u}`}];let m=h(u,d),y=/* @__PURE__ */ new Set,w=/* @__PURE__ */ new Set,T=/* @__PURE__ */ new Map,E=/* @__PURE__ */ new Map,D=f();for(let i of m){let o=n(u,i),s=l(o,a(o,`utf8`));if(s.errors.length){d.push({code:`parse`,file:i,message:`Cannot validate ${i}: ${s.errors[0].message}`});continue}if(g(i)){i.includes(`__tests__/`)?e(i).endsWith(`__tests__`)&&v(s.program)&&w.add(e(e(i))):d.push({code:`test-location`,file:i,message:`Place tests in a sibling __tests__/ directory.`});continue}if(i.split(`/`).includes(`__tests__`))continue;/^domain\/[^/]+$/.test(i)&&i!==`domain/table.ts`&&d.push({code:`domain-entry`,file:i,message:`Domain source belongs in domain/<module>/ or domain/shared/. Only domain/table.ts assembles module tables.`}),_(s.program)&&i!==`domain/table.ts`&&y.add(e(i));let c=x(i)??``,f=/* @__PURE__ */ new Set;E.set(i,f);for(let e of b(s.program)){let n=p(D,o,e);if(!n)continue;let i=t(u,n).split(r).join(`/`);f.add(i);let a=x(i);if(c&&a&&c!==a){let e=T.get(c)??/* @__PURE__ */ new Set;T.set(c,e),e.add(a)}}}for(let e of y)w.has(e)||d.push({code:`tests`,file:e,message:`${e}/__tests__/ must contain a .test or .spec file with a nonempty, non-skipped test. Parent or child suites do not count.`});d.push(...C(E));for(let e of S(T))d.push({code:`cycle`,file:e[0],message:`Module dependency cycle: ${e.join(` → `)}.`});return d.sort((e,t)=>e.file.localeCompare(t.file)||e.code.localeCompare(t.code))}function f(){return new u({tsconfig:`auto`,extensions:[`.ts`,`.tsx`,`.mts`,`.cts`,`.js`,`.jsx`,`.mjs`,`.cjs`,`.json`],extensionAlias:{".js":[`.ts`,`.tsx`,`.js`],".mjs":[`.mts`,`.mjs`],".cjs":[`.cts`,`.cjs`]},conditionNames:[`types`,`import`,`node`,`default`],symlinks:!0})}function p(t,r,i){return t.resolveFileSync(r,i).path||(i.startsWith(`.`)?n(e(r),i):null)}function m(e){if(!i(e))return null;if(i(n(e,`convex.config.ts`)))return s(n(e,`convex.config.ts`));e=s(e);for(let t of h(e,[]))if(!t.includes(`__tests__/`)&&!g(t))return n(e,t);return null}function*h(e,i){let a=/* @__PURE__ */ new Set([`_generated`,`__tests__`,`api`,`domain`,`application`,`migrations`,`components`]);function*s(c){for(let l of o(c,{withFileTypes:!0}).sort((e,t)=>e.name.localeCompare(t.name))){let o=n(c,l.name),u=t(e,o).split(r).join(`/`);if(l.isSymbolicLink()){i.push({code:`symlink`,file:u,message:`Keep application source inside its owning directory; symlinked files and folders are not allowed.`});continue}l.isDirectory()?(c===e&&!a.has(l.name)&&i.push({code:`root-directory`,file:u,message:`Root folder ${l.name}/ is not allowed. Use api/, domain/, application/, migrations/, components/, __tests__/, or _generated/.`}),l.name!==`_generated`&&l.name!==`node_modules`&&!l.name.startsWith(`.`)&&(yield*s(o))):/\.[cm]?[jt]sx?$/.test(l.name)&&!/\.d\.[cm]?ts$/.test(l.name)&&(yield u)}}yield*s(e)}function g(e){return/\.(?:test|spec)\.[cm]?[jt]sx?$/.test(e)}function _(e){return e.body.some(e=>{let t=e.type===`ExportNamedDeclaration`?e.declaration:e;return t&&`declare`in t&&t.declare||e.type===`ImportDeclaration`||e.type===`EmptyStatement`?!1:e.type===`ExportNamedDeclaration`?e.exportKind===`type`||!e.declaration?!1:![`TSInterfaceDeclaration`,`TSTypeAliasDeclaration`,`TSDeclareFunction`].includes(e.declaration.type):![`TSInterfaceDeclaration`,`TSTypeAliasDeclaration`,`TSDeclareFunction`,`ExportAllDeclaration`].includes(e.type)})}function v(e){let t=/* @__PURE__ */ new Map([[`test`,`test`],[`it`,`it`],[`describe`,`describe`],[`suite`,`suite`]]);for(let n of e.body){let e=n.type===`ExportNamedDeclaration`?n.declaration:n;if(e?.type===`FunctionDeclaration`&&e.id&&t.delete(e.id.name),e?.type===`VariableDeclaration`)for(let n of e.declarations)n.id.type===`Identifier`&&t.delete(n.id.name);if(n.type===`ImportDeclaration`)for(let e of n.specifiers)t.delete(e.local.name),[`vitest`,`vite-plus/test`,`bun:test`,`node:test`,`@jest/globals`].includes(n.source.value)&&(e.type===`ImportNamespaceSpecifier`?t.set(e.local.name,`*`):e.type===`ImportDefaultSpecifier`?t.set(e.local.name,`test`):e.imported.type===`Identifier`&&t.set(e.local.name,e.imported.name))}let n=[];new c({CallExpression(e){n.push(e)}}).visit(e);let r=n.filter(e=>{let n=y(e.callee,t);return[`test`,`it`,`describe`,`suite`].includes(n[0])&&(n.some(e=>[`skip`,`todo`,`skipIf`,`runIf`].includes(e))||e.arguments.some(e=>e.type===`ObjectExpression`&&e.properties.some(e=>e.type===`Property`&&[`skip`,`todo`].includes(e.key.type===`Identifier`?e.key.name:e.key.type===`Literal`?String(e.key.value):``)&&(e.value.type!==`Literal`||e.value.value!==!1))))});return n.some(e=>{let n=y(e.callee,t);return![`test`,`it`].includes(n[0])||r.some(t=>e.start>=t.start&&e.end<=t.end)?!1:e.arguments.some(e=>(e.type===`ArrowFunctionExpression`||e.type===`FunctionExpression`)&&e.body&&(e.body.type!==`BlockStatement`||e.body.body.some(e=>e.type!==`EmptyStatement`)))})}function y(e,t){if(e.type===`Identifier`){let n=t.get(e.name);return n?[n]:[]}if(e.type===`CallExpression`)return y(e.callee,t);if(e.type===`MemberExpression`){let n=y(e.object,t),r=!e.computed&&e.property.type===`Identifier`?e.property.name:e.property.type===`Literal`?String(e.property.value):``;return!n.length||!r?[]:n[0]===`*`?[r]:[...n,r]}return[]}function b(e){let t=[];return new c({ImportDeclaration(e){e.importKind!==`type`&&(e.specifiers.length===0||e.specifiers.some(e=>e.type!==`ImportSpecifier`||e.importKind!==`type`))&&t.push(e.source.value)},ExportNamedDeclaration(e){e.source&&e.exportKind!==`type`&&e.specifiers.some(e=>e.exportKind!==`type`)&&t.push(e.source.value)},ExportAllDeclaration(e){e.exportKind!==`type`&&t.push(e.source.value)},ImportExpression(e){e.source.type===`Literal`&&String(e.source.value)===e.source.value&&t.push(String(e.source.value))}}).visit(e),t}function x(e){let t=e.split(`/`);return t[0]===`domain`&&t.length>=3&&t[1]!==`__tests__`?`domain/${t[1]}`:null}function S(e){let t=/* @__PURE__ */ new Set,n=[],r=[];function i(a){let o=n.indexOf(a);if(o>=0){r.push([...n.slice(o),a]);return}if(!t.has(a)){n.push(a);for(let t of e.get(a)??[])i(t);n.pop(),t.add(a)}}for(let t of e.keys())i(t);return r}function C(e){let t=/* @__PURE__ */ new Map;for(let[n,r]of e){let i=x(n)??``;if(!i||i===`domain/shared`)continue;let a=/* @__PURE__ */ new Set;function o(n){if(!n.startsWith(`domain/shared/`)||a.has(n))return;a.add(n);let r=t.get(n)??/* @__PURE__ */ new Set;r.add(i),t.set(n,r);for(let t of e.get(n)??[])o(t)}for(let e of r)o(e)}let n=[];for(let[e,r]of t)r.size===1&&n.push({code:`shared-owner`,file:e,message:`This shared implementation is used only by ${[...r][0]}. Move it into that module until another module needs it.`});return n}export{m as architectureAnchor,f as createResolver,d as inspectArchitecture,p as resolveImport};
1
+ import{dirname as e,relative as t,resolve as n,sep as r}from"node:path";import{existsSync as i,readFileSync as a,readdirSync as o,realpathSync as s}from"node:fs";import{Visitor as c,parseSync as l}from"oxc-parser";import{ResolverFactory as u}from"oxc-resolver";function d(o={}){let c=n(o.cwd??process.cwd(),o.convexDir??`convex`),u=i(c)?s(c):c,d=[];if(!i(u))return[{code:`missing-root`,file:`.`,message:`Convex directory does not exist: ${u}`}];let m=g(u,d),b=/* @__PURE__ */ new Set,T=/* @__PURE__ */ new Set,E=/* @__PURE__ */ new Map,D=/* @__PURE__ */ new Map,O=f();for(let i of m){let o=n(u,i),s=l(o,a(o,`utf8`));if(s.errors.length){d.push({code:`parse`,file:i,message:`Cannot validate ${i}: ${s.errors[0].message}`});continue}if(_(i)){i.includes(`__tests__/`)?e(i).endsWith(`__tests__`)&&y(s.program)&&T.add(e(e(i))):d.push({code:`test-location`,file:i,message:`Place tests in a sibling __tests__/ directory.`});continue}if(i.split(`/`).includes(`__tests__`))continue;/^domain\/[^/]+$/.test(i)&&i!==`domain/table.ts`&&d.push({code:`domain-entry`,file:i,message:`Domain source belongs in domain/<module>/ or domain/shared/. Only domain/table.ts assembles module tables.`}),v(s.program)&&i!==`domain/table.ts`&&!h(i,a(o,`utf8`))&&b.add(e(i));let c=S(i)??``,f=/* @__PURE__ */ new Set;D.set(i,f);for(let e of x(s.program)){let n=p(O,o,e);if(!n)continue;let i=t(u,n).split(r).join(`/`);f.add(i);let a=S(i);if(c&&a&&c!==a){let e=E.get(c)??/* @__PURE__ */ new Set;E.set(c,e),e.add(a)}}}for(let e of b)T.has(e)||d.push({code:`tests`,file:e,message:`${e}/__tests__/ must contain a .test or .spec file with a nonempty, non-skipped test. Parent or child suites do not count.`});d.push(...w(D));for(let e of C(E))d.push({code:`cycle`,file:e[0],message:`Module dependency cycle: ${e.join(` → `)}.`});return d.sort((e,t)=>e.file.localeCompare(t.file)||e.code.localeCompare(t.code))}function f(){return new u({tsconfig:`auto`,extensions:[`.ts`,`.tsx`,`.mts`,`.cts`,`.js`,`.jsx`,`.mjs`,`.cjs`,`.json`],extensionAlias:{".js":[`.ts`,`.tsx`,`.js`],".mjs":[`.mts`,`.mjs`],".cjs":[`.cts`,`.cjs`]},conditionNames:[`types`,`import`,`node`,`default`],symlinks:!0})}function p(t,r,i){return t.resolveFileSync(r,i).path||(i.startsWith(`.`)?n(e(r),i):null)}function m(e){if(!i(e))return null;if(i(n(e,`convex.config.ts`)))return s(n(e,`convex.config.ts`));e=s(e);for(let t of g(e,[]))if(!t.includes(`__tests__/`)&&!_(t))return n(e,t);return null}function h(e,t){let n=e===`relations.ts`?`defineRelations`:e===`querying.ts`?`createQueryEngine`:null;if(!n)return!1;let r=l(e,t);if(r.errors.length)return!1;let i=/* @__PURE__ */ new Map,a=/* @__PURE__ */ new Map,o=0,s=!1;function c(e,t=/* @__PURE__ */ new Set){if(e.type===`Identifier`){if(t.has(e.name))return null;let n=a.get(e.name);return n?c(n,new Set(t).add(e.name)):i.get(e.name)??null}return e.type===`MemberExpression`&&!e.computed&&e.property.type===`Identifier`&&c(e.object,t)===`*`?e.property.name:null}function u(e,t,n=!1){if(e.type===`Identifier`||e.type===`Literal`)return!0;if(e.type===`TSAsExpression`||e.type===`TSSatisfiesExpression`||e.type===`ParenthesizedExpression`)return u(e.expression,t,n);if(e.type===`MemberExpression`)return!e.computed&&u(e.object,t);if(e.type===`ArrayExpression`)return e.elements.every(e=>e!==null&&u(e,t));if(e.type===`ObjectExpression`)return e.properties.every(e=>e.type===`Property`&&!e.computed&&e.kind===`init`&&!e.method&&u(e.value,t));if(e.type===`ArrowFunctionExpression`&&n&&!t&&e.params.length===1&&e.params[0].type===`Identifier`&&!e.async){let t=e.body.type===`ParenthesizedExpression`?e.body.expression:e.body;return t.type===`ObjectExpression`&&u(t,e.params[0].name)}if(e.type===`CallExpression`&&t){let n=e.callee,r=[];for(;n.type===`MemberExpression`&&!n.computed&&n.property.type===`Identifier`;)r.unshift(n.property.name),n=n.object;return n.type===`Identifier`&&n.name===t&&(r.length===2&&[`one`,`many`].includes(r[0])||r.length===3&&r[2]===`through`)&&e.arguments.every(e=>u(e,t))}return!1}for(let t of r.program.body){if(t.type===`ImportDeclaration`){if(t.importKind===`type`)continue;for(let n of t.specifiers)(n.type!==`ImportSpecifier`||n.importKind!==`type`)&&[`cvx-kit`,`cvx-kit/${e.slice(0,-3)}`].includes(t.source.value)&&i.set(n.local.name,n.type===`ImportSpecifier`?n.imported.type===`Identifier`?n.imported.name:``:n.type===`ImportNamespaceSpecifier`?`*`:``);continue}if(t.type===`EmptyStatement`||t.type===`TSTypeAliasDeclaration`||t.type===`TSInterfaceDeclaration`)continue;let r=t.type===`ExportNamedDeclaration`?t.declaration:t;if(r?.type!==`VariableDeclaration`||r.kind!==`const`)return!1;for(let e of r.declarations){if(e.id.type!==`Identifier`||!e.init)return!1;if(e.init.type===`CallExpression`&&c(e.init.callee)===n){if(!e.init.arguments.every((e,t)=>u(e,void 0,n===`defineRelations`&&t===1)))return!1;o++,s||=t.type===`ExportNamedDeclaration`}else if(t.type===`ExportNamedDeclaration`||!u(e.init))return!1;a.set(e.id.name,e.init)}}return o===1&&s}function*g(e,i){let a=/* @__PURE__ */ new Set([`_generated`,`__tests__`,`api`,`domain`,`application`,`migrations`,`components`]);function*s(c){for(let l of o(c,{withFileTypes:!0}).sort((e,t)=>e.name.localeCompare(t.name))){let o=n(c,l.name),u=t(e,o).split(r).join(`/`);if(l.isSymbolicLink()){i.push({code:`symlink`,file:u,message:`Keep application source inside its owning directory; symlinked files and folders are not allowed.`});continue}l.isDirectory()?(c===e&&!a.has(l.name)&&i.push({code:`root-directory`,file:u,message:`Root folder ${l.name}/ is not allowed. Use api/, domain/, application/, migrations/, components/, __tests__/, or _generated/.`}),l.name!==`_generated`&&l.name!==`node_modules`&&!l.name.startsWith(`.`)&&(yield*s(o))):/\.[cm]?[jt]sx?$/.test(l.name)&&!/\.d\.[cm]?ts$/.test(l.name)&&(yield u)}}yield*s(e)}function _(e){return/\.(?:test|spec)\.[cm]?[jt]sx?$/.test(e)}function v(e){return e.body.some(e=>{let t=e.type===`ExportNamedDeclaration`?e.declaration:e;return t&&`declare`in t&&t.declare||e.type===`ImportDeclaration`||e.type===`EmptyStatement`?!1:e.type===`ExportNamedDeclaration`?e.exportKind===`type`||!e.declaration?!1:![`TSInterfaceDeclaration`,`TSTypeAliasDeclaration`,`TSDeclareFunction`].includes(e.declaration.type):![`TSInterfaceDeclaration`,`TSTypeAliasDeclaration`,`TSDeclareFunction`,`ExportAllDeclaration`].includes(e.type)})}function y(e){let t=/* @__PURE__ */ new Map([[`test`,`test`],[`it`,`it`],[`describe`,`describe`],[`suite`,`suite`]]);for(let n of e.body){let e=n.type===`ExportNamedDeclaration`?n.declaration:n;if(e?.type===`FunctionDeclaration`&&e.id&&t.delete(e.id.name),e?.type===`VariableDeclaration`)for(let n of e.declarations)n.id.type===`Identifier`&&t.delete(n.id.name);if(n.type===`ImportDeclaration`)for(let e of n.specifiers)t.delete(e.local.name),[`vitest`,`vite-plus/test`,`bun:test`,`node:test`,`@jest/globals`].includes(n.source.value)&&(e.type===`ImportNamespaceSpecifier`?t.set(e.local.name,`*`):e.type===`ImportDefaultSpecifier`?t.set(e.local.name,`test`):e.imported.type===`Identifier`&&t.set(e.local.name,e.imported.name))}let n=[];new c({CallExpression(e){n.push(e)}}).visit(e);let r=n.filter(e=>{let n=b(e.callee,t);return[`test`,`it`,`describe`,`suite`].includes(n[0])&&(n.some(e=>[`skip`,`todo`,`skipIf`,`runIf`].includes(e))||e.arguments.some(e=>e.type===`ObjectExpression`&&e.properties.some(e=>e.type===`Property`&&[`skip`,`todo`].includes(e.key.type===`Identifier`?e.key.name:e.key.type===`Literal`?String(e.key.value):``)&&(e.value.type!==`Literal`||e.value.value!==!1))))});return n.some(e=>{let n=b(e.callee,t);return![`test`,`it`].includes(n[0])||r.some(t=>e.start>=t.start&&e.end<=t.end)?!1:e.arguments.some(e=>(e.type===`ArrowFunctionExpression`||e.type===`FunctionExpression`)&&e.body&&(e.body.type!==`BlockStatement`||e.body.body.some(e=>e.type!==`EmptyStatement`)))})}function b(e,t){if(e.type===`Identifier`){let n=t.get(e.name);return n?[n]:[]}if(e.type===`CallExpression`)return b(e.callee,t);if(e.type===`MemberExpression`){let n=b(e.object,t),r=!e.computed&&e.property.type===`Identifier`?e.property.name:e.property.type===`Literal`?String(e.property.value):``;return!n.length||!r?[]:n[0]===`*`?[r]:[...n,r]}return[]}function x(e){let t=[];return new c({ImportDeclaration(e){e.importKind!==`type`&&(e.specifiers.length===0||e.specifiers.some(e=>e.type!==`ImportSpecifier`||e.importKind!==`type`))&&t.push(e.source.value)},ExportNamedDeclaration(e){e.source&&e.exportKind!==`type`&&e.specifiers.some(e=>e.exportKind!==`type`)&&t.push(e.source.value)},ExportAllDeclaration(e){e.exportKind!==`type`&&t.push(e.source.value)},ImportExpression(e){e.source.type===`Literal`&&String(e.source.value)===e.source.value&&t.push(String(e.source.value))}}).visit(e),t}function S(e){let t=e.split(`/`);return t[0]===`domain`&&t.length>=3&&t[1]!==`__tests__`?`domain/${t[1]}`:null}function C(e){let t=/* @__PURE__ */ new Set,n=[],r=[];function i(a){let o=n.indexOf(a);if(o>=0){r.push([...n.slice(o),a]);return}if(!t.has(a)){n.push(a);for(let t of e.get(a)??[])i(t);n.pop(),t.add(a)}}for(let t of e.keys())i(t);return r}function w(e){let t=/* @__PURE__ */ new Map;for(let[n,r]of e){let i=S(n)??``;if(!i||i===`domain/shared`)continue;let a=/* @__PURE__ */ new Set;function o(n){if(!n.startsWith(`domain/shared/`)||a.has(n))return;a.add(n);let r=t.get(n)??/* @__PURE__ */ new Set;r.add(i),t.set(n,r);for(let t of e.get(n)??[])o(t)}for(let e of r)o(e)}let n=[];for(let[e,r]of t)r.size===1&&n.push({code:`shared-owner`,file:e,message:`This shared implementation is used only by ${[...r][0]}. Move it into that module until another module needs it.`});return n}export{m as architectureAnchor,f as createResolver,d as inspectArchitecture,h as narrowRootDeclaration,p as resolveImport};
2
2
  //# sourceMappingURL=architecture.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"architecture.mjs","names":["inspectArchitecture","requestedRoot","resolve","options","root","existsSync","realpathSync","diagnostics","files","sourceFiles","required","tested","graph","dependencies","resolver","createResolver","file","filename","parsed","parseSync","readFileSync","testFile","dirname","hasRunnableTest","executable","owner","moduleOwner","targets","source","runtimeImports","target","resolveImport","targetFile","relative","sep","targetOwner","edges","directory","sharedOwnership","cycle","cycles","a","b","ResolverFactory","architectureAnchor","allowed","scan","entry","readdirSync","path","program","declaration","statement","names","item","specifier","calls","Visitor","node","skipped","parts","testCallee","part","argument","property","skip","name","base","imports","s","completed","stack","found","visit","index","dependency","consumers","visited","owners","next"],"sources":["../../src/oxlint/architecture.ts"],"sourcesContent":["import { existsSync, readdirSync, readFileSync, realpathSync } from 'node:fs'\nimport { dirname, relative, resolve, sep } from 'node:path'\nimport { parseSync, Visitor, type Program, type Node, type CallExpression } from 'oxc-parser'\nimport { ResolverFactory } from 'oxc-resolver'\n\nexport interface ArchitectureOptions {\n\tcwd?: string\n\tconvexDir?: string\n}\nexport interface ArchitectureDiagnostic {\n\tcode:\n\t\t| 'missing-root'\n\t\t| 'root-directory'\n\t\t| 'tests'\n\t\t| 'test-location'\n\t\t| 'parse'\n\t\t| 'cycle'\n\t\t| 'symlink'\n\t\t| 'domain-entry'\n\t\t| 'shared-owner'\n\tfile: string\n\tmessage: string\n}\n\n/** Full-project checks, independent of the consumer's test runner. No persistent cache. */\nexport function inspectArchitecture(options: ArchitectureOptions = {}): ArchitectureDiagnostic[] {\n\tconst requestedRoot = resolve(options.cwd ?? process.cwd(), options.convexDir ?? 'convex')\n\tconst root = existsSync(requestedRoot) ? realpathSync(requestedRoot) : requestedRoot\n\tconst diagnostics: ArchitectureDiagnostic[] = []\n\tif (!existsSync(root))\n\t\treturn [\n\t\t\t{ code: 'missing-root', file: '.', message: `Convex directory does not exist: ${root}` },\n\t\t]\n\tconst files = sourceFiles(root, diagnostics)\n\tconst required = new Set<string>()\n\tconst tested = new Set<string>()\n\tconst graph = new Map<string, Set<string>>()\n\tconst dependencies = new Map<string, Set<string>>()\n\tconst resolver = createResolver()\n\tfor (const file of files) {\n\t\tconst filename = resolve(root, file)\n\t\tconst parsed = parseSync(filename, readFileSync(filename, 'utf8'))\n\t\tif (parsed.errors.length) {\n\t\t\tdiagnostics.push({\n\t\t\t\tcode: 'parse',\n\t\t\t\tfile,\n\t\t\t\tmessage: `Cannot validate ${file}: ${parsed.errors[0].message}`,\n\t\t\t})\n\t\t\tcontinue\n\t\t}\n\t\tif (testFile(file)) {\n\t\t\tif (!file.includes('__tests__/'))\n\t\t\t\tdiagnostics.push({\n\t\t\t\t\tcode: 'test-location',\n\t\t\t\t\tfile,\n\t\t\t\t\tmessage: 'Place tests in a sibling __tests__/ directory.',\n\t\t\t\t})\n\t\t\telse if (dirname(file).endsWith('__tests__') && hasRunnableTest(parsed.program))\n\t\t\t\ttested.add(dirname(dirname(file)))\n\t\t\tcontinue\n\t\t}\n\t\tif (file.split('/').includes('__tests__')) continue\n\t\tif (/^domain\\/[^/]+$/.test(file) && file !== 'domain/table.ts')\n\t\t\tdiagnostics.push({\n\t\t\t\tcode: 'domain-entry',\n\t\t\t\tfile,\n\t\t\t\tmessage:\n\t\t\t\t\t'Domain source belongs in domain/<module>/ or domain/shared/. Only domain/table.ts assembles module tables.',\n\t\t\t})\n\t\tif (executable(parsed.program) && file !== 'domain/table.ts') required.add(dirname(file))\n\t\tconst owner = moduleOwner(file) ?? ''\n\t\tconst targets = new Set<string>()\n\t\tdependencies.set(file, targets)\n\t\tfor (const source of runtimeImports(parsed.program)) {\n\t\t\tconst target = resolveImport(resolver, filename, source)\n\t\t\tif (!target) continue\n\t\t\tconst targetFile = relative(root, target).split(sep).join('/')\n\t\t\ttargets.add(targetFile)\n\t\t\tconst targetOwner = moduleOwner(targetFile)\n\t\t\tif (owner && targetOwner && owner !== targetOwner) {\n\t\t\t\tconst edges = graph.get(owner) ?? new Set<string>()\n\t\t\t\tgraph.set(owner, edges)\n\t\t\t\tedges.add(targetOwner)\n\t\t\t}\n\t\t}\n\t}\n\tfor (const directory of required) {\n\t\tif (!tested.has(directory))\n\t\t\tdiagnostics.push({\n\t\t\t\tcode: 'tests',\n\t\t\t\tfile: directory,\n\t\t\t\tmessage: `${directory}/__tests__/ must contain a .test or .spec file with a nonempty, non-skipped test. Parent or child suites do not count.`,\n\t\t\t})\n\t}\n\tdiagnostics.push(...sharedOwnership(dependencies))\n\tfor (const cycle of cycles(graph))\n\t\tdiagnostics.push({\n\t\t\tcode: 'cycle',\n\t\t\tfile: cycle[0],\n\t\t\tmessage: `Module dependency cycle: ${cycle.join(' → ')}.`,\n\t\t})\n\treturn diagnostics.sort((a, b) => a.file.localeCompare(b.file) || a.code.localeCompare(b.code))\n}\n\nexport function createResolver() {\n\treturn new ResolverFactory({\n\t\ttsconfig: 'auto',\n\t\textensions: ['.ts', '.tsx', '.mts', '.cts', '.js', '.jsx', '.mjs', '.cjs', '.json'],\n\t\textensionAlias: {\n\t\t\t'.js': ['.ts', '.tsx', '.js'],\n\t\t\t'.mjs': ['.mts', '.mjs'],\n\t\t\t'.cjs': ['.cts', '.cjs'],\n\t\t},\n\t\tconditionNames: ['types', 'import', 'node', 'default'],\n\t\tsymlinks: true,\n\t})\n}\n\nexport function resolveImport(resolver: ResolverFactory, filename: string, source: string) {\n\tconst found = resolver.resolveFileSync(filename, source).path\n\tif (found) return found\n\t// Keep path checks useful in unsaved/editor fixtures and before Convex codegen.\n\treturn source.startsWith('.') ? resolve(dirname(filename), source) : null\n}\n\n/** The lint rule runs the project scan on one deterministic source file. */\nexport function architectureAnchor(root: string) {\n\tif (!existsSync(root)) return null\n\tif (existsSync(resolve(root, 'convex.config.ts')))\n\t\treturn realpathSync(resolve(root, 'convex.config.ts'))\n\troot = realpathSync(root)\n\tfor (const file of sourceFiles(root, []))\n\t\tif (!file.includes('__tests__/') && !testFile(file)) return resolve(root, file)\n\treturn null\n}\n\nfunction* sourceFiles(root: string, diagnostics: ArchitectureDiagnostic[]): Generator<string> {\n\tconst allowed = new Set([\n\t\t'_generated',\n\t\t'__tests__',\n\t\t'api',\n\t\t'domain',\n\t\t'application',\n\t\t'migrations',\n\t\t'components',\n\t])\n\tfunction* scan(directory: string): Generator<string> {\n\t\tfor (const entry of readdirSync(directory, { withFileTypes: true }).sort((a, b) =>\n\t\t\ta.name.localeCompare(b.name),\n\t\t)) {\n\t\t\tconst path = resolve(directory, entry.name)\n\t\t\tconst file = relative(root, path).split(sep).join('/')\n\t\t\tif (entry.isSymbolicLink()) {\n\t\t\t\tdiagnostics.push({\n\t\t\t\t\tcode: 'symlink',\n\t\t\t\t\tfile,\n\t\t\t\t\tmessage:\n\t\t\t\t\t\t'Keep application source inside its owning directory; symlinked files and folders are not allowed.',\n\t\t\t\t})\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif (entry.isDirectory()) {\n\t\t\t\tif (directory === root && !allowed.has(entry.name))\n\t\t\t\t\tdiagnostics.push({\n\t\t\t\t\t\tcode: 'root-directory',\n\t\t\t\t\t\tfile,\n\t\t\t\t\t\tmessage: `Root folder ${entry.name}/ is not allowed. Use api/, domain/, application/, migrations/, components/, __tests__/, or _generated/.`,\n\t\t\t\t\t})\n\t\t\t\tif (\n\t\t\t\t\tentry.name !== '_generated' &&\n\t\t\t\t\tentry.name !== 'node_modules' &&\n\t\t\t\t\t!entry.name.startsWith('.')\n\t\t\t\t)\n\t\t\t\t\tyield* scan(path)\n\t\t\t} else if (/\\.[cm]?[jt]sx?$/.test(entry.name) && !/\\.d\\.[cm]?ts$/.test(entry.name)) yield file\n\t\t}\n\t}\n\tyield* scan(root)\n}\n\nfunction testFile(file: string) {\n\treturn /\\.(?:test|spec)\\.[cm]?[jt]sx?$/.test(file)\n}\n\nfunction executable(program: Program) {\n\treturn program.body.some((statement) => {\n\t\tconst declaration =\n\t\t\tstatement.type === 'ExportNamedDeclaration' ? statement.declaration : statement\n\t\tif (declaration && 'declare' in declaration && declaration.declare) return false\n\t\tif (statement.type === 'ImportDeclaration' || statement.type === 'EmptyStatement') return false\n\t\tif (statement.type === 'ExportNamedDeclaration') {\n\t\t\tif (statement.exportKind === 'type' || !statement.declaration) return false\n\t\t\treturn !['TSInterfaceDeclaration', 'TSTypeAliasDeclaration', 'TSDeclareFunction'].includes(\n\t\t\t\tstatement.declaration.type,\n\t\t\t)\n\t\t}\n\t\treturn ![\n\t\t\t'TSInterfaceDeclaration',\n\t\t\t'TSTypeAliasDeclaration',\n\t\t\t'TSDeclareFunction',\n\t\t\t'ExportAllDeclaration',\n\t\t].includes(statement.type)\n\t})\n}\n\nfunction hasRunnableTest(program: Program) {\n\tconst names = new Map([\n\t\t['test', 'test'],\n\t\t['it', 'it'],\n\t\t['describe', 'describe'],\n\t\t['suite', 'suite'],\n\t])\n\tfor (const statement of program.body) {\n\t\tconst declaration =\n\t\t\tstatement.type === 'ExportNamedDeclaration' ? statement.declaration : statement\n\t\tif (declaration?.type === 'FunctionDeclaration' && declaration.id)\n\t\t\tnames.delete(declaration.id.name)\n\t\tif (declaration?.type === 'VariableDeclaration')\n\t\t\tfor (const item of declaration.declarations) {\n\t\t\t\tif (item.id.type === 'Identifier') names.delete(item.id.name)\n\t\t\t}\n\t\tif (statement.type !== 'ImportDeclaration') continue\n\t\tfor (const specifier of statement.specifiers) {\n\t\t\tnames.delete(specifier.local.name)\n\t\t\tif (\n\t\t\t\t!['vitest', 'vite-plus/test', 'bun:test', 'node:test', '@jest/globals'].includes(\n\t\t\t\t\tstatement.source.value,\n\t\t\t\t)\n\t\t\t)\n\t\t\t\tcontinue\n\t\t\tif (specifier.type === 'ImportNamespaceSpecifier') names.set(specifier.local.name, '*')\n\t\t\telse if (specifier.type === 'ImportDefaultSpecifier') names.set(specifier.local.name, 'test')\n\t\t\telse if (specifier.imported.type === 'Identifier')\n\t\t\t\tnames.set(specifier.local.name, specifier.imported.name)\n\t\t}\n\t}\n\tconst calls: CallExpression[] = []\n\tnew Visitor({\n\t\tCallExpression(node) {\n\t\t\tcalls.push(node)\n\t\t},\n\t}).visit(program)\n\tconst skipped = calls.filter((node) => {\n\t\tconst parts = testCallee(node.callee, names)\n\t\treturn (\n\t\t\t['test', 'it', 'describe', 'suite'].includes(parts[0]) &&\n\t\t\t(parts.some((part) => ['skip', 'todo', 'skipIf', 'runIf'].includes(part)) ||\n\t\t\t\tnode.arguments.some(\n\t\t\t\t\t(argument) =>\n\t\t\t\t\t\targument.type === 'ObjectExpression' &&\n\t\t\t\t\t\targument.properties.some(\n\t\t\t\t\t\t\t(property) =>\n\t\t\t\t\t\t\t\tproperty.type === 'Property' &&\n\t\t\t\t\t\t\t\t['skip', 'todo'].includes(\n\t\t\t\t\t\t\t\t\tproperty.key.type === 'Identifier'\n\t\t\t\t\t\t\t\t\t\t? property.key.name\n\t\t\t\t\t\t\t\t\t\t: property.key.type === 'Literal'\n\t\t\t\t\t\t\t\t\t\t\t? String(property.key.value)\n\t\t\t\t\t\t\t\t\t\t\t: '',\n\t\t\t\t\t\t\t\t) &&\n\t\t\t\t\t\t\t\t!(property.value.type === 'Literal' && property.value.value === false),\n\t\t\t\t\t\t),\n\t\t\t\t))\n\t\t)\n\t})\n\treturn calls.some((node) => {\n\t\tconst parts = testCallee(node.callee, names)\n\t\tif (\n\t\t\t!['test', 'it'].includes(parts[0]) ||\n\t\t\tskipped.some((skip) => node.start >= skip.start && node.end <= skip.end)\n\t\t)\n\t\t\treturn false\n\t\t// each(...) is a factory; only the outer call has the test callback.\n\t\treturn node.arguments.some(\n\t\t\t(argument) =>\n\t\t\t\t(argument.type === 'ArrowFunctionExpression' || argument.type === 'FunctionExpression') &&\n\t\t\t\targument.body &&\n\t\t\t\t(argument.body.type !== 'BlockStatement' ||\n\t\t\t\t\targument.body.body.some((statement) => statement.type !== 'EmptyStatement')),\n\t\t)\n\t})\n}\n\nfunction testCallee(node: Node, names: Map<string, string>): string[] {\n\tif (node.type === 'Identifier') {\n\t\tconst name = names.get(node.name)\n\t\treturn name ? [name] : []\n\t}\n\tif (node.type === 'CallExpression') return testCallee(node.callee, names)\n\tif (node.type === 'MemberExpression') {\n\t\tconst base = testCallee(node.object, names)\n\t\tconst property =\n\t\t\t!node.computed && node.property.type === 'Identifier'\n\t\t\t\t? node.property.name\n\t\t\t\t: node.property.type === 'Literal'\n\t\t\t\t\t? String(node.property.value)\n\t\t\t\t\t: ''\n\t\tif (!base.length || !property) return []\n\t\treturn base[0] === '*' ? [property] : [...base, property]\n\t}\n\treturn []\n}\n\nfunction runtimeImports(program: Program) {\n\tconst imports: string[] = []\n\tnew Visitor({\n\t\tImportDeclaration(node) {\n\t\t\tif (\n\t\t\t\tnode.importKind !== 'type' &&\n\t\t\t\t(node.specifiers.length === 0 ||\n\t\t\t\t\tnode.specifiers.some((s) => s.type !== 'ImportSpecifier' || s.importKind !== 'type'))\n\t\t\t)\n\t\t\t\timports.push(node.source.value)\n\t\t},\n\t\tExportNamedDeclaration(node) {\n\t\t\tif (\n\t\t\t\tnode.source &&\n\t\t\t\tnode.exportKind !== 'type' &&\n\t\t\t\tnode.specifiers.some((specifier) => specifier.exportKind !== 'type')\n\t\t\t)\n\t\t\t\timports.push(node.source.value)\n\t\t},\n\t\tExportAllDeclaration(node) {\n\t\t\tif (node.exportKind !== 'type') imports.push(node.source.value)\n\t\t},\n\t\tImportExpression(node) {\n\t\t\tif (node.source.type === 'Literal' && String(node.source.value) === node.source.value)\n\t\t\t\timports.push(String(node.source.value))\n\t\t},\n\t}).visit(program)\n\treturn imports\n}\n\nfunction moduleOwner(file: string) {\n\tconst parts = file.split('/')\n\treturn parts[0] === 'domain' && parts.length >= 3 && parts[1] !== '__tests__'\n\t\t? `domain/${parts[1]}`\n\t\t: null\n}\n\nfunction cycles(graph: Map<string, Set<string>>) {\n\tconst completed = new Set<string>()\n\tconst stack: string[] = []\n\tconst found: string[][] = []\n\tfunction visit(owner: string) {\n\t\tconst index = stack.indexOf(owner)\n\t\tif (index >= 0) {\n\t\t\tfound.push([...stack.slice(index), owner])\n\t\t\treturn\n\t\t}\n\t\tif (completed.has(owner)) return\n\t\tstack.push(owner)\n\t\tfor (const dependency of graph.get(owner) ?? []) visit(dependency)\n\t\tstack.pop()\n\t\tcompleted.add(owner)\n\t}\n\tfor (const owner of graph.keys()) visit(owner)\n\treturn found\n}\n\nfunction sharedOwnership(dependencies: Map<string, Set<string>>): ArchitectureDiagnostic[] {\n\tconst consumers = new Map<string, Set<string>>()\n\tfor (const [file, targets] of dependencies) {\n\t\tconst owner = moduleOwner(file) ?? ''\n\t\tif (!owner || owner === 'domain/shared') continue\n\t\tconst visited = new Set<string>()\n\t\tfunction visit(target: string) {\n\t\t\tif (!target.startsWith('domain/shared/') || visited.has(target)) return\n\t\t\tvisited.add(target)\n\t\t\tconst owners = consumers.get(target) ?? new Set<string>()\n\t\t\towners.add(owner)\n\t\t\tconsumers.set(target, owners)\n\t\t\tfor (const next of dependencies.get(target) ?? []) visit(next)\n\t\t}\n\t\tfor (const target of targets) visit(target)\n\t}\n\tconst diagnostics: ArchitectureDiagnostic[] = []\n\tfor (const [file, owners] of consumers) {\n\t\tif (owners.size === 1)\n\t\t\tdiagnostics.push({\n\t\t\t\tcode: 'shared-owner',\n\t\t\t\tfile,\n\t\t\t\tmessage: `This shared implementation is used only by ${[...owners][0]}. Move it into that module until another module needs it.`,\n\t\t\t})\n\t}\n\treturn diagnostics\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"architecture.mjs","names":["inspectArchitecture","requestedRoot","resolve","options","root","existsSync","realpathSync","diagnostics","files","sourceFiles","required","tested","graph","dependencies","resolver","createResolver","file","filename","parsed","parseSync","readFileSync","testFile","dirname","hasRunnableTest","executable","narrowRootDeclaration","owner","moduleOwner","targets","source","runtimeImports","target","resolveImport","targetFile","relative","sep","targetOwner","edges","directory","sharedOwnership","cycle","cycles","a","b","ResolverFactory","architectureAnchor","factory","imports","aliases","factories","exported","factoryName","node","active","init","declarative","relationParameter","registryCallback","value","property","body","callee","path","argument","statement","specifier","declaration","item","index","allowed","scan","entry","readdirSync","program","names","calls","Visitor","skipped","parts","testCallee","part","skip","name","base","s","completed","stack","found","visit","dependency","consumers","visited","owners","next"],"sources":["../../src/oxlint/architecture.ts"],"sourcesContent":["import { existsSync, readdirSync, readFileSync, realpathSync } from 'node:fs'\nimport { dirname, relative, resolve, sep } from 'node:path'\nimport { parseSync, Visitor, type Program, type Node, type CallExpression } from 'oxc-parser'\nimport { ResolverFactory } from 'oxc-resolver'\n\nexport interface ArchitectureOptions {\n\tcwd?: string\n\tconvexDir?: string\n}\nexport interface ArchitectureDiagnostic {\n\tcode:\n\t\t| 'missing-root'\n\t\t| 'root-directory'\n\t\t| 'tests'\n\t\t| 'test-location'\n\t\t| 'parse'\n\t\t| 'cycle'\n\t\t| 'symlink'\n\t\t| 'domain-entry'\n\t\t| 'shared-owner'\n\tfile: string\n\tmessage: string\n}\n\n/** Full-project checks, independent of the consumer's test runner. No persistent cache. */\nexport function inspectArchitecture(options: ArchitectureOptions = {}): ArchitectureDiagnostic[] {\n\tconst requestedRoot = resolve(options.cwd ?? process.cwd(), options.convexDir ?? 'convex')\n\tconst root = existsSync(requestedRoot) ? realpathSync(requestedRoot) : requestedRoot\n\tconst diagnostics: ArchitectureDiagnostic[] = []\n\tif (!existsSync(root))\n\t\treturn [\n\t\t\t{ code: 'missing-root', file: '.', message: `Convex directory does not exist: ${root}` },\n\t\t]\n\tconst files = sourceFiles(root, diagnostics)\n\tconst required = new Set<string>()\n\tconst tested = new Set<string>()\n\tconst graph = new Map<string, Set<string>>()\n\tconst dependencies = new Map<string, Set<string>>()\n\tconst resolver = createResolver()\n\tfor (const file of files) {\n\t\tconst filename = resolve(root, file)\n\t\tconst parsed = parseSync(filename, readFileSync(filename, 'utf8'))\n\t\tif (parsed.errors.length) {\n\t\t\tdiagnostics.push({\n\t\t\t\tcode: 'parse',\n\t\t\t\tfile,\n\t\t\t\tmessage: `Cannot validate ${file}: ${parsed.errors[0].message}`,\n\t\t\t})\n\t\t\tcontinue\n\t\t}\n\t\tif (testFile(file)) {\n\t\t\tif (!file.includes('__tests__/'))\n\t\t\t\tdiagnostics.push({\n\t\t\t\t\tcode: 'test-location',\n\t\t\t\t\tfile,\n\t\t\t\t\tmessage: 'Place tests in a sibling __tests__/ directory.',\n\t\t\t\t})\n\t\t\telse if (dirname(file).endsWith('__tests__') && hasRunnableTest(parsed.program))\n\t\t\t\ttested.add(dirname(dirname(file)))\n\t\t\tcontinue\n\t\t}\n\t\tif (file.split('/').includes('__tests__')) continue\n\t\tif (/^domain\\/[^/]+$/.test(file) && file !== 'domain/table.ts')\n\t\t\tdiagnostics.push({\n\t\t\t\tcode: 'domain-entry',\n\t\t\t\tfile,\n\t\t\t\tmessage:\n\t\t\t\t\t'Domain source belongs in domain/<module>/ or domain/shared/. Only domain/table.ts assembles module tables.',\n\t\t\t})\n\t\tif (\n\t\t\texecutable(parsed.program) &&\n\t\t\tfile !== 'domain/table.ts' &&\n\t\t\t!narrowRootDeclaration(file, readFileSync(filename, 'utf8'))\n\t\t)\n\t\t\trequired.add(dirname(file))\n\t\tconst owner = moduleOwner(file) ?? ''\n\t\tconst targets = new Set<string>()\n\t\tdependencies.set(file, targets)\n\t\tfor (const source of runtimeImports(parsed.program)) {\n\t\t\tconst target = resolveImport(resolver, filename, source)\n\t\t\tif (!target) continue\n\t\t\tconst targetFile = relative(root, target).split(sep).join('/')\n\t\t\ttargets.add(targetFile)\n\t\t\tconst targetOwner = moduleOwner(targetFile)\n\t\t\tif (owner && targetOwner && owner !== targetOwner) {\n\t\t\t\tconst edges = graph.get(owner) ?? new Set<string>()\n\t\t\t\tgraph.set(owner, edges)\n\t\t\t\tedges.add(targetOwner)\n\t\t\t}\n\t\t}\n\t}\n\tfor (const directory of required) {\n\t\tif (!tested.has(directory))\n\t\t\tdiagnostics.push({\n\t\t\t\tcode: 'tests',\n\t\t\t\tfile: directory,\n\t\t\t\tmessage: `${directory}/__tests__/ must contain a .test or .spec file with a nonempty, non-skipped test. Parent or child suites do not count.`,\n\t\t\t})\n\t}\n\tdiagnostics.push(...sharedOwnership(dependencies))\n\tfor (const cycle of cycles(graph))\n\t\tdiagnostics.push({\n\t\t\tcode: 'cycle',\n\t\t\tfile: cycle[0],\n\t\t\tmessage: `Module dependency cycle: ${cycle.join(' → ')}.`,\n\t\t})\n\treturn diagnostics.sort((a, b) => a.file.localeCompare(b.file) || a.code.localeCompare(b.code))\n}\n\nexport function createResolver() {\n\treturn new ResolverFactory({\n\t\ttsconfig: 'auto',\n\t\textensions: ['.ts', '.tsx', '.mts', '.cts', '.js', '.jsx', '.mjs', '.cjs', '.json'],\n\t\textensionAlias: {\n\t\t\t'.js': ['.ts', '.tsx', '.js'],\n\t\t\t'.mjs': ['.mts', '.mjs'],\n\t\t\t'.cjs': ['.cts', '.cjs'],\n\t\t},\n\t\tconditionNames: ['types', 'import', 'node', 'default'],\n\t\tsymlinks: true,\n\t})\n}\n\nexport function resolveImport(resolver: ResolverFactory, filename: string, source: string) {\n\tconst found = resolver.resolveFileSync(filename, source).path\n\tif (found) return found\n\t// Keep path checks useful in unsaved/editor fixtures and before Convex codegen.\n\treturn source.startsWith('.') ? resolve(dirname(filename), source) : null\n}\n\n/** The lint rule runs the project scan on one deterministic source file. */\nexport function architectureAnchor(root: string) {\n\tif (!existsSync(root)) return null\n\tif (existsSync(resolve(root, 'convex.config.ts')))\n\t\treturn realpathSync(resolve(root, 'convex.config.ts'))\n\troot = realpathSync(root)\n\tfor (const file of sourceFiles(root, []))\n\t\tif (!file.includes('__tests__/') && !testFile(file)) return resolve(root, file)\n\treturn null\n}\n\n/** Only these two factory declarations may omit root business ownership. */\nexport function narrowRootDeclaration(file: string, source: string): boolean {\n\tconst factory =\n\t\tfile === 'relations.ts'\n\t\t\t? 'defineRelations'\n\t\t\t: file === 'querying.ts'\n\t\t\t\t? 'createQueryEngine'\n\t\t\t\t: null\n\tif (!factory) return false\n\tconst parsed = parseSync(file, source)\n\tif (parsed.errors.length) return false\n\tconst imports = new Map<string, string>()\n\tconst aliases = new Map<string, Node>()\n\tlet factories = 0\n\tlet exported = false\n\tfunction factoryName(node: Node, active = new Set<string>()): string | null {\n\t\tif (node.type === 'Identifier') {\n\t\t\tif (active.has(node.name)) return null\n\t\t\tconst init = aliases.get(node.name)\n\t\t\treturn init\n\t\t\t\t? factoryName(init, new Set(active).add(node.name))\n\t\t\t\t: (imports.get(node.name) ?? null)\n\t\t}\n\t\tif (\n\t\t\tnode.type === 'MemberExpression' &&\n\t\t\t!node.computed &&\n\t\t\tnode.property.type === 'Identifier' &&\n\t\t\tfactoryName(node.object, active) === '*'\n\t\t)\n\t\t\treturn node.property.name\n\t\treturn null\n\t}\n\tfunction declarative(node: Node, relationParameter?: string, registryCallback = false): boolean {\n\t\tif (node.type === 'Identifier' || node.type === 'Literal') return true\n\t\tif (\n\t\t\tnode.type === 'TSAsExpression' ||\n\t\t\tnode.type === 'TSSatisfiesExpression' ||\n\t\t\tnode.type === 'ParenthesizedExpression'\n\t\t)\n\t\t\treturn declarative(node.expression, relationParameter, registryCallback)\n\t\tif (node.type === 'MemberExpression')\n\t\t\treturn !node.computed && declarative(node.object, relationParameter)\n\t\tif (node.type === 'ArrayExpression')\n\t\t\treturn node.elements.every((value) => value !== null && declarative(value, relationParameter))\n\t\tif (node.type === 'ObjectExpression')\n\t\t\treturn node.properties.every(\n\t\t\t\t(property) =>\n\t\t\t\t\tproperty.type === 'Property' &&\n\t\t\t\t\t!property.computed &&\n\t\t\t\t\tproperty.kind === 'init' &&\n\t\t\t\t\t!property.method &&\n\t\t\t\t\tdeclarative(property.value, relationParameter),\n\t\t\t)\n\t\tif (\n\t\t\tnode.type === 'ArrowFunctionExpression' &&\n\t\t\tregistryCallback &&\n\t\t\t!relationParameter &&\n\t\t\tnode.params.length === 1 &&\n\t\t\tnode.params[0].type === 'Identifier' &&\n\t\t\t!node.async\n\t\t) {\n\t\t\tconst body = node.body.type === 'ParenthesizedExpression' ? node.body.expression : node.body\n\t\t\treturn body.type === 'ObjectExpression' && declarative(body, node.params[0].name)\n\t\t}\n\t\tif (node.type === 'CallExpression' && relationParameter) {\n\t\t\tlet callee: Node = node.callee\n\t\t\tconst path: string[] = []\n\t\t\twhile (\n\t\t\t\tcallee.type === 'MemberExpression' &&\n\t\t\t\t!callee.computed &&\n\t\t\t\tcallee.property.type === 'Identifier'\n\t\t\t) {\n\t\t\t\tpath.unshift(callee.property.name)\n\t\t\t\tcallee = callee.object\n\t\t\t}\n\t\t\treturn (\n\t\t\t\tcallee.type === 'Identifier' &&\n\t\t\t\tcallee.name === relationParameter &&\n\t\t\t\t((path.length === 2 && ['one', 'many'].includes(path[0])) ||\n\t\t\t\t\t(path.length === 3 && path[2] === 'through')) &&\n\t\t\t\tnode.arguments.every((argument) => declarative(argument, relationParameter))\n\t\t\t)\n\t\t}\n\t\treturn false\n\t}\n\tfor (const statement of parsed.program.body) {\n\t\tif (statement.type === 'ImportDeclaration') {\n\t\t\tif (statement.importKind === 'type') continue\n\t\t\tfor (const specifier of statement.specifiers) {\n\t\t\t\tif (specifier.type === 'ImportSpecifier' && specifier.importKind === 'type') continue\n\t\t\t\tif (['cvx-kit', `cvx-kit/${file.slice(0, -3)}`].includes(statement.source.value))\n\t\t\t\t\timports.set(\n\t\t\t\t\t\tspecifier.local.name,\n\t\t\t\t\t\tspecifier.type === 'ImportSpecifier'\n\t\t\t\t\t\t\t? specifier.imported.type === 'Identifier'\n\t\t\t\t\t\t\t\t? specifier.imported.name\n\t\t\t\t\t\t\t\t: ''\n\t\t\t\t\t\t\t: specifier.type === 'ImportNamespaceSpecifier'\n\t\t\t\t\t\t\t\t? '*'\n\t\t\t\t\t\t\t\t: '',\n\t\t\t\t\t)\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\t\tif (\n\t\t\tstatement.type === 'EmptyStatement' ||\n\t\t\tstatement.type === 'TSTypeAliasDeclaration' ||\n\t\t\tstatement.type === 'TSInterfaceDeclaration'\n\t\t)\n\t\t\tcontinue\n\t\tconst declaration =\n\t\t\tstatement.type === 'ExportNamedDeclaration' ? statement.declaration : statement\n\t\tif (declaration?.type !== 'VariableDeclaration' || declaration.kind !== 'const') return false\n\t\tfor (const item of declaration.declarations) {\n\t\t\tif (item.id.type !== 'Identifier' || !item.init) return false\n\t\t\tif (item.init.type === 'CallExpression' && factoryName(item.init.callee) === factory) {\n\t\t\t\tif (\n\t\t\t\t\t!item.init.arguments.every((argument, index) =>\n\t\t\t\t\t\tdeclarative(argument, undefined, factory === 'defineRelations' && index === 1),\n\t\t\t\t\t)\n\t\t\t\t)\n\t\t\t\t\treturn false\n\t\t\t\tfactories++\n\t\t\t\texported ||= statement.type === 'ExportNamedDeclaration'\n\t\t\t} else if (statement.type === 'ExportNamedDeclaration' || !declarative(item.init))\n\t\t\t\treturn false\n\t\t\taliases.set(item.id.name, item.init)\n\t\t}\n\t}\n\treturn factories === 1 && exported\n}\n\nfunction* sourceFiles(root: string, diagnostics: ArchitectureDiagnostic[]): Generator<string> {\n\tconst allowed = new Set([\n\t\t'_generated',\n\t\t'__tests__',\n\t\t'api',\n\t\t'domain',\n\t\t'application',\n\t\t'migrations',\n\t\t'components',\n\t])\n\tfunction* scan(directory: string): Generator<string> {\n\t\tfor (const entry of readdirSync(directory, { withFileTypes: true }).sort((a, b) =>\n\t\t\ta.name.localeCompare(b.name),\n\t\t)) {\n\t\t\tconst path = resolve(directory, entry.name)\n\t\t\tconst file = relative(root, path).split(sep).join('/')\n\t\t\tif (entry.isSymbolicLink()) {\n\t\t\t\tdiagnostics.push({\n\t\t\t\t\tcode: 'symlink',\n\t\t\t\t\tfile,\n\t\t\t\t\tmessage:\n\t\t\t\t\t\t'Keep application source inside its owning directory; symlinked files and folders are not allowed.',\n\t\t\t\t})\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif (entry.isDirectory()) {\n\t\t\t\tif (directory === root && !allowed.has(entry.name))\n\t\t\t\t\tdiagnostics.push({\n\t\t\t\t\t\tcode: 'root-directory',\n\t\t\t\t\t\tfile,\n\t\t\t\t\t\tmessage: `Root folder ${entry.name}/ is not allowed. Use api/, domain/, application/, migrations/, components/, __tests__/, or _generated/.`,\n\t\t\t\t\t})\n\t\t\t\tif (\n\t\t\t\t\tentry.name !== '_generated' &&\n\t\t\t\t\tentry.name !== 'node_modules' &&\n\t\t\t\t\t!entry.name.startsWith('.')\n\t\t\t\t)\n\t\t\t\t\tyield* scan(path)\n\t\t\t} else if (/\\.[cm]?[jt]sx?$/.test(entry.name) && !/\\.d\\.[cm]?ts$/.test(entry.name)) yield file\n\t\t}\n\t}\n\tyield* scan(root)\n}\n\nfunction testFile(file: string) {\n\treturn /\\.(?:test|spec)\\.[cm]?[jt]sx?$/.test(file)\n}\n\nfunction executable(program: Program) {\n\treturn program.body.some((statement) => {\n\t\tconst declaration =\n\t\t\tstatement.type === 'ExportNamedDeclaration' ? statement.declaration : statement\n\t\tif (declaration && 'declare' in declaration && declaration.declare) return false\n\t\tif (statement.type === 'ImportDeclaration' || statement.type === 'EmptyStatement') return false\n\t\tif (statement.type === 'ExportNamedDeclaration') {\n\t\t\tif (statement.exportKind === 'type' || !statement.declaration) return false\n\t\t\treturn !['TSInterfaceDeclaration', 'TSTypeAliasDeclaration', 'TSDeclareFunction'].includes(\n\t\t\t\tstatement.declaration.type,\n\t\t\t)\n\t\t}\n\t\treturn ![\n\t\t\t'TSInterfaceDeclaration',\n\t\t\t'TSTypeAliasDeclaration',\n\t\t\t'TSDeclareFunction',\n\t\t\t'ExportAllDeclaration',\n\t\t].includes(statement.type)\n\t})\n}\n\nfunction hasRunnableTest(program: Program) {\n\tconst names = new Map([\n\t\t['test', 'test'],\n\t\t['it', 'it'],\n\t\t['describe', 'describe'],\n\t\t['suite', 'suite'],\n\t])\n\tfor (const statement of program.body) {\n\t\tconst declaration =\n\t\t\tstatement.type === 'ExportNamedDeclaration' ? statement.declaration : statement\n\t\tif (declaration?.type === 'FunctionDeclaration' && declaration.id)\n\t\t\tnames.delete(declaration.id.name)\n\t\tif (declaration?.type === 'VariableDeclaration')\n\t\t\tfor (const item of declaration.declarations) {\n\t\t\t\tif (item.id.type === 'Identifier') names.delete(item.id.name)\n\t\t\t}\n\t\tif (statement.type !== 'ImportDeclaration') continue\n\t\tfor (const specifier of statement.specifiers) {\n\t\t\tnames.delete(specifier.local.name)\n\t\t\tif (\n\t\t\t\t!['vitest', 'vite-plus/test', 'bun:test', 'node:test', '@jest/globals'].includes(\n\t\t\t\t\tstatement.source.value,\n\t\t\t\t)\n\t\t\t)\n\t\t\t\tcontinue\n\t\t\tif (specifier.type === 'ImportNamespaceSpecifier') names.set(specifier.local.name, '*')\n\t\t\telse if (specifier.type === 'ImportDefaultSpecifier') names.set(specifier.local.name, 'test')\n\t\t\telse if (specifier.imported.type === 'Identifier')\n\t\t\t\tnames.set(specifier.local.name, specifier.imported.name)\n\t\t}\n\t}\n\tconst calls: CallExpression[] = []\n\tnew Visitor({\n\t\tCallExpression(node) {\n\t\t\tcalls.push(node)\n\t\t},\n\t}).visit(program)\n\tconst skipped = calls.filter((node) => {\n\t\tconst parts = testCallee(node.callee, names)\n\t\treturn (\n\t\t\t['test', 'it', 'describe', 'suite'].includes(parts[0]) &&\n\t\t\t(parts.some((part) => ['skip', 'todo', 'skipIf', 'runIf'].includes(part)) ||\n\t\t\t\tnode.arguments.some(\n\t\t\t\t\t(argument) =>\n\t\t\t\t\t\targument.type === 'ObjectExpression' &&\n\t\t\t\t\t\targument.properties.some(\n\t\t\t\t\t\t\t(property) =>\n\t\t\t\t\t\t\t\tproperty.type === 'Property' &&\n\t\t\t\t\t\t\t\t['skip', 'todo'].includes(\n\t\t\t\t\t\t\t\t\tproperty.key.type === 'Identifier'\n\t\t\t\t\t\t\t\t\t\t? property.key.name\n\t\t\t\t\t\t\t\t\t\t: property.key.type === 'Literal'\n\t\t\t\t\t\t\t\t\t\t\t? String(property.key.value)\n\t\t\t\t\t\t\t\t\t\t\t: '',\n\t\t\t\t\t\t\t\t) &&\n\t\t\t\t\t\t\t\t!(property.value.type === 'Literal' && property.value.value === false),\n\t\t\t\t\t\t),\n\t\t\t\t))\n\t\t)\n\t})\n\treturn calls.some((node) => {\n\t\tconst parts = testCallee(node.callee, names)\n\t\tif (\n\t\t\t!['test', 'it'].includes(parts[0]) ||\n\t\t\tskipped.some((skip) => node.start >= skip.start && node.end <= skip.end)\n\t\t)\n\t\t\treturn false\n\t\t// each(...) is a factory; only the outer call has the test callback.\n\t\treturn node.arguments.some(\n\t\t\t(argument) =>\n\t\t\t\t(argument.type === 'ArrowFunctionExpression' || argument.type === 'FunctionExpression') &&\n\t\t\t\targument.body &&\n\t\t\t\t(argument.body.type !== 'BlockStatement' ||\n\t\t\t\t\targument.body.body.some((statement) => statement.type !== 'EmptyStatement')),\n\t\t)\n\t})\n}\n\nfunction testCallee(node: Node, names: Map<string, string>): string[] {\n\tif (node.type === 'Identifier') {\n\t\tconst name = names.get(node.name)\n\t\treturn name ? [name] : []\n\t}\n\tif (node.type === 'CallExpression') return testCallee(node.callee, names)\n\tif (node.type === 'MemberExpression') {\n\t\tconst base = testCallee(node.object, names)\n\t\tconst property =\n\t\t\t!node.computed && node.property.type === 'Identifier'\n\t\t\t\t? node.property.name\n\t\t\t\t: node.property.type === 'Literal'\n\t\t\t\t\t? String(node.property.value)\n\t\t\t\t\t: ''\n\t\tif (!base.length || !property) return []\n\t\treturn base[0] === '*' ? [property] : [...base, property]\n\t}\n\treturn []\n}\n\nfunction runtimeImports(program: Program) {\n\tconst imports: string[] = []\n\tnew Visitor({\n\t\tImportDeclaration(node) {\n\t\t\tif (\n\t\t\t\tnode.importKind !== 'type' &&\n\t\t\t\t(node.specifiers.length === 0 ||\n\t\t\t\t\tnode.specifiers.some((s) => s.type !== 'ImportSpecifier' || s.importKind !== 'type'))\n\t\t\t)\n\t\t\t\timports.push(node.source.value)\n\t\t},\n\t\tExportNamedDeclaration(node) {\n\t\t\tif (\n\t\t\t\tnode.source &&\n\t\t\t\tnode.exportKind !== 'type' &&\n\t\t\t\tnode.specifiers.some((specifier) => specifier.exportKind !== 'type')\n\t\t\t)\n\t\t\t\timports.push(node.source.value)\n\t\t},\n\t\tExportAllDeclaration(node) {\n\t\t\tif (node.exportKind !== 'type') imports.push(node.source.value)\n\t\t},\n\t\tImportExpression(node) {\n\t\t\tif (node.source.type === 'Literal' && String(node.source.value) === node.source.value)\n\t\t\t\timports.push(String(node.source.value))\n\t\t},\n\t}).visit(program)\n\treturn imports\n}\n\nfunction moduleOwner(file: string) {\n\tconst parts = file.split('/')\n\treturn parts[0] === 'domain' && parts.length >= 3 && parts[1] !== '__tests__'\n\t\t? `domain/${parts[1]}`\n\t\t: null\n}\n\nfunction cycles(graph: Map<string, Set<string>>) {\n\tconst completed = new Set<string>()\n\tconst stack: string[] = []\n\tconst found: string[][] = []\n\tfunction visit(owner: string) {\n\t\tconst index = stack.indexOf(owner)\n\t\tif (index >= 0) {\n\t\t\tfound.push([...stack.slice(index), owner])\n\t\t\treturn\n\t\t}\n\t\tif (completed.has(owner)) return\n\t\tstack.push(owner)\n\t\tfor (const dependency of graph.get(owner) ?? []) visit(dependency)\n\t\tstack.pop()\n\t\tcompleted.add(owner)\n\t}\n\tfor (const owner of graph.keys()) visit(owner)\n\treturn found\n}\n\nfunction sharedOwnership(dependencies: Map<string, Set<string>>): ArchitectureDiagnostic[] {\n\tconst consumers = new Map<string, Set<string>>()\n\tfor (const [file, targets] of dependencies) {\n\t\tconst owner = moduleOwner(file) ?? ''\n\t\tif (!owner || owner === 'domain/shared') continue\n\t\tconst visited = new Set<string>()\n\t\tfunction visit(target: string) {\n\t\t\tif (!target.startsWith('domain/shared/') || visited.has(target)) return\n\t\t\tvisited.add(target)\n\t\t\tconst owners = consumers.get(target) ?? new Set<string>()\n\t\t\towners.add(owner)\n\t\t\tconsumers.set(target, owners)\n\t\t\tfor (const next of dependencies.get(target) ?? []) visit(next)\n\t\t}\n\t\tfor (const target of targets) visit(target)\n\t}\n\tconst diagnostics: ArchitectureDiagnostic[] = []\n\tfor (const [file, owners] of consumers) {\n\t\tif (owners.size === 1)\n\t\t\tdiagnostics.push({\n\t\t\t\tcode: 'shared-owner',\n\t\t\t\tfile,\n\t\t\t\tmessage: `This shared implementation is used only by ${[...owners][0]}. Move it into that module until another module needs it.`,\n\t\t\t})\n\t}\n\treturn diagnostics\n}\n"],"mappings":"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"}
@@ -5,10 +5,19 @@ export declare const consumerOptions: z.ZodObject<{
5
5
  convexDir: z.ZodDefault<z.ZodString>;
6
6
  }, z.core.$strip>;
7
7
  export declare function appFile(context: Context, filename?: string): string | null;
8
- export declare function imported(context: Context, node: ESTree.Node): {
8
+ export declare function imported(context: Context, node: ESTree.Node, active?: Set<ESTree.Node>): {
9
9
  source: string;
10
10
  name: string;
11
11
  } | null;
12
+ /** Follow immutable bindings only; a same-named parameter never inherits outer provenance. */
13
+ export declare function localInitializer(context: Context, node: ESTree.Node): ESTree.Node | null;
14
+ export declare function localDestructured(context: Context, node: ESTree.Node): {
15
+ expression: ESTree.Expression;
16
+ name: string;
17
+ } | null;
18
+ export type ReadProvenance = 'table' | 'dtoSchema' | 'dto' | 'engine' | 'reader' | 'include' | 'context' | 'db' | 'stream' | 'relationship' | 'bounded' | 'page' | 'validator' | 'foundation' | 'queryRegistry' | 'queryOperation';
19
+ /** Suspend dependencies on a work stack; null in-progress entries terminate alias cycles. */
20
+ export declare function readProvenance(context: Context, node: ESTree.Node): ReadProvenance | null;
12
21
  export declare function sourceVisitors(context: Context, check: (node: ESTree.Node, source: string) => void): Visitor;
13
22
  export declare function isFunctionsImport(context: Context, source: string): boolean;
14
23
  export declare function typeOnlySource(node: ESTree.Node): boolean;
@@ -1,2 +1,2 @@
1
- import{createResolver as e,resolveImport as t}from"./architecture.mjs";import{z as n}from"zod";import{dirname as r,relative as i,resolve as a,sep as o}from"node:path";import{existsSync as s,realpathSync as c}from"node:fs";const l=n.object({convexDir:n.string().min(1).default(`convex`)});function u(e,t=e.filename){let n=a(e.cwd,l.parse(e.options[0]??{}).convexDir),r=s(n)?c(n):n,u=i(r,s(t)?c(t):t).split(o).join(`/`);return u===`..`||u.startsWith(`../`)||u.startsWith(`/`)?null:u}function d(e,t){if(t.type===`CallExpression`)return d(e,t.callee);if(t.type===`MemberExpression`){let n=d(e,t.object),r=E(t);return n&&r&&[`*`,`z`,`default`].includes(n.name)?{source:n.source,name:r}:null}if(t.type!==`Identifier`)return null;for(let n of D(e,t)?.defs??[]){if(n.type!==`ImportBinding`||n.parent?.type!==`ImportDeclaration`||n.parent.importKind===`type`)continue;let e=n.node;if(e.type!==`ImportSpecifier`||e.importKind!==`type`)return{source:n.parent.source.value,name:e.type===`ImportSpecifier`?k(e.imported)??``:e.type===`ImportDefaultSpecifier`?`default`:`*`}}return null}function f(e,t){function n(e,n){let r=T(n);r&&t(e,r)}return{ImportDeclaration(e){n(e,e.source)},ExportNamedDeclaration(e){n(e,e.source)},ExportAllDeclaration(e){n(e,e.source)},ImportExpression(e){n(e,e.source)},TSImportType(e){n(e,e.source)},CallExpression(t){t.callee.type===`Identifier`&&t.callee.name===`require`&&!D(e,t.callee)?.defs.length&&n(t,t.arguments[0])}}}function p(n,i){let o=i.startsWith(`.`)?a(r(n.filename),i):t(e(),n.filename,i);return o!==null&&u(n,o)?.replace(/\.[cm]?[jt]s$/,``)===`functions`}function m(e){return e.type===`TSImportType`||e.type===`ImportDeclaration`&&(e.importKind===`type`||e.specifiers.length>0&&e.specifiers.every(e=>e.type===`ImportSpecifier`&&e.importKind===`type`))||(e.type===`ExportNamedDeclaration`||e.type===`ExportAllDeclaration`)&&e.exportKind===`type`}function h(e){return e.callee.type===`MemberExpression`&&e.callee.object.type===`MemberExpression`&&E(e.callee.object)===`db`}function g(e,t){let n=d(e,t.callee);return n&&/^(?:node:)?(?:https?|net|tls|fs)(?:\/|$)|^(?:undici|axios)(?:\/|$)/.test(n.source)?!0:t.callee.type===`Identifier`&&t.callee.name===`fetch`&&!D(e,t.callee)?.defs.length||t.callee.type===`MemberExpression`&&E(t.callee)===`fetch`&&t.callee.object.type===`Identifier`&&t.callee.object.name===`globalThis`&&!D(e,t.callee.object)?.defs.length}function _(e,t){if(t.type===`MemberExpression`){let n=d(e,t.object);return n?.name===`components`&&/_generated\/api/.test(n.source)?!0:_(e,t.object)}return t.type===`ObjectExpression`&&t.properties.some(t=>t.type===`Property`&&_(e,t.value))}function v(e){return e.type===`MemberExpression`?v(e.object):e}function y(e){return e.type===`Identifier`?[e.name]:e.type===`MemberExpression`?[...y(e.object),E(e)??``]:[]}function b(e){return e.type===`MemberExpression`?E(e)===`table`||b(e.object):e.type===`CallExpression`&&b(e.callee)}function x(e){return e.callee.type===`MemberExpression`&&[`insert`,`patch`,`replace`,`delete`].includes(E(e.callee)??``)&&e.callee.object.type===`MemberExpression`&&E(e.callee.object)===`db`}function S(e,t){return e.type===`CallExpression`?e.callee.type===`MemberExpression`&&E(e.callee)===t&&(t!==`query`||E(e.callee.object)===`db`)||S(e.callee,t):e.type===`MemberExpression`&&S(e.object,t)}function C(e,t){return{type:`problem`,docs:{description:e},schema:[],messages:t}}function w(e,t){let n=a(e.cwd,l.parse(e.options[0]??{}).convexDir),r=s(n)?c(n):n,u=i(r,s(t)?c(t):t).split(o).join(`/`).match(/^components\/([^/]+)(?:\/|$)/);return u?a(r,`components`,u[1]):null}function T(e){return e?.type===`Literal`&&`value`in e&&String(e.value)===e.value?String(e.value):e?.type===`TemplateLiteral`&&e.expressions.length===0?e.quasis[0].value.cooked:null}function E(e){return e.type===`MemberExpression`?e.computed?T(e.property):e.property.name:null}function D(e,t){if(t.type!==`Identifier`)return null;let n=e.sourceCode.getScope(t);for(;n;){let e=n.set.get(t.name);if(e)return e;n=n.upper}return null}function O(e){let t=/* @__PURE__ */ new Set;for(let n of e.body)if(n.type===`ExportNamedDeclaration`&&!n.source)for(let e of n.specifiers)t.add(k(e.local)??``);else n.type===`ExportDefaultDeclaration`&&n.declaration.type===`Identifier`&&t.add(n.declaration.name);return t}function k(e){return e.type===`Identifier`?e.name:T(e)}function A(e){return e.type===`CallExpression`?!0:e.type===`AwaitExpression`?A(e.argument):e.type===`BlockStatement`&&e.body.length>0&&e.body.every(e=>e.type===`ReturnStatement`&&e.argument!==null&&A(e.argument)||e.type===`ExpressionStatement`&&A(e.expression))}export{u as appFile,D as binding,w as componentRoot,l as consumerOptions,_ as containsComponentReference,A as delegatingBody,k as exportName,O as exportedNames,S as hasCall,d as imported,h as isDbAccess,x as isDbWrite,g as isExternalCall,p as isFunctionsImport,b as isTableChain,y as memberPath,C as metadata,E as propertyName,v as rootMember,f as sourceVisitors,T as staticString,m as typeOnlySource};
1
+ import{createResolver as e,resolveImport as t}from"./architecture.mjs";import{z as n}from"zod";import{dirname as r,relative as i,resolve as a,sep as o}from"node:path";import{existsSync as s,readFileSync as c,realpathSync as l}from"node:fs";import{parseSync as u}from"oxc-parser";const d=n.object({convexDir:n.string().min(1).default(`convex`)});function f(e,t=e.filename){let n=a(e.cwd,d.parse(e.options[0]??{}).convexDir),r=s(n)?l(n):n,c=i(r,s(t)?l(t):t).split(o).join(`/`);return c===`..`||c.startsWith(`../`)||c.startsWith(`/`)?null:c}function p(e,t,n=/* @__PURE__ */ new Set){if(n.has(t)||n.size>32)return null;if(n=new Set(n).add(t),t.type===`TSAsExpression`||t.type===`TSSatisfiesExpression`||t.type===`TSNonNullExpression`)return p(e,t.expression,n);if(t.type===`CallExpression`)return p(e,t.callee,n);if(t.type===`MemberExpression`){let r=p(e,t.object,n),i=N(t);return r&&i&&[`*`,`z`,`v`,`default`].includes(r.name)?{source:r.source,name:i}:null}if(t.type!==`Identifier`)return null;let r=m(e,t);if(r&&r.type!==`CallExpression`&&r.type!==`AwaitExpression`)return p(e,r,n);let i=h(e,t);if(i){let t=p(e,i.expression,n);return t&&[`*`,`z`,`v`,`default`].includes(t.name)?{source:t.source,name:i.name}:null}for(let n of P(e,t)?.defs??[]){if(n.type!==`ImportBinding`||n.parent?.type!==`ImportDeclaration`||n.parent.importKind===`type`)continue;let e=n.node;if(e.type!==`ImportSpecifier`||e.importKind!==`type`)return{source:n.parent.source.value,name:e.type===`ImportSpecifier`?I(e.imported)??``:e.type===`ImportDefaultSpecifier`?`default`:`*`}}return null}function m(e,t){let n=P(e,t);if(!n||n.references.some(e=>e.isWrite()&&!e.init))return null;let r=n.defs.length===1?n.defs[0]:null;return r?.type===`Variable`&&r.parent?.type===`VariableDeclaration`&&r.parent.kind===`const`&&r.node.type===`VariableDeclarator`&&r.node.id.type===`Identifier`?r.node.init:null}function h(e,t){let n=P(e,t);if(!n||n.references.some(e=>e.isWrite()&&!e.init))return null;let r=n.defs.length===1?n.defs[0]:null;if(r?.type!==`Variable`||r.parent?.type!==`VariableDeclaration`||r.parent.kind!==`const`||r.node.type!==`VariableDeclarator`||r.node.id.type!==`ObjectPattern`||!r.node.init)return null;for(let e of r.node.id.properties)if(e.type===`Property`&&e.value.type===`Identifier`&&e.value.name===n.name){let t=e.computed?M(e.key):I(e.key);if(t)return{expression:r.node.init,name:t}}return null}const g=[`query`,`internalQuery`,`mutation`,`internalMutation`],_=/* @__PURE__ */ new WeakMap;function v(e,t){let n=B(e).nodes;if(n.has(t))return n.get(t)??null;n.set(t,null);let r=[{node:t,evaluation:V(e,t)}],i=null;for(;r.length;){let t=r[r.length-1],a=t.evaluation.next(i);a.done?(i=a.value,n.set(t.node,i),r.pop()):n.has(a.value)?i=n.get(a.value)??null:(n.set(a.value,null),r.push({node:a.value,evaluation:V(e,a.value)}),i=null)}return i}function y(e,t){function n(e,n){let r=M(n);r&&t(e,r)}return{ImportDeclaration(e){n(e,e.source)},ExportNamedDeclaration(e){n(e,e.source)},ExportAllDeclaration(e){n(e,e.source)},ImportExpression(e){n(e,e.source)},TSImportType(e){n(e,e.source)},CallExpression(t){t.callee.type===`Identifier`&&t.callee.name===`require`&&!P(e,t.callee)?.defs.length&&n(t,t.arguments[0])}}}function b(n,i){let o=i.startsWith(`.`)?a(r(n.filename),i):t(e(),n.filename,i);return o!==null&&f(n,o)?.replace(/\.[cm]?[jt]s$/,``)===`functions`}function x(e){return e.type===`TSImportType`||e.type===`ImportDeclaration`&&(e.importKind===`type`||e.specifiers.length>0&&e.specifiers.every(e=>e.type===`ImportSpecifier`&&e.importKind===`type`))||(e.type===`ExportNamedDeclaration`||e.type===`ExportAllDeclaration`)&&e.exportKind===`type`}function S(e){return e.callee.type===`MemberExpression`&&e.callee.object.type===`MemberExpression`&&N(e.callee.object)===`db`}function C(e,t){let n=p(e,t.callee);return n&&/^(?:node:)?(?:https?|net|tls|fs)(?:\/|$)|^(?:undici|axios)(?:\/|$)/.test(n.source)?!0:t.callee.type===`Identifier`&&t.callee.name===`fetch`&&!P(e,t.callee)?.defs.length||t.callee.type===`MemberExpression`&&N(t.callee)===`fetch`&&t.callee.object.type===`Identifier`&&t.callee.object.name===`globalThis`&&!P(e,t.callee.object)?.defs.length}function w(e,t){if(t.type===`MemberExpression`){let n=p(e,t.object);return n?.name===`components`&&/_generated\/api/.test(n.source)?!0:w(e,t.object)}return t.type===`ObjectExpression`&&t.properties.some(t=>t.type===`Property`&&w(e,t.value))}function T(e){return e.type===`MemberExpression`?T(e.object):e}function E(e){return e.type===`Identifier`?[e.name]:e.type===`MemberExpression`?[...E(e.object),N(e)??``]:[]}function D(e){return e.type===`MemberExpression`?N(e)===`table`||D(e.object):e.type===`CallExpression`&&D(e.callee)}function O(e){return e.callee.type===`MemberExpression`&&[`insert`,`patch`,`replace`,`delete`].includes(N(e.callee)??``)&&e.callee.object.type===`MemberExpression`&&N(e.callee.object)===`db`}function k(e,t){return e.type===`CallExpression`?e.callee.type===`MemberExpression`&&N(e.callee)===t&&(t!==`query`||N(e.callee.object)===`db`)||k(e.callee,t):e.type===`MemberExpression`&&k(e.object,t)}function A(e,t){return{type:`problem`,docs:{description:e},schema:[],messages:t}}function j(e,t){let n=a(e.cwd,d.parse(e.options[0]??{}).convexDir),r=s(n)?l(n):n,c=i(r,s(t)?l(t):t).split(o).join(`/`).match(/^components\/([^/]+)(?:\/|$)/);return c?a(r,`components`,c[1]):null}function M(e){return e?.type===`Literal`&&`value`in e&&String(e.value)===e.value?String(e.value):e?.type===`TemplateLiteral`&&e.expressions.length===0?e.quasis[0].value.cooked:null}function N(e){return e.type===`MemberExpression`?e.computed?M(e.property):e.property.name:null}function P(e,t){if(t.type!==`Identifier`)return null;let n=e.sourceCode.getScope(t);for(;n;){let e=n.set.get(t.name);if(e)return e;n=n.upper}return null}function F(e){let t=/* @__PURE__ */ new Set;for(let n of e.body)if(n.type===`ExportNamedDeclaration`&&!n.source)for(let e of n.specifiers)t.add(I(e.local)??``);else n.type===`ExportDefaultDeclaration`&&n.declaration.type===`Identifier`&&t.add(n.declaration.name);return t}function I(e){return e.type===`Identifier`?e.name:M(e)}function L(e){return e.type===`CallExpression`?!0:e.type===`AwaitExpression`?L(e.argument):e.type===`BlockStatement`&&e.body.length>0&&e.body.every(e=>e.type===`ReturnStatement`&&e.argument!==null&&L(e.argument)||e.type===`ExpressionStatement`&&L(e.expression))}function R(e,n){let r=B(e),i=t(r.resolver,e.filename,n.source),a=i&&f(e,i);if(!i||!a||!/^(?:domain\/.+\/schema\.ts|querying\.ts|foundation\.ts)$/.test(a)||!s(i))return null;let o=`${i}:${n.name}`;if(r.imports.has(o))return r.imports.get(o)??null;let c=z(e,i,n.name);return r.imports.set(o,c),c}function z(e,t,n){let r=B(e),i=r.files.get(t);if(i||(i=u(t,c(t,`utf8`)),r.files.set(t,i)),i.errors.length)return null;let a=/* @__PURE__ */ new Map,o=/* @__PURE__ */ new Map,s=/* @__PURE__ */ new Map,l=/* @__PURE__ */ new Map;for(let e of i.program.body){if(e.type===`ImportDeclaration`&&e.importKind!==`type`)for(let t of e.specifiers)t.type===`ImportSpecifier`&&t.importKind!==`type`&&a.set(t.local.name,{source:e.source.value,name:t.imported.type===`Identifier`?t.imported.name:``}),t.type===`ImportNamespaceSpecifier`&&a.set(t.local.name,{source:e.source.value,name:`*`});let t=e.type===`ExportNamedDeclaration`?e.declaration:e;if(t?.type===`VariableDeclaration`&&t.kind===`const`){for(let n of t.declarations)if(n.init){if(n.id.type===`ObjectPattern`)for(let t of n.id.properties){if(t.type!==`Property`||t.value.type!==`Identifier`)continue;let r=t.computed?G(t.key):t.key.type===`Identifier`?t.key.name:null;r&&(o.set(t.value.name,n.init),s.set(t.value.name,r),e.type===`ExportNamedDeclaration`&&l.set(t.value.name,t.value.name))}n.id.type===`Identifier`&&(o.set(n.id.name,n.init),e.type===`ExportNamedDeclaration`&&l.set(n.id.name,n.id.name))}}if(e.type===`ExportNamedDeclaration`&&!e.source&&e.exportKind!==`type`)for(let t of e.specifiers)t.exportKind!==`type`&&t.local.type===`Identifier`&&t.exported.type===`Identifier`&&l.set(t.exported.name,t.local.name)}let d=l.get(n);if(!d)return null;function f(e,t=/* @__PURE__ */ new Set){if(e.type===`Identifier`){if(t.has(e.name)||t.size>16)return null;let n=a.get(e.name);if(n)return n;let r=o.get(e.name);return r?f(r,new Set(t).add(e.name)):null}if(e.type===`MemberExpression`&&!e.computed&&e.property.type===`Identifier`){let n=f(e.object,t);if(n?.name===`*`)return{source:n.source,name:e.property.name}}return null}function p(e,t=/* @__PURE__ */ new Set){if(e.type===`TSAsExpression`||e.type===`TSSatisfiesExpression`||e.type===`ParenthesizedExpression`)return p(e.expression,t);if(e.type===`Identifier`){if(t.has(e.name)||t.size>16)return null;let n=o.get(e.name),r=n?p(n,new Set(t).add(e.name)):null;return s.has(e.name)?r===`foundation`&&s.get(e.name)===`Query`?`queryRegistry`:null:r}if(e.type===`MemberExpression`&&!e.computed&&e.property.type===`Identifier`)return p(e.object,t)===`foundation`&&e.property.name===`Query`?`queryRegistry`:null;if(e.type!==`CallExpression`&&e.type!==`NewExpression`)return null;let n=f(e.callee);return n&&U(n)?`foundation`:n&&[`cvx-kit`,`cvx-kit/zod-table`,`cvx-kit/tenancy`].includes(n.source)&&[`zodTable`,`tenantTable`,`zodVariantTable`].includes(n.name)?`table`:n&&[`cvx-kit`,`cvx-kit/querying`].includes(n.source)&&n.name===`createQueryEngine`?`engine`:null}let m=o.get(d),h=m?p(m):null;return s.has(d)?h===`foundation`&&s.get(d)===`Query`?`queryRegistry`:null:h}function B(t){let n=_.get(t);return n||(n={nodes:/* @__PURE__ */ new Map,files:/* @__PURE__ */ new Map,imports:/* @__PURE__ */ new Map,resolver:e()},_.set(t,n)),n}function*V(e,t){if(t.type===`AwaitExpression`)return yield t.argument;if(t.type===`TSAsExpression`||t.type===`TSSatisfiesExpression`||t.type===`TSNonNullExpression`)return yield t.expression;if(t.type===`Identifier`){if(P(e,t)?.references.some(e=>e.isWrite()&&!e.init))return null;let n=m(e,t);if(n)return yield n;let r=h(e,t);if(r){let e=yield r.expression;if(e===`context`&&r.name===`db`)return`db`;if(e===`page`&&r.name===`page`)return`bounded`;if(e===`table`&&r.name===`publicDto`)return`dtoSchema`;if(e===`foundation`&&r.name===`Query`)return`queryRegistry`}let i=P(e,t)?.defs[0];if(i?.type===`Parameter`&&(i.node.type===`ArrowFunctionExpression`||i.node.type===`FunctionExpression`)){let t=i.node.parent;if(t?.type===`CallExpression`&&t.arguments[0]===i.node&&i.node.params[0]===i.name&&(t.callee.type===`Identifier`||t.callee.type===`MemberExpression`)){let n=p(e,t.callee);if(n&&H(n))return`context`}if(t?.type===`CallExpression`&&t.callee.type===`MemberExpression`){let e=yield t.callee.object,n=N(t.callee);if(n===`handler`&&e===`queryOperation`&&t.arguments[0]===i.node&&i.node.params[1]===i.name)return`context`;if(i.node.params[0]!==i.name)return null;if((n===`execute`||n===`paginate`)&&t.arguments[1]===i.node&&(e===`stream`||e===`relationship`))return`bounded`;if(n===`then`&&t.arguments[0]===i.node&&(e===`bounded`||e===`page`))return e}let n=i.node.parent,r=n?.type===`Property`?n.parent:null,a=r?.type===`ObjectExpression`?r.parent:null,o=a?.type===`CallExpression`?p(e,a.callee):null;if(n?.type===`Property`&&(n.computed?M(n.key):I(n.key))===`operations`&&a?.type===`CallExpression`&&a.arguments[0]===r&&(yield a.callee)===`queryRegistry`&&r?.type===`ObjectExpression`&&i.node.params[0]?.type===`ObjectPattern`&&i.node.params[0].properties.some(e=>e.type===`Property`&&e.value===i.name&&(e.computed?M(e.key):I(e.key))===`query`)&&W(e,r))return`queryOperation`;if(n?.type===`Property`&&(n.computed?M(n.key):I(n.key))===`handler`&&a?.type===`CallExpression`&&a.arguments[0]===r&&i.node.params[1]===i.name&&(yield a.callee)===`queryOperation`||n?.type===`Property`&&(n.computed?M(n.key):I(n.key))===`handler`&&i.node.params[0]===i.name&&o&&(a?.type===`CallExpression`&&a.arguments[0]===r&&(a.callee.type===`Identifier`||a.callee.type===`MemberExpression`)&&H(o)||b(e,o.source)&&/^(?:auth|role|admin|system)(?:Query|Mutation)$/.test(o.name)))return`context`}let a=p(e,t);return a&&[`zod`,`zod/v4`,`convex/values`].includes(a.source)&&[`z`,`v`,`*`,`default`].includes(a.name)?`validator`:a?R(e,a):null}if(t.type===`MemberExpression`){let n=p(e,t);if(n){let t=R(e,n);if(t)return t}let r=yield t.object,i=N(t);return r===`context`&&i===`db`?`db`:r===`foundation`&&i===`Query`?`queryRegistry`:r===`reader`?`stream`:r===`page`&&i===`page`?`bounded`:r===`table`&&[`publicDto`,`dto`].includes(i??``)?`dtoSchema`:r===`validator`?`validator`:null}if(t.type!==`CallExpression`&&t.type!==`NewExpression`)return null;let n=yield t.callee;if(n===`engine`)return`reader`;if(n===`include`&&t.arguments[0]&&(yield t.arguments[0])===`stream`)return`stream`;let r=p(e,t.callee);if(r&&U(r))return`foundation`;if(r&&[`cvx-kit`,`cvx-kit/zod-table`,`cvx-kit/tenancy`].includes(r.source)&&[`zodTable`,`tenantTable`,`zodVariantTable`].includes(r.name))return`table`;if(r&&[`cvx-kit`,`cvx-kit/querying`].includes(r.source)&&r.name===`createQueryEngine`)return`engine`;if(r&&[`cvx-kit`,`cvx-kit/auth`].includes(r.source)&&r.name===`createInclude`)return`include`;if(r?.source===`convex-helpers/server/stream`&&r.name===`stream`&&t.arguments[0]&&(yield t.arguments[0])===`db`)return`db`;if(t.callee.type!==`MemberExpression`)return null;let i=yield t.callee.object,a=N(t.callee);if(i===`table`&&a===`toPublicDto`)return`dto`;if(i===`table`&&[`select`,`dto`].includes(a??``))return`dtoSchema`;if(i===`dtoSchema`&&[`parse`,`parseAsync`].includes(a??``))return`dto`;if(i===`db`&&a===`query`)return`stream`;if(i===`stream`&&a===`relation`)return`relationship`;if(i===`context`&&a===`include`&&t.arguments[0]&&(yield t.arguments[0])===`stream`)return`stream`;if(i===`stream`||i===`relationship`){if([`take`,`execute`].includes(a??``))return`bounded`;if(a===`paginate`)return`page`;if([`withIndex`,`withSearchIndex`,`filter`,`filterWith`,`map`,`flatMap`,`distinct`,`order`,`matching`,`when`,`otherwise`,`fullTableScan`,`where`,`with`].includes(a??``))return i}return i===`bounded`&&a===`map`?`bounded`:i===`validator`?`validator`:null}function H(e){return/_generated\/server(?:\.[cm]?[jt]s)?$/.test(e.source)&&g.includes(e.name)||e.source===`convex/server`&&g.some(t=>e.name===`${t}Generic`)}function U(e){return e.source===`cvx-kit`&&e.name===`createFoundation`||e.source===`cvx-kit/effect`&&e.name===`createEffectFoundation`||[`cvx-kit`,`cvx-kit/components/foundation`].includes(e.source)&&e.name===`Foundation`}function W(e,t){let n=t.properties.find(e=>e.type===`Property`&&(e.computed?M(e.key):I(e.key))===`context`);if(n?.type!==`Property`)return!1;let r=n.value;if(r.type!==`ArrowFunctionExpression`&&r.type!==`FunctionExpression`)return!1;let i=r.params[0];if(i?.type!==`Identifier`||P(e,i)?.references.some(e=>e.isWrite()&&!e.init))return!1;let a=r.body,o=a?.type===`BlockStatement`&&a.body.length===1&&a.body[0].type===`ReturnStatement`?a.body[0].argument:a;return o?.type===`Identifier`&&P(e,o)===P(e,i)}function G(e){return e.type===`Literal`&&String(e.value)===e.value?String(e.value):e.type===`TemplateLiteral`&&e.expressions.length===0?e.quasis[0].value.cooked:null}export{f as appFile,P as binding,j as componentRoot,d as consumerOptions,w as containsComponentReference,L as delegatingBody,I as exportName,F as exportedNames,k as hasCall,p as imported,S as isDbAccess,O as isDbWrite,C as isExternalCall,b as isFunctionsImport,D as isTableChain,h as localDestructured,m as localInitializer,E as memberPath,A as metadata,N as propertyName,v as readProvenance,T as rootMember,y as sourceVisitors,M as staticString,x as typeOnlySource};
2
2
  //# sourceMappingURL=ast.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"ast.mjs","names":["consumerOptions","z","appFile","context","requestedRoot","resolve","root","existsSync","realpathSync","file","relative","filename","sep","imported","node","owner","name","propertyName","def","binding","specifier","exportName","sourceVisitors","visit","text","staticString","source","check","isFunctionsImport","target","dirname","resolveImport","createResolver","typeOnlySource","isDbAccess","isExternalCall","ref","containsComponentReference","property","rootMember","memberPath","isTableChain","isDbWrite","hasCall","metadata","componentRoot","match","scope","variable","exportedNames","names","statement","program","delegatingBody"],"sources":["../../src/oxlint/ast.ts"],"sourcesContent":["import { existsSync, realpathSync } from 'node:fs'\nimport { dirname, relative, resolve, sep } from 'node:path'\nimport type { Context, ESTree, RuleMeta, Scope, Visitor } from '@oxlint/plugins'\nimport { z } from 'zod'\nimport { createResolver, resolveImport } from './architecture'\n\nexport const consumerOptions = z.object({ convexDir: z.string().min(1).default('convex') })\n\nexport function appFile(context: Context, filename = context.filename) {\n\tconst requestedRoot = resolve(\n\t\tcontext.cwd,\n\t\tconsumerOptions.parse(context.options[0] ?? {}).convexDir,\n\t)\n\tconst root = existsSync(requestedRoot) ? realpathSync(requestedRoot) : requestedRoot\n\tconst file = relative(root, existsSync(filename) ? realpathSync(filename) : filename)\n\t\t.split(sep)\n\t\t.join('/')\n\treturn file === '..' || file.startsWith('../') || file.startsWith('/') ? null : file\n}\n\nexport function imported(\n\tcontext: Context,\n\tnode: ESTree.Node,\n): { source: string; name: string } | null {\n\tif (node.type === 'CallExpression') return imported(context, node.callee)\n\tif (node.type === 'MemberExpression') {\n\t\tconst owner = imported(context, node.object)\n\t\tconst name = propertyName(node)\n\t\treturn owner && name && ['*', 'z', 'default'].includes(owner.name)\n\t\t\t? { source: owner.source, name }\n\t\t\t: null\n\t}\n\tif (node.type !== 'Identifier') return null\n\tfor (const def of binding(context, node)?.defs ?? []) {\n\t\tif (\n\t\t\tdef.type !== 'ImportBinding' ||\n\t\t\tdef.parent?.type !== 'ImportDeclaration' ||\n\t\t\tdef.parent.importKind === 'type'\n\t\t)\n\t\t\tcontinue\n\t\tconst specifier = def.node\n\t\tif (specifier.type === 'ImportSpecifier' && specifier.importKind === 'type') continue\n\t\treturn {\n\t\t\tsource: def.parent.source.value,\n\t\t\tname:\n\t\t\t\tspecifier.type === 'ImportSpecifier'\n\t\t\t\t\t? (exportName(specifier.imported) ?? '')\n\t\t\t\t\t: specifier.type === 'ImportDefaultSpecifier'\n\t\t\t\t\t\t? 'default'\n\t\t\t\t\t\t: '*',\n\t\t}\n\t}\n\treturn null\n}\n\nexport function sourceVisitors(\n\tcontext: Context,\n\tcheck: (node: ESTree.Node, source: string) => void,\n): Visitor {\n\tfunction visit(node: ESTree.Node, source: ESTree.Node | null | undefined) {\n\t\tconst text = staticString(source)\n\t\tif (text) check(node, text)\n\t}\n\treturn {\n\t\tImportDeclaration(node) {\n\t\t\tvisit(node, node.source)\n\t\t},\n\t\tExportNamedDeclaration(node) {\n\t\t\tvisit(node, node.source)\n\t\t},\n\t\tExportAllDeclaration(node) {\n\t\t\tvisit(node, node.source)\n\t\t},\n\t\tImportExpression(node) {\n\t\t\tvisit(node, node.source)\n\t\t},\n\t\tTSImportType(node) {\n\t\t\tvisit(node, node.source)\n\t\t},\n\t\tCallExpression(node) {\n\t\t\tif (\n\t\t\t\tnode.callee.type === 'Identifier' &&\n\t\t\t\tnode.callee.name === 'require' &&\n\t\t\t\t!binding(context, node.callee)?.defs.length\n\t\t\t)\n\t\t\t\tvisit(node, node.arguments[0])\n\t\t},\n\t}\n}\n\nexport function isFunctionsImport(context: Context, source: string) {\n\tconst target = source.startsWith('.')\n\t\t? resolve(dirname(context.filename), source)\n\t\t: resolveImport(createResolver(), context.filename, source)\n\treturn target !== null && appFile(context, target)?.replace(/\\.[cm]?[jt]s$/, '') === 'functions'\n}\n\nexport function typeOnlySource(node: ESTree.Node) {\n\treturn (\n\t\tnode.type === 'TSImportType' ||\n\t\t(node.type === 'ImportDeclaration' &&\n\t\t\t(node.importKind === 'type' ||\n\t\t\t\t(node.specifiers.length > 0 &&\n\t\t\t\t\tnode.specifiers.every(\n\t\t\t\t\t\t(specifier) => specifier.type === 'ImportSpecifier' && specifier.importKind === 'type',\n\t\t\t\t\t)))) ||\n\t\t((node.type === 'ExportNamedDeclaration' || node.type === 'ExportAllDeclaration') &&\n\t\t\tnode.exportKind === 'type')\n\t)\n}\n\nexport function isDbAccess(node: ESTree.CallExpression) {\n\treturn (\n\t\tnode.callee.type === 'MemberExpression' &&\n\t\tnode.callee.object.type === 'MemberExpression' &&\n\t\tpropertyName(node.callee.object) === 'db'\n\t)\n}\n\nexport function isExternalCall(context: Context, node: ESTree.CallExpression) {\n\tconst ref = imported(context, node.callee)\n\tif (ref && /^(?:node:)?(?:https?|net|tls|fs)(?:\\/|$)|^(?:undici|axios)(?:\\/|$)/.test(ref.source))\n\t\treturn true\n\treturn (\n\t\t(node.callee.type === 'Identifier' &&\n\t\t\tnode.callee.name === 'fetch' &&\n\t\t\t!binding(context, node.callee)?.defs.length) ||\n\t\t(node.callee.type === 'MemberExpression' &&\n\t\t\tpropertyName(node.callee) === 'fetch' &&\n\t\t\tnode.callee.object.type === 'Identifier' &&\n\t\t\tnode.callee.object.name === 'globalThis' &&\n\t\t\t!binding(context, node.callee.object)?.defs.length)\n\t)\n}\n\nexport function containsComponentReference(context: Context, node: ESTree.Node): boolean {\n\tif (node.type === 'MemberExpression') {\n\t\tconst owner = imported(context, node.object)\n\t\tif (owner?.name === 'components' && /_generated\\/api/.test(owner.source)) return true\n\t\treturn containsComponentReference(context, node.object)\n\t}\n\tif (node.type === 'ObjectExpression')\n\t\treturn node.properties.some(\n\t\t\t(property) =>\n\t\t\t\tproperty.type === 'Property' && containsComponentReference(context, property.value),\n\t\t)\n\treturn false\n}\n\nexport function rootMember(node: ESTree.Node): ESTree.Node {\n\treturn node.type === 'MemberExpression' ? rootMember(node.object) : node\n}\n\nexport function memberPath(node: ESTree.Node): string[] {\n\tif (node.type === 'Identifier') return [node.name]\n\tif (node.type === 'MemberExpression')\n\t\treturn [...memberPath(node.object), propertyName(node) ?? '']\n\treturn []\n}\n\nexport function isTableChain(node: ESTree.Node): boolean {\n\tif (node.type === 'MemberExpression')\n\t\treturn propertyName(node) === 'table' || isTableChain(node.object)\n\treturn node.type === 'CallExpression' && isTableChain(node.callee)\n}\n\nexport function isDbWrite(node: ESTree.CallExpression) {\n\treturn (\n\t\tnode.callee.type === 'MemberExpression' &&\n\t\t['insert', 'patch', 'replace', 'delete'].includes(propertyName(node.callee) ?? '') &&\n\t\tnode.callee.object.type === 'MemberExpression' &&\n\t\tpropertyName(node.callee.object) === 'db'\n\t)\n}\n\nexport function hasCall(node: ESTree.Node, name: string): boolean {\n\tif (node.type === 'CallExpression')\n\t\treturn (\n\t\t\t(node.callee.type === 'MemberExpression' &&\n\t\t\t\tpropertyName(node.callee) === name &&\n\t\t\t\t(name !== 'query' || propertyName(node.callee.object) === 'db')) ||\n\t\t\thasCall(node.callee, name)\n\t\t)\n\tif (node.type === 'MemberExpression') return hasCall(node.object, name)\n\treturn false\n}\n\nexport function metadata(description: string, messages: Record<string, string>): RuleMeta {\n\treturn { type: 'problem', docs: { description }, schema: [], messages }\n}\n\nexport function componentRoot(context: Context, filename: string) {\n\tconst requestedRoot = resolve(\n\t\tcontext.cwd,\n\t\tconsumerOptions.parse(context.options[0] ?? {}).convexDir,\n\t)\n\tconst root = existsSync(requestedRoot) ? realpathSync(requestedRoot) : requestedRoot\n\tconst file = relative(root, existsSync(filename) ? realpathSync(filename) : filename)\n\t\t.split(sep)\n\t\t.join('/')\n\tconst match = file.match(/^components\\/([^/]+)(?:\\/|$)/)\n\treturn match ? resolve(root, 'components', match[1]) : null\n}\n\nexport function staticString(node: ESTree.Node | null | undefined) {\n\tif (node?.type === 'Literal' && 'value' in node && String(node.value) === node.value)\n\t\treturn String(node.value)\n\tif (node?.type === 'TemplateLiteral' && node.expressions.length === 0)\n\t\treturn node.quasis[0].value.cooked\n\treturn null\n}\n\nexport function propertyName(node: ESTree.Node): string | null {\n\tif (node.type !== 'MemberExpression') return null\n\treturn node.computed ? staticString(node.property) : node.property.name\n}\n\nexport function binding(context: Context, node: ESTree.Node) {\n\tif (node.type !== 'Identifier') return null\n\tlet scope: Scope | null = context.sourceCode.getScope(node)\n\twhile (scope) {\n\t\tconst variable = scope.set.get(node.name)\n\t\tif (variable) return variable\n\t\tscope = scope.upper\n\t}\n\treturn null\n}\n\nexport function exportedNames(program: ESTree.Program) {\n\tconst names = new Set<string>()\n\tfor (const statement of program.body) {\n\t\tif (statement.type === 'ExportNamedDeclaration' && !statement.source) {\n\t\t\tfor (const specifier of statement.specifiers) names.add(exportName(specifier.local) ?? '')\n\t\t} else if (\n\t\t\tstatement.type === 'ExportDefaultDeclaration' &&\n\t\t\tstatement.declaration.type === 'Identifier'\n\t\t) {\n\t\t\tnames.add(statement.declaration.name)\n\t\t}\n\t}\n\treturn names\n}\n\nexport function exportName(node: ESTree.Node): string | null {\n\treturn node.type === 'Identifier' ? node.name : staticString(node)\n}\n\nexport function delegatingBody(node: ESTree.Node): boolean {\n\tif (node.type === 'CallExpression') return true\n\tif (node.type === 'AwaitExpression') return delegatingBody(node.argument)\n\tif (node.type === 'BlockStatement')\n\t\treturn (\n\t\t\tnode.body.length > 0 &&\n\t\t\tnode.body.every(\n\t\t\t\t(statement) =>\n\t\t\t\t\t(statement.type === 'ReturnStatement' &&\n\t\t\t\t\t\tstatement.argument !== null &&\n\t\t\t\t\t\tdelegatingBody(statement.argument)) ||\n\t\t\t\t\t(statement.type === 'ExpressionStatement' && delegatingBody(statement.expression)),\n\t\t\t)\n\t\t)\n\treturn false\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"ast.mjs","names":["consumerOptions","z","appFile","context","requestedRoot","resolve","root","existsSync","realpathSync","file","relative","filename","sep","imported","active","node","owner","name","propertyName","initializer","localInitializer","member","localDestructured","def","binding","specifier","exportName","variable","reference","property","staticString","nativeReadBuilders","provenanceCaches","readProvenance","cache","provenanceCache","stack","evaluateReadProvenance","result","frame","step","sourceVisitors","visit","text","source","check","isFunctionsImport","target","dirname","resolveImport","createResolver","typeOnlySource","isDbAccess","isExternalCall","ref","containsComponentReference","rootMember","memberPath","isTableChain","isDbWrite","hasCall","metadata","componentRoot","match","scope","exportedNames","names","statement","program","delegatingBody","importedReadProvenance","key","physicalReadProvenance","parsed","parseSync","readFileSync","imports","declarations","members","exports","declaration","item","physicalString","local","factoryImport","importedFactory","init","evaluate","value","factory","foundationFactory","callbackCall","nativeReadBuilder","method","object","call","p","registryPreservesContext","importedValue","callee","callback","host","r","body","returned"],"sources":["../../src/oxlint/ast.ts"],"sourcesContent":["import { existsSync, readFileSync, realpathSync } from 'node:fs'\nimport { dirname, relative, resolve, sep } from 'node:path'\nimport type { Context, ESTree, RuleMeta, Scope, Visitor } from '@oxlint/plugins'\nimport { z } from 'zod'\nimport { parseSync, type Node } from 'oxc-parser'\nimport { createResolver, resolveImport } from './architecture'\n\nexport const consumerOptions = z.object({ convexDir: z.string().min(1).default('convex') })\n\nexport function appFile(context: Context, filename = context.filename) {\n\tconst requestedRoot = resolve(\n\t\tcontext.cwd,\n\t\tconsumerOptions.parse(context.options[0] ?? {}).convexDir,\n\t)\n\tconst root = existsSync(requestedRoot) ? realpathSync(requestedRoot) : requestedRoot\n\tconst file = relative(root, existsSync(filename) ? realpathSync(filename) : filename)\n\t\t.split(sep)\n\t\t.join('/')\n\treturn file === '..' || file.startsWith('../') || file.startsWith('/') ? null : file\n}\n\nexport function imported(\n\tcontext: Context,\n\tnode: ESTree.Node,\n\tactive = new Set<ESTree.Node>(),\n): { source: string; name: string } | null {\n\tif (active.has(node) || active.size > 32) return null\n\tactive = new Set(active).add(node)\n\tif (\n\t\tnode.type === 'TSAsExpression' ||\n\t\tnode.type === 'TSSatisfiesExpression' ||\n\t\tnode.type === 'TSNonNullExpression'\n\t)\n\t\treturn imported(context, node.expression, active)\n\tif (node.type === 'CallExpression') return imported(context, node.callee, active)\n\tif (node.type === 'MemberExpression') {\n\t\tconst owner = imported(context, node.object, active)\n\t\tconst name = propertyName(node)\n\t\treturn owner && name && ['*', 'z', 'v', 'default'].includes(owner.name)\n\t\t\t? { source: owner.source, name }\n\t\t\t: null\n\t}\n\tif (node.type !== 'Identifier') return null\n\tconst initializer = localInitializer(context, node)\n\tif (\n\t\tinitializer &&\n\t\tinitializer.type !== 'CallExpression' &&\n\t\tinitializer.type !== 'AwaitExpression'\n\t)\n\t\treturn imported(context, initializer, active)\n\tconst member = localDestructured(context, node)\n\tif (member) {\n\t\tconst owner = imported(context, member.expression, active)\n\t\treturn owner && ['*', 'z', 'v', 'default'].includes(owner.name)\n\t\t\t? { source: owner.source, name: member.name }\n\t\t\t: null\n\t}\n\tfor (const def of binding(context, node)?.defs ?? []) {\n\t\tif (\n\t\t\tdef.type !== 'ImportBinding' ||\n\t\t\tdef.parent?.type !== 'ImportDeclaration' ||\n\t\t\tdef.parent.importKind === 'type'\n\t\t)\n\t\t\tcontinue\n\t\tconst specifier = def.node\n\t\tif (specifier.type === 'ImportSpecifier' && specifier.importKind === 'type') continue\n\t\treturn {\n\t\t\tsource: def.parent.source.value,\n\t\t\tname:\n\t\t\t\tspecifier.type === 'ImportSpecifier'\n\t\t\t\t\t? (exportName(specifier.imported) ?? '')\n\t\t\t\t\t: specifier.type === 'ImportDefaultSpecifier'\n\t\t\t\t\t\t? 'default'\n\t\t\t\t\t\t: '*',\n\t\t}\n\t}\n\treturn null\n}\n\n/** Follow immutable bindings only; a same-named parameter never inherits outer provenance. */\nexport function localInitializer(context: Context, node: ESTree.Node): ESTree.Node | null {\n\tconst variable = binding(context, node)\n\tif (!variable || variable.references.some((reference) => reference.isWrite() && !reference.init))\n\t\treturn null\n\tconst def = variable.defs.length === 1 ? variable.defs[0] : null\n\treturn def?.type === 'Variable' &&\n\t\tdef.parent?.type === 'VariableDeclaration' &&\n\t\tdef.parent.kind === 'const' &&\n\t\tdef.node.type === 'VariableDeclarator' &&\n\t\tdef.node.id.type === 'Identifier'\n\t\t? def.node.init\n\t\t: null\n}\n\nexport function localDestructured(context: Context, node: ESTree.Node) {\n\tconst variable = binding(context, node)\n\tif (!variable || variable.references.some((reference) => reference.isWrite() && !reference.init))\n\t\treturn null\n\tconst def = variable.defs.length === 1 ? variable.defs[0] : null\n\tif (\n\t\tdef?.type !== 'Variable' ||\n\t\tdef.parent?.type !== 'VariableDeclaration' ||\n\t\tdef.parent.kind !== 'const' ||\n\t\tdef.node.type !== 'VariableDeclarator' ||\n\t\tdef.node.id.type !== 'ObjectPattern' ||\n\t\t!def.node.init\n\t)\n\t\treturn null\n\tfor (const property of def.node.id.properties) {\n\t\tif (\n\t\t\tproperty.type === 'Property' &&\n\t\t\tproperty.value.type === 'Identifier' &&\n\t\t\tproperty.value.name === variable.name\n\t\t) {\n\t\t\tconst name = property.computed ? staticString(property.key) : exportName(property.key)\n\t\t\tif (name) return { expression: def.node.init, name }\n\t\t}\n\t}\n\treturn null\n}\n\nexport type ReadProvenance =\n\t| 'table'\n\t| 'dtoSchema'\n\t| 'dto'\n\t| 'engine'\n\t| 'reader'\n\t| 'include'\n\t| 'context'\n\t| 'db'\n\t| 'stream'\n\t| 'relationship'\n\t| 'bounded'\n\t| 'page'\n\t| 'validator'\n\t| 'foundation'\n\t| 'queryRegistry'\n\t| 'queryOperation'\n\nconst nativeReadBuilders = ['query', 'internalQuery', 'mutation', 'internalMutation']\n\n// Weak keys keep caches local to a lint invocation; no file state survives a new context.\nconst provenanceCaches = new WeakMap<\n\tContext,\n\t{\n\t\tnodes: Map<ESTree.Node, ReadProvenance | null>\n\t\tfiles: Map<string, ReturnType<typeof parseSync>>\n\t\timports: Map<string, ReadProvenance | null>\n\t\tresolver: ReturnType<typeof createResolver>\n\t}\n>()\n/** Suspend dependencies on a work stack; null in-progress entries terminate alias cycles. */\nexport function readProvenance(context: Context, node: ESTree.Node): ReadProvenance | null {\n\tconst cache = provenanceCache(context).nodes\n\tif (cache.has(node)) return cache.get(node) ?? null\n\tcache.set(node, null)\n\tconst stack = [{ node, evaluation: evaluateReadProvenance(context, node) }]\n\tlet result: ReadProvenance | null = null\n\twhile (stack.length) {\n\t\tconst frame = stack[stack.length - 1]!\n\t\tconst step = frame.evaluation.next(result)\n\t\tif (step.done) {\n\t\t\tresult = step.value\n\t\t\tcache.set(frame.node, result)\n\t\t\tstack.pop()\n\t\t} else if (cache.has(step.value)) {\n\t\t\tresult = cache.get(step.value) ?? null\n\t\t} else {\n\t\t\tcache.set(step.value, null)\n\t\t\tstack.push({ node: step.value, evaluation: evaluateReadProvenance(context, step.value) })\n\t\t\tresult = null\n\t\t}\n\t}\n\treturn result\n}\nexport function sourceVisitors(\n\tcontext: Context,\n\tcheck: (node: ESTree.Node, source: string) => void,\n): Visitor {\n\tfunction visit(node: ESTree.Node, source: ESTree.Node | null | undefined) {\n\t\tconst text = staticString(source)\n\t\tif (text) check(node, text)\n\t}\n\treturn {\n\t\tImportDeclaration(node) {\n\t\t\tvisit(node, node.source)\n\t\t},\n\t\tExportNamedDeclaration(node) {\n\t\t\tvisit(node, node.source)\n\t\t},\n\t\tExportAllDeclaration(node) {\n\t\t\tvisit(node, node.source)\n\t\t},\n\t\tImportExpression(node) {\n\t\t\tvisit(node, node.source)\n\t\t},\n\t\tTSImportType(node) {\n\t\t\tvisit(node, node.source)\n\t\t},\n\t\tCallExpression(node) {\n\t\t\tif (\n\t\t\t\tnode.callee.type === 'Identifier' &&\n\t\t\t\tnode.callee.name === 'require' &&\n\t\t\t\t!binding(context, node.callee)?.defs.length\n\t\t\t)\n\t\t\t\tvisit(node, node.arguments[0])\n\t\t},\n\t}\n}\n\nexport function isFunctionsImport(context: Context, source: string) {\n\tconst target = source.startsWith('.')\n\t\t? resolve(dirname(context.filename), source)\n\t\t: resolveImport(createResolver(), context.filename, source)\n\treturn target !== null && appFile(context, target)?.replace(/\\.[cm]?[jt]s$/, '') === 'functions'\n}\n\nexport function typeOnlySource(node: ESTree.Node) {\n\treturn (\n\t\tnode.type === 'TSImportType' ||\n\t\t(node.type === 'ImportDeclaration' &&\n\t\t\t(node.importKind === 'type' ||\n\t\t\t\t(node.specifiers.length > 0 &&\n\t\t\t\t\tnode.specifiers.every(\n\t\t\t\t\t\t(specifier) => specifier.type === 'ImportSpecifier' && specifier.importKind === 'type',\n\t\t\t\t\t)))) ||\n\t\t((node.type === 'ExportNamedDeclaration' || node.type === 'ExportAllDeclaration') &&\n\t\t\tnode.exportKind === 'type')\n\t)\n}\n\nexport function isDbAccess(node: ESTree.CallExpression) {\n\treturn (\n\t\tnode.callee.type === 'MemberExpression' &&\n\t\tnode.callee.object.type === 'MemberExpression' &&\n\t\tpropertyName(node.callee.object) === 'db'\n\t)\n}\n\nexport function isExternalCall(context: Context, node: ESTree.CallExpression) {\n\tconst ref = imported(context, node.callee)\n\tif (ref && /^(?:node:)?(?:https?|net|tls|fs)(?:\\/|$)|^(?:undici|axios)(?:\\/|$)/.test(ref.source))\n\t\treturn true\n\treturn (\n\t\t(node.callee.type === 'Identifier' &&\n\t\t\tnode.callee.name === 'fetch' &&\n\t\t\t!binding(context, node.callee)?.defs.length) ||\n\t\t(node.callee.type === 'MemberExpression' &&\n\t\t\tpropertyName(node.callee) === 'fetch' &&\n\t\t\tnode.callee.object.type === 'Identifier' &&\n\t\t\tnode.callee.object.name === 'globalThis' &&\n\t\t\t!binding(context, node.callee.object)?.defs.length)\n\t)\n}\n\nexport function containsComponentReference(context: Context, node: ESTree.Node): boolean {\n\tif (node.type === 'MemberExpression') {\n\t\tconst owner = imported(context, node.object)\n\t\tif (owner?.name === 'components' && /_generated\\/api/.test(owner.source)) return true\n\t\treturn containsComponentReference(context, node.object)\n\t}\n\tif (node.type === 'ObjectExpression')\n\t\treturn node.properties.some(\n\t\t\t(property) =>\n\t\t\t\tproperty.type === 'Property' && containsComponentReference(context, property.value),\n\t\t)\n\treturn false\n}\n\nexport function rootMember(node: ESTree.Node): ESTree.Node {\n\treturn node.type === 'MemberExpression' ? rootMember(node.object) : node\n}\n\nexport function memberPath(node: ESTree.Node): string[] {\n\tif (node.type === 'Identifier') return [node.name]\n\tif (node.type === 'MemberExpression')\n\t\treturn [...memberPath(node.object), propertyName(node) ?? '']\n\treturn []\n}\n\nexport function isTableChain(node: ESTree.Node): boolean {\n\tif (node.type === 'MemberExpression')\n\t\treturn propertyName(node) === 'table' || isTableChain(node.object)\n\treturn node.type === 'CallExpression' && isTableChain(node.callee)\n}\n\nexport function isDbWrite(node: ESTree.CallExpression) {\n\treturn (\n\t\tnode.callee.type === 'MemberExpression' &&\n\t\t['insert', 'patch', 'replace', 'delete'].includes(propertyName(node.callee) ?? '') &&\n\t\tnode.callee.object.type === 'MemberExpression' &&\n\t\tpropertyName(node.callee.object) === 'db'\n\t)\n}\n\nexport function hasCall(node: ESTree.Node, name: string): boolean {\n\tif (node.type === 'CallExpression')\n\t\treturn (\n\t\t\t(node.callee.type === 'MemberExpression' &&\n\t\t\t\tpropertyName(node.callee) === name &&\n\t\t\t\t(name !== 'query' || propertyName(node.callee.object) === 'db')) ||\n\t\t\thasCall(node.callee, name)\n\t\t)\n\tif (node.type === 'MemberExpression') return hasCall(node.object, name)\n\treturn false\n}\n\nexport function metadata(description: string, messages: Record<string, string>): RuleMeta {\n\treturn { type: 'problem', docs: { description }, schema: [], messages }\n}\n\nexport function componentRoot(context: Context, filename: string) {\n\tconst requestedRoot = resolve(\n\t\tcontext.cwd,\n\t\tconsumerOptions.parse(context.options[0] ?? {}).convexDir,\n\t)\n\tconst root = existsSync(requestedRoot) ? realpathSync(requestedRoot) : requestedRoot\n\tconst file = relative(root, existsSync(filename) ? realpathSync(filename) : filename)\n\t\t.split(sep)\n\t\t.join('/')\n\tconst match = file.match(/^components\\/([^/]+)(?:\\/|$)/)\n\treturn match ? resolve(root, 'components', match[1]) : null\n}\n\nexport function staticString(node: ESTree.Node | null | undefined) {\n\tif (node?.type === 'Literal' && 'value' in node && String(node.value) === node.value)\n\t\treturn String(node.value)\n\tif (node?.type === 'TemplateLiteral' && node.expressions.length === 0)\n\t\treturn node.quasis[0].value.cooked\n\treturn null\n}\n\nexport function propertyName(node: ESTree.Node): string | null {\n\tif (node.type !== 'MemberExpression') return null\n\treturn node.computed ? staticString(node.property) : node.property.name\n}\n\nexport function binding(context: Context, node: ESTree.Node) {\n\tif (node.type !== 'Identifier') return null\n\tlet scope: Scope | null = context.sourceCode.getScope(node)\n\twhile (scope) {\n\t\tconst variable = scope.set.get(node.name)\n\t\tif (variable) return variable\n\t\tscope = scope.upper\n\t}\n\treturn null\n}\n\nexport function exportedNames(program: ESTree.Program) {\n\tconst names = new Set<string>()\n\tfor (const statement of program.body) {\n\t\tif (statement.type === 'ExportNamedDeclaration' && !statement.source) {\n\t\t\tfor (const specifier of statement.specifiers) names.add(exportName(specifier.local) ?? '')\n\t\t} else if (\n\t\t\tstatement.type === 'ExportDefaultDeclaration' &&\n\t\t\tstatement.declaration.type === 'Identifier'\n\t\t) {\n\t\t\tnames.add(statement.declaration.name)\n\t\t}\n\t}\n\treturn names\n}\n\nexport function exportName(node: ESTree.Node): string | null {\n\treturn node.type === 'Identifier' ? node.name : staticString(node)\n}\n\nexport function delegatingBody(node: ESTree.Node): boolean {\n\tif (node.type === 'CallExpression') return true\n\tif (node.type === 'AwaitExpression') return delegatingBody(node.argument)\n\tif (node.type === 'BlockStatement')\n\t\treturn (\n\t\t\tnode.body.length > 0 &&\n\t\t\tnode.body.every(\n\t\t\t\t(statement) =>\n\t\t\t\t\t(statement.type === 'ReturnStatement' &&\n\t\t\t\t\t\tstatement.argument !== null &&\n\t\t\t\t\t\tdelegatingBody(statement.argument)) ||\n\t\t\t\t\t(statement.type === 'ExpressionStatement' && delegatingBody(statement.expression)),\n\t\t\t)\n\t\t)\n\treturn false\n}\n\n/** Read only the owning schema/facade's top-level declaration, never arbitrary helper bodies. */\nfunction importedReadProvenance(\n\tcontext: Context,\n\tref: { source: string; name: string },\n): ReadProvenance | null {\n\tconst cache = provenanceCache(context)\n\tconst target = resolveImport(cache.resolver, context.filename, ref.source)\n\tconst file = target && appFile(context, target)\n\tif (\n\t\t!target ||\n\t\t!file ||\n\t\t!/^(?:domain\\/.+\\/schema\\.ts|querying\\.ts|foundation\\.ts)$/.test(file) ||\n\t\t!existsSync(target)\n\t)\n\t\treturn null\n\tconst key = `${target}:${ref.name}`\n\tif (cache.imports.has(key)) return cache.imports.get(key) ?? null\n\tconst result = physicalReadProvenance(context, target, ref.name)\n\tcache.imports.set(key, result)\n\treturn result\n}\nfunction physicalReadProvenance(\n\tcontext: Context,\n\ttarget: string,\n\tname: string,\n): ReadProvenance | null {\n\tconst cache = provenanceCache(context)\n\tlet parsed = cache.files.get(target)\n\tif (!parsed) {\n\t\tparsed = parseSync(target, readFileSync(target, 'utf8'))\n\t\tcache.files.set(target, parsed)\n\t}\n\tif (parsed.errors.length) return null\n\tconst imports = new Map<string, { source: string; name: string }>()\n\tconst declarations = new Map<string, Node>()\n\tconst members = new Map<string, string>()\n\tconst exports = new Map<string, string>()\n\tfor (const statement of parsed.program.body) {\n\t\tif (statement.type === 'ImportDeclaration' && statement.importKind !== 'type') {\n\t\t\tfor (const specifier of statement.specifiers) {\n\t\t\t\tif (specifier.type === 'ImportSpecifier' && specifier.importKind !== 'type')\n\t\t\t\t\timports.set(specifier.local.name, {\n\t\t\t\t\t\tsource: statement.source.value,\n\t\t\t\t\t\tname: specifier.imported.type === 'Identifier' ? specifier.imported.name : '',\n\t\t\t\t\t})\n\t\t\t\tif (specifier.type === 'ImportNamespaceSpecifier')\n\t\t\t\t\timports.set(specifier.local.name, { source: statement.source.value, name: '*' })\n\t\t\t}\n\t\t}\n\t\tconst declaration =\n\t\t\tstatement.type === 'ExportNamedDeclaration' ? statement.declaration : statement\n\t\tif (declaration?.type === 'VariableDeclaration' && declaration.kind === 'const') {\n\t\t\tfor (const item of declaration.declarations) {\n\t\t\t\tif (!item.init) continue\n\t\t\t\tif (item.id.type === 'ObjectPattern') {\n\t\t\t\t\tfor (const property of item.id.properties) {\n\t\t\t\t\t\tif (property.type !== 'Property' || property.value.type !== 'Identifier') continue\n\t\t\t\t\t\tconst member = property.computed\n\t\t\t\t\t\t\t? physicalString(property.key)\n\t\t\t\t\t\t\t: property.key.type === 'Identifier'\n\t\t\t\t\t\t\t\t? property.key.name\n\t\t\t\t\t\t\t\t: null\n\t\t\t\t\t\tif (!member) continue\n\t\t\t\t\t\tdeclarations.set(property.value.name, item.init)\n\t\t\t\t\t\tmembers.set(property.value.name, member)\n\t\t\t\t\t\tif (statement.type === 'ExportNamedDeclaration')\n\t\t\t\t\t\t\texports.set(property.value.name, property.value.name)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (item.id.type !== 'Identifier') continue\n\t\t\t\tdeclarations.set(item.id.name, item.init)\n\t\t\t\tif (statement.type === 'ExportNamedDeclaration') exports.set(item.id.name, item.id.name)\n\t\t\t}\n\t\t}\n\t\tif (\n\t\t\tstatement.type === 'ExportNamedDeclaration' &&\n\t\t\t!statement.source &&\n\t\t\tstatement.exportKind !== 'type'\n\t\t) {\n\t\t\tfor (const specifier of statement.specifiers)\n\t\t\t\tif (\n\t\t\t\t\tspecifier.exportKind !== 'type' &&\n\t\t\t\t\tspecifier.local.type === 'Identifier' &&\n\t\t\t\t\tspecifier.exported.type === 'Identifier'\n\t\t\t\t)\n\t\t\t\t\texports.set(specifier.exported.name, specifier.local.name)\n\t\t}\n\t}\n\tconst local = exports.get(name)\n\tif (!local) return null\n\tfunction factoryImport(\n\t\tnode: Node,\n\t\tactive = new Set<string>(),\n\t): { source: string; name: string } | null {\n\t\tif (node.type === 'Identifier') {\n\t\t\tif (active.has(node.name) || active.size > 16) return null\n\t\t\tconst importedFactory = imports.get(node.name)\n\t\t\tif (importedFactory) return importedFactory\n\t\t\tconst init = declarations.get(node.name)\n\t\t\treturn init ? factoryImport(init, new Set(active).add(node.name)) : null\n\t\t}\n\t\tif (node.type === 'MemberExpression' && !node.computed && node.property.type === 'Identifier') {\n\t\t\tconst owner = factoryImport(node.object, active)\n\t\t\tif (owner?.name === '*') return { source: owner.source, name: node.property.name }\n\t\t}\n\t\treturn null\n\t}\n\tfunction evaluate(node: Node, active = new Set<string>()): ReadProvenance | null {\n\t\tif (\n\t\t\tnode.type === 'TSAsExpression' ||\n\t\t\tnode.type === 'TSSatisfiesExpression' ||\n\t\t\tnode.type === 'ParenthesizedExpression'\n\t\t)\n\t\t\treturn evaluate(node.expression, active)\n\t\tif (node.type === 'Identifier') {\n\t\t\tif (active.has(node.name) || active.size > 16) return null\n\t\t\tconst init = declarations.get(node.name)\n\t\t\tconst value = init ? evaluate(init, new Set(active).add(node.name)) : null\n\t\t\treturn members.has(node.name)\n\t\t\t\t? value === 'foundation' && members.get(node.name) === 'Query'\n\t\t\t\t\t? 'queryRegistry'\n\t\t\t\t\t: null\n\t\t\t\t: value\n\t\t}\n\t\tif (node.type === 'MemberExpression' && !node.computed && node.property.type === 'Identifier')\n\t\t\treturn evaluate(node.object, active) === 'foundation' && node.property.name === 'Query'\n\t\t\t\t? 'queryRegistry'\n\t\t\t\t: null\n\t\tif (node.type !== 'CallExpression' && node.type !== 'NewExpression') return null\n\t\tconst factory = factoryImport(node.callee)\n\t\tif (factory && foundationFactory(factory)) return 'foundation'\n\t\tif (\n\t\t\tfactory &&\n\t\t\t['cvx-kit', 'cvx-kit/zod-table', 'cvx-kit/tenancy'].includes(factory.source) &&\n\t\t\t['zodTable', 'tenantTable', 'zodVariantTable'].includes(factory.name)\n\t\t)\n\t\t\treturn 'table'\n\t\tif (\n\t\t\tfactory &&\n\t\t\t['cvx-kit', 'cvx-kit/querying'].includes(factory.source) &&\n\t\t\tfactory.name === 'createQueryEngine'\n\t\t)\n\t\t\treturn 'engine'\n\t\treturn null\n\t}\n\tconst declaration = declarations.get(local)\n\tconst value = declaration ? evaluate(declaration) : null\n\treturn members.has(local)\n\t\t? value === 'foundation' && members.get(local) === 'Query'\n\t\t\t? 'queryRegistry'\n\t\t\t: null\n\t\t: value\n}\n\nfunction provenanceCache(context: Context) {\n\tlet cache = provenanceCaches.get(context)\n\tif (!cache) {\n\t\tcache = { nodes: new Map(), files: new Map(), imports: new Map(), resolver: createResolver() }\n\t\tprovenanceCaches.set(context, cache)\n\t}\n\treturn cache\n}\n\nfunction* evaluateReadProvenance(\n\tcontext: Context,\n\tnode: ESTree.Node,\n): Generator<ESTree.Node, ReadProvenance | null, ReadProvenance | null> {\n\tif (node.type === 'AwaitExpression') return yield node.argument\n\tif (\n\t\tnode.type === 'TSAsExpression' ||\n\t\tnode.type === 'TSSatisfiesExpression' ||\n\t\tnode.type === 'TSNonNullExpression'\n\t)\n\t\treturn yield node.expression\n\tif (node.type === 'Identifier') {\n\t\tconst variable = binding(context, node)\n\t\tif (variable?.references.some((reference) => reference.isWrite() && !reference.init))\n\t\t\treturn null\n\t\tconst initializer = localInitializer(context, node)\n\t\tif (initializer) return yield initializer\n\t\tconst member = localDestructured(context, node)\n\t\tif (member) {\n\t\t\tconst owner = yield member.expression\n\t\t\tif (owner === 'context' && member.name === 'db') return 'db'\n\t\t\tif (owner === 'page' && member.name === 'page') return 'bounded'\n\t\t\tif (owner === 'table' && member.name === 'publicDto') return 'dtoSchema'\n\t\t\tif (owner === 'foundation' && member.name === 'Query') return 'queryRegistry'\n\t\t}\n\t\tconst def = binding(context, node)?.defs[0]\n\t\tif (\n\t\t\tdef?.type === 'Parameter' &&\n\t\t\t(def.node.type === 'ArrowFunctionExpression' || def.node.type === 'FunctionExpression')\n\t\t) {\n\t\t\tconst callbackCall = def.node.parent\n\t\t\tif (\n\t\t\t\tcallbackCall?.type === 'CallExpression' &&\n\t\t\t\tcallbackCall.arguments[0] === def.node &&\n\t\t\t\tdef.node.params[0] === def.name &&\n\t\t\t\t(callbackCall.callee.type === 'Identifier' ||\n\t\t\t\t\tcallbackCall.callee.type === 'MemberExpression')\n\t\t\t) {\n\t\t\t\tconst ref = imported(context, callbackCall.callee)\n\t\t\t\tif (ref && nativeReadBuilder(ref)) return 'context'\n\t\t\t}\n\t\t\tif (\n\t\t\t\tcallbackCall?.type === 'CallExpression' &&\n\t\t\t\tcallbackCall.callee.type === 'MemberExpression'\n\t\t\t) {\n\t\t\t\tconst owner = yield callbackCall.callee.object\n\t\t\t\tconst method = propertyName(callbackCall.callee)\n\t\t\t\tif (\n\t\t\t\t\tmethod === 'handler' &&\n\t\t\t\t\towner === 'queryOperation' &&\n\t\t\t\t\tcallbackCall.arguments[0] === def.node &&\n\t\t\t\t\tdef.node.params[1] === def.name\n\t\t\t\t)\n\t\t\t\t\treturn 'context'\n\t\t\t\tif (def.node.params[0] !== def.name) return null\n\t\t\t\tif (\n\t\t\t\t\t(method === 'execute' || method === 'paginate') &&\n\t\t\t\t\tcallbackCall.arguments[1] === def.node &&\n\t\t\t\t\t(owner === 'stream' || owner === 'relationship')\n\t\t\t\t)\n\t\t\t\t\treturn 'bounded'\n\t\t\t\tif (\n\t\t\t\t\tmethod === 'then' &&\n\t\t\t\t\tcallbackCall.arguments[0] === def.node &&\n\t\t\t\t\t(owner === 'bounded' || owner === 'page')\n\t\t\t\t)\n\t\t\t\t\treturn owner\n\t\t\t}\n\t\t\tconst property = def.node.parent\n\t\t\tconst object = property?.type === 'Property' ? property.parent : null\n\t\t\tconst call = object?.type === 'ObjectExpression' ? object.parent : null\n\t\t\tconst ref = call?.type === 'CallExpression' ? imported(context, call.callee) : null\n\t\t\tif (\n\t\t\t\tproperty?.type === 'Property' &&\n\t\t\t\t(property.computed ? staticString(property.key) : exportName(property.key)) ===\n\t\t\t\t\t'operations' &&\n\t\t\t\tcall?.type === 'CallExpression' &&\n\t\t\t\tcall.arguments[0] === object &&\n\t\t\t\t(yield call.callee) === 'queryRegistry' &&\n\t\t\t\tobject?.type === 'ObjectExpression' &&\n\t\t\t\tdef.node.params[0]?.type === 'ObjectPattern' &&\n\t\t\t\tdef.node.params[0].properties.some(\n\t\t\t\t\t(p) =>\n\t\t\t\t\t\tp.type === 'Property' &&\n\t\t\t\t\t\tp.value === def.name &&\n\t\t\t\t\t\t(p.computed ? staticString(p.key) : exportName(p.key)) === 'query',\n\t\t\t\t) &&\n\t\t\t\tregistryPreservesContext(context, object)\n\t\t\t)\n\t\t\t\treturn 'queryOperation'\n\n\t\t\tif (\n\t\t\t\tproperty?.type === 'Property' &&\n\t\t\t\t(property.computed ? staticString(property.key) : exportName(property.key)) === 'handler' &&\n\t\t\t\tcall?.type === 'CallExpression' &&\n\t\t\t\tcall.arguments[0] === object &&\n\t\t\t\tdef.node.params[1] === def.name &&\n\t\t\t\t(yield call.callee) === 'queryOperation'\n\t\t\t)\n\t\t\t\treturn 'context'\n\n\t\t\tif (\n\t\t\t\tproperty?.type === 'Property' &&\n\t\t\t\t(property.computed ? staticString(property.key) : exportName(property.key)) === 'handler' &&\n\t\t\t\tdef.node.params[0] === def.name &&\n\t\t\t\tref &&\n\t\t\t\t((call?.type === 'CallExpression' &&\n\t\t\t\t\tcall.arguments[0] === object &&\n\t\t\t\t\t(call.callee.type === 'Identifier' || call.callee.type === 'MemberExpression') &&\n\t\t\t\t\tnativeReadBuilder(ref)) ||\n\t\t\t\t\t(isFunctionsImport(context, ref.source) &&\n\t\t\t\t\t\t/^(?:auth|role|admin|system)(?:Query|Mutation)$/.test(ref.name)))\n\t\t\t)\n\t\t\t\treturn 'context'\n\t\t}\n\t\tconst ref = imported(context, node)\n\t\tif (\n\t\t\tref &&\n\t\t\t['zod', 'zod/v4', 'convex/values'].includes(ref.source) &&\n\t\t\t['z', 'v', '*', 'default'].includes(ref.name)\n\t\t)\n\t\t\treturn 'validator'\n\t\tif (ref) return importedReadProvenance(context, ref)\n\t\treturn null\n\t}\n\tif (node.type === 'MemberExpression') {\n\t\tconst ref = imported(context, node)\n\t\tif (ref) {\n\t\t\tconst importedValue = importedReadProvenance(context, ref)\n\t\t\tif (importedValue) return importedValue\n\t\t}\n\t\tconst owner = yield node.object\n\t\tconst name = propertyName(node)\n\t\tif (owner === 'context' && name === 'db') return 'db'\n\t\tif (owner === 'foundation' && name === 'Query') return 'queryRegistry'\n\t\tif (owner === 'reader') return 'stream'\n\t\tif (owner === 'page' && name === 'page') return 'bounded'\n\t\tif (owner === 'table' && ['publicDto', 'dto'].includes(name ?? '')) return 'dtoSchema'\n\t\tif (owner === 'validator') return 'validator'\n\t\treturn null\n\t}\n\tif (node.type !== 'CallExpression' && node.type !== 'NewExpression') return null\n\tconst callee = yield node.callee\n\tif (callee === 'engine') return 'reader'\n\tif (callee === 'include' && node.arguments[0] && (yield node.arguments[0]) === 'stream')\n\t\treturn 'stream'\n\tconst ref = imported(context, node.callee)\n\tif (ref && foundationFactory(ref)) return 'foundation'\n\tif (\n\t\tref &&\n\t\t['cvx-kit', 'cvx-kit/zod-table', 'cvx-kit/tenancy'].includes(ref.source) &&\n\t\t['zodTable', 'tenantTable', 'zodVariantTable'].includes(ref.name)\n\t)\n\t\treturn 'table'\n\tif (\n\t\tref &&\n\t\t['cvx-kit', 'cvx-kit/querying'].includes(ref.source) &&\n\t\tref.name === 'createQueryEngine'\n\t)\n\t\treturn 'engine'\n\tif (ref && ['cvx-kit', 'cvx-kit/auth'].includes(ref.source) && ref.name === 'createInclude')\n\t\treturn 'include'\n\tif (\n\t\tref?.source === 'convex-helpers/server/stream' &&\n\t\tref.name === 'stream' &&\n\t\tnode.arguments[0] &&\n\t\t(yield node.arguments[0]) === 'db'\n\t)\n\t\treturn 'db'\n\tif (node.callee.type !== 'MemberExpression') return null\n\tconst owner = yield node.callee.object\n\tconst name = propertyName(node.callee)\n\tif (owner === 'table' && name === 'toPublicDto') return 'dto'\n\tif (owner === 'table' && ['select', 'dto'].includes(name ?? '')) return 'dtoSchema'\n\tif (owner === 'dtoSchema' && ['parse', 'parseAsync'].includes(name ?? '')) return 'dto'\n\tif (owner === 'db' && name === 'query') return 'stream'\n\tif (owner === 'stream' && name === 'relation') return 'relationship'\n\tif (\n\t\towner === 'context' &&\n\t\tname === 'include' &&\n\t\tnode.arguments[0] &&\n\t\t(yield node.arguments[0]) === 'stream'\n\t)\n\t\treturn 'stream'\n\tif (owner === 'stream' || owner === 'relationship') {\n\t\tif (['take', 'execute'].includes(name ?? '')) return 'bounded'\n\t\tif (name === 'paginate') return 'page'\n\t\tif (\n\t\t\t[\n\t\t\t\t'withIndex',\n\t\t\t\t'withSearchIndex',\n\t\t\t\t'filter',\n\t\t\t\t'filterWith',\n\t\t\t\t'map',\n\t\t\t\t'flatMap',\n\t\t\t\t'distinct',\n\t\t\t\t'order',\n\t\t\t\t'matching',\n\t\t\t\t'when',\n\t\t\t\t'otherwise',\n\t\t\t\t'fullTableScan',\n\t\t\t\t'where',\n\t\t\t\t'with',\n\t\t\t].includes(name ?? '')\n\t\t)\n\t\t\treturn owner\n\t}\n\tif (owner === 'bounded' && name === 'map') return 'bounded'\n\tif (owner === 'validator') return 'validator'\n\treturn null\n}\n\n/** Match native registration contracts by both their import source and exported name. */\nfunction nativeReadBuilder(ref: { source: string; name: string }) {\n\treturn (\n\t\t(/_generated\\/server(?:\\.[cm]?[jt]s)?$/.test(ref.source) &&\n\t\t\tnativeReadBuilders.includes(ref.name)) ||\n\t\t(ref.source === 'convex/server' &&\n\t\t\tnativeReadBuilders.some((name) => ref.name === `${name}Generic`))\n\t)\n}\n\nfunction foundationFactory(ref: { source: string; name: string }) {\n\treturn (\n\t\t(ref.source === 'cvx-kit' && ref.name === 'createFoundation') ||\n\t\t(ref.source === 'cvx-kit/effect' && ref.name === 'createEffectFoundation') ||\n\t\t(['cvx-kit', 'cvx-kit/components/foundation'].includes(ref.source) && ref.name === 'Foundation')\n\t)\n}\n\n/** The supported registry mapping passes the host through unchanged. */\nfunction registryPreservesContext(context: Context, object: ESTree.ObjectExpression) {\n\tconst property = object.properties.find(\n\t\t(p) =>\n\t\t\tp.type === 'Property' && (p.computed ? staticString(p.key) : exportName(p.key)) === 'context',\n\t)\n\tif (property?.type !== 'Property') return false\n\tconst callback = property.value\n\tif (callback.type !== 'ArrowFunctionExpression' && callback.type !== 'FunctionExpression')\n\t\treturn false\n\tconst host = callback.params[0]\n\tif (\n\t\thost?.type !== 'Identifier' ||\n\t\tbinding(context, host)?.references.some((r) => r.isWrite() && !r.init)\n\t)\n\t\treturn false\n\tconst body = callback.body\n\tconst returned =\n\t\tbody?.type === 'BlockStatement' &&\n\t\tbody.body.length === 1 &&\n\t\tbody.body[0].type === 'ReturnStatement'\n\t\t\t? body.body[0].argument\n\t\t\t: body\n\treturn returned?.type === 'Identifier' && binding(context, returned) === binding(context, host)\n}\n\nfunction physicalString(node: Node): string | null {\n\tif (node.type === 'Literal' && String(node.value) === node.value) return String(node.value)\n\tif (node.type === 'TemplateLiteral' && node.expressions.length === 0)\n\t\treturn node.quasis[0].value.cooked\n\treturn null\n}\n"],"mappings":"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"}
package/dist/oxlint.d.mts CHANGED
@@ -3,7 +3,7 @@ import { OwnershipRuleName } from "./oxlint/ownership.mjs";
3
3
  import { Plugin, Rule } from "@oxlint/plugins";
4
4
  //#region src/oxlint.d.ts
5
5
  export declare function checkArchitecture(options?: ArchitectureOptions): ArchitectureDiagnostic[];
6
- export type RuleName = OwnershipRuleName | 'component-boundaries' | 'no-component-env' | 'schema-file-boundaries' | 'no-internal-reexports' | 'public-api-first' | 'named-private-helpers' | 'no-raw-builders' | 'no-handwritten-references' | 'domain-import-boundaries' | 'public-functions-in-api' | 'thin-api-adapters' | 'no-inline-enums' | 'no-unbounded-reads' | 'no-manual-timestamps' | 'reserved-domain-file-anatomy' | 'root-facade-ownership';
6
+ export type RuleName = OwnershipRuleName | 'component-boundaries' | 'no-component-env' | 'schema-file-boundaries' | 'no-internal-reexports' | 'public-api-first' | 'named-private-helpers' | 'no-raw-builders' | 'no-handwritten-references' | 'domain-import-boundaries' | 'public-functions-in-api' | 'thin-api-adapters' | 'no-inline-enums' | 'no-unbounded-reads' | 'no-manual-timestamps' | 'reserved-domain-file-anatomy' | 'root-facade-ownership' | 'no-manual-id-projection' | 'no-copied-pagination';
7
7
  export declare const rules: Record<RuleName, Rule>;
8
8
  declare const plugin: Plugin;
9
9
  //#endregion