declare module '@ember-data/model/migration-support' {
  /**
   * This module provides support for migrating away from @ember-data/model
   * to @warp-drive/schema-record.
   *
   * It includes:
   *
   * - A `withDefaults` function to assist in creating a schema in LegacyMode
   * - A `registerDerivations` function to register the derivations necessary to support LegacyMode
   * - A `DelegatingSchemaService` that can be used to provide a schema service that works with both
   *   @ember-data/model and @warp-drive/schema-record simultaneously for migration purposes.
   * - A `WithLegacy` type util that can be used to create a type that includes the legacy
   *   properties and methods of a record.
   *
   * Using LegacyMode features on a SchemaRecord *requires* the use of these derivations and schema
   * additions. LegacyMode is not intended to be a long-term solution, but rather a stepping stone
   * to assist in more rapidly adopting modern WarpDrive features.
   *
   * @module
   */
  import type { Snapshot } from '@ember-data/legacy-compat/-private';
  import type Store from '@ember-data/store';
  import type { SchemaService } from '@ember-data/store/types';
  import type { StableRecordIdentifier } from '@warp-drive/core-types';
  import type { ChangedAttributesHash } from '@warp-drive/core-types/cache';
  import type { ObjectValue } from '@warp-drive/core-types/json/raw';
  import type { TypedRecordInstance, TypeFromInstance } from '@warp-drive/core-types/record';
  import type { Derivation, HashFn, Transformation } from '@warp-drive/core-types/schema/concepts';
  import type { ArrayField, DerivedField, FieldSchema, GenericField, HashField, LegacyResourceSchema, ObjectField, ObjectSchema, ResourceSchema } from '@warp-drive/core-types/schema/fields';
  import type { WithPartial } from '@warp-drive/core-types/utils';
  import type { MinimalLegacyRecord } from '@ember-data/model/-private/model-methods';
  import { belongsTo, hasMany } from '@ember-data/model/-private/model-methods';
  import RecordState from '@ember-data/model/-private/record-state';
  import type BelongsToReference from '@ember-data/model/-private/references/belongs-to';
  import type HasManyReference from '@ember-data/model/-private/references/has-many';
  import type { _MaybeBelongsToFields, MaybeHasManyFields } from '@ember-data/model/-private/type-utils';
  export type WithLegacyDerivations<T extends TypedRecordInstance> = T & MinimalLegacyRecord & {
      belongsTo: typeof belongsTo;
      hasMany: typeof hasMany;
  };
  type AttributesSchema = ReturnType<Exclude<SchemaService['attributesDefinitionFor'], undefined>>;
  type RelationshipsSchema = ReturnType<Exclude<SchemaService['relationshipsDefinitionFor'], undefined>>;
  interface LegacyModeRecord<T extends TypedRecordInstance> {
      id: string | null;
      serialize(options?: Record<string, unknown>): unknown;
      destroyRecord(options?: Record<string, unknown>): Promise<this>;
      unloadRecord(): void;
      changedAttributes(): ChangedAttributesHash;
      rollbackAttributes(): void;
      _createSnapshot(): Snapshot<T>;
      save(options?: Record<string, unknown>): Promise<this>;
      reload(options?: Record<string, unknown>): Promise<T>;
      belongsTo<K extends _MaybeBelongsToFields<T>>(prop: K): BelongsToReference<T, K>;
      hasMany<K extends MaybeHasManyFields<T>>(prop: K): HasManyReference<T, K>;
      deleteRecord(): void;
      adapterError: unknown;
      constructor: {
          modelName: TypeFromInstance<T>;
      };
      currentState: RecordState;
      dirtyType: 'deleted' | 'created' | 'updated' | '';
      errors: unknown;
      hasDirtyAttributes: boolean;
      isDeleted: boolean;
      isEmpty: boolean;
      isError: boolean;
      isLoaded: boolean;
      isLoading: boolean;
      isDestroying: boolean;
      isDestroyed: boolean;
      isNew: boolean;
      isSaving: boolean;
      isValid: boolean;
  }
  /**
   * A Type utility that enables quickly adding type information for the fields
   * defined by `import { withDefaults } from '@ember-data/model/migration-support'`.
   *
   * Example:
   *
   * ```ts
   * import { withDefaults, WithLegacy } from '@ember-data/model/migration-support';
   * import { Type } from '@warp-drive/core-types/symbols';
   * import type { HasMany } from '@ember-data/model';
   *
   * export const UserSchema = withDefaults({
   *   type: 'user',
   *   fields: [
   *     { name: 'firstName', kind: 'attribute' },
   *     { name: 'lastName', kind: 'attribute' },
   *     { name: 'age', kind: 'attribute' },
   *     { name: 'friends',
   *       kind: 'hasMany',
   *       type: 'user',
   *       options: { inverse: 'friends', async: false }
   *     },
   *     { name: 'bestFriend',
   *       kind: 'belongsTo',
   *       type: 'user',
   *       options: { inverse: null, async: false }
   *     },
   *   ],
   * });
   *
   * export type User = WithLegacy<{
   *   firstName: string;
   *   lastName: string;
   *   age: number;
   *   friends: HasMany<User>;
   *   bestFriend: User | null;
   *   [Type]: 'user';
   * }>
   * ```
   *
   */
  export type WithLegacy<T extends TypedRecordInstance> = T & LegacyModeRecord<T>;
  /**
   * A function which adds the necessary fields to a schema and marks it as
   * being in LegacyMode. This is used to support the legacy features of
   * @ember-data/model while migrating to WarpDrive.
   *
   * Example:
   *
   * ```ts
   * import { withDefaults, WithLegacy } from '@ember-data/model/migration-support';
   * import { Type } from '@warp-drive/core-types/symbols';
   * import type { HasMany } from '@ember-data/model';
   *
   * export const UserSchema = withDefaults({
   *   type: 'user',
   *   fields: [
   *     { name: 'firstName', kind: 'attribute' },
   *     { name: 'lastName', kind: 'attribute' },
   *     { name: 'age', kind: 'attribute' },
   *     { name: 'friends',
   *       kind: 'hasMany',
   *       type: 'user',
   *       options: { inverse: 'friends', async: false }
   *     },
   *     { name: 'bestFriend',
   *       kind: 'belongsTo',
   *       type: 'user',
   *       options: { inverse: null, async: false }
   *     },
   *   ],
   * });
   *
   * export type User = WithLegacy<{
   *   firstName: string;
   *   lastName: string;
   *   age: number;
   *   friends: HasMany<User>;
   *   bestFriend: User | null;
   *   [Type]: 'user';
   * }>
   * ```
   *
   * Using this function require registering the derivations
   * it requires with the schema service.
   *
   * ```ts
   * import { registerDerivations } from '@ember-data/model/migration-support';
   *
   * registerDerivations(schema);
   * ```
   *
   * @param {LegacyResourceSchema} schema The schema to add legacy support to.
   * @return {LegacyResourceSchema} The schema with legacy support added.
   * @public
   */
  export function withDefaults(schema: WithPartial<LegacyResourceSchema, 'legacy' | 'identity'>): LegacyResourceSchema;
  /**
   * A function which registers the necessary derivations to support
   * the LegacyMode features of @ember-data/model while migrating to WarpDrive.
   *
   * This must be called in order to use the fields added by:
   *
   * ```ts
   * import { withDefaults } from '@ember-data/model/migration-support';
   * ```
   *
   * @param {SchemaService} schema The schema service to register the derivations with.
   * @return {void}
   * @public
   */
  export function registerDerivations(schema: SchemaService): void;
  /**
   * A class which provides a schema service that delegates between
   * a primary schema service and one that supports legacy model
   * classes as its schema source.
   *
   * When the primary schema service has a schema for the given
   * resource, it will be used. Otherwise, the fallback schema
   * service will be used.
   *
   * This can be used when incrementally migrating from Models to
   * SchemaRecords by enabling unmigrated Models to continue to
   * provide their own schema information to the application.
   *
   * ```ts
   * import { DelegatingSchemaService } from '@ember-data/model/migration-support';
   * import { SchemaService } from '@warp-drive/schema-record';
   *
   * class AppStore extends Store {
   *   createSchemaService() {
   *     const schema = new SchemaService();
   *     return new DelegatingSchemaService(this, schema);
   *   }
   * }
   * ```
   *
   * All calls to register resources, derivations, transformations, hash functions
   * etc. will be delegated to the primary schema service.
   *
   * @class DelegatingSchemaService
   * @public
   */
  export interface DelegatingSchemaService {
      attributesDefinitionFor?(resource: StableRecordIdentifier | {
          type: string;
      }): AttributesSchema;
      relationshipsDefinitionFor?(resource: StableRecordIdentifier | {
          type: string;
      }): RelationshipsSchema;
      doesTypeExist?(type: string): boolean;
  }
  export class DelegatingSchemaService implements SchemaService {
      _preferred: SchemaService;
      _secondary: SchemaService;
      constructor(store: Store, schema: SchemaService);
      isDelegated(resource: StableRecordIdentifier | {
          type: string;
      }): boolean;
      resourceTypes(): Readonly<string[]>;
      hasResource(resource: StableRecordIdentifier | {
          type: string;
      }): boolean;
      hasTrait(type: string): boolean;
      resourceHasTrait(resource: StableRecordIdentifier | {
          type: string;
      }, trait: string): boolean;
      fields(resource: StableRecordIdentifier | {
          type: string;
      }): Map<string, FieldSchema>;
      transformation(field: GenericField | ObjectField | ArrayField | {
          type: string;
      }): Transformation;
      hashFn(field: HashField | {
          type: string;
      }): HashFn;
      derivation(field: DerivedField | {
          type: string;
      }): Derivation;
      resource(resource: StableRecordIdentifier | {
          type: string;
      }): ResourceSchema | ObjectSchema;
      registerResources(schemas: Array<ResourceSchema | ObjectSchema>): void;
      registerResource(schema: ResourceSchema | ObjectSchema): void;
      registerTransformation(transform: Transformation): void;
      registerDerivation<R, T, FM extends ObjectValue | null>(derivation: Derivation<R, T, FM>): void;
      registerHashFn(hashFn: HashFn): void;
  }
  export {};
}
//# sourceMappingURL=migration-support.d.ts.map