@workos/oagen 0.11.0 → 0.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -0
- package/dist/cli/index.mjs +131 -15
- package/dist/cli/index.mjs.map +1 -1
- package/dist/compat/index.d.mts +4 -2
- package/dist/compat/index.d.mts.map +1 -1
- package/dist/compat/index.mjs +6 -3
- package/dist/compat/index.mjs.map +1 -1
- package/dist/{diff-DZvzV9p3.mjs → diff-C38px0NK.mjs} +4 -3
- package/dist/diff-C38px0NK.mjs.map +1 -0
- package/dist/{differ-8emGtevH.d.mts → differ-fdF9qogA.d.mts} +9 -2
- package/dist/differ-fdF9qogA.d.mts.map +1 -0
- package/dist/index.d.mts +61 -3
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +3 -3
- package/dist/index.mjs.map +1 -1
- package/dist/{overlay-Dddz3Awz.mjs → overlay-xp7F8_dW.mjs} +85 -2
- package/dist/overlay-xp7F8_dW.mjs.map +1 -0
- package/dist/scripts/smoke/baseline.mjs +1 -1
- package/dist/scripts/smoke/baseline.mjs.map +1 -1
- package/dist/smoke.d.mts +24 -0
- package/dist/smoke.d.mts.map +1 -1
- package/dist/smoke.mjs +1 -1
- package/dist/smoke.mjs.map +1 -1
- package/dist/{tree-sitter-C53w_0WE.mjs → tree-sitter-DcUvm0KA.mjs} +23 -2
- package/dist/tree-sitter-DcUvm0KA.mjs.map +1 -0
- package/dist/{types-DpD1SBY_.d.mts → types-BL762XqW.d.mts} +7 -2
- package/dist/{types-DpD1SBY_.d.mts.map → types-BL762XqW.d.mts.map} +1 -1
- package/dist/verify/index.d.mts +2 -2
- package/dist/verify/index.mjs +3 -3
- package/docs/advanced/index.md +1 -0
- package/docs/advanced/transform-spec.md +124 -0
- package/docs/cli.md +13 -11
- package/docs/core/compatibility-policy.md +26 -0
- package/docs/core/compatibility.md +6 -0
- package/docs/index.md +1 -0
- package/package.json +1 -1
- package/dist/diff-DZvzV9p3.mjs.map +0 -1
- package/dist/differ-8emGtevH.d.mts.map +0 -1
- package/dist/overlay-Dddz3Awz.mjs.map +0 -1
- package/dist/tree-sitter-C53w_0WE.mjs.map +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"differ-8emGtevH.d.mts","names":[],"sources":["../src/compat/classify.ts","../src/compat/spec-filter.ts","../src/compat/differ.ts"],"mappings":";;;;UAaiB,gBAAA;EAcJ;EAZX,QAAA,EAAU,oBAAA;EAAV;EAEA,QAAA,EAAU,oBAAA;EAAV;EAEA,MAAA;EAAA;EAEA,kBAAA;EAEA;EAAA,UAAA,EAAY,gBAAA;EAEZ;EAAA,GAAA,EAAK,MAAA;EAEL;EAAA,GAAA,EAAK,MAAA;EAEL;EAAA,OAAA;AAAA;AAIF;AAAA,UAAiB,oBAAA;EACf,OAAA,EAAS,gBAAA;EACT,OAAA;IACE,QAAA;IACA,QAAA;IACA,QAAA;EAAA;AAAA;;;;AAYJ;iBAAgB,qBAAA,CACd,QAAA,EAAU,YAAA,EACV,SAAA,EAAW,YAAA,cACX,MAAA,EAAQ,iBAAA,GACP,gBAAA;;;;iBAkUa,mBAAA,CAAoB,MAAA,EAAQ,YAAA,GAAe,gBAAA;;iBAc3C,gBAAA,CAAiB,OAAA,EAAS,gBAAA,KAAqB,oBAAA;;;;AAzX/D;;;;iBCJgB,gBAAA,CAAiB,IAAA,EAAM,OAAA,EAAS,KAAA,EAAO,aAAA,GAAgB,GAAA;;;;;iBA0CvD,qBAAA,CAAsB,IAAA,EAAM,OAAA,GAAU,GAAA,SAAY,GAAA;;;;;;iBAalD,qBAAA,CAAsB,IAAA,EAAM,OAAA,EAAS,KAAA,EAAO,aAAA,GAAgB,GAAA;;;;;;iBAqB5D,sBAAA,CAAuB,IAAA,EAAM,OAAA,GAAU,GAAA;;;;ADpDvD;iBCkEgB,mBAAA,CAAoB,IAAA,EAAM,OAAA,GAAU,GAAA;;;;;;;;;;;ADjDpD;;;;;iBCqGgB,aAAA,CACd,OAAA,EAAS,UAAA,EACT,YAAA,EAAc,GAAA,UACd,IAAA;EACE,UAAA,GAAa,GAAA;EACb,WAAA,GAAc,GAAA;EACd,UAAA,GAAa,GAAA,SAAY,GAAA;AAAA,IAE1B,UAAA;;;;UChIc,gBAAA;EACf,OAAA,EAAS,gBAAA;EACT,OAAA,EAAS,oBAAA;AAAA;;;;;iBAOK,aAAA,CACd,QAAA,EAAU,cAAA,EACV,SAAA,EAAW,cAAA,EACX,MAAA,GAAS,iBAAA,GACR,gBAAA;;;;;AFXH;;;;iBE4FgB,YAAA,CAAa,QAAA,EAAU,UAAA,EAAY,SAAA,EAAW,UAAA,EAAY,KAAA,EAAO,aAAA,GAAgB,UAAA"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"overlay-Dddz3Awz.mjs","names":["defaultNodeHints"],"sources":["../src/compat/policy.ts","../src/compat/schema.ts","../src/compat/ir.ts","../src/compat/config.ts","../src/compat/classify.ts","../src/compat/language-hints.ts","../src/compat/spec-filter.ts","../src/compat/differ.ts","../src/compat/extractor-registry.ts","../src/compat/overlay.ts"],"sourcesContent":["/**\n * Language-aware compatibility policy.\n *\n * Defines which aspects of the public API surface are breaking in each\n * language. Built-in defaults capture language semantics (e.g., PHP has\n * named arguments, Go does not). Config overrides allow per-SDK divergence.\n */\n\nimport type { LanguageId } from './ir.js';\n\n/** Policy hints that determine what constitutes a breaking change. */\nexport interface CompatPolicyHints {\n /** Callers reference parameter names at the call site (PHP named args, Python/Ruby keyword args, Kotlin/C# named args). */\n callerUsesParamNames: boolean;\n /** Constructor positional order is part of the public API. */\n constructorOrderMatters: boolean;\n /** Method parameter names are visible to callers. */\n methodParameterNamesArePublicApi: boolean;\n /** Constructor parameter names are visible to callers. */\n constructorParameterNamesArePublicApi: boolean;\n /** Method overload sets are part of the public API (Kotlin, C#). */\n overloadsArePublicApi: boolean;\n /** Function arity is part of the public API (Elixir, Go). */\n arityIsPublicApi: boolean;\n}\n\n/** Built-in language defaults. */\nconst LANGUAGE_DEFAULTS: Record<LanguageId, CompatPolicyHints> = {\n php: {\n callerUsesParamNames: true,\n constructorOrderMatters: true,\n methodParameterNamesArePublicApi: true,\n constructorParameterNamesArePublicApi: true,\n overloadsArePublicApi: false,\n arityIsPublicApi: false,\n },\n python: {\n callerUsesParamNames: true,\n constructorOrderMatters: true,\n methodParameterNamesArePublicApi: true,\n constructorParameterNamesArePublicApi: true,\n overloadsArePublicApi: false,\n arityIsPublicApi: false,\n },\n ruby: {\n callerUsesParamNames: true,\n constructorOrderMatters: true,\n methodParameterNamesArePublicApi: true,\n constructorParameterNamesArePublicApi: true,\n overloadsArePublicApi: false,\n arityIsPublicApi: false,\n },\n go: {\n callerUsesParamNames: false,\n constructorOrderMatters: true,\n methodParameterNamesArePublicApi: false,\n constructorParameterNamesArePublicApi: false,\n overloadsArePublicApi: false,\n arityIsPublicApi: true,\n },\n kotlin: {\n callerUsesParamNames: true,\n constructorOrderMatters: false,\n methodParameterNamesArePublicApi: true,\n constructorParameterNamesArePublicApi: true,\n overloadsArePublicApi: true,\n arityIsPublicApi: false,\n },\n dotnet: {\n callerUsesParamNames: true,\n constructorOrderMatters: false,\n methodParameterNamesArePublicApi: true,\n constructorParameterNamesArePublicApi: true,\n overloadsArePublicApi: true,\n arityIsPublicApi: false,\n },\n elixir: {\n callerUsesParamNames: true,\n constructorOrderMatters: false,\n methodParameterNamesArePublicApi: true,\n constructorParameterNamesArePublicApi: false,\n overloadsArePublicApi: false,\n arityIsPublicApi: true,\n },\n rust: {\n callerUsesParamNames: false,\n constructorOrderMatters: true,\n methodParameterNamesArePublicApi: false,\n constructorParameterNamesArePublicApi: false,\n overloadsArePublicApi: false,\n arityIsPublicApi: true,\n },\n node: {\n callerUsesParamNames: false,\n constructorOrderMatters: false,\n methodParameterNamesArePublicApi: false,\n constructorParameterNamesArePublicApi: false,\n overloadsArePublicApi: false,\n arityIsPublicApi: false,\n },\n};\n\n/** Get the built-in default policy for a language. */\nexport function getDefaultPolicy(language: LanguageId): CompatPolicyHints {\n return { ...LANGUAGE_DEFAULTS[language] };\n}\n\n/** Merge user overrides onto language defaults. Only provided keys are overridden. */\nexport function mergePolicy(defaults: CompatPolicyHints, overrides: Partial<CompatPolicyHints>): CompatPolicyHints {\n return { ...defaults, ...overrides };\n}\n\n/** All supported language IDs. */\nexport const ALL_LANGUAGE_IDS: readonly LanguageId[] = Object.keys(LANGUAGE_DEFAULTS) as LanguageId[];\n","/**\n * Schema versioning for compatibility snapshots.\n *\n * Snapshots are versioned so consumers can detect format changes and\n * apply migration logic if needed.\n */\n\nimport type { CompatSnapshot } from './ir.js';\n\n/** Current schema version for compatibility snapshots. */\nexport const COMPAT_SCHEMA_VERSION = '1';\n\n/** Validate that a parsed snapshot has a compatible schema version. */\nexport function isCompatibleSchemaVersion(snapshot: { schemaVersion?: string }): boolean {\n return snapshot.schemaVersion === COMPAT_SCHEMA_VERSION;\n}\n\n/** Validate the basic structure of a parsed compat snapshot. */\nexport function validateSnapshot(data: unknown): data is CompatSnapshot {\n if (typeof data !== 'object' || data === null) return false;\n const obj = data as Record<string, unknown>;\n return (\n typeof obj.schemaVersion === 'string' &&\n typeof obj.source === 'object' &&\n obj.source !== null &&\n typeof obj.policies === 'object' &&\n obj.policies !== null &&\n Array.isArray(obj.symbols)\n );\n}\n","/**\n * Rich compatibility IR for cross-language compatibility verification.\n *\n * These types represent the public API surface of an SDK in a language-aware,\n * machine-readable format. They extend the basic ApiSurface with richer\n * parameter semantics, sensitivity flags, and provenance metadata.\n */\n\nimport type { CompatPolicyHints } from './policy.js';\n\n/** Language identifier for emitter targets. */\nexport type LanguageId = 'node' | 'php' | 'python' | 'ruby' | 'go' | 'kotlin' | 'dotnet' | 'elixir' | 'rust';\n\n/** A full compatibility snapshot of an SDK's public API surface. */\nexport interface CompatSnapshot {\n schemaVersion: string;\n source: {\n specSha?: string;\n extractedAt: string;\n };\n policies: CompatPolicyHints;\n symbols: CompatSymbol[];\n}\n\n/** Kind of public API symbol. */\nexport type CompatSymbolKind =\n | 'service_accessor'\n | 'callable'\n | 'constructor'\n | 'field'\n | 'property'\n | 'enum'\n | 'enum_member'\n | 'alias';\n\n/** Visibility level of a symbol. */\nexport type CompatVisibility = 'public' | 'protected' | 'internal';\n\n/** Stability classification of a symbol. */\nexport type CompatStability = 'stable' | 'unstable' | 'deprecated';\n\n/** How the symbol was generated. */\nexport type CompatSourceKind =\n | 'generated_service_wrapper'\n | 'generated_model_constructor'\n | 'generated_resource_constructor'\n | 'generated_enum'\n | 'compat_alias';\n\n/** A single public API symbol with its full metadata. */\nexport interface CompatSymbol {\n id: string;\n kind: CompatSymbolKind;\n fqName: string;\n ownerFqName?: string;\n displayName: string;\n visibility: CompatVisibility;\n stability: CompatStability;\n sourceKind: CompatSourceKind;\n operationId?: string;\n schemaName?: string;\n route?: {\n method: string;\n path: string;\n };\n parameters?: CompatParameter[];\n returns?: CompatTypeRef;\n /** Type reference for field/property symbols. */\n typeRef?: CompatTypeRef;\n /** Value for enum member symbols. */\n value?: string | number;\n /** Relative path to the source file where this symbol is defined. */\n sourceFile?: string;\n}\n\n/** How a parameter is passed at the call site. */\nexport type CompatPassingStyle =\n | 'positional'\n | 'keyword'\n | 'named'\n | 'keyword_or_positional'\n | 'options_object'\n | 'builder';\n\n/** A parameter on a callable or constructor symbol. */\nexport interface CompatParameter {\n publicName: string;\n wireName?: string;\n position: number;\n required: boolean;\n nullable: boolean;\n hasDefault: boolean;\n passing: CompatPassingStyle;\n type: CompatTypeRef;\n sensitivity: ParameterSensitivity;\n}\n\n/** Which aspects of this parameter are part of the public API contract. */\nexport interface ParameterSensitivity {\n order: boolean;\n publicName: boolean;\n requiredness: boolean;\n type: boolean;\n}\n\n/** A type reference — either a named type or an inline description. */\nexport interface CompatTypeRef {\n name: string;\n nullable?: boolean;\n array?: boolean;\n generic?: string[];\n}\n\n// ---------------------------------------------------------------------------\n// Bridge: ApiSurface → CompatSnapshot\n// ---------------------------------------------------------------------------\n\nimport type { ApiSurface, ApiParam } from './types.js';\nimport { getDefaultPolicy } from './policy.js';\nimport { COMPAT_SCHEMA_VERSION } from './schema.js';\n\n/**\n * Convert a legacy ApiSurface to a CompatSnapshot.\n *\n * This bridge allows existing extractors (which produce ApiSurface) to feed\n * into the new classified diff engine without requiring immediate migration.\n */\nexport function apiSurfaceToSnapshot(surface: ApiSurface): CompatSnapshot {\n const language = (surface.language || 'node') as LanguageId;\n const symbols: CompatSymbol[] = [];\n\n // Convert classes → service_accessor symbols + callable/constructor children\n for (const [className, cls] of Object.entries(surface.classes)) {\n symbols.push({\n id: `class:${className}`,\n kind: 'service_accessor',\n fqName: className,\n displayName: className,\n visibility: 'public',\n stability: cls.deprecationMessage ? 'deprecated' : 'stable',\n sourceKind: 'generated_service_wrapper',\n ...(cls.sourceFile ? { sourceFile: cls.sourceFile } : {}),\n });\n\n // Constructor\n if (cls.constructorParams.length > 0) {\n symbols.push({\n id: `ctor:${className}`,\n kind: 'constructor',\n fqName: `${className}.constructor`,\n ownerFqName: className,\n displayName: `new ${className}`,\n visibility: 'public',\n stability: 'stable',\n sourceKind: 'generated_resource_constructor',\n parameters: cls.constructorParams.map((p, i) => apiParamToCompatParam(p, i, language)),\n ...(cls.sourceFile ? { sourceFile: cls.sourceFile } : {}),\n });\n }\n\n // Methods\n for (const [methodName, overloads] of Object.entries(cls.methods)) {\n for (let oi = 0; oi < overloads.length; oi++) {\n const method = overloads[oi];\n const suffix = overloads.length > 1 ? `#${oi}` : '';\n symbols.push({\n id: `method:${className}.${methodName}${suffix}`,\n kind: 'callable',\n fqName: `${className}.${methodName}`,\n ownerFqName: className,\n displayName: `${className}.${methodName}`,\n visibility: 'public',\n stability: 'stable',\n sourceKind: 'generated_service_wrapper',\n parameters: method.params.map((p, i) => apiParamToCompatParam(p, i, language)),\n returns: { name: method.returnType },\n ...(cls.sourceFile ? { sourceFile: cls.sourceFile } : {}),\n });\n }\n }\n\n // Properties\n for (const [propName, prop] of Object.entries(cls.properties)) {\n symbols.push({\n id: `prop:${className}.${propName}`,\n kind: 'property',\n fqName: `${className}.${propName}`,\n ownerFqName: className,\n displayName: `${className}.${propName}`,\n visibility: 'public',\n stability: 'stable',\n sourceKind: 'generated_service_wrapper',\n typeRef: { name: prop.type },\n ...(cls.sourceFile ? { sourceFile: cls.sourceFile } : {}),\n });\n }\n }\n\n // Convert interfaces → field symbols\n for (const [ifaceName, iface] of Object.entries(surface.interfaces)) {\n symbols.push({\n id: `iface:${ifaceName}`,\n kind: 'alias',\n fqName: ifaceName,\n displayName: ifaceName,\n visibility: 'public',\n stability: 'stable',\n sourceKind: 'generated_resource_constructor',\n ...(iface.sourceFile ? { sourceFile: iface.sourceFile } : {}),\n });\n\n for (const [fieldName, field] of Object.entries(iface.fields)) {\n symbols.push({\n id: `field:${ifaceName}.${fieldName}`,\n kind: 'field',\n fqName: `${ifaceName}.${fieldName}`,\n ownerFqName: ifaceName,\n displayName: `${ifaceName}.${fieldName}`,\n visibility: 'public',\n stability: 'stable',\n sourceKind: 'generated_resource_constructor',\n typeRef: { name: field.type },\n ...(iface.sourceFile ? { sourceFile: iface.sourceFile } : {}),\n });\n }\n\n // Constructor if interface has one\n if (iface.hasCustomConstructor) {\n symbols.push({\n id: `ctor:${ifaceName}`,\n kind: 'constructor',\n fqName: `${ifaceName}.constructor`,\n ownerFqName: ifaceName,\n displayName: `new ${ifaceName}`,\n visibility: 'public',\n stability: 'stable',\n sourceKind: 'generated_resource_constructor',\n ...(iface.sourceFile ? { sourceFile: iface.sourceFile } : {}),\n });\n }\n }\n\n // Convert type aliases\n for (const [aliasName, alias] of Object.entries(surface.typeAliases)) {\n symbols.push({\n id: `alias:${aliasName}`,\n kind: 'alias',\n fqName: aliasName,\n displayName: aliasName,\n visibility: 'public',\n stability: 'stable',\n sourceKind: 'generated_resource_constructor',\n ...(alias.sourceFile ? { sourceFile: alias.sourceFile } : {}),\n });\n }\n\n // Convert enums\n for (const [enumName, enumDef] of Object.entries(surface.enums)) {\n symbols.push({\n id: `enum:${enumName}`,\n kind: 'enum',\n fqName: enumName,\n displayName: enumName,\n visibility: 'public',\n stability: 'stable',\n sourceKind: 'generated_enum',\n ...(enumDef.sourceFile ? { sourceFile: enumDef.sourceFile } : {}),\n });\n\n for (const [memberName, memberValue] of Object.entries(enumDef.members)) {\n symbols.push({\n id: `enum_member:${enumName}.${memberName}`,\n kind: 'enum_member',\n fqName: `${enumName}.${memberName}`,\n ownerFqName: enumName,\n displayName: `${enumName}.${memberName}`,\n visibility: 'public',\n stability: 'stable',\n sourceKind: 'generated_enum',\n value: memberValue,\n ...(enumDef.sourceFile ? { sourceFile: enumDef.sourceFile } : {}),\n });\n }\n }\n\n return {\n schemaVersion: COMPAT_SCHEMA_VERSION,\n source: { extractedAt: surface.extractedAt },\n policies: getDefaultPolicy(language),\n symbols,\n };\n}\n\n/** Convert a legacy ApiParam to a CompatParameter. */\nfunction apiParamToCompatParam(param: ApiParam, position: number, language: LanguageId): CompatParameter {\n const policy = getDefaultPolicy(language);\n return {\n publicName: param.name,\n position,\n required: !param.optional,\n nullable: false,\n hasDefault: param.optional,\n passing: param.passingStyle ?? inferPassingStyle(language),\n type: { name: param.type },\n sensitivity: {\n order: policy.constructorOrderMatters,\n publicName: policy.methodParameterNamesArePublicApi,\n requiredness: true,\n type: true,\n },\n };\n}\n\n/** Infer the default parameter passing style for a language. */\nfunction inferPassingStyle(language: LanguageId): CompatPassingStyle {\n switch (language) {\n case 'python':\n case 'ruby':\n case 'elixir':\n return 'keyword';\n case 'php':\n case 'kotlin':\n case 'dotnet':\n return 'named';\n case 'node':\n return 'options_object';\n default:\n return 'positional';\n }\n}\n","/**\n * Compat configuration types for `oagen.config.ts`.\n *\n * The `compat` section of the config holds human-authored policy:\n * fail thresholds, language overrides, and intentional break approvals.\n * Generated state (manifests, snapshots, reports) lives elsewhere.\n */\n\nimport type { LanguageId } from './ir.js';\nimport type { CompatPolicyHints } from './policy.js';\n\n// ---------------------------------------------------------------------------\n// Change categories\n// ---------------------------------------------------------------------------\n\n/** Breaking change categories — changes that break callers. */\nexport type BreakingChangeCategory =\n | 'symbol_removed'\n | 'symbol_renamed'\n | 'parameter_removed'\n | 'parameter_renamed'\n | 'parameter_requiredness_increased'\n | 'parameter_type_narrowed'\n | 'parameter_position_changed_order_sensitive'\n | 'constructor_position_changed_order_sensitive'\n | 'named_arg_name_removed'\n | 'keyword_name_removed'\n | 'overload_removed'\n | 'union_wrapper_migration_without_compat_alias'\n | 'field_type_changed'\n | 'return_type_changed'\n | 'enum_member_value_changed';\n\n/** Soft-risk change categories — may affect callers depending on usage. */\nexport type SoftRiskChangeCategory =\n | 'parameter_added_non_terminal_optional'\n | 'constructor_reordered_named_friendly'\n | 'default_value_changed'\n | 'wrapper_stricter_than_previous_sdk_but_matches_spec'\n | 'doc_surface_drift';\n\n/** Additive change categories — safe to ship. */\nexport type AdditiveChangeCategory =\n | 'symbol_added'\n | 'parameter_added_optional_terminal'\n | 'new_constructor_overload_added'\n | 'new_wrapper_alias_added';\n\n/** All change categories. */\nexport type CompatChangeCategory = BreakingChangeCategory | SoftRiskChangeCategory | AdditiveChangeCategory;\n\n/** Change severity levels. */\nexport type CompatChangeSeverity = 'breaking' | 'soft-risk' | 'additive';\n\n/** Provenance bucket — where the drift originated. */\nexport type CompatProvenance =\n | 'spec_shape_change'\n | 'spec_ordering_change'\n | 'emitter_template_change'\n | 'compat_extractor_change'\n | 'operation_hint_change'\n | 'manual_override_change'\n | 'normalization_change'\n | 'unknown';\n\n// ---------------------------------------------------------------------------\n// Fail threshold\n// ---------------------------------------------------------------------------\n\n/** Level at which `verify` should fail. */\nexport type CompatFailLevel = 'none' | 'breaking' | 'soft-risk';\n\n// ---------------------------------------------------------------------------\n// Approvals\n// ---------------------------------------------------------------------------\n\n/** A single intentional-break approval in `oagen.config.ts`. */\nexport interface CompatApproval {\n /** Fully-qualified symbol (e.g., \"WorkOS\\\\Service\\\\UserManagement::createUser\"). */\n symbol: string;\n /** The kind of change being approved. */\n category: CompatChangeCategory;\n /** Languages this approval applies to. Omit for all impacted languages. */\n appliesTo?: LanguageId[] | 'all-impacted-languages';\n /** Optional narrowing criteria. */\n match?: {\n parameter?: string;\n member?: string;\n oldName?: string;\n newName?: string;\n };\n /** Minimum release level required for this break. */\n allowedReleaseLevel?: 'major' | 'minor' | 'patch';\n /** Human-readable reason for this approval. */\n reason: string;\n /** Issue tracker reference (e.g., \"SDK-1234\"). */\n issue?: string;\n /** Auto-expire this approval after a version is released. */\n expiresAfterVersion?: string;\n /** Whether this approval is currently active. */\n approved?: boolean;\n}\n\n// ---------------------------------------------------------------------------\n// Config section\n// ---------------------------------------------------------------------------\n\n/** The `compat` section of `oagen.config.ts`. */\nexport interface CompatConfig {\n /** Level at which `oagen verify` should fail. Default: 'breaking'. */\n failOn?: CompatFailLevel;\n /** Path to write the machine-readable compat report. */\n reportPath?: string;\n /** Include provenance explanations in reports. */\n explain?: boolean;\n /** Path to the baseline compatibility snapshot. */\n baselinePath?: string;\n /** Per-language policy overrides. Sparse — only override what diverges. */\n languagePolicy?: Partial<Record<LanguageId, Partial<CompatPolicyHints>>>;\n /** Intentional break approvals. */\n allow?: CompatApproval[];\n}\n\n// ---------------------------------------------------------------------------\n// Category → severity mapping\n// ---------------------------------------------------------------------------\n\nconst BREAKING_CATEGORIES: ReadonlySet<BreakingChangeCategory> = new Set<BreakingChangeCategory>([\n 'symbol_removed',\n 'symbol_renamed',\n 'parameter_removed',\n 'parameter_renamed',\n 'parameter_requiredness_increased',\n 'parameter_type_narrowed',\n 'parameter_position_changed_order_sensitive',\n 'constructor_position_changed_order_sensitive',\n 'named_arg_name_removed',\n 'keyword_name_removed',\n 'overload_removed',\n 'union_wrapper_migration_without_compat_alias',\n 'field_type_changed',\n 'return_type_changed',\n 'enum_member_value_changed',\n]);\n\nconst SOFT_RISK_CATEGORIES: ReadonlySet<SoftRiskChangeCategory> = new Set<SoftRiskChangeCategory>([\n 'parameter_added_non_terminal_optional',\n 'constructor_reordered_named_friendly',\n 'default_value_changed',\n 'wrapper_stricter_than_previous_sdk_but_matches_spec',\n 'doc_surface_drift',\n]);\n\n/** Get the default severity for a change category. */\nexport function defaultSeverityForCategory(category: CompatChangeCategory): CompatChangeSeverity {\n if (BREAKING_CATEGORIES.has(category as BreakingChangeCategory)) return 'breaking';\n if (SOFT_RISK_CATEGORIES.has(category as SoftRiskChangeCategory)) return 'soft-risk';\n return 'additive';\n}\n\n/** Check whether a severity meets or exceeds a fail threshold. */\nexport function severityMeetsThreshold(severity: CompatChangeSeverity, threshold: CompatFailLevel): boolean {\n if (threshold === 'none') return false;\n if (threshold === 'soft-risk') return severity === 'breaking' || severity === 'soft-risk';\n return severity === 'breaking';\n}\n","/**\n * Change classifier for compatibility verification.\n *\n * Takes raw diffs between baseline and candidate compat snapshots and\n * classifies each change into a specific category with policy-aware severity.\n */\n\nimport type { CompatSymbol, CompatParameter } from './ir.js';\nimport type { CompatPolicyHints } from './policy.js';\nimport type { CompatChangeCategory, CompatChangeSeverity, CompatProvenance } from './config.js';\nimport { defaultSeverityForCategory } from './config.js';\n\n/** A single classified compatibility change. */\nexport interface ClassifiedChange {\n /** Specific change category. */\n category: CompatChangeCategory;\n /** Policy-aware severity (may differ from defaultSeverityForCategory). */\n severity: CompatChangeSeverity;\n /** Fully-qualified symbol path. */\n symbol: string;\n /** Deterministic ID for grouping related changes across languages. */\n conceptualChangeId: string;\n /** Where the drift originated. */\n provenance: CompatProvenance;\n /** Description of the old state. */\n old: Record<string, string>;\n /** Description of the new state. */\n new: Record<string, string>;\n /** Human-readable explanation. */\n message: string;\n}\n\n/** Result of classifying all changes between two snapshots. */\nexport interface ClassificationResult {\n changes: ClassifiedChange[];\n summary: {\n breaking: number;\n softRisk: number;\n additive: number;\n };\n}\n\n// ---------------------------------------------------------------------------\n// Classification engine\n// ---------------------------------------------------------------------------\n\n/**\n * Classify changes between a baseline and candidate symbol.\n * Returns one or more classified changes for the diff.\n */\nexport function classifySymbolChanges(\n baseline: CompatSymbol,\n candidate: CompatSymbol | undefined,\n policy: CompatPolicyHints,\n): ClassifiedChange[] {\n const changes: ClassifiedChange[] = [];\n\n // Build spec-level ref for cross-language grouping.\n // Prefer schemaName from either symbol (baseline for removals, candidate for adds).\n const specRef = baseline.schemaName ?? candidate?.schemaName;\n\n // Symbol removed\n if (!candidate) {\n changes.push(\n makeChange({\n category: 'symbol_removed',\n symbol: baseline.fqName,\n old: { symbol: baseline.fqName },\n new: { symbol: '(removed)' },\n message: `Symbol \"${baseline.displayName}\" was removed`,\n policy,\n specRef,\n }),\n );\n return changes;\n }\n\n // Symbol renamed\n if (baseline.fqName !== candidate.fqName && baseline.id === candidate.id) {\n changes.push(\n makeChange({\n category: 'symbol_renamed',\n symbol: baseline.fqName,\n old: { name: baseline.fqName },\n new: { name: candidate.fqName },\n message: `Symbol renamed from \"${baseline.displayName}\" to \"${candidate.displayName}\"`,\n policy,\n specRef,\n }),\n );\n }\n\n // Parameter-level changes (for callables and constructors)\n if (baseline.parameters && candidate.parameters) {\n changes.push(...classifyParameterChanges(baseline, candidate, policy, specRef));\n }\n\n // Return type changes (for callables)\n if (baseline.returns && candidate.returns && baseline.returns.name !== candidate.returns.name) {\n changes.push(\n makeChange({\n category: 'return_type_changed',\n symbol: baseline.fqName,\n old: { returnType: baseline.returns.name },\n new: { returnType: candidate.returns.name },\n message: `Return type changed for \"${baseline.displayName}\" from \"${baseline.returns.name}\" to \"${candidate.returns.name}\"`,\n policy,\n specRef,\n }),\n );\n }\n\n // Field/property type changes\n if (baseline.typeRef && candidate.typeRef && baseline.typeRef.name !== candidate.typeRef.name) {\n changes.push(\n makeChange({\n category: 'field_type_changed',\n symbol: baseline.fqName,\n old: { type: baseline.typeRef.name },\n new: { type: candidate.typeRef.name },\n message: `Type changed for \"${baseline.displayName}\" from \"${baseline.typeRef.name}\" to \"${candidate.typeRef.name}\"`,\n policy,\n specRef,\n }),\n );\n }\n\n // Enum member value changes\n if (\n baseline.kind === 'enum_member' &&\n candidate.kind === 'enum_member' &&\n baseline.value !== undefined &&\n candidate.value !== undefined &&\n baseline.value !== candidate.value\n ) {\n changes.push(\n makeChange({\n category: 'enum_member_value_changed',\n symbol: baseline.fqName,\n old: { value: String(baseline.value) },\n new: { value: String(candidate.value) },\n message: `Enum value changed for \"${baseline.displayName}\" from \"${baseline.value}\" to \"${candidate.value}\"`,\n policy,\n }),\n );\n }\n\n return changes;\n}\n\n/**\n * Classify parameter-level changes between two symbol versions.\n */\nfunction classifyParameterChanges(\n baseline: CompatSymbol,\n candidate: CompatSymbol,\n policy: CompatPolicyHints,\n specRef?: string,\n): ClassifiedChange[] {\n const changes: ClassifiedChange[] = [];\n const baseParams = baseline.parameters ?? [];\n const candParams = candidate.parameters ?? [];\n\n const baseByName = new Map(baseParams.map((p) => [p.publicName, p]));\n const candByName = new Map(candParams.map((p) => [p.publicName, p]));\n const isConstructor = baseline.kind === 'constructor';\n\n // Check each baseline parameter\n for (const baseParam of baseParams) {\n const candParam = candByName.get(baseParam.publicName);\n\n if (!candParam) {\n // Parameter removed — check if it was renamed\n const positionalMatch = candParams[baseParam.position];\n if (positionalMatch && !baseByName.has(positionalMatch.publicName)) {\n // Position preserved but name changed → rename\n const isBreakingRename = parameterNameIsPublicApi(baseParam, policy, isConstructor);\n changes.push(\n makeChange({\n category: 'parameter_renamed',\n symbol: baseline.fqName,\n old: { parameter: baseParam.publicName },\n new: { parameter: positionalMatch.publicName },\n message: `Parameter \"${baseParam.publicName}\" renamed to \"${positionalMatch.publicName}\" on \"${baseline.displayName}\"`,\n policy,\n specRef,\n severityOverride: isBreakingRename ? undefined : 'soft-risk',\n }),\n );\n } else {\n // Truly removed\n changes.push(\n makeChange({\n category: 'parameter_removed',\n symbol: baseline.fqName,\n old: { parameter: baseParam.publicName },\n new: { parameter: '(removed)' },\n message: `Parameter \"${baseParam.publicName}\" removed from \"${baseline.displayName}\"`,\n policy,\n specRef,\n }),\n );\n }\n continue;\n }\n\n // Requiredness increased (optional → required)\n if (!baseParam.required && candParam.required) {\n changes.push(\n makeChange({\n category: 'parameter_requiredness_increased',\n symbol: baseline.fqName,\n old: { parameter: baseParam.publicName, required: 'false' },\n new: { parameter: candParam.publicName, required: 'true' },\n message: `Parameter \"${baseParam.publicName}\" became required on \"${baseline.displayName}\"`,\n policy,\n specRef,\n }),\n );\n }\n\n // Type narrowed\n if (baseParam.type.name !== candParam.type.name) {\n changes.push(\n makeChange({\n category: 'parameter_type_narrowed',\n symbol: baseline.fqName,\n old: { parameter: baseParam.publicName, type: baseParam.type.name },\n new: { parameter: candParam.publicName, type: candParam.type.name },\n message: `Parameter type changed for \"${baseParam.publicName}\" on \"${baseline.displayName}\"`,\n policy,\n specRef,\n }),\n );\n }\n\n // Position changed (order-sensitive)\n if (baseParam.position !== candParam.position) {\n const orderMatters = isConstructor ? policy.constructorOrderMatters : baseParam.sensitivity.order;\n\n if (orderMatters) {\n const category: CompatChangeCategory = isConstructor\n ? 'constructor_position_changed_order_sensitive'\n : 'parameter_position_changed_order_sensitive';\n changes.push(\n makeChange({\n category,\n symbol: baseline.fqName,\n old: { parameter: baseParam.publicName, position: String(baseParam.position) },\n new: { parameter: candParam.publicName, position: String(candParam.position) },\n message: `Parameter \"${baseParam.publicName}\" moved from position ${baseParam.position} to ${candParam.position} on \"${baseline.displayName}\"`,\n policy,\n specRef,\n }),\n );\n } else {\n // Reordered but in a named-friendly language → soft-risk\n changes.push(\n makeChange({\n category: 'constructor_reordered_named_friendly',\n symbol: baseline.fqName,\n old: { parameter: baseParam.publicName, position: String(baseParam.position) },\n new: { parameter: candParam.publicName, position: String(candParam.position) },\n message: `Parameter \"${baseParam.publicName}\" reordered on \"${baseline.displayName}\" (named-friendly language)`,\n policy,\n specRef,\n }),\n );\n }\n }\n }\n\n // Check for new parameters in candidate\n for (const candParam of candParams) {\n if (!baseByName.has(candParam.publicName)) {\n // Check if this was already captured as a rename\n const isRename = changes.some(\n (c) => c.category === 'parameter_renamed' && c.new.parameter === candParam.publicName,\n );\n if (isRename) continue;\n\n const isTerminal = candParam.position === candParams.length - 1;\n const category: CompatChangeCategory = candParam.required\n ? 'parameter_requiredness_increased'\n : isTerminal\n ? 'parameter_added_optional_terminal'\n : 'parameter_added_non_terminal_optional';\n\n if (candParam.required) {\n changes.push(\n makeChange({\n category,\n symbol: baseline.fqName,\n old: { parameter: '(absent)' },\n new: { parameter: candParam.publicName, required: 'true' },\n message: `Required parameter \"${candParam.publicName}\" added to \"${baseline.displayName}\"`,\n policy,\n specRef,\n }),\n );\n } else {\n changes.push(\n makeChange({\n category,\n symbol: baseline.fqName,\n old: { parameter: '(absent)' },\n new: { parameter: candParam.publicName },\n message: `Optional parameter \"${candParam.publicName}\" added to \"${baseline.displayName}\"`,\n policy,\n specRef,\n }),\n );\n }\n }\n }\n\n return changes;\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction parameterNameIsPublicApi(param: CompatParameter, policy: CompatPolicyHints, isConstructor: boolean): boolean {\n if (param.sensitivity.publicName) return true;\n if (isConstructor) return policy.constructorParameterNamesArePublicApi;\n return policy.methodParameterNamesArePublicApi;\n}\n\n/**\n * Build a deterministic conceptual change ID.\n *\n * When `specRef` is provided (e.g. \"GenerateLinkBody.admin_emails\"), it is\n * used instead of the language-specific symbol name. This ensures the same\n * spec entity produces the same ID across all languages, enabling cross-\n * language rollup in reports.\n */\nfunction buildConceptualChangeId(\n category: CompatChangeCategory,\n symbol: string,\n match: Record<string, string>,\n specRef?: string,\n): string {\n const identity = specRef ?? symbol;\n const parts = ['chg', category, identity.replace(/[^a-zA-Z0-9_.]/g, '_')];\n if (match.parameter) parts.push(match.parameter);\n if (match.member) parts.push(match.member);\n return parts.join('_').toLowerCase();\n}\n\nfunction makeChange(opts: {\n category: CompatChangeCategory;\n symbol: string;\n old: Record<string, string>;\n new: Record<string, string>;\n message: string;\n policy: CompatPolicyHints;\n provenance?: CompatProvenance;\n severityOverride?: CompatChangeSeverity;\n specRef?: string;\n}): ClassifiedChange {\n return {\n category: opts.category,\n severity: opts.severityOverride ?? defaultSeverityForCategory(opts.category),\n symbol: opts.symbol,\n conceptualChangeId: buildConceptualChangeId(opts.category, opts.symbol, opts.old, opts.specRef),\n provenance: opts.provenance ?? 'unknown',\n old: opts.old,\n new: opts.new,\n message: opts.message,\n };\n}\n\n/**\n * Classify a new symbol as additive.\n */\nexport function classifyAddedSymbol(symbol: CompatSymbol): ClassifiedChange {\n return {\n category: 'symbol_added',\n severity: 'additive',\n symbol: symbol.fqName,\n conceptualChangeId: buildConceptualChangeId('symbol_added', symbol.fqName, {}, symbol.schemaName),\n provenance: 'unknown',\n old: { symbol: '(absent)' },\n new: { symbol: symbol.fqName },\n message: `Symbol \"${symbol.displayName}\" was added`,\n };\n}\n\n/** Summarize a list of classified changes by severity. */\nexport function summarizeChanges(changes: ClassifiedChange[]): ClassificationResult['summary'] {\n let breaking = 0;\n let softRisk = 0;\n let additive = 0;\n for (const c of changes) {\n if (c.severity === 'breaking') breaking++;\n else if (c.severity === 'soft-risk') softRisk++;\n else additive++;\n }\n return { breaking, softRisk, additive };\n}\n","import type { ApiSurface, LanguageHints } from './types.js';\nimport { splitWords } from '../utils/naming.js';\n\n/** Untyped map patterns — hoisted to avoid allocation on every isTypeEquivalent call. */\nconst UNTYPED_MAP_PATTERNS = new Set([\n 'Record<string, unknown>',\n 'Record<string, any>',\n '{ [key: string]: any; }',\n '{ [key: string]: unknown; }',\n 'any',\n]);\n\nexport const NAMED_TYPE_RE = /^[A-Z][a-zA-Z0-9]*$/;\n\n/** Check whether a type name exists as an interface, class, or enum in a surface. */\nexport function typeExistsInSurface(name: string, surface: ApiSurface): boolean {\n return !!(surface.interfaces[name] || surface.classes[name] || surface.enums[name]);\n}\n\n/** Split a PascalCase string into words, keeping only words > 2 chars. */\nfunction splitPascalWords(s: string): string[] {\n return splitWords(s).filter((w) => w.length > 2);\n}\n\n/**\n * Check whether two named types share enough PascalCase word components to\n * be considered equivalent (handles name reordering from Json merges, etc.).\n * Both names have `Response$` stripped before comparison.\n */\nexport function namedTypeWordsOverlap(a: string, b: string, minOverlap = 1): boolean {\n const aNoResp = a.replace(/Response$/, '');\n const bNoResp = b.replace(/Response$/, '');\n const aWords = new Set(splitPascalWords(aNoResp).map((w) => w.toLowerCase()));\n const bWords = new Set(splitPascalWords(bNoResp).map((w) => w.toLowerCase()));\n const overlap = [...aWords].filter((w) => bWords.has(w));\n return overlap.length >= minOverlap && overlap.length >= Math.min(aWords.size, bWords.size) - 1;\n}\n\n/** Split a pipe-delimited union string into trimmed, non-empty members. */\nfunction parseUnionMembers(s: string): string[] {\n return s\n .split('|')\n .map((p) => p.trim())\n .filter(Boolean);\n}\n\n/**\n * Default implementation of isNullableOnlyDifference — shared across extractors.\n * Returns true when stripping nullable wrappers from both sides yields the same\n * type, but the original types differ (i.e., the only difference is nullability).\n */\nexport function defaultIsNullableOnlyDifference(\n hints: Pick<LanguageHints, 'stripNullable'>,\n a: string,\n b: string,\n): boolean {\n return (hints.stripNullable(a) ?? a) === (hints.stripNullable(b) ?? b) && a !== b;\n}\n\n/**\n * Node/TypeScript language hints — reference implementation.\n * Extracted from the hardcoded logic previously in differ.ts and overlay.ts.\n */\nexport const nodeHints: LanguageHints = {\n stripNullable(type: string): string | null {\n const members = parseUnionMembers(type);\n const stripped = members.filter((p) => p !== 'null');\n if (stripped.length === members.length) {\n return null; // no null member found\n }\n return stripped.join(' | ');\n },\n\n isNullableOnlyDifference(a: string, b: string): boolean {\n return (nodeHints.stripNullable(a) ?? a) === (nodeHints.stripNullable(b) ?? b) && a !== b;\n },\n\n isUnionReorder(a: string, b: string): boolean {\n const membersA = parseUnionMembers(a).sort();\n const membersB = parseUnionMembers(b).sort();\n if (membersA.length !== membersB.length || membersA.length < 2) return false;\n return membersA.every((m, i) => m === membersB[i]);\n },\n\n isGenericTypeParam(type: string): boolean {\n if (/^[A-Z]$/.test(type)) return true;\n if (/^T[A-Z][a-zA-Z]*$/.test(type)) return true;\n if (/^[A-Z]\\[\\]$/.test(type) || /^T[A-Z][a-zA-Z]*\\[\\]$/.test(type)) return true;\n return false;\n },\n\n isExtractionArtifact(type: string): boolean {\n return type === 'any' || type === 'Record<string, unknown>';\n },\n\n tolerateCategoryMismatch: true,\n\n extractReturnTypeName(returnType: string): string | null {\n let inner = returnType;\n while (inner.startsWith('Promise<') && inner.endsWith('>')) {\n inner = inner.slice(8, -1);\n }\n const genericMatch = inner.match(/^[A-Za-z]+<(.+)>$/);\n if (genericMatch) {\n inner = genericMatch[1];\n }\n inner = inner.replace(/\\[\\]$/, '');\n if (['void', 'string', 'number', 'boolean', 'any', 'unknown', 'null', 'undefined'].includes(inner)) {\n return null;\n }\n return inner;\n },\n\n extractParamTypeName(paramType: string): string | null {\n if (['string', 'number', 'boolean', 'any', 'unknown'].includes(paramType)) {\n return null;\n }\n return paramType;\n },\n\n propertyMatchesClass(propertyName: string, className: string): boolean {\n // Support both camelCase and snake_case properties matching PascalCase classes\n // e.g., \"organizations\" ≡ \"Organizations\", \"api_keys\" ≡ \"ApiKeys\"\n const normalizedProp = propertyName.replace(/[-_]/g, '').toLowerCase();\n return normalizedProp === className.toLowerCase();\n },\n\n derivedModelNames(modelName: string): string[] {\n return [`${modelName}Response`, `Serialized${modelName}`];\n },\n\n isTypeEquivalent(baselineType: string, candidateType: string, candidateSurface: ApiSurface): boolean {\n // Check if one side is a named enum and the other is an inline union\n // of that enum's string literal values.\n // e.g., baseline: '\"active\" | \"inactive\"', candidate: 'ConnectionState'\n // or baseline: 'ConnectionState', candidate: '\"active\" | \"inactive\"'\n\n // Try: candidate is enum name, baseline is inline union of string literals.\n // The generated enum may have MORE members than the baseline (new spec values),\n // so check that all baseline members exist in the enum (subset match).\n const candEnum = candidateSurface.enums[candidateType];\n if (candEnum) {\n const enumValuesSet = new Set(Object.values(candEnum.members).flatMap((v) => [`\"${v}\"`, `'${v}'`]));\n const baseMembers = parseUnionMembers(baselineType);\n if (baseMembers.length > 0 && baseMembers.every((m) => enumValuesSet.has(m))) {\n return true;\n }\n }\n\n // Tolerate untyped-map equivalences:\n // { [key: string]: any; } ≡ Record<string, unknown> ≡ Record<string, any>\n if (UNTYPED_MAP_PATTERNS.has(baselineType) && UNTYPED_MAP_PATTERNS.has(candidateType)) {\n return true;\n }\n\n // Tolerate inline object literal vs named model in candidate.\n // e.g., baseline: '{ type: \"organization\"; id: string; }', candidate: 'ApiKeyOwner'\n // The named model is more structured but semantically equivalent.\n if (baselineType.startsWith('{') && baselineType.endsWith('}')) {\n if (typeExistsInSurface(candidateType, candidateSurface)) {\n return true;\n }\n }\n\n // Tolerate named-type-to-named-type mismatches when both types exist\n // as models/interfaces/enums in their respective surfaces. This handles\n // cases where the parser qualifies inline types with parent names while\n // the live SDK uses shared types:\n // baseline: RoleResponse, candidate: OrganizationMembershipRole\n // baseline: ConnectionType, candidate: ProfileConnectionType\n // baseline: AuditLogTargetSchema[], candidate: AuditLogSchemaJsonTarget[]\n const baseClean = baselineType.replace(/\\[\\]$/, '');\n const candClean = candidateType.replace(/\\[\\]$/, '');\n const sameArrayness = baselineType.endsWith('[]') === candidateType.endsWith('[]');\n\n // Response suffix equivalence (both directions)\n if (sameArrayness) {\n if (candClean === baseClean + 'Response' || baseClean === candClean + 'Response') {\n return true;\n }\n }\n\n // Both are named types (PascalCase, no operators) — check if candidate\n // is a known model/interface/enum, and baseline looks like a named type too.\n // This tolerates the parser's qualified naming vs the live SDK's shared naming.\n if (sameArrayness && NAMED_TYPE_RE.test(baseClean) && NAMED_TYPE_RE.test(candClean)) {\n if (typeExistsInSurface(candClean, candidateSurface)) {\n // One name contains the other (e.g., ProfileConnectionType contains ConnectionType)\n if (candClean.includes(baseClean) || baseClean.includes(candClean)) {\n return true;\n }\n // Strip Response suffix and check containment\n const baseNoResp = baseClean.replace(/Response$/, '');\n const candNoResp = candClean.replace(/Response$/, '');\n if (candNoResp.includes(baseNoResp) || baseNoResp.includes(candNoResp)) {\n return true;\n }\n // Word-component overlap: split PascalCase into words and check\n // if they share enough meaningful words (handles name reordering\n // from Json merges: AuditLogTargetSchema vs AuditLogSchemaJsonTarget)\n if (namedTypeWordsOverlap(baseClean, candClean, 2)) {\n return true;\n }\n }\n }\n\n return false;\n },\n};\n\n/**\n * Merge partial language hint overrides over nodeHints defaults.\n * Any hint not provided falls back to the Node/TypeScript implementation.\n */\nexport function resolveHints(overrides: Partial<LanguageHints>): LanguageHints {\n return { ...nodeHints, ...overrides };\n}\n","import type { ApiSpec, TypeRef } from '../ir/types.js';\nimport { walkTypeRef } from '../ir/types.js';\nimport type { ApiSurface, LanguageHints } from './types.js';\n\n/**\n * Compute the set of symbol names that are derivable from the OpenAPI spec.\n * Only these names should be compared during compat verification — everything\n * else in the baseline is hand-written and out of scope for generation.\n */\nexport function specDerivedNames(spec: ApiSpec, hints: LanguageHints): Set<string> {\n const names = new Set<string>();\n\n // Build set of top-level enum names for filtering inline enums\n const topLevelEnumNames = new Set(spec.enums.map((e) => e.name));\n\n // Service classes\n for (const service of spec.services) {\n names.add(service.name);\n for (const op of service.operations) {\n // Operation methods are matched by the class diff, not by name here\n collectTypeRefNames(op.response, names, hints, topLevelEnumNames);\n if (op.requestBody) collectTypeRefNames(op.requestBody, names, hints, topLevelEnumNames);\n for (const p of [...op.pathParams, ...op.queryParams, ...op.headerParams, ...(op.cookieParams ?? [])]) {\n collectTypeRefNames(p.type, names, hints, topLevelEnumNames);\n }\n }\n }\n\n // Models → domain interface + language-specific derived names\n for (const model of spec.models) {\n names.add(model.name);\n for (const derived of hints.derivedModelNames(model.name)) {\n names.add(derived);\n }\n for (const field of model.fields) {\n collectTypeRefNames(field.type, names, hints, topLevelEnumNames);\n }\n }\n\n // Enums → type aliases\n for (const e of spec.enums) {\n names.add(e.name);\n }\n\n return names;\n}\n\n/**\n * Compute a map of enum name → set of wire values that appear in the spec.\n * Used by filterSurface to exclude hand-added enum members that aren't in the spec.\n */\nexport function specDerivedEnumValues(spec: ApiSpec): Map<string, Set<string | number>> {\n const result = new Map<string, Set<string | number>>();\n for (const e of spec.enums) {\n result.set(e.name, new Set(e.values.map((v) => v.value)));\n }\n return result;\n}\n\n/**\n * Compute the set of field paths (e.g., \"Organization.name\") that are defined\n * in the OpenAPI spec's model schemas. Used by filterSurface to exclude\n * hand-added SDK fields that reference spec-derived types.\n */\nexport function specDerivedFieldPaths(spec: ApiSpec, hints: LanguageHints): Set<string> {\n const paths = new Set<string>();\n for (const model of spec.models) {\n for (const field of model.fields) {\n paths.add(`${model.name}.${field.name}`);\n }\n // Also add field paths for derived model names (e.g., OrganizationResponse.name)\n for (const derived of hints.derivedModelNames(model.name)) {\n for (const field of model.fields) {\n paths.add(`${derived}.${field.name}`);\n }\n }\n }\n return paths;\n}\n\n/**\n * Compute the set of method paths (e.g., \"SSO.authorize\") that are defined\n * as operations in the OpenAPI spec's services. Used by filterSurface to\n * exclude hand-written SDK methods that don't correspond to spec operations.\n */\nexport function specDerivedMethodPaths(spec: ApiSpec): Set<string> {\n const paths = new Set<string>();\n for (const service of spec.services) {\n for (const op of service.operations) {\n paths.add(`${service.name}.${op.name}`);\n }\n }\n return paths;\n}\n\n/**\n * Compute the set of HTTP operation keys (e.g., \"GET /sso/authorize\") that\n * exist in the spec. Used for overlay-based method matching.\n */\nexport function specDerivedHttpKeys(spec: ApiSpec): Set<string> {\n const keys = new Set<string>();\n for (const service of spec.services) {\n for (const op of service.operations) {\n keys.add(`${op.httpMethod.toUpperCase()} ${op.path}`);\n }\n }\n return keys;\n}\n\nfunction collectTypeRefNames(ref: TypeRef, out: Set<string>, hints: LanguageHints, topLevelEnums?: Set<string>): void {\n walkTypeRef(ref, {\n model: (r) => {\n out.add(r.name);\n for (const derived of hints.derivedModelNames(r.name)) {\n out.add(derived);\n }\n },\n enum: (r) => {\n // Only include enums that are top-level (in spec.enums). Inline enums\n // embedded in TypeRefs (e.g., query parameter enums) may not be emitted\n // by all emitters, so they should not create false-positive violations.\n if (!topLevelEnums || topLevelEnums.has(r.name)) {\n out.add(r.name);\n }\n },\n });\n}\n\nfunction filterRecord<T>(record: Record<string, T>, allowed: Set<string>): Record<string, T> {\n const result: Record<string, T> = {};\n for (const [name, value] of Object.entries(record)) {\n if (allowed.has(name)) result[name] = value;\n }\n return result;\n}\n\n/**\n * Filter an ApiSurface to only include symbols whose names appear in the\n * allowed set. Symbols not in the set are dropped entirely — they won't\n * count toward the total or produce violations.\n *\n * For interfaces: when fieldPaths is provided, only keeps fields that appear\n * in the spec-derived field paths. This prevents false positives from hand-added\n * SDK fields that reference spec-derived types but aren't defined in the spec.\n *\n * For classes: when methodPaths is provided, only keeps methods whose names\n * appear in the spec-derived method paths. This prevents false positives from\n * hand-written SDK methods (e.g., SSO.authorization_url, Webhooks.construct_event)\n * that don't correspond to spec operations. Properties on service classes are\n * also filtered: only UPPER_CASE constants that are spec-derivable are kept.\n */\nexport function filterSurface(\n surface: ApiSurface,\n allowedNames: Set<string>,\n opts?: {\n fieldPaths?: Set<string>;\n methodPaths?: Set<string>;\n enumValues?: Map<string, Set<string | number>>;\n },\n): ApiSurface {\n const { fieldPaths, methodPaths, enumValues } = opts ?? {};\n const filteredInterfaces = filterRecord(surface.interfaces, allowedNames);\n\n // Filter interface fields by spec-derived field paths if provided\n if (fieldPaths) {\n for (const [name, iface] of Object.entries(filteredInterfaces)) {\n const filteredFields: Record<string, (typeof iface.fields)[string]> = {};\n for (const [fieldName, field] of Object.entries(iface.fields)) {\n // Keep the field if its path is spec-derived\n if (fieldPaths.has(`${name}.${fieldName}`)) {\n filteredFields[fieldName] = field;\n }\n }\n filteredInterfaces[name] = { ...iface, fields: filteredFields };\n }\n }\n\n let filteredClasses = filterRecord(surface.classes, allowedNames);\n\n // Filter class methods and properties by spec-derived method paths if provided\n if (methodPaths) {\n // Build a set of service-class names that have spec-derived methods.\n // Only filter methods on these classes; non-service model classes keep all members.\n const serviceClassNames = new Set<string>();\n for (const path of methodPaths) {\n const dot = path.indexOf('.');\n if (dot !== -1) serviceClassNames.add(path.slice(0, dot));\n }\n\n const newClasses: Record<string, (typeof filteredClasses)[string]> = {};\n for (const [name, cls] of Object.entries(filteredClasses)) {\n if (serviceClassNames.has(name)) {\n // Service class — filter methods and properties by spec-derived method paths\n const filteredMethods: typeof cls.methods = {};\n for (const [methodName, overloads] of Object.entries(cls.methods)) {\n if (methodPaths.has(`${name}.${methodName}`)) {\n filteredMethods[methodName] = overloads;\n }\n }\n\n // Filter properties: only keep properties that are spec-derivable.\n // Hand-written constants (PROVIDERS, DEFAULT_TOLERANCE, WIDGET_SCOPES)\n // are not derivable from the spec and should be excluded.\n const filteredProperties: typeof cls.properties = {};\n for (const [propName, prop] of Object.entries(cls.properties)) {\n if (methodPaths.has(`${name}.${propName}`)) {\n filteredProperties[propName] = prop;\n }\n }\n\n newClasses[name] = {\n ...cls,\n methods: filteredMethods,\n properties: filteredProperties,\n };\n } else if (fieldPaths) {\n // Non-service (model) class — filter properties by spec-derived field paths.\n // In some languages (Ruby, PHP), models are represented as classes with\n // properties rather than interfaces with fields. Apply the same field-level\n // filtering used for interfaces to exclude hand-added SDK fields.\n const filteredProperties: typeof cls.properties = {};\n for (const [propName, prop] of Object.entries(cls.properties)) {\n if (fieldPaths.has(`${name}.${propName}`)) {\n filteredProperties[propName] = prop;\n }\n }\n\n // Also filter methods on model classes: convenience methods like\n // `primary_email` are hand-written and not spec-derivable.\n // Keep utility methods (from_json, to_json, etc.) if they appear in fieldPaths,\n // otherwise drop non-spec methods.\n const filteredMethods: typeof cls.methods = {};\n for (const [methodName, overloads] of Object.entries(cls.methods)) {\n if (fieldPaths.has(`${name}.${methodName}`) || methodPaths.has(`${name}.${methodName}`)) {\n filteredMethods[methodName] = overloads;\n }\n }\n\n newClasses[name] = {\n ...cls,\n methods: filteredMethods,\n properties: filteredProperties,\n };\n } else {\n // No filtering available — keep as-is\n newClasses[name] = cls;\n }\n }\n filteredClasses = newClasses;\n }\n\n // Filter enum members by spec-derived values if provided\n let filteredEnums = filterRecord(surface.enums, allowedNames);\n if (enumValues) {\n const newEnums: Record<string, (typeof filteredEnums)[string]> = {};\n for (const [name, enumDef] of Object.entries(filteredEnums)) {\n const specValues = enumValues.get(name);\n if (!specValues) {\n // Enum not in spec values map — keep as-is\n newEnums[name] = enumDef;\n continue;\n }\n // Filter members: keep only those whose wire value is in the spec.\n // Use case-insensitive comparison since some extractors produce\n // PascalCase values (e.g., \"Pending\") while the spec has lowercase.\n const specValuesLower = new Set([...specValues].map((v) => String(v).toLowerCase()));\n const filteredMembers: typeof enumDef.members = {};\n for (const [member, value] of Object.entries(enumDef.members)) {\n if (specValues.has(value) || specValuesLower.has(String(value).toLowerCase())) {\n filteredMembers[member] = value;\n }\n }\n newEnums[name] = { ...enumDef, members: filteredMembers };\n }\n filteredEnums = newEnums;\n }\n\n return {\n ...surface,\n classes: filteredClasses,\n interfaces: filteredInterfaces,\n typeAliases: filterRecord(surface.typeAliases, allowedNames),\n enums: filteredEnums,\n exports: {}, // exports are structural, not symbol-level — skip for scoped comparison\n };\n}\n","/**\n * Compatibility diff engine.\n *\n * Compares two API surfaces (or compat snapshots) and produces classified\n * changes with policy-aware severity, provenance, and conceptual change IDs.\n *\n * This replaces the previous unclassified diff engine with a richer model\n * that supports cross-language severity analysis and approval matching.\n */\n\nimport type { ApiSurface, ApiMethod, LanguageHints, DiffResult, Violation, Addition } from './types.js';\nimport type { CompatSnapshot, CompatSymbol } from './ir.js';\nimport type { CompatPolicyHints } from './policy.js';\nimport type { ClassifiedChange, ClassificationResult } from './classify.js';\nimport { classifySymbolChanges, classifyAddedSymbol, summarizeChanges } from './classify.js';\nimport { NAMED_TYPE_RE, typeExistsInSurface } from './language-hints.js';\n\nexport {\n specDerivedNames,\n specDerivedFieldPaths,\n specDerivedMethodPaths,\n specDerivedHttpKeys,\n specDerivedEnumValues,\n filterSurface,\n} from './spec-filter.js';\n\n// ---------------------------------------------------------------------------\n// New: CompatSnapshot-based diff\n// ---------------------------------------------------------------------------\n\n/** Result of diffing two compat snapshots. */\nexport interface CompatDiffResult {\n changes: ClassifiedChange[];\n summary: ClassificationResult['summary'];\n}\n\n/**\n * Diff two compat snapshots, producing classified changes with\n * policy-aware severity.\n */\nexport function diffSnapshots(\n baseline: CompatSnapshot,\n candidate: CompatSnapshot,\n policy?: CompatPolicyHints,\n): CompatDiffResult {\n const effectivePolicy = policy ?? baseline.policies;\n const changes: ClassifiedChange[] = [];\n\n // Build set of service wrapper fqNames from both snapshots so we can\n // suppress constructor noise — users never instantiate service classes\n // directly, so their constructor changes are not public-API breaking.\n const serviceAccessors = new Set<string>();\n for (const sym of baseline.symbols) {\n if (sym.kind === 'service_accessor') serviceAccessors.add(sym.fqName);\n }\n for (const sym of candidate.symbols) {\n if (sym.kind === 'service_accessor') serviceAccessors.add(sym.fqName);\n }\n\n // Index candidate symbols by ID and fqName for lookup\n const candById = new Map<string, CompatSymbol>();\n const candByFqName = new Map<string, CompatSymbol>();\n for (const sym of candidate.symbols) {\n candById.set(sym.id, sym);\n candByFqName.set(sym.fqName, sym);\n }\n\n // Index baseline symbols by fqName\n const baseByFqName = new Set<string>();\n for (const sym of baseline.symbols) {\n baseByFqName.add(sym.fqName);\n }\n\n // Compare each baseline symbol against candidate\n for (const baseSym of baseline.symbols) {\n if (isServiceWrapperConstructor(baseSym, serviceAccessors)) continue;\n const candSym = candById.get(baseSym.id) ?? candByFqName.get(baseSym.fqName);\n changes.push(...classifySymbolChanges(baseSym, candSym, effectivePolicy));\n }\n\n // Detect added symbols\n for (const candSym of candidate.symbols) {\n if (!baseByFqName.has(candSym.fqName)) {\n if (isServiceWrapperConstructor(candSym, serviceAccessors)) continue;\n changes.push(classifyAddedSymbol(candSym));\n }\n }\n\n return {\n changes,\n summary: summarizeChanges(changes),\n };\n}\n\n/**\n * Check if a symbol is a constructor belonging to a service wrapper class.\n *\n * Service wrapper constructors are internal plumbing (taking a client/config\n * object) — users interact with services via `client.admin_portal`, not\n * `new AdminPortal(...)`. Changes to these constructors should not be\n * reported as breaking.\n *\n * Catches two patterns:\n * - Ruby: kind === 'constructor', ownerFqName is a service_accessor\n * - PHP: kind === 'callable' with fqName ending in '.__construct'\n */\nfunction isServiceWrapperConstructor(sym: CompatSymbol, serviceAccessors: Set<string>): boolean {\n if (!sym.ownerFqName || !serviceAccessors.has(sym.ownerFqName)) return false;\n if (sym.kind === 'constructor') return true;\n if (sym.kind === 'callable' && sym.fqName.endsWith('.__construct')) return true;\n return false;\n}\n\n// ---------------------------------------------------------------------------\n// Legacy: ApiSurface-based diff (delegates to existing logic)\n// ---------------------------------------------------------------------------\n\n/**\n * Compare two ApiSurface objects and return a DiffResult.\n *\n * This preserves the existing diffing behavior used by the overlay retry loop,\n * compat check, and all existing tests. The internal implementation uses the\n * same algorithms as before to maintain full backward compatibility with\n * overlay patching and verification workflows.\n */\nexport function diffSurfaces(baseline: ApiSurface, candidate: ApiSurface, hints: LanguageHints): DiffResult {\n const violations: Violation[] = [];\n const additions: Addition[] = [];\n let totalBaseline = 0;\n let preserved = 0;\n\n // Diff classes\n for (const [name, baseClass] of Object.entries(baseline.classes)) {\n totalBaseline++;\n const candClass = candidate.classes[name];\n if (!candClass) {\n violations.push({\n category: 'public-api',\n severity: 'breaking',\n symbolPath: name,\n baseline: name,\n candidate: '(missing)',\n message: `Class \"${name}\" exists in baseline but not in generated output`,\n });\n totalBaseline += Object.values(baseClass.methods).reduce((sum, overloads) => sum + overloads.length, 0);\n totalBaseline += Object.keys(baseClass.properties).length;\n continue;\n }\n preserved++;\n\n // Diff methods (each method name maps to an array of overloads)\n for (const [methodName, baseOverloads] of Object.entries(baseClass.methods)) {\n const candOverloads = candClass.methods[methodName];\n for (const baseMethod of baseOverloads) {\n totalBaseline++;\n if (!candOverloads || candOverloads.length === 0) {\n violations.push({\n category: 'public-api',\n severity: 'breaking',\n symbolPath: `${name}.${methodName}`,\n baseline: methodName,\n candidate: '(missing)',\n message: `Method \"${name}.${methodName}\" exists in baseline but not in generated output`,\n });\n continue;\n }\n const candMethod = candOverloads.find((c) => signaturesMatch(baseMethod, c));\n if (!candMethod) {\n // Fallback: check language-specific signature equivalence\n const equivalentMethod = hints.isSignatureEquivalent\n ? candOverloads.find((c) => hints.isSignatureEquivalent!(baseMethod, c, candidate))\n : undefined;\n if (equivalentMethod) {\n preserved++;\n continue;\n }\n violations.push({\n category: 'signature',\n severity: 'breaking',\n symbolPath: `${name}.${methodName}`,\n baseline: formatSignature(baseMethod),\n candidate: formatSignature(candOverloads[0]),\n message: `Signature mismatch for \"${name}.${methodName}\"`,\n });\n continue;\n }\n preserved++;\n }\n }\n\n // Check for new methods (additions)\n for (const methodName of Object.keys(candClass.methods)) {\n if (!baseClass.methods[methodName]) {\n additions.push({ symbolPath: `${name}.${methodName}`, symbolType: 'method' });\n }\n }\n\n // Diff properties\n for (const [propName, baseProp] of Object.entries(baseClass.properties)) {\n totalBaseline++;\n const candProp = candClass.properties[propName];\n if (!candProp) {\n violations.push({\n category: 'public-api',\n severity: 'breaking',\n symbolPath: `${name}.${propName}`,\n baseline: baseProp.type,\n candidate: '(missing)',\n message: `Property \"${name}.${propName}\" exists in baseline but not in generated output`,\n });\n continue;\n }\n if (baseProp.type !== candProp.type) {\n const nullableOnly = hints.isNullableOnlyDifference(baseProp.type, candProp.type);\n violations.push({\n category: 'signature',\n severity: nullableOnly ? 'warning' : 'breaking',\n symbolPath: `${name}.${propName}`,\n baseline: baseProp.type,\n candidate: candProp.type,\n message: `Property type mismatch for \"${name}.${propName}\"`,\n });\n if (nullableOnly) preserved++;\n continue;\n }\n preserved++;\n }\n\n // Check for new properties (additions)\n for (const propName of Object.keys(candClass.properties)) {\n if (!baseClass.properties[propName]) {\n additions.push({ symbolPath: `${name}.${propName}`, symbolType: 'property' });\n }\n }\n }\n\n // Check for new classes (additions)\n for (const name of Object.keys(candidate.classes)) {\n if (!baseline.classes[name]) {\n additions.push({ symbolPath: name, symbolType: 'class' });\n }\n }\n\n // Precompute lowercased field/property name sets for field-structure matching\n const candIfaceFieldSets = new Map<string, Set<string>>();\n for (const [n, iface] of Object.entries(candidate.interfaces)) {\n candIfaceFieldSets.set(n, new Set(Object.keys(iface.fields).map((f) => f.toLowerCase())));\n }\n const candClassPropSets = new Map<string, Set<string>>();\n for (const [n, cls] of Object.entries(candidate.classes)) {\n candClassPropSets.set(n, new Set(Object.keys(cls.properties).map((f) => f.toLowerCase())));\n }\n\n // Diff interfaces\n for (const [name, baseIface] of Object.entries(baseline.interfaces)) {\n totalBaseline++;\n const candIface = candidate.interfaces[name];\n if (!candIface) {\n let tolerated = false;\n if (hints.tolerateCategoryMismatch && name.startsWith('Serialized')) {\n const baseName = name.slice('Serialized'.length);\n if (candidate.interfaces[baseName] || candidate.classes[baseName]) {\n tolerated = true;\n }\n }\n if (tolerated) {\n preserved++;\n totalBaseline += Object.keys(baseIface.fields).length;\n preserved += Object.keys(baseIface.fields).length;\n continue;\n }\n if (!tolerated) {\n const baseFieldNamesLower = new Set(Object.keys(baseIface.fields).map((f) => f.toLowerCase()));\n if (baseFieldNamesLower.size > 0) {\n for (const [, candFieldNamesLower] of candIfaceFieldSets) {\n if (\n candFieldNamesLower.size === baseFieldNamesLower.size &&\n [...baseFieldNamesLower].every((f) => candFieldNamesLower.has(f))\n ) {\n tolerated = true;\n break;\n }\n }\n if (!tolerated) {\n for (const [, candPropNamesLower] of candClassPropSets) {\n if (\n candPropNamesLower.size === baseFieldNamesLower.size &&\n [...baseFieldNamesLower].every((f) => candPropNamesLower.has(f))\n ) {\n tolerated = true;\n break;\n }\n }\n }\n } else {\n tolerated = true;\n }\n }\n if (tolerated) {\n preserved++;\n totalBaseline += Object.keys(baseIface.fields).length;\n preserved += Object.keys(baseIface.fields).length;\n continue;\n }\n violations.push({\n category: 'public-api',\n severity: 'breaking',\n symbolPath: name,\n baseline: name,\n candidate: '(missing)',\n message: `Interface \"${name}\" exists in baseline but not in generated output`,\n });\n totalBaseline += Object.keys(baseIface.fields).length;\n continue;\n }\n preserved++;\n\n for (const [fieldName, baseField] of Object.entries(baseIface.fields)) {\n totalBaseline++;\n const candField = candIface.fields[fieldName];\n if (!candField) {\n const baseTypeClean = baseField.type.replace(/\\[\\]$/, '').replace(/ \\| null$/, '');\n const typeIsUnresolvable = NAMED_TYPE_RE.test(baseTypeClean) && !typeExistsInSurface(baseTypeClean, candidate);\n violations.push({\n category: 'public-api',\n severity: typeIsUnresolvable ? 'warning' : 'breaking',\n symbolPath: `${name}.${fieldName}`,\n baseline: baseField.type,\n candidate: '(missing)',\n message: `Field \"${name}.${fieldName}\" exists in baseline but not in generated output`,\n });\n if (typeIsUnresolvable) preserved++;\n continue;\n }\n if (baseField.type !== candField.type) {\n if (hints.isUnionReorder(baseField.type, candField.type)) {\n preserved++;\n continue;\n }\n if (hints.isTypeEquivalent?.(baseField.type, candField.type, candidate)) {\n preserved++;\n continue;\n }\n const nullableOnly = hints.isNullableOnlyDifference(baseField.type, candField.type);\n const genericParam = hints.isGenericTypeParam(baseField.type);\n const extractionArtifact = hints.isExtractionArtifact(candField.type);\n const isWarning = nullableOnly || genericParam || extractionArtifact;\n violations.push({\n category: 'signature',\n severity: isWarning ? 'warning' : 'breaking',\n symbolPath: `${name}.${fieldName}`,\n baseline: baseField.type,\n candidate: candField.type,\n message: `Field type mismatch for \"${name}.${fieldName}\"`,\n });\n if (isWarning) preserved++;\n continue;\n }\n preserved++;\n }\n\n for (const fieldName of Object.keys(candIface.fields)) {\n if (!baseIface.fields[fieldName]) {\n additions.push({ symbolPath: `${name}.${fieldName}`, symbolType: 'property' });\n }\n }\n }\n\n // Check for new interfaces (additions)\n for (const name of Object.keys(candidate.interfaces)) {\n if (!baseline.interfaces[name]) {\n additions.push({ symbolPath: name, symbolType: 'interface' });\n }\n }\n\n // Diff type aliases\n for (const [name, baseAlias] of Object.entries(baseline.typeAliases)) {\n totalBaseline++;\n const candAlias = candidate.typeAliases[name];\n if (!candAlias) {\n if (hints.tolerateCategoryMismatch && typeExistsInSurface(name, candidate)) {\n preserved++;\n continue;\n }\n violations.push({\n category: 'public-api',\n severity: 'breaking',\n symbolPath: name,\n baseline: baseAlias.value,\n candidate: '(missing)',\n message: `Type alias \"${name}\" exists in baseline but not in generated output`,\n });\n continue;\n }\n if (baseAlias.value !== candAlias.value) {\n if (hints.isUnionReorder(baseAlias.value, candAlias.value)) {\n preserved++;\n continue;\n }\n const nullableOnly = hints.isNullableOnlyDifference(baseAlias.value, candAlias.value);\n violations.push({\n category: 'signature',\n severity: nullableOnly ? 'warning' : 'breaking',\n symbolPath: name,\n baseline: baseAlias.value,\n candidate: candAlias.value,\n message: `Type alias value mismatch for \"${name}\"`,\n });\n if (nullableOnly) preserved++;\n continue;\n }\n preserved++;\n }\n\n // Check for new type aliases (additions)\n for (const name of Object.keys(candidate.typeAliases)) {\n if (!baseline.typeAliases[name]) {\n additions.push({ symbolPath: name, symbolType: 'type-alias' });\n }\n }\n\n // Diff enums\n for (const [name, baseEnum] of Object.entries(baseline.enums)) {\n totalBaseline++;\n const candEnum = candidate.enums[name];\n if (!candEnum) {\n violations.push({\n category: 'public-api',\n severity: 'breaking',\n symbolPath: name,\n baseline: name,\n candidate: '(missing)',\n message: `Enum \"${name}\" exists in baseline but not in generated output`,\n });\n continue;\n }\n\n const candValueToMembers = new Map<string | number, string[]>();\n for (const [candMember, candValue] of Object.entries(candEnum.members)) {\n const existing = candValueToMembers.get(candValue);\n if (existing) {\n existing.push(candMember);\n } else {\n candValueToMembers.set(candValue, [candMember]);\n }\n }\n\n let enumMatch = true;\n for (const [member, value] of Object.entries(baseEnum.members)) {\n if (candEnum.members[member] === value) {\n continue;\n }\n\n const valueMatches = candValueToMembers.get(value);\n if (valueMatches && valueMatches.length > 0) {\n violations.push({\n category: 'signature',\n severity: 'warning',\n symbolPath: `${name}.${member}`,\n baseline: `${member}=${String(value)}`,\n candidate: `${valueMatches[0]}=${String(value)}`,\n message: `Enum member name differs for \"${name}.${member}\" (value \"${value}\" preserved as \"${valueMatches[0]}\")`,\n });\n continue;\n }\n\n const lowerValue = String(value).toLowerCase();\n const caseInsensitiveMatch = [...candValueToMembers.entries()].find(\n ([candVal]) => String(candVal).toLowerCase() === lowerValue,\n );\n if (caseInsensitiveMatch) {\n violations.push({\n category: 'signature',\n severity: 'warning',\n symbolPath: `${name}.${member}`,\n baseline: `${member}=${String(value)}`,\n candidate: `${caseInsensitiveMatch[1][0]}=${String(caseInsensitiveMatch[0])}`,\n message: `Enum member value case differs for \"${name}.${member}\" (baseline \"${value}\" vs candidate \"${caseInsensitiveMatch[0]}\")`,\n });\n continue;\n }\n\n const isExtractionArtifact =\n String(value) === member || member === 'JsonEnumDefaultValue' || member === 'JsonProperty';\n if (isExtractionArtifact) {\n violations.push({\n category: 'signature',\n severity: 'warning',\n symbolPath: `${name}.${member}`,\n baseline: String(value),\n candidate: '(extraction artifact)',\n message: `Enum member \"${name}.${member}\" appears to be an extraction artifact`,\n });\n continue;\n }\n\n violations.push({\n category: 'signature',\n severity: 'breaking',\n symbolPath: `${name}.${member}`,\n baseline: String(value),\n candidate: member in candEnum.members ? String(candEnum.members[member]) : '(missing)',\n message: `Enum member mismatch for \"${name}.${member}\"`,\n });\n enumMatch = false;\n }\n if (enumMatch) {\n preserved++;\n }\n }\n\n // Check for new enums (additions)\n for (const name of Object.keys(candidate.enums)) {\n if (!baseline.enums[name]) {\n additions.push({ symbolPath: name, symbolType: 'enum' });\n }\n }\n\n // Diff barrel exports\n for (const [path, baseExports] of Object.entries(baseline.exports)) {\n const candExports = candidate.exports[path];\n if (!candExports) {\n for (const exp of baseExports) {\n violations.push({\n category: 'export-structure',\n severity: 'warning',\n symbolPath: `exports[${path}].${exp}`,\n baseline: exp,\n candidate: '(missing)',\n message: `Export \"${exp}\" from \"${path}\" not found in generated output`,\n });\n }\n continue;\n }\n const candSet = new Set(candExports);\n for (const exp of baseExports) {\n if (!candSet.has(exp)) {\n violations.push({\n category: 'export-structure',\n severity: 'warning',\n symbolPath: `exports[${path}].${exp}`,\n baseline: exp,\n candidate: '(missing)',\n message: `Export \"${exp}\" from \"${path}\" not found in generated output`,\n });\n }\n }\n }\n\n return {\n preservationScore: totalBaseline > 0 ? Math.round((preserved / totalBaseline) * 100) : 100,\n totalBaselineSymbols: totalBaseline,\n preservedSymbols: preserved,\n violations,\n additions,\n };\n}\n\n// ---------------------------------------------------------------------------\n// Internal helpers (legacy)\n// ---------------------------------------------------------------------------\n\nfunction signaturesMatch(baseline: ApiMethod, candidate: ApiMethod): boolean {\n if (baseline.returnType !== candidate.returnType) return false;\n for (let i = 0; i < baseline.params.length; i++) {\n const baseParam = baseline.params[i];\n const candParam = candidate.params[i];\n if (!candParam) return false;\n if (baseParam.type !== candParam.type) return false;\n if (baseParam.name !== candParam.name) return false;\n }\n for (let i = baseline.params.length; i < candidate.params.length; i++) {\n if (!candidate.params[i].optional) return false;\n }\n return true;\n}\n\nfunction formatSignature(method: ApiMethod): string {\n const params = method.params.map((p) => `${p.name}${p.optional ? '?' : ''}: ${p.type}`).join(', ');\n return `(${params}) => ${method.returnType}`;\n}\n","import { RegistryError } from '../errors.js';\nimport type { Extractor } from './types.js';\n\nconst extractors = new Map<string, Extractor>();\n\nexport function registerExtractor(extractor: Extractor): void {\n extractors.set(extractor.language, extractor);\n}\n\nexport function getExtractor(language: string): Extractor {\n const extractor = extractors.get(language);\n if (!extractor) {\n const available = [...extractors.keys()].join(', ') || '(none)';\n throw new RegistryError(\n `No extractor registered for language: ${language}. Available: ${available}`,\n `Register an extractor for \"${language}\" via registerExtractor() or add one in your oagen.config.ts plugin.`,\n );\n }\n return extractor;\n}\n","import type { ApiSurface, ApiInterface, ApiMethod, OverlayLookup, LanguageHints } from './types.js';\nimport type { ClassifiedChange } from './classify.js';\nimport type { ApiSpec, Model } from '../ir/types.js';\nimport { toSnakeCase, splitWords } from '../utils/naming.js';\nimport { nodeHints as defaultNodeHints } from './language-hints.js';\n\nexport type { MethodOverlay, OverlayLookup } from './types.js';\n\nexport interface ManifestEntry {\n operationId: string;\n sdkResourceProperty: string;\n sdkMethodName: string;\n httpMethod: string;\n path: string;\n pathParams: string[];\n bodyFields: string[];\n queryFields: string[];\n}\n\n/**\n * Find the class name that owns a given SDK resource property.\n * E.g. if the surface has a class \"Organizations\" with property \"organizations\",\n * and sdkResourceProperty is \"organizations\", return \"Organizations\".\n */\nfunction findClassForProperty(\n surface: ApiSurface,\n sdkResourceProperty: string,\n hints: LanguageHints,\n): string | undefined {\n for (const [className, cls] of Object.entries(surface.classes)) {\n // Check if the class itself maps to this property (language-specific match)\n if (hints.propertyMatchesClass(sdkResourceProperty, className)) {\n return className;\n }\n // Check properties — resolve to the property's type class, not the parent.\n // This prevents generic parent classes (e.g., WorkOS) from being returned\n // when the actual resource class (e.g., ApiKeys) should be used.\n for (const [propName, prop] of Object.entries(cls.properties)) {\n if (propName === sdkResourceProperty) {\n const propType = (prop as { type?: string }).type;\n if (propType && surface.classes[propType]) {\n return propType;\n }\n // Property type not in surface — skip rather than return the parent\n return undefined;\n }\n }\n }\n\n // Strategy 3: Word-suffix fallback\n // \"adminPortal\" → [\"admin\",\"portal\"]; class \"Portal\" → [\"portal\"]\n // [\"portal\"] is a suffix of [\"admin\",\"portal\"] → match\n const propWords = splitWords(sdkResourceProperty).map((w) => w.toLowerCase());\n if (propWords.length > 1) {\n for (const [className] of Object.entries(surface.classes)) {\n const classWords = splitWords(className).map((w) => w.toLowerCase());\n if (classWords.length > 0 && classWords.length < propWords.length) {\n const suffix = propWords.slice(propWords.length - classWords.length);\n if (classWords.every((w, i) => w === suffix[i])) {\n return className;\n }\n }\n }\n }\n\n return undefined;\n}\n\nexport function buildOverlayLookup(\n surface: ApiSurface,\n manifest?: ManifestEntry[],\n spec?: ApiSpec,\n hints?: LanguageHints,\n options?: { strictModelMatch?: boolean },\n): OverlayLookup {\n const resolvedHints = hints ?? defaultNodeHints;\n const lookup: OverlayLookup = {\n methodByOperation: new Map(),\n httpKeyByMethod: new Map(),\n interfaceByName: new Map(),\n typeAliasByName: new Map(),\n requiredExports: new Map(),\n modelNameByIR: new Map(),\n fileBySymbol: new Map(),\n };\n\n // If manifest available, map operationId → HTTP method + path → existing method\n if (manifest) {\n for (const entry of manifest) {\n const key = `${entry.httpMethod.toUpperCase()} ${entry.path}`;\n const className = findClassForProperty(surface, entry.sdkResourceProperty, resolvedHints);\n if (className) {\n let resolvedMethodName = entry.sdkMethodName;\n let methods = surface.classes[className]?.methods[resolvedMethodName];\n\n // Exact match failed — try prefix match on the resolved class.\n // Handles cases where the generated name is shorter than the existing name\n // (e.g., manifest says \"delete\" but existing SDK has \"deleteApiKey\").\n // Only accept when exactly one candidate matches — ambiguous matches are worse than no match.\n if (!methods) {\n const classMethods = surface.classes[className]?.methods ?? {};\n const prefix = resolvedMethodName.toLowerCase();\n const candidates: [string, ApiMethod[]][] = [];\n for (const [name, overloads] of Object.entries(classMethods)) {\n if (name.toLowerCase().startsWith(prefix) && name !== resolvedMethodName) {\n candidates.push([name, overloads]);\n }\n }\n if (candidates.length === 1) {\n methods = candidates[0][1];\n resolvedMethodName = candidates[0][0];\n } else if (candidates.length > 1) {\n // Disambiguate: prefer the candidate whose name is <prefix><pathSegment>\n // derived from the FIRST segment of the operation path. This avoids\n // mismatching when a class combines operations from multiple path groups\n // (e.g., /organizations and /organization_domains both in Organizations).\n const firstSegment =\n entry.path\n .split('/')\n .filter(Boolean)[0]\n ?.replace(/[{}_-]/g, '') ?? '';\n if (firstSegment) {\n const segLower = firstSegment.toLowerCase();\n // Try the path segment as-is and as singular\n const segSingular = segLower.endsWith('s') ? segLower.slice(0, -1) : segLower;\n const best = candidates.find(([name]) => {\n const lower = name.toLowerCase();\n return lower === prefix + segLower || lower === prefix + segSingular;\n });\n if (best) {\n methods = best[1];\n resolvedMethodName = best[0];\n }\n }\n\n // HTTP verb disambiguation: when path disambiguation fails, use the\n // HTTP method to prefer method names that match the verb semantics.\n // E.g., GET → list/get, POST → create, PUT → set/update, DELETE → delete/remove.\n if (!methods) {\n const verbMatch = disambiguateByHttpVerb(candidates, entry.httpMethod);\n if (verbMatch) {\n methods = verbMatch[1];\n resolvedMethodName = verbMatch[0];\n }\n }\n }\n }\n\n // Suffix match: the existing SDK may use a longer controller-prefixed\n // method name that ends with the transformed name.\n // (e.g., manifest says \"validate_api_key\" but existing SDK has\n // \"api_keys_controller_validate_api_key\").\n // Only accept when exactly one candidate matches — ambiguous matches are worse than no match.\n if (!methods) {\n const classMethods = surface.classes[className]?.methods ?? {};\n const suffix = resolvedMethodName.toLowerCase();\n const candidates: [string, ApiMethod[]][] = [];\n for (const [name, overloads] of Object.entries(classMethods)) {\n if (name.toLowerCase().endsWith(suffix) && name !== resolvedMethodName) {\n candidates.push([name, overloads]);\n }\n }\n if (candidates.length === 1) {\n methods = candidates[0][1];\n resolvedMethodName = candidates[0][0];\n }\n }\n\n // Word-part subsequence match: the surface method may have extra words\n // inserted into the manifest method name. For example:\n // \"disableFlag\" → \"disableFeatureFlag\" ([\"disable\",\"Flag\"] ⊂ [\"disable\",\"Feature\",\"Flag\"])\n // \"getByExternalId\" → \"getOrganizationByExternalId\"\n // Only accept when exactly one candidate matches, or use HTTP verb disambiguation.\n if (!methods) {\n const manifestWords = splitCamelCase(resolvedMethodName);\n if (manifestWords.length >= 2) {\n const classMethods = surface.classes[className]?.methods ?? {};\n const candidates: [string, ApiMethod[]][] = [];\n for (const [name, overloads] of Object.entries(classMethods)) {\n if (name === resolvedMethodName) continue;\n const surfaceWords = splitCamelCase(name);\n if (surfaceWords.length > manifestWords.length && isSubsequence(manifestWords, surfaceWords)) {\n candidates.push([name, overloads]);\n }\n }\n if (candidates.length === 1) {\n methods = candidates[0][1];\n resolvedMethodName = candidates[0][0];\n } else if (candidates.length > 1) {\n const verbMatch = disambiguateByHttpVerb(candidates, entry.httpMethod);\n if (verbMatch) {\n methods = verbMatch[1];\n resolvedMethodName = verbMatch[0];\n }\n }\n }\n }\n\n // Reverse prefix match: the manifest name may be LONGER than the surface\n // name (e.g., \"createResources\" → \"createResource\", \"removeRoleByCriteria\" → \"removeRole\").\n // Check if the manifest name starts with a surface name. Only accept unique matches.\n if (!methods) {\n const classMethods = surface.classes[className]?.methods ?? {};\n const manifestLower = resolvedMethodName.toLowerCase();\n const candidates: [string, ApiMethod[]][] = [];\n for (const [name, overloads] of Object.entries(classMethods)) {\n if (name === resolvedMethodName) continue;\n if (manifestLower.startsWith(name.toLowerCase()) && name.length >= 3) {\n candidates.push([name, overloads]);\n }\n }\n if (candidates.length === 1) {\n methods = candidates[0][1];\n resolvedMethodName = candidates[0][0];\n } else if (candidates.length > 1) {\n const verbMatch = disambiguateByHttpVerb(candidates, entry.httpMethod);\n if (verbMatch) {\n methods = verbMatch[1];\n resolvedMethodName = verbMatch[0];\n }\n }\n }\n\n const method = methods?.[0];\n if (method) {\n lookup.methodByOperation.set(key, {\n className,\n methodName: resolvedMethodName,\n params: method.params,\n returnType: method.returnType,\n });\n lookup.httpKeyByMethod.set(`${className}.${resolvedMethodName}`, key);\n }\n }\n }\n }\n\n // Map interface and type alias names\n for (const name of Object.keys(surface.interfaces)) {\n lookup.interfaceByName.set(name, name);\n }\n for (const name of Object.keys(surface.typeAliases)) {\n lookup.typeAliasByName.set(name, name);\n }\n\n // Map barrel exports\n for (const [path, symbols] of Object.entries(surface.exports)) {\n lookup.requiredExports.set(path, new Set(symbols));\n }\n\n // Populate fileBySymbol from enriched surface\n for (const record of [surface.classes, surface.interfaces, surface.typeAliases, surface.enums] as Record<\n string,\n { sourceFile?: string }\n >[]) {\n for (const [name, item] of Object.entries(record)) {\n if (item.sourceFile) lookup.fileBySymbol.set(name, item.sourceFile);\n }\n }\n\n // Auto-infer IR model name → SDK interface name mappings\n if (spec) {\n buildModelNameMap(surface, spec, lookup, resolvedHints, options);\n\n // Remap fileBySymbol so IR model names point to the SDK symbol's file\n for (const [irName, sdkName] of lookup.modelNameByIR) {\n const filePath = lookup.fileBySymbol.get(sdkName);\n if (filePath) {\n lookup.fileBySymbol.set(irName, filePath);\n }\n }\n }\n\n return lookup;\n}\n\n// ---------------------------------------------------------------------------\n// HTTP verb disambiguation\n// ---------------------------------------------------------------------------\n\n/** Map HTTP methods to preferred method name prefixes for disambiguation. */\nconst HTTP_VERB_PREFIXES: Record<string, string[]> = {\n GET: ['list', 'get', 'fetch', 'retrieve', 'find'],\n POST: ['create', 'add', 'insert', 'send'],\n PUT: ['set', 'update', 'replace', 'put'],\n PATCH: ['update', 'patch', 'modify'],\n DELETE: ['delete', 'remove', 'revoke'],\n};\n\n/**\n * Disambiguate multiple method candidates using HTTP verb semantics.\n * Returns the best match or undefined if no unique match is found.\n */\nfunction disambiguateByHttpVerb<T>(candidates: [string, T][], httpMethod: string): [string, T] | undefined {\n const prefixes = HTTP_VERB_PREFIXES[httpMethod.toUpperCase()];\n if (!prefixes) return undefined;\n\n const verbCandidates = candidates.filter(([name]) => {\n const lower = name.toLowerCase();\n return prefixes.some((p) => lower.startsWith(p));\n });\n\n if (verbCandidates.length === 1) return verbCandidates[0];\n return undefined;\n}\n\n// ---------------------------------------------------------------------------\n// Word-part matching helpers\n// ---------------------------------------------------------------------------\n\n/** Split a camelCase identifier into its word parts (e.g., \"getByExternalId\" → [\"get\",\"By\",\"External\",\"Id\"]). */\nfunction splitCamelCase(name: string): string[] {\n const parts: string[] = [];\n let start = 0;\n for (let i = 1; i < name.length; i++) {\n if (name[i] >= 'A' && name[i] <= 'Z') {\n parts.push(name.slice(start, i));\n start = i;\n }\n }\n parts.push(name.slice(start));\n return parts;\n}\n\n/** Check if `needle` words form a subsequence of `haystack` words (case-insensitive). */\nfunction isSubsequence(needle: string[], haystack: string[]): boolean {\n let ni = 0;\n for (let hi = 0; hi < haystack.length && ni < needle.length; hi++) {\n if (needle[ni].toLowerCase() === haystack[hi].toLowerCase()) ni++;\n }\n return ni === needle.length;\n}\n\n// ---------------------------------------------------------------------------\n// Automatic model name inference\n// ---------------------------------------------------------------------------\n\n/**\n * Normalize a field name to a canonical form for comparison.\n * Handles camelCase → snake_case so \"createdAt\" and \"created_at\" match.\n */\nfunction normalizeFieldName(name: string): string {\n return toSnakeCase(name);\n}\n\n/**\n * Compute the Jaccard similarity between two sets of normalized field names.\n * Returns score (0–1) and raw intersection count.\n */\nfunction jaccardSimilarity(a: Set<string>, b: Set<string>): { score: number; intersection: number } {\n if (a.size === 0 && b.size === 0) return { score: 0, intersection: 0 };\n let intersection = 0;\n for (const item of a) {\n if (b.has(item)) intersection++;\n }\n const union = a.size + b.size - intersection;\n return { score: union === 0 ? 0 : intersection / union, intersection };\n}\n\n/**\n * Build a set of normalized field names from an IR model.\n */\nfunction irModelFieldSignature(model: Model): Set<string> {\n return new Set(model.fields.map((f) => normalizeFieldName(f.name)));\n}\n\n/**\n * Build a set of normalized field names from an SDK interface.\n */\nfunction sdkInterfaceFieldSignature(iface: ApiInterface): Set<string> {\n return new Set(Object.keys(iface.fields).map(normalizeFieldName));\n}\n\n/**\n * Populate the modelNameByIR map using two strategies:\n *\n * 1. Operation-based matching (high confidence):\n * When a manifest maps an HTTP operation to an SDK method, extract the\n * method's return type and parameter types. Match them against the IR\n * operation's response model and request body model.\n *\n * 2. Field-structure matching (fallback):\n * For IR models not matched by operations, compare their field names\n * against all SDK interfaces using Jaccard similarity. A match requires\n * ≥60% field overlap with ≥3 fields in common.\n */\nfunction buildModelNameMap(\n surface: ApiSurface,\n spec: ApiSpec,\n lookup: OverlayLookup,\n hints: LanguageHints,\n options?: { strictModelMatch?: boolean },\n): void {\n const mapped = new Set<string>(); // IR model names already mapped\n const usedSdkNames = new Set<string>(); // SDK names already claimed\n\n // --- Strategy 1: Operation-based matching ---\n if (lookup.methodByOperation.size > 0) {\n for (const service of spec.services) {\n for (const op of service.operations) {\n const httpKey = `${op.httpMethod.toUpperCase()} ${op.path}`;\n const methodOverlay = lookup.methodByOperation.get(httpKey);\n if (!methodOverlay) continue;\n\n // Match response model → SDK return type\n if (op.response.kind === 'model' && !mapped.has(op.response.name)) {\n const sdkTypeName = hints.extractReturnTypeName(methodOverlay.returnType);\n if (sdkTypeName && surface.interfaces[sdkTypeName]) {\n lookup.modelNameByIR.set(op.response.name, sdkTypeName);\n mapped.add(op.response.name);\n usedSdkNames.add(sdkTypeName);\n }\n }\n\n // Match request body model → SDK param type\n if (op.requestBody?.kind === 'model' && !mapped.has(op.requestBody.name)) {\n for (const param of methodOverlay.params) {\n const sdkTypeName = hints.extractParamTypeName(param.type);\n if (sdkTypeName && surface.interfaces[sdkTypeName]) {\n lookup.modelNameByIR.set(op.requestBody.name, sdkTypeName);\n mapped.add(op.requestBody.name);\n usedSdkNames.add(sdkTypeName);\n break;\n }\n }\n }\n }\n }\n }\n\n // --- Strategy 2: Field-structure matching ---\n // Pre-compute SDK interface field signatures\n const sdkSignatures: { name: string; fields: Set<string>; fieldCount: number }[] = [];\n for (const [name, iface] of Object.entries(surface.interfaces)) {\n if (usedSdkNames.has(name)) continue;\n const fields = sdkInterfaceFieldSignature(iface);\n if (fields.size >= 2) {\n sdkSignatures.push({ name, fields, fieldCount: fields.size });\n }\n }\n\n const sdkSignatureNames = new Set(sdkSignatures.map((s) => s.name));\n\n for (const model of spec.models) {\n if (mapped.has(model.name)) continue;\n if (model.fields.length < 2) continue;\n\n // Strategy 2a: Prefer exact name match — if the IR model name matches an SDK\n // interface name exactly, use it without Jaccard scoring. This prevents\n // false positives when a superset interface (e.g., DirectoryUserWithGroups)\n // scores higher than the exact match (DirectoryUser).\n if (sdkSignatureNames.has(model.name) && !usedSdkNames.has(model.name)) {\n lookup.modelNameByIR.set(model.name, model.name);\n mapped.add(model.name);\n usedSdkNames.add(model.name);\n continue;\n }\n\n // Strategy 2a+: Try derived model names before falling back to Jaccard\n const derivedNames = hints.derivedModelNames(model.name);\n for (const derived of derivedNames) {\n if (sdkSignatureNames.has(derived) && !usedSdkNames.has(derived)) {\n lookup.modelNameByIR.set(model.name, derived);\n mapped.add(model.name);\n usedSdkNames.add(derived);\n break;\n }\n }\n if (mapped.has(model.name)) continue;\n\n // In strict mode, skip Jaccard entirely\n if (options?.strictModelMatch) continue;\n\n // Strategy 2b: Fall back to Jaccard field-similarity matching\n const irFields = irModelFieldSignature(model);\n let bestMatch: string | null = null;\n let bestScore = 0;\n\n for (const sdk of sdkSignatures) {\n if (usedSdkNames.has(sdk.name)) continue;\n\n const { score, intersection } = jaccardSimilarity(irFields, sdk.fields);\n\n // Require ≥60% Jaccard AND enough fields in common (scaled by model size)\n const minIntersection = Math.max(3, Math.ceil(irFields.size * 0.5));\n if (score > bestScore && score >= 0.6 && intersection >= minIntersection) {\n bestScore = score;\n bestMatch = sdk.name;\n }\n }\n\n if (bestMatch) {\n lookup.modelNameByIR.set(model.name, bestMatch);\n mapped.add(model.name);\n usedSdkNames.add(bestMatch);\n }\n }\n}\n\n/** Categories that can be patched by the overlay retry loop. */\nconst PATCHABLE_CATEGORIES = new Set(['symbol_removed', 'symbol_renamed']);\n\n/** Check if a classified change is patchable by the overlay loop. */\nexport function isPatchableChange(change: ClassifiedChange): boolean {\n return PATCHABLE_CATEGORIES.has(change.category);\n}\n\n/**\n * Patch overlay with classified changes from a failed verification.\n * Adds explicit name mappings for symbols that were generated with wrong names.\n * Returns a new OverlayLookup (immutable).\n */\nexport function patchOverlay(overlay: OverlayLookup, changes: ClassifiedChange[], baseline: ApiSurface): OverlayLookup {\n const patched: OverlayLookup = {\n methodByOperation: new Map(overlay.methodByOperation),\n httpKeyByMethod: new Map(overlay.httpKeyByMethod),\n interfaceByName: new Map(overlay.interfaceByName),\n typeAliasByName: new Map(overlay.typeAliasByName),\n requiredExports: new Map(Array.from(overlay.requiredExports.entries()).map(([k, v]) => [k, new Set(v)])),\n modelNameByIR: new Map(overlay.modelNameByIR),\n fileBySymbol: new Map(overlay.fileBySymbol),\n };\n\n let warnedManifest = false;\n\n for (const c of changes) {\n if (!isPatchableChange(c)) continue;\n\n // symbol is the fqName, e.g. \"ClassName.methodName\" or \"ClassName\"\n const parts = c.symbol.split('.');\n if (parts.length === 2) {\n const [className, methodName] = parts;\n const baseClass = baseline.classes[className];\n if (baseClass && baseClass.methods[methodName]?.length > 0) {\n const httpKey = overlay.httpKeyByMethod.get(`${className}.${methodName}`);\n if (!httpKey && overlay.httpKeyByMethod.size === 0 && !warnedManifest) {\n console.warn(\n 'Warning: No operations map in .oagen-manifest.json. Method-level violations cannot be auto-patched. ' +\n 'Implement buildOperationsMap in your emitter for the self-correcting loop to resolve these.',\n );\n warnedManifest = true;\n }\n if (httpKey) {\n const method = baseClass.methods[methodName][0];\n patched.methodByOperation.set(httpKey, {\n className,\n methodName,\n params: method.params,\n returnType: method.returnType,\n });\n }\n }\n const baseIface = baseline.interfaces[className];\n if (baseIface) {\n patched.interfaceByName.set(className, className);\n }\n } else if (parts.length === 1) {\n const name = parts[0];\n if (baseline.interfaces[name]) {\n patched.interfaceByName.set(name, name);\n }\n if (baseline.typeAliases[name]) {\n patched.typeAliasByName.set(name, name);\n }\n }\n }\n\n return patched;\n}\n"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"tree-sitter-C53w_0WE.mjs","names":[],"sources":["../src/ir/types.ts","../src/errors.ts","../src/utils/naming.ts","../src/utils/tree-sitter.ts"],"sourcesContent":["import type { SdkBehavior } from './sdk-behavior.js';\n\n/** Authentication scheme extracted from OpenAPI securitySchemes */\nexport type AuthScheme =\n | { kind: 'bearer' }\n | { kind: 'apiKey'; in: 'header' | 'query' | 'cookie'; name: string }\n | { kind: 'oauth2'; flows: Record<string, unknown> };\n\n/** Root IR node representing the full API surface */\n/** A server entry from the OpenAPI servers array */\nexport interface ServerEntry {\n url: string;\n description?: string;\n}\n\n/** Root IR node representing the full API surface */\nexport interface ApiSpec {\n name: string;\n version: string;\n description?: string;\n baseUrl: string;\n servers?: ServerEntry[];\n services: Service[];\n models: Model[];\n enums: Enum[];\n auth?: AuthScheme[];\n /** Language-agnostic runtime policies (retry, errors, telemetry, etc.). */\n sdk: SdkBehavior;\n}\n\n/** A service groups related operations (maps to an SDK resource class) */\nexport interface Service {\n name: string;\n description?: string;\n operations: Operation[];\n}\n\n/** A single API operation (maps to an SDK method) */\n/** Per-operation security requirement: scheme name → scope list. */\nexport interface SecurityRequirement {\n schemeName: string;\n scopes: string[];\n}\n\nexport interface Operation {\n name: string;\n description?: string;\n httpMethod: HttpMethod;\n path: string;\n pathParams: Parameter[];\n queryParams: Parameter[];\n headerParams: Parameter[];\n cookieParams?: Parameter[];\n requestBody?: TypeRef;\n requestBodyEncoding?: 'json' | 'form-data' | 'form-urlencoded' | 'binary' | 'text';\n response: TypeRef;\n successResponses?: SuccessResponse[];\n errors: ErrorResponse[];\n pagination?: PaginationMeta;\n injectIdempotencyKey: boolean;\n deprecated?: boolean;\n async?: boolean;\n /** Per-operation security overrides. When present, overrides the global spec-level security. */\n security?: SecurityRequirement[];\n /**\n * Mutually-exclusive parameter groups parsed from `x-mutually-exclusive-parameter-groups`.\n * Each group represents a logical choice the caller must (or may) make between\n * several subsets of query/path/header parameters. The grouped parameters remain\n * in their original arrays (queryParams, pathParams, etc.) for wire-format purposes;\n * this field adds the grouping metadata so emitters can render sum types.\n */\n parameterGroups?: ParameterGroup[];\n}\n\n/**\n * A mutually-exclusive parameter group. The caller must supply exactly one\n * variant (when `optional` is false) or may omit the group entirely (when true).\n */\nexport interface ParameterGroup {\n /** Group name from the extension (e.g. \"parent_resource\"). */\n name: string;\n /** True when the whole group may be omitted. */\n optional: boolean;\n /** Ordered variants (insertion order matches the spec). */\n variants: ParameterGroupVariant[];\n}\n\n/**\n * One variant within a mutually-exclusive parameter group.\n */\nexport interface ParameterGroupVariant {\n /** Variant name from the extension (e.g. \"by_id\", \"by_external_id\"). */\n name: string;\n /**\n * References to the actual parameter IR nodes. These are the same\n * objects that live in operation.queryParams / .pathParams / .headerParams --\n * shared by identity, not duplicated.\n */\n parameters: Parameter[];\n}\n\n/** Structured pagination metadata for auto-paging iterator generation */\nexport interface PaginationMeta {\n strategy: 'cursor' | 'offset' | 'link-header';\n param: string;\n limitParam?: string;\n dataPath?: string;\n itemType: TypeRef;\n}\n\nexport type HttpMethod = 'get' | 'post' | 'put' | 'patch' | 'delete' | 'head' | 'options' | 'trace';\n\nexport interface Parameter {\n name: string;\n type: TypeRef;\n required: boolean;\n description?: string;\n deprecated?: boolean;\n default?: unknown;\n example?: unknown;\n style?: 'form' | 'simple' | 'label' | 'matrix';\n explode?: boolean;\n}\n\n/** Type reference — the core type system of the IR */\nexport type TypeRef = PrimitiveType | ArrayType | ModelRef | EnumRef | UnionType | NullableType | LiteralType | MapType;\n\nexport interface PrimitiveType {\n kind: 'primitive';\n type: 'string' | 'integer' | 'number' | 'boolean' | 'unknown';\n format?: string;\n}\n\nexport interface ArrayType {\n kind: 'array';\n items: TypeRef;\n}\n\nexport interface ModelRef {\n kind: 'model';\n name: string;\n}\n\nexport interface EnumRef {\n kind: 'enum';\n name: string;\n values?: (string | number)[];\n}\n\nexport interface LiteralType {\n kind: 'literal';\n value: string | number | boolean | null;\n}\n\nexport interface UnionType {\n kind: 'union';\n variants: TypeRef[];\n discriminator?: { property: string; mapping: Record<string, string> };\n /** Which OAS composition keyword produced this union. Emitters can use this to\n * distinguish inheritance (allOf) from exclusive union (oneOf) from open union (anyOf). */\n compositionKind?: 'allOf' | 'oneOf' | 'anyOf';\n}\n\nexport interface NullableType {\n kind: 'nullable';\n inner: TypeRef;\n}\n\nexport interface MapType {\n kind: 'map';\n valueType: TypeRef;\n keyType?: TypeRef;\n}\n\n/**\n * A generic type parameter on a model.\n * Example: `DirectoryUser<TCustomAttributes = Record<string, unknown>>`\n * → `{ name: 'TCustomAttributes', default: { kind: 'map', valueType: { kind: 'primitive', type: 'unknown' } } }`\n */\nexport interface TypeParam {\n name: string;\n /** Default type when the param is not specified. */\n default?: TypeRef;\n}\n\n/** Model definition (maps to an SDK model/data class) */\nexport interface Model {\n name: string;\n description?: string;\n fields: Field[];\n /** Generic type parameters. Empty/undefined for non-generic models. */\n typeParams?: TypeParam[];\n /**\n * When set, this model is a discriminated union over allOf+oneOf variants.\n * Emitters should generate a dispatcher (factory) instead of a regular dataclass.\n * The `property` field is the discriminator key (e.g. \"event\"), and `mapping`\n * maps each discriminator value to the concrete variant model name.\n */\n discriminator?: {\n property: string;\n mapping: Record<string, string>;\n };\n}\n\nexport interface Field {\n name: string;\n type: TypeRef;\n required: boolean;\n description?: string;\n readOnly?: boolean;\n writeOnly?: boolean;\n deprecated?: boolean;\n default?: unknown;\n example?: unknown;\n}\n\n/** Enum definition */\nexport interface Enum {\n name: string;\n values: EnumValue[];\n}\n\nexport interface EnumValue {\n name: string;\n value: string | number;\n description?: string;\n deprecated?: boolean;\n}\n\n/**\n * Exhaustive check helper for TypeRef switches.\n * If a new kind is added to TypeRef, any switch that doesn't handle it\n * will fail to compile because `never` won't accept the unhandled variant.\n *\n * Usage:\n * switch (ref.kind) {\n * case 'primitive': ...\n * case 'array': ...\n * // If you forget 'literal', TypeScript errors here:\n * default: assertNever(ref);\n * }\n */\nexport function assertNever(x: never): never {\n // Inline to avoid importing from ../errors.js (ir/ is layer 0, must not import upward)\n const kind = (x as TypeRef).kind;\n const err = new Error(\n `Unexpected TypeRef kind: ${kind}\\nHint: If you added a new TypeRef variant, handle it in every switch/case that calls assertNever.`,\n );\n err.name = 'InternalError';\n throw err;\n}\n\n/**\n * Generic depth-first walker for TypeRef trees.\n * Handles recursion into array/nullable/union/map children and provides\n * an exhaustive `assertNever` check so callers don't need to repeat the\n * switch boilerplate. Supply callbacks only for the leaf kinds you care about.\n */\nexport function walkTypeRef(\n ref: TypeRef,\n visitor: {\n model?: (ref: ModelRef) => void;\n enum?: (ref: EnumRef) => void;\n primitive?: (ref: PrimitiveType) => void;\n literal?: (ref: LiteralType) => void;\n },\n): void {\n switch (ref.kind) {\n case 'model':\n visitor.model?.(ref);\n break;\n case 'enum':\n visitor.enum?.(ref);\n break;\n case 'array':\n walkTypeRef(ref.items, visitor);\n break;\n case 'nullable':\n walkTypeRef(ref.inner, visitor);\n break;\n case 'union':\n for (const v of ref.variants) walkTypeRef(v, visitor);\n break;\n case 'map':\n if (ref.keyType) walkTypeRef(ref.keyType, visitor);\n walkTypeRef(ref.valueType, visitor);\n break;\n case 'literal':\n visitor.literal?.(ref);\n break;\n case 'primitive':\n visitor.primitive?.(ref);\n break;\n default:\n assertNever(ref);\n }\n}\n\n/**\n * Generic depth-first mapper for TypeRef trees.\n * Like walkTypeRef but returns a transformed value instead of void.\n * Handles recursion into array/nullable/union/map children, passing\n * already-mapped child values to the parent callback.\n */\nexport function mapTypeRef<T>(\n ref: TypeRef,\n mapper: {\n primitive: (ref: PrimitiveType) => T;\n array: (ref: ArrayType, mappedItems: T) => T;\n model: (ref: ModelRef) => T;\n enum: (ref: EnumRef) => T;\n union: (ref: UnionType, mappedVariants: T[]) => T;\n nullable: (ref: NullableType, mappedInner: T) => T;\n literal: (ref: LiteralType) => T;\n map: (ref: MapType, mappedValue: T, mappedKey?: T) => T;\n },\n): T {\n switch (ref.kind) {\n case 'primitive':\n return mapper.primitive(ref);\n case 'array':\n return mapper.array(ref, mapTypeRef(ref.items, mapper));\n case 'model':\n return mapper.model(ref);\n case 'enum':\n return mapper.enum(ref);\n case 'union':\n return mapper.union(\n ref,\n ref.variants.map((v) => mapTypeRef(v, mapper)),\n );\n case 'nullable':\n return mapper.nullable(ref, mapTypeRef(ref.inner, mapper));\n case 'literal':\n return mapper.literal(ref);\n case 'map':\n return mapper.map(\n ref,\n mapTypeRef(ref.valueType, mapper),\n ref.keyType ? mapTypeRef(ref.keyType, mapper) : undefined,\n );\n default:\n return assertNever(ref);\n }\n}\n\n// --- IR traversal utilities ---\n\n/**\n * Collect all model names referenced (directly or transitively) by a TypeRef.\n */\nexport function collectModelRefs(ref: TypeRef): string[] {\n const names: string[] = [];\n walkTypeRef(ref, { model: (r) => names.push(r.name) });\n return names;\n}\n\n/**\n * Collect all enum names referenced by a TypeRef.\n */\nexport function collectEnumRefs(ref: TypeRef): string[] {\n const names: string[] = [];\n walkTypeRef(ref, { enum: (r) => names.push(r.name) });\n return names;\n}\n\n/**\n * Collect all TypeRef-referenced model and enum names from a model's fields.\n * Returns { models, enums } sets for generating import statements.\n */\nexport function collectFieldDependencies(model: Model): {\n models: Set<string>;\n enums: Set<string>;\n} {\n const models = new Set<string>();\n const enums = new Set<string>();\n\n for (const field of model.fields) {\n for (const name of collectModelRefs(field.type)) {\n if (name !== model.name) models.add(name);\n }\n for (const name of collectEnumRefs(field.type)) {\n enums.add(name);\n }\n }\n\n return { models, enums };\n}\n\n/**\n * Assign each model to the service that first references it.\n * Models referenced by multiple services are assigned to the first.\n * Models not referenced by any service are unassigned (absent from the map).\n */\nexport function assignModelsToServices(models: Model[], services: Service[]): Map<string, string> {\n const modelToService = new Map<string, string>();\n const modelNames = new Set(models.map((m) => m.name));\n\n for (const service of services) {\n const referencedModels = new Set<string>();\n\n for (const op of service.operations) {\n if (op.requestBody) {\n for (const name of collectModelRefs(op.requestBody)) {\n referencedModels.add(name);\n }\n }\n for (const name of collectModelRefs(op.response)) {\n referencedModels.add(name);\n }\n for (const param of [...op.pathParams, ...op.queryParams, ...op.headerParams, ...(op.cookieParams ?? [])]) {\n for (const name of collectModelRefs(param.type)) {\n referencedModels.add(name);\n }\n }\n if (op.pagination) {\n for (const name of collectModelRefs(op.pagination.itemType)) {\n referencedModels.add(name);\n }\n }\n }\n\n // Transitively collect models referenced by the directly-referenced models\n const toVisit = [...referencedModels];\n while (toVisit.length > 0) {\n const name = toVisit.pop()!;\n const model = models.find((m) => m.name === name);\n if (!model) continue;\n for (const field of model.fields) {\n for (const ref of collectModelRefs(field.type)) {\n if (!referencedModels.has(ref) && modelNames.has(ref)) {\n referencedModels.add(ref);\n toVisit.push(ref);\n }\n }\n }\n }\n\n for (const name of referencedModels) {\n if (!modelToService.has(name)) {\n modelToService.set(name, service.name);\n }\n }\n }\n\n return modelToService;\n}\n\n/**\n * Collect all model names referenced as request bodies across all services.\n */\nexport function collectRequestBodyModels(services: Service[]): Set<string> {\n const result = new Set<string>();\n for (const service of services) {\n for (const op of service.operations) {\n if (op.requestBody) {\n for (const name of collectModelRefs(op.requestBody)) {\n result.add(name);\n }\n }\n }\n }\n return result;\n}\n\nexport interface ErrorResponse {\n statusCode: number;\n type?: TypeRef;\n}\n\n/** A successful response entry from a 2xx status code */\nexport interface SuccessResponse {\n statusCode: number;\n type: TypeRef;\n}\n","/**\n * Structured error hierarchy for oagen.\n *\n * Every error carries a human-readable `hint` that suggests a recovery action.\n * The hint is appended to the `message` so it appears in stack traces and logs.\n */\n\n/** Base class for all oagen errors. */\nexport class OagenError extends Error {\n readonly hint: string;\n\n constructor(message: string, hint: string) {\n const fullMessage = hint ? `${message}\\nHint: ${hint}` : message;\n super(fullMessage);\n this.name = 'OagenError';\n this.hint = hint;\n }\n}\n\n/** Thrown when a command should terminate with a specific exit code. */\nexport class CommandError extends OagenError {\n readonly exitCode: number;\n\n constructor(message: string, hint: string, exitCode: number) {\n super(message, hint);\n this.name = 'CommandError';\n this.exitCode = exitCode;\n }\n}\n\n/** Thrown when an OpenAPI spec cannot be parsed or has an unsupported version. */\nexport class SpecParseError extends OagenError {\n constructor(message: string, hint: string) {\n super(message, hint);\n this.name = 'SpecParseError';\n }\n}\n\n/** Thrown when configuration files (manifests, API surfaces, overlays) are missing or malformed. */\nexport class ConfigError extends OagenError {\n constructor(message: string, hint: string) {\n super(message, hint);\n this.name = 'ConfigError';\n }\n}\n\n/** Thrown when a config file exists but cannot be loaded or evaluated. */\nexport class ConfigLoadError extends ConfigError {\n constructor(message: string, hint: string) {\n super(message, hint);\n this.name = 'ConfigLoadError';\n }\n}\n\n/** Thrown when a config targets a different IR version than the installed package. */\nexport class ConfigVersionMismatchError extends ConfigError {\n constructor(message: string, hint: string) {\n super(message, hint);\n this.name = 'ConfigVersionMismatchError';\n }\n}\n\n/** Thrown when an API surface extractor encounters a problem. */\nexport class ExtractorError extends OagenError {\n constructor(message: string, hint: string) {\n super(message, hint);\n this.name = 'ExtractorError';\n }\n}\n\n/** Thrown when a requested language or extractor is not found in a registry. */\nexport class RegistryError extends OagenError {\n constructor(message: string, hint: string) {\n super(message, hint);\n this.name = 'RegistryError';\n }\n}\n\n/** Thrown for internal invariant violations that indicate a bug. */\nexport class InternalError extends OagenError {\n constructor(message: string, hint: string) {\n super(message, hint);\n this.name = 'InternalError';\n }\n}\n","/**\n * Known compound tokens that the regex-based splitter over-splits.\n * Each entry is [lowercase-word-sequence, canonical-form].\n * Sorted longest-first so greedy matching works correctly.\n */\nconst COMPOUND_WORDS: [string[], string][] = [\n [['m', '2', 'm'], 'M2M'],\n [['o', 'auth'], 'OAuth'],\n];\n\n/**\n * Recombine adjacent words that form a known compound token.\n */\nfunction recombineCompounds(words: string[]): string[] {\n const result: string[] = [];\n let i = 0;\n while (i < words.length) {\n let matched = false;\n for (const [pattern, canonical] of COMPOUND_WORDS) {\n if (i + pattern.length <= words.length) {\n const matches = pattern.every((p, j) => words[i + j].toLowerCase() === p);\n if (matches) {\n result.push(canonical);\n i += pattern.length;\n matched = true;\n break;\n }\n }\n }\n if (!matched) {\n result.push(words[i]);\n i++;\n }\n }\n return result;\n}\n\n/**\n * Split a string into words, handling:\n * - camelCase / PascalCase boundaries\n * - snake_case / kebab-case separators\n * - Consecutive capitals (e.g., \"HTTPClient\" → [\"HTTP\", \"Client\"])\n * - Numbers as word boundaries (e.g., \"OAuth2Token\" → [\"OAuth\", \"2\", \"Token\"])\n * - Known compounds are recombined (e.g., \"M2M\" stays as one word)\n */\nexport function splitWords(s: string): string[] {\n if (!s) return [];\n\n const words = s\n .replace(/[^a-zA-Z0-9_\\-\\s.]/g, '_') // replace non-alphanumeric chars with separator\n .replace(/([a-z])([A-Z])/g, '$1\\0$2') // camelCase boundary\n .replace(/([A-Z]+)([A-Z][a-z])/g, '$1\\0$2') // consecutive caps boundary\n .replace(/([a-zA-Z])(\\d)/g, '$1\\0$2') // letter to number\n .replace(/(\\d)([a-zA-Z])/g, '$1\\0$2') // number to letter\n .split(/[\\0_\\-\\s.]+/)\n .filter((w) => w.length > 0);\n\n return recombineCompounds(words);\n}\n\nexport const ACRONYM_SET = new Set(['SSO', 'FGA', 'SAML', 'SCIM', 'JWT', 'HMAC', 'M2M']);\n\nexport function toPascalCase(s: string, acronyms?: Set<string>): string {\n const merged = acronyms ? new Set([...ACRONYM_SET, ...acronyms]) : ACRONYM_SET;\n return splitWords(s)\n .map((w) => {\n const upper = w.toUpperCase();\n if (merged.has(upper)) return upper;\n // Special case: OAuth should stay as OAuth, not OAUTH\n if (upper === 'OAUTH') return 'OAuth';\n return w.charAt(0).toUpperCase() + w.slice(1).toLowerCase();\n })\n .join('');\n}\n\nexport function toCamelCase(s: string, acronyms?: Set<string>): string {\n const merged = acronyms ? new Set([...ACRONYM_SET, ...acronyms]) : ACRONYM_SET;\n const words = splitWords(s);\n if (words.length === 0) return '';\n return words\n .map((w, i) => {\n if (i === 0) return w.toLowerCase();\n const upper = w.toUpperCase();\n if (merged.has(upper)) return upper;\n if (upper === 'OAUTH') return 'OAuth';\n return w.charAt(0).toUpperCase() + w.slice(1).toLowerCase();\n })\n .join('');\n}\n\nexport function toSnakeCase(s: string): string {\n return splitWords(s)\n .map((w) => w.toLowerCase())\n .join('_');\n}\n\nexport function toKebabCase(s: string): string {\n return splitWords(s)\n .map((w) => w.toLowerCase())\n .join('-');\n}\n\nexport function toUpperSnakeCase(s: string): string {\n return splitWords(s)\n .map((w) => w.toUpperCase())\n .join('_');\n}\n\nconst BACKEND_SUFFIXES = ['Controller'];\n\nexport function stripBackendSuffixes(name: string): string {\n for (const suffix of BACKEND_SUFFIXES) {\n if (name.endsWith(suffix) && name.length > suffix.length) {\n return name.slice(0, -suffix.length);\n }\n }\n return name;\n}\n\nexport function stripBackendPrefixes(name: string): string {\n return name.replace(/Userland/g, '').replace(/Controller/g, '');\n}\n\n/**\n * Remove ListItem / ByExternalId / ByResourceId / ForResource markers from PascalCase names.\n * E.g. \"DirectoriesListItemState\" → \"DirectoriesState\"\n */\nexport function stripListItemMarkers(name: string): string {\n return name\n .replace(/ListItem/g, '')\n .replace(/ByExternalId/g, '')\n .replace(/ByResourceId/g, '')\n .replace(/ForResource/g, '');\n}\n\n/** Words that look plural but must NOT be singularized. */\nconst SINGULAR_SAFE_LIST = new Set([\n 'Status',\n 'Address',\n 'Access',\n 'Process',\n 'Progress',\n 'Success',\n 'Radius',\n 'Canvas',\n 'Alias',\n 'Basis',\n 'Bus',\n 'Species',\n 'Series',\n]);\n\n/**\n * Conservative singularize for the leading PascalCase word.\n * Only applied to the first word of a PascalCase name (the resource word).\n * - `ies` → `y` (e.g. Directories → Directory)\n * - trailing `s` for words >4 chars (e.g. Organizations → Organization)\n * Safe-listed words are never singularized.\n */\nexport function singularize(word: string): string {\n if (SINGULAR_SAFE_LIST.has(word)) return word;\n if (word.endsWith('ies') && word.length > 4) {\n return word.slice(0, -3) + 'y';\n }\n if (word.endsWith('ses') && word.length > 4) {\n // e.g. \"Processes\" — but \"Process\" is safe-listed, this handles non-safe ones\n return word.slice(0, -2);\n }\n if (word.endsWith('s') && !word.endsWith('ss') && word.length > 4) {\n return word.slice(0, -1);\n }\n return word;\n}\n\n/**\n * Compose all backend name cleaning transforms in order:\n * 1. Strip backend prefixes (Userland, Controller)\n * 2. Strip backend suffixes (Dto, DTO, Controller)\n * 3. Strip ListItem / ByExternalId markers\n * 4. Singularize leading resource word\n *\n * Must be idempotent: `cleanSchemaName(cleanSchemaName(x)) === cleanSchemaName(x)`\n */\n/** Strip `.js` extensions from import/export specifiers for dedup comparison. */\nexport function normalizeJsExtension(text: string): string {\n return text.replace(/\\.js(['\"])/g, '$1');\n}\n\nexport function cleanSchemaName(name: string): string {\n let result = stripBackendPrefixes(stripBackendSuffixes(name));\n result = stripListItemMarkers(result);\n\n // Singularize the leading PascalCase word\n const match = result.match(/^([A-Z][a-z]*)/);\n if (match) {\n const leadWord = match[1];\n const singular = singularize(leadWord);\n if (singular !== leadWord) {\n result = singular + result.slice(leadWord.length);\n }\n }\n\n return result;\n}\n","/**\n * Shared tree-sitter utilities.\n *\n * tree-sitter 0.21.x has a native binding bug: its internal UTF-16 buffer is\n * 32 768 uint16 units (32 768 characters for BMP text). When the JS input\n * callback returns a string >= 32 768 chars, `napi_get_value_string_utf16`\n * overflows and the C layer throws \"Invalid argument\". Work around this by\n * supplying a chunked callback for large sources instead of a raw string.\n */\n\nimport type Parser from 'tree-sitter';\n\nconst TS_SAFE_CHUNK = 32_767;\n\nexport function safeParse(parser: Parser, source: string): Parser.Tree {\n if (source.length < TS_SAFE_CHUNK) {\n return parser.parse(source);\n }\n return parser.parse((offset: number) => source.slice(offset, offset + TS_SAFE_CHUNK));\n}\n"],"mappings":"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"}
|