@davidlj95/ngx-meta
Version:
Set your Angular site's metadata: standard meta tags, Open Graph, Twitter Cards, JSON-LD structured data and more. Supports SSR (and Angular Universal). Use a service. Use routes' data. Set it up in a flash! 🚀
1 lines • 84 kB
Source Map (JSON)
{"version":3,"file":"davidlj95-ngx-meta-core.mjs","sources":["../../src/core/src/providers/core-feature.ts","../../src/core/src/utils/is-defined.ts","../../src/core/src/messaging/format-dev-message.ts","../../src/core/src/messaging/maybe-non-http-url-dev-message.ts","../../src/core/src/messaging/maybe-too-long-dev-message.ts","../../src/core/src/module-name.ts","../../src/core/src/utils/make-injection-token.ts","../../src/core/src/utils/with-options.ts","../../src/core/src/defaults/defaults.ts","../../src/core/src/defaults/with-ngx-meta-defaults.ts","../../src/core/src/formatter/title-formatter.ts","../../src/core/src/formatter/with-ngx-meta-title-formatter.ts","../../src/core/src/globals/global-metadata.ts","../../src/core/src/head-elements/head-element-upsert-or-remove.ts","../../src/core/src/managers/ngx-meta-metadata-manager.ts","../../src/core/src/managers/metadata-registry.ts","../../src/core/src/loader/provide-ngx-meta-metadata-loader.ts","../../src/core/src/loader/ngx-meta-metadata-loader.module.ts","../../src/core/src/managers/provider/v1/make-metadata-manager-provider-from-setter-factory.ts","../../src/core/src/managers/provider/v2/provide-ngx-meta-manager.ts","../../src/core/src/meta-elements/v1/make-key-val-meta-definition.ts","../../src/core/src/meta-elements/v1/make-composed-key-val-meta-definition.ts","../../src/core/src/meta-elements/v1/ngx-meta-meta.service.ts","../../src/core/src/meta-elements/v2/ngx-meta-elements.service.ts","../../src/core/src/meta-elements/v2/with-name-attribute.ts","../../src/core/src/meta-elements/v2/with-property-attribute.ts","../../src/core/src/meta-elements/v2/with-content-attribute.ts","../../src/core/src/meta-elements/v2/composed-metadata-name.ts","../../src/core/src/managers/provider/v2/provide-ngx-meta-module-manager.ts","../../src/core/src/providers/provide-ngx-meta-core.ts","../../src/core/src/providers/ngx-meta-core.module.ts","../../src/core/src/routing/route-metadata-strategy.ts","../../src/core/src/utils/is-object.ts","../../src/core/src/resolvers/metadata-json-resolver.ts","../../src/core/src/resolvers/metadata-resolver.ts","../../src/core/src/service/ngx-meta.service.ts","../../src/core/src/url-resolution/angular-router-url.ts","../../src/core/src/url-resolution/no-op-url-resolver.ts","../../src/core/src/url-resolution/url-resolver.ts","../../src/core/src/url-resolution/default-url-resolver.ts","../../src/core/src/url-resolution/with-ngx-meta-base-url.ts","../../src/core/davidlj95-ngx-meta-core.ts"],"sourcesContent":["import { Provider } from '@angular/core'\n\n/**\n * Inspired from Angular router\n *\n * https://github.com/angular/angular/blob/17.0.7/packages/router/src/provide_router.ts#L80-L96\n * @internal\n */\nexport const enum CoreFeatureKind {\n Defaults,\n BaseUrl,\n TitleFormatter,\n}\n\n/**\n * @internal\n */\nexport interface CoreFeature<FeatureKind extends CoreFeatureKind> {\n _kind: FeatureKind\n _providers: Provider[]\n}\n\nexport const coreFeature = <FeatureKind extends CoreFeatureKind>(\n kind: FeatureKind,\n providers: Provider[],\n): CoreFeature<FeatureKind> => ({\n _kind: kind,\n _providers: providers,\n})\n\nexport const isCoreFeature = (\n anObject: object,\n): anObject is CoreFeature<CoreFeatureKind> =>\n ('_providers' satisfies keyof CoreFeature<CoreFeatureKind>) in anObject\n\n/**\n * @internal\n */\nexport type CoreFeatures = readonly CoreFeature<CoreFeatureKind>[]\n\nexport const providersFromCoreFeatures = (features: CoreFeatures): Provider[] =>\n features.map((f) => f._providers)\n","/**\n * Typescript's type guard helper to ensure a value is neither `null` nor `undefined`.\n *\n * @param value - Value to check\n *\n * @internal\n */\nexport const _isDefined = <T>(value: T | null | undefined): value is T =>\n value !== null && value !== undefined\n","/**\n * @internal\n */\nexport interface _FormatDevMessageOptions {\n module: string\n property?: string\n value?: string | null\n link?: string\n}\n\n/**\n * @internal\n */\nexport const _formatDevMessage = (\n message: string,\n options: _FormatDevMessageOptions,\n): string => {\n const header = [`ngx-meta/${options.module}:`, options.property, message]\n .filter((s) => !!s)\n .join(' ')\n const body = options.value ? `-> Value: \"${options.value}\"` : undefined\n const footer = options.link\n ? `For more information, see ${options.link}`\n : undefined\n return [header, body, footer].filter((s) => !!s).join('\\n')\n}\n","import {\n _formatDevMessage,\n _FormatDevMessageOptions,\n} from './format-dev-message'\n\n/**\n * Logs an error message about a URL not being HTTP or HTTPs\n *\n * Useful to warn developers about some metadata that requires absolute HTTP\n * or HTTPs URLs\n *\n * MUST be used with `ngDevMode` so that this message only runs in development\n *\n * @internal\n */\n/* istanbul ignore next https://github.com/istanbuljs/istanbuljs/issues/719 */\nexport const _maybeNonHttpUrlDevMessage = (\n url: string | URL | undefined | null,\n opts: _FormatDevMessageOptions & { shouldInsteadOfMust?: boolean },\n) => {\n const urlStr = url?.toString()\n if (urlStr && !(urlStr.startsWith('http') || urlStr.startsWith('https'))) {\n const shouldOrMust = opts.shouldInsteadOfMust ? 'should' : 'must'\n console.warn(\n _formatDevMessage(\n `URL ${shouldOrMust} be absolute and use either http or https`,\n opts,\n ),\n )\n }\n}\n","import {\n _formatDevMessage,\n _FormatDevMessageOptions,\n} from './format-dev-message'\n\n/**\n * Logs a warn message when a value string exceeds a length threshold\n *\n * Useful to warn developers about some metadata improperly used\n *\n * MUST be used with `ngDevMode` so that this message only runs in development\n *\n * @internal\n */\n/* istanbul ignore next https://github.com/istanbuljs/istanbuljs/issues/719 */\nexport const _maybeTooLongDevMessage = (\n value: string | undefined | null,\n maxLength: number,\n opts: _FormatDevMessageOptions,\n) => {\n if (value && value.length > maxLength) {\n console.warn(\n _formatDevMessage(`exceeds recommended size of ${maxLength} chars`, opts),\n )\n }\n}\n","export const MODULE_NAME = 'core'\n","import { InjectionToken } from '@angular/core'\nimport { _formatDevMessage } from '../messaging'\nimport { MODULE_NAME } from '../module-name'\n\n/** @visibleForTesting */\nexport const INJECTION_TOKENS = new Map<string, InjectionToken<unknown>>()\n/** @visibleForTesting */\nexport const INJECTION_TOKEN_FACTORIES = new Map<string, () => unknown>()\n\n/**\n * Creates an injection token with the given factory function if it doesn't exist.\n * To determine if an injection token exists, the description string is used.\n *\n * Useful to create {@link _LazyInjectionToken}s.\n\n * \\> The function can't be used to create a lazy injection token directly\n * \\> As a function call won't be tree-shaken. Which is the main purpose of lazy tokens.\n * \\> More in https://github.com/davidlj95/ngx/pull/902\n *\n * It also adds the library name as prefix to the injection token description.\n * In order to locate library's injectable easily when debugging an Angular project.\n *\n * @internal\n */\nexport const _makeInjectionToken: <T>(\n description: string,\n factory?: () => T,\n) => InjectionToken<T> = (description, factory) => {\n const injectionToken =\n INJECTION_TOKENS.get(description) ??\n new InjectionToken(\n `ngx-meta ${description}`,\n /* istanbul ignore next https://github.com/istanbuljs/istanbuljs/issues/719 */\n factory ? { factory } : undefined,\n )\n INJECTION_TOKENS.set(description, injectionToken)\n /* istanbul ignore next https://github.com/istanbuljs/istanbuljs/issues/719 */\n if (ngDevMode && factory) {\n if (\n (INJECTION_TOKEN_FACTORIES.get(description)?.toString() ??\n factory.toString()) !== factory.toString()\n ) {\n console.warn(\n _formatDevMessage(\n [\n 'trying to create an injection token with same description but different factory. ',\n 'The existing injection token will be used and this new factory will be ignored. ',\n 'This use case is a bit weird anyway. Ensure no duplicate injection tokens are created. ',\n ].join('\\n'),\n {\n module: MODULE_NAME,\n value: description,\n },\n ),\n )\n }\n INJECTION_TOKEN_FACTORIES.set(description, factory)\n }\n return injectionToken\n}\n","/**\n * Helper function to combine multiple options (objects).\n *\n * In case of specifying same options more than once, the latter one will take precedence.\n * Provide them sorted by ascendant priority. Less priority options first. Top priority options last.\n *\n * Can be used to combine options for:\n *\n * - {@link provideNgxMetaManager}\n *\n * @param options - Options to combine.\n *\n * @public\n */\nexport const withOptions = <T extends object>(...options: readonly T[]): T =>\n options.reduce<T>((acc, curr) => ({ ...acc, ...curr }), {} as T)\n","import { inject } from '@angular/core'\nimport { MetadataValues } from '../service'\nimport { _LazyInjectionToken, _makeInjectionToken } from '../utils'\n\nexport const defaults: _LazyInjectionToken<MetadataValues> = () =>\n _makeInjectionToken(ngDevMode ? 'Metadata defaults' : 'Defs')\n\nexport const injectDefaults = (): MetadataValues | null =>\n inject(defaults(), { optional: true })\n","import { MetadataValues } from '../service'\nimport {\n coreFeature,\n CoreFeature,\n CoreFeatureKind,\n} from '../providers/core-feature'\nimport { defaults as defaultsToken } from './defaults'\n\n/**\n * Sets up default metadata values.\n *\n * When setting metadata values for a page, default values will be used as\n * fallback when a metadata value isn't specified.\n *\n * @example\n *\n * <b>Using standalone, recommended API</b>\n * ```typescript\n * provideNgxMetaCore(\n * withNgxMetaDefaults({title: 'Default title'})\n * )\n * ```\n *\n * <b>Using module-based API</b>\n * ```typescript\n * NgxMetaCoreModule.forRoot(\n * withNgxMetaDefaults({title: 'Default title'})\n * )\n * ```\n *\n * See also:\n *\n * - {@link provideNgxMetaCore}: to use it with the standalone, recommended API.\n *\n * - {@link NgxMetaCoreModule.(forRoot:1)}: to use it with the module-based API.\n *\n * - {@link https://ngx-meta.dev/guides/defaults/ | Defaults guide}\n *\n * - {@link https://ngx-meta.dev/guides/metadata-values-json/ | Metadata values JSON guide}\n *\n * @param defaults - Default metadata values to use\n *\n * @public\n */\nexport const withNgxMetaDefaults = (\n defaults: MetadataValues,\n): CoreFeature<CoreFeatureKind.Defaults> =>\n coreFeature(CoreFeatureKind.Defaults, [\n { provide: defaultsToken(), useValue: defaults },\n ])\n","import { _LazyInjectionToken, _makeInjectionToken } from '../utils'\n\n/**\n * Formats page titles.\n *\n * The default is to provide the page title as is.\n *\n * @internal\n */\nexport const _titleFormatter: _LazyInjectionToken<TitleFormatter> = () =>\n _makeInjectionToken(\n ngDevMode ? 'Title formatter' : 'TF',\n () => (title) => title,\n )\n\n/**\n * Page title formatter function type\n *\n * @param titleFormatter - Title to format. The one specified in metadata values.\n * @returns Formatted title\n *\n * @beta\n */\nexport type TitleFormatter = (title: string) => string\n","import {\n coreFeature,\n CoreFeature,\n CoreFeatureKind,\n} from '../providers/core-feature'\nimport { _titleFormatter, TitleFormatter } from './title-formatter'\nimport { FactoryProvider } from '@angular/core'\n\n/**\n * Provides a page title formatter.\n *\n * The formatter will be called with the specified page title metadata.\n * Its output will be the value placed as the page's title by the metadata manager.\n * This way you can prepend or append your site name or brand to all page titles, for instance.\n *\n * Built-in metadata managers that use this formatter are:\n *\n * - {@link Standard.title}\n *\n * - {@link OpenGraph.title}\n *\n * - {@link TwitterCard.title}\n *\n * @example\n *\n * <b>Using standalone, recommended API</b>\n * ```typescript\n * provideNgxMetaCore(\n * withNgxMetaTitleFormatter((title) => `${title} - Site name`)\n * )\n * ```\n *\n * <b>Using module-based API</b>\n * ```typescript\n * NgxMetaCoreModule.forRoot(\n * withNgxMetaTitleFormatter((title) => `${title} - Site name`)\n * )\n * ```\n *\n * See also:\n *\n * - {@link provideNgxMetaCore}: to use it with the standalone, recommended API.\n *\n * - {@link NgxMetaCoreModule.(forRoot:1)}: to use it with the module-based API.\n *\n * - {@link https://ngx-meta.dev/guides/title-formatting/ | Title formatting guide}\n *\n *\n * @param titleFormatter - A function that takes the page title set in metadata values and returns the formatted title\n *\n * @beta\n */\nexport const withNgxMetaTitleFormatter = (\n titleFormatter: TitleFormatter,\n): CoreFeature<CoreFeatureKind.TitleFormatter> =>\n coreFeature(CoreFeatureKind.TitleFormatter, [\n {\n provide: _titleFormatter(),\n useFactory: () => titleFormatter,\n } satisfies FactoryProvider,\n ])\n","import { GlobalMetadataImage } from './global-metadata-image'\nimport { AngularRouterUrl } from '../url-resolution'\n\n/**\n * Specifies metadata that will be used by more than one module.\n *\n * @public\n */\nexport interface GlobalMetadata {\n /**\n * Sets title for:\n *\n * - {@link Standard.title} (needs standard module)\n *\n * - {@link OpenGraph.title} (needs Open Graph module)\n *\n * - {@link TwitterCard.title} (needs Twitter Cards module)\n *\n * Title will be formatted for all of them when\n * {@link https://ngx-meta.dev/guides/title-formatting | title formatting} is set up.\n */\n readonly title?: string\n\n /**\n * Sets description for:\n *\n * - {@link Standard.description} (needs standard module)\n *\n * - {@link OpenGraph.description} (needs Open Graph module)\n *\n * - {@link TwitterCard.description} (needs Twitter Cards module)\n */\n readonly description?: string | null\n\n /**\n * Sets application name for:\n *\n * - {@link Standard.applicationName} (needs standard module)\n *\n * - {@link OpenGraph.siteName} (needs Open Graph module)\n */\n readonly applicationName?: string | null\n\n /**\n * Sets canonical URL for:\n *\n * - {@link Standard.canonicalUrl} (needs standard module)\n *\n * - {@link OpenGraph.url} (needs Open Graph module)\n *\n * If {@link https://ngx-meta.dev/guides/url-resolution/ | URL resolution} feature is enabled, you may use\n * a relative URL here. It will be resolved and the absolute URL will be used instead.\n *\n * You can also use the special value {@link ANGULAR_ROUTER_URL} to use the current Angular router's URL\n * as the relative URL to be resolved into an absolute one.\n */\n readonly canonicalUrl?: URL | AngularRouterUrl | string | null\n\n /**\n * Sets localization of this page.\n *\n * Value must be a valid language tag complying with BCP 47.\n * For instance: \"`es`\" or \"`es-ES`\"\n *\n * For:\n *\n * - {@link Standard.locale} (needs standard module)\n *\n * - {@link OpenGraph.locale} (needs Open Graph module)\n *\n * @remarks\n *\n * See also:\n *\n * - {@link https://datatracker.ietf.org/doc/html/rfc5646 | RFC 5646 / BCP 47}\n */\n readonly locale?: string | null\n\n /**\n * {@inheritDoc GlobalMetadataImage}\n */\n readonly image?: GlobalMetadataImage | null\n}\n\n/**\n * @internal\n */\nexport const _GLOBAL_TITLE = 'title' satisfies keyof GlobalMetadata\n/**\n * @internal\n */\nexport const _GLOBAL_DESCRIPTION = 'description' satisfies keyof GlobalMetadata\n/**\n * @internal\n */\nexport const _GLOBAL_APPLICATION_NAME =\n 'applicationName' satisfies keyof GlobalMetadata\n/**\n * @internal\n */\nexport const _GLOBAL_CANONICAL_URL =\n 'canonicalUrl' satisfies keyof GlobalMetadata\n/**\n * @internal\n */\nexport const _GLOBAL_LOCALE = 'locale' satisfies keyof GlobalMetadata\n/**\n * @internal\n */\nexport const _GLOBAL_IMAGE = 'image' satisfies keyof GlobalMetadata\n","import { inject } from '@angular/core'\nimport { DOCUMENT } from '@angular/common'\nimport { _isDefined, _LazyInjectionToken, _makeInjectionToken } from '../utils'\n\n/**\n * @internal\n */\nexport const _headElementUpsertOrRemove: _LazyInjectionToken<\n _HeadElementUpsertOrRemove\n> = () =>\n _makeInjectionToken(\n ngDevMode ? 'Head element upsert or remove util' : 'HEUOR',\n () => {\n const head = inject(DOCUMENT).head\n return (selector, element) => {\n const existingScriptElement = head.querySelector(selector)\n if (existingScriptElement) {\n head.removeChild(existingScriptElement)\n }\n\n if (!_isDefined(element)) {\n return\n }\n head.appendChild(element)\n }\n },\n )\n\n/**\n * @internal\n */\nexport type _HeadElementUpsertOrRemove = (\n selector: string,\n element: HTMLElement | null | undefined,\n) => void\n","import { inject } from '@angular/core'\n\n/**\n * Abstract class every metadata manager must implement.\n *\n * Used as {@link https://angular.dev/guide/di/dependency-injection-providers#using-an-injectiontoken-object | injection token}\n * to provide metadata managers the library will take into account.\n *\n * @remarks\n *\n * See also:\n *\n * - {@link https://ngx-meta.dev/guides/manage-your-custom-metadata/ | Manage your custom metadata guide}\n *\n * - {@link makeMetadataManagerProviderFromSetterFactory} for a helper to create a metadata manager\n *\n * - {@link provideNgxMetaManager} for an experimental helper to create a metadata manager\n *\n * @typeParam Value - Value type that can be handled by the setter\n *\n * @public\n */\nexport abstract class NgxMetaMetadataManager<Value = unknown> {\n /**\n * Identifies the metadata manager.\n *\n * Used to avoid setting same metadata twice in case same two managers are\n * injected by mistake.\n */\n abstract readonly id: string\n /**\n * {@inheritDoc MetadataResolverOptions}\n */\n abstract readonly resolverOptions: MetadataResolverOptions\n /**\n * A function that alters a page's metadata with the provided value.\n */\n abstract readonly set: MetadataSetter<Value>\n}\n\n/**\n * @internal\n */\nexport const _injectMetadataManagers: () => readonly NgxMetaMetadataManager[] =\n () =>\n // https://stackoverflow.com/q/74598049/3263250\n (inject(NgxMetaMetadataManager, {\n optional: true,\n }) as readonly NgxMetaMetadataManager[] | null) ?? []\n\n/**\n * Options to resolve metadata values for a metadata manager\n *\n * Used in {@link NgxMetaMetadataManager.resolverOptions} with type {@link MetadataResolverOptions}\n *\n * @public\n */\nexport interface MetadataResolverOptions {\n /**\n * JSON path to use to access a metadata values JSON object when resolving a metadata value.\n *\n * @example\n * The following JSON path\n *\n * ```typescript\n * const jsonPath = `['foo', 'bar']`\n * ```\n *\n * When resolving the following sample metadata values JSON\n *\n * ```typescript\n * const metadataValues = {\n * foo: {\n * bar: 'fooBar'\n * }\n * }\n * ```\n *\n * Would access the `bar` key inside the `foo` object and resolve `fooBar` as metadata value\n */\n readonly jsonPath: readonly string[]\n\n /**\n * Global key in a metadata values object to use when resolving a metadata value.\n *\n * @example\n * The following global\n *\n * ```typescript\n * const global = 'foo'\n * ```\n *\n * When resolving the following sample metadata values JSON\n *\n * ```typescript\n * const metadataValues = {\n * foo: 'bar'\n * }\n * ```\n *\n * Would access the `foo` global key and resolve `bar` as metadata value\n *\n * Defaults to `undefined` (no global to be used for the metadata manager)\n */\n readonly global?: string\n\n /**\n * Enables merging the metadata value when it's an object and multiple values are found\n *\n * @example\n *\n * Given a metadata manager whose:\n *\n * - {@link MetadataResolverOptions.jsonPath} is `['foo', 'bar']`\n *\n * - {@link MetadataResolverOptions.global} is `bar`\n *\n * Then resolving the following metadata values:\n *\n * ```typescript\n * const metadataValues = {\n * bar: {a: 'a', b: 'b'},\n * foo: {\n * bar: { b: 'B', c: 'C'}\n * }\n * }\n * ```\n *\n * Would resolve to two objects (the JSON path one and the global one).\n *\n * If specifying both, specific JSON path one will take preference (as mentioned in the\n * {@link https://ngx-meta.dev/guides/metadata-values-json/#combining-both | metadata values JSON guide}).\n *\n * So it would resolve to `{ b: 'B', c: 'C' }`. However, when enabling object merging, both objects resolved\n * are merged (with specific one taking preference too). Therefore, final value resolved would be\n * `{ a: 'a', b: 'B', c: 'C' }`\n *\n * This merging also happens when objects are found during defaults and route values resolution.\n */\n readonly objectMerge?: boolean\n}\n\n/**\n * See {@link NgxMetaMetadataManager.set}\n *\n * @typeParam T - Value type the setter accepts as argument\n *\n * @public\n */\nexport type MetadataSetter<T> = (value: T) => void\n","import { Provider } from '@angular/core'\nimport {\n _injectMetadataManagers,\n NgxMetaMetadataManager,\n} from './ngx-meta-metadata-manager'\nimport { _LazyInjectionToken, _makeInjectionToken } from '../utils'\n\n/**\n * @internal\n */\nexport interface MetadataRegistry {\n readonly register: (manager: NgxMetaMetadataManager) => void\n readonly getAll: () => Iterable<NgxMetaMetadataManager>\n readonly findByGlobalOrJsonPath: (\n globalOrJsonPath: string,\n ) => Iterable<NgxMetaMetadataManager>\n}\n\nconst metadataRegistryFactory: () => MetadataRegistry = () => {\n const managers = _injectMetadataManagers()\n const managersById = new Map<string, NgxMetaMetadataManager>()\n const register: MetadataRegistry['register'] = (manager) => {\n /* istanbul ignore next https://github.com/istanbuljs/istanbuljs/issues/719 */\n if (managersById.has(manager.id)) {\n return\n }\n managersById.set(manager.id, manager)\n }\n managers.forEach(register)\n const getAll: MetadataRegistry['getAll'] = () => managersById.values()\n const findByGlobalOrJsonPath: MetadataRegistry['findByGlobalOrJsonPath'] = (\n globalOrJsonPath,\n ) =>\n [...getAll()].filter(\n (manager) =>\n manager.resolverOptions.global == globalOrJsonPath ||\n manager.resolverOptions.jsonPath.join('.') == globalOrJsonPath,\n )\n return {\n register,\n getAll,\n findByGlobalOrJsonPath,\n }\n}\n\nexport const metadataRegistry: _LazyInjectionToken<MetadataRegistry> = () =>\n _makeInjectionToken(\n ngDevMode ? 'Metadata Registry' : 'MReg',\n metadataRegistryFactory,\n )\n\nexport const provideMetadataRegistry: () => Provider = () => ({\n provide: metadataRegistry(),\n useFactory: metadataRegistryFactory,\n})\n","import { ENVIRONMENT_INITIALIZER, inject, Provider } from '@angular/core'\nimport {\n metadataRegistry,\n provideMetadataRegistry,\n} from '../managers/metadata-registry'\n\n/**\n * Allows to load metadata managers after library has been initialized.\n *\n * @remarks\n *\n * This is the standalone, recommended API. Using this API is preferred.\n * However, you may also use {@link NgxMetaMetadataLoaderModule} as the Angular module-based equivalent API.\n *\n * @public\n */\nexport const provideNgxMetaMetadataLoader = (): Provider => [\n provideMetadataRegistry(),\n {\n provide: ENVIRONMENT_INITIALIZER,\n multi: true,\n useFactory: () => {\n const globalRegistry = inject(metadataRegistry(), { skipSelf: true })\n const localRegistry = inject(metadataRegistry())\n return () => {\n const localMetadata = localRegistry.getAll()\n for (const metadata of localMetadata) {\n globalRegistry.register(metadata)\n }\n }\n },\n },\n]\n","import { NgModule } from '@angular/core'\nimport { provideNgxMetaMetadataLoader } from './provide-ngx-meta-metadata-loader'\n\n/**\n * Allows to load metadata managers after library has been initialized.\n *\n * Check out {@link provideNgxMetaMetadataLoader} for the standalone, recommended API.\n *\n * @public\n */\n@NgModule({\n providers: [provideNgxMetaMetadataLoader()],\n})\nexport class NgxMetaMetadataLoaderModule {}\n","// noinspection JSDeprecatedSymbols\n\nimport {\n MetadataResolverOptions,\n NgxMetaMetadataManager,\n} from '../../ngx-meta-metadata-manager'\nimport { FactoryProvider } from '@angular/core'\nimport { MetadataSetterFactory } from '../metadata-setter-factory'\n\n/**\n * Creates an Angular {@link https://angular.dev/guide/di/dependency-injection-providers#factory-providers-usefactory | factory provider}\n * providing an {@link NgxMetaMetadataManager}.\n *\n * See {@link https://ngx-meta.dev/guides/manage-your-custom-metadata/ | manage custom metadata guide} for an example.\n *\n * @deprecated Use {@link provideNgxMetaManager} APIs instead.\n * See {@link https://ngx-meta.dev/migrations/02-manager-provider-apis/ } for more information.\n *\n * @remarks\n *\n * Factory providers are used for built-in modules instead of Angular services.\n * Reason is that code created by `@Injectable` decorator takes many bytes,\n * whereas a call to this function creating a factory provider takes fewer.\n *\n * See {@link https://github.com/davidlj95/ngx/issues/112}\n *\n * @param setterFactory - Function that creates a {@link NgxMetaMetadataManager} given some dependencies\n * @param opts - Options to create the factory\n * @public\n */\n/* istanbul ignore next - unused. was covered when used */\nexport const makeMetadataManagerProviderFromSetterFactory = <T>(\n setterFactory: MetadataSetterFactory<T>,\n opts: MakeMetadataManagerProviderFromSetterFactoryOptions,\n): FactoryProvider => {\n const deps = opts.d ?? []\n return {\n provide: NgxMetaMetadataManager,\n multi: true,\n useFactory: (...deps: unknown[]) => ({\n id: opts.id ?? opts.jP.join('.'),\n resolverOptions: {\n jsonPath: opts.jP,\n global: opts.g,\n objectMerge: opts.m,\n },\n set: setterFactory(...deps),\n }),\n deps,\n }\n}\n\n/**\n * Options argument object for {@link makeMetadataManagerProviderFromSetterFactory}.\n *\n * @deprecated Use {@link provideNgxMetaManager} APIs instead.\n * See {@link https://ngx-meta.dev/migrations/02-manager-provider-apis/ } for more information.\n *\n * @public\n */\nexport interface MakeMetadataManagerProviderFromSetterFactoryOptions {\n /**\n * Dependencies to inject to the setter factory.\n *\n * See also:\n *\n * - {@link https://angular.dev/guide/di/dependency-injection-providers#factory-providers-usefactory:~:text=property%20is%20an%20array%20of%20provider%20tokens | Factory providers' deps}\n *\n * - {@link https://angular.dev/api/core/FactoryProvider#deps | FactoryProvider#deps}\n *\n * Defaults to no dependencies\n */\n d?: FactoryProvider['deps']\n /**\n * Metadata manager identifier\n *\n * See {@link NgxMetaMetadataManager.id}\n *\n * Defaults to the JSON path joined by dots (`['standard', 'title'] => 'standard.title'`)\n */\n id?: string\n /**\n * See {@link MetadataResolverOptions.jsonPath}\n */\n jP: MetadataResolverOptions['jsonPath']\n /**\n * See {@link MetadataResolverOptions.global}\n */\n g?: MetadataResolverOptions['global']\n /**\n * See {@link MetadataResolverOptions.objectMerge}\n */\n m?: MetadataResolverOptions['objectMerge']\n}\n","import { FactoryProvider, Provider } from '@angular/core'\nimport {\n MetadataResolverOptions,\n NgxMetaMetadataManager,\n} from '../../ngx-meta-metadata-manager'\nimport { GlobalMetadata } from '../../../globals'\nimport { MetadataSetterFactory } from '../metadata-setter-factory'\nimport { StringKeyOf } from '../../../utils/string-key-of'\n\n/**\n * Creates an {@link NgxMetaMetadataManager} provider to manage some metadata.\n *\n * Check out {@link https://ngx-meta.dev/guides/manage-your-custom-metadata/ | manage your custom metadata guide} to\n * learn how to provide your custom metadata managers.\n *\n * @remarks\n *\n * Options can be specified using helper functions. {@link withOptions} can be used to combine more than one.\n *\n * Available option functions:\n *\n * - {@link withManagerDeps}\n *\n * - {@link withManagerGlobal}\n *\n * - {@link withManagerObjectMerging}\n *\n * @example\n *\n * ```typescript\n * const CUSTOM_TITLE_PROVIDER = provideNgxMetaManager<string | undefined>(\n * 'custom.title',\n * (metaElementsService: NgxMetaElementsService) => (value) => {\n * metaElementsService.set(\n * withNameAttribute('custom:title'),\n * withContentAttribute(value),\n * )\n * },\n * withOptions(\n * withManagerDeps(NgxMetaElementsService),\n * withGlobal('title'),\n * ),\n * )\n * ```\n *\n * @param jsonPath - Path to access the metadata value this manager needs given a JSON object\n * containing metadata values. Path is expressed as the keys to use to access the value\n * joined by a \".\" character.\n * You can use {@link withManagerJsonPath} to provide an array of keys instead.\n * For more information, checkout {@link MetadataResolverOptions.jsonPath}\n * @param setterFactory - Factory function that creates the {@link MetadataSetter} function for the manager (which\n * manages the metadata element on the page).\n * You can inject dependencies either using {@link withManagerDeps} option, that will be passed\n * as arguments to the setter factory function. This way is preferred, as takes fewer bytes of\n * your bundle size. However, type safety depends on you.\n * Or use {@link https://angular.dev/api/core/inject | Angular's `inject` function} for a more\n * type-safe option.\n * @param options - Extra options for the metadata manager provider creation. Use one of the helpers listed in this\n * method's reference docs to supply one or more of them.\n * @public\n */\nexport const provideNgxMetaManager = <T>(\n jsonPath: string,\n setterFactory: MetadataSetterFactory<T>,\n /* istanbul ignore next - quite simple */\n options: _ProvideNgxMetaManagerOptions = {},\n): Provider =>\n ({\n provide: NgxMetaMetadataManager,\n multi: true,\n useFactory: (...deps: readonly unknown[]) =>\n ({\n id: jsonPath,\n set: setterFactory(...deps),\n resolverOptions: {\n jsonPath: jsonPath.split('.'),\n global: options.g,\n objectMerge: options.o,\n },\n }) satisfies NgxMetaMetadataManager<T>,\n deps: options.d,\n }) satisfies FactoryProvider\n\n/**\n * @internal\n */\nexport type _ProvideNgxMetaManagerOptions = Partial<{\n d: FactoryProvider['deps']\n g: MetadataResolverOptions['global']\n i: NgxMetaMetadataManager['id']\n o: MetadataResolverOptions['objectMerge']\n}>\n\n/**\n * Specifies dependencies to inject to the setter factory function passed to {@link provideNgxMetaManager}\n *\n * See also:\n *\n * - {@link https://angular.dev/guide/di/dependency-injection-providers#factory-providers-usefactory:~:text=property%20is%20an%20array%20of%20provider%20tokens | Factory providers' deps}\n *\n * - {@link https://angular.dev/api/core/FactoryProvider#deps | FactoryProvider#deps}\n *\n * @param deps - Dependencies to inject. Each argument declares the dependency to inject.\n *\n * @public\n */\nexport const withManagerDeps = (\n ...deps: Exclude<FactoryProvider['deps'], undefined>\n): _ProvideNgxMetaManagerOptions => ({\n d: deps,\n})\n\n/**\n * Sets the global key to use for a metadata manager created with {@link provideNgxMetaManager}\n *\n * @param global - See {@link MetadataResolverOptions.global}\n *\n * @public\n */\nexport const withManagerGlobal = <G extends string = keyof GlobalMetadata>(\n global: G,\n): _ProvideNgxMetaManagerOptions => ({ g: global })\n\n/**\n * Enables object merging for the manager being created with {@link provideNgxMetaManager}\n *\n * See {@link MetadataResolverOptions.objectMerge} for more information.\n *\n * @public\n */\nexport const withManagerObjectMerging = (): _ProvideNgxMetaManagerOptions => ({\n o: true,\n})\n\n/**\n * Transforms a JSON Path specified as an array of keys into a string joined by dots.\n *\n * Useful to use with {@link provideNgxMetaManager} to avoid repeating same keys around.\n *\n * @remarks\n *\n * You can specify a type to ensure the keys are valid. See example below.\n *\n * Beware that specifying a type won't work if:\n *\n * The type refers other types and more than 2 levels are specified:\n *\n * ```typescript\n * interface CustomMetadata { custom: Custom }\n * interface Custom { moar: Moar }\n *\n * // 👇❌ Reports incorrect Typescript error about `never` type\n * withManagerJsonPath<CustomMetadata>('custom', 'moar', 'foo')\n * ```\n *\n * More than 3 keys are specified:\n *\n * ```typescript\n * interface CustomMetadata {\n * custom: {\n * moar: {\n * moarThanMoar: {\n * foo: string\n * }\n * }\n * }\n * }\n *\n * // 👇❌ Reports incorrect Typescript error about `never` type\n * withManagerJsonPath<CustomMetadata>('custom', 'moar', 'moarThanMoar', 'foo') //\n * ```\n *\n * Omit the type to skip type checking and its limitations:\n *\n * ```typescript\n * withManagerJsonPath('whatever', 'untyped', 'keys')\n * ```\n *\n * @example\n *\n * ```typescript\n * interface CustomMetadata {\n * custom: {\n * title: string\n * }\n * }\n *\n * withManagerJsonPath<CustomMetadata>('custom','title') // ✅ No error. IDE helps you auto-complete.\n * withManagerJsonPath<CustomMetadata>('custom','not-a-prop') // ❌ Typescript error\n * withManagerJsonPath('no', 'type', 'checks')\n * ```\n *\n * @param jsonPath - Parts of the JSON Path to join into a string.\n *\n * @public\n */\nexport const withManagerJsonPath: WithManagerJsonPath = (\n ...jsonPath: MetadataResolverOptions['jsonPath']\n) => jsonPath.join('.')\n\n/**\n * @internal\n */\ninterface WithManagerJsonPath {\n <T extends object>(key1: StringKeyOf<T>): string\n <T extends object>(\n key1: StringKeyOf<T>,\n key2: StringKeyOf<T[typeof key1]>,\n ): string\n <T extends object>(\n key1: StringKeyOf<T>,\n key2: StringKeyOf<T[typeof key1]>,\n key3: StringKeyOf<T[typeof key1][typeof key2]>,\n ): string\n (...jsonPaths: readonly string[]): string\n}\n","// noinspection JSDeprecatedSymbols\n\nimport { MetaDefinition } from '@angular/platform-browser'\nimport { NgxMetaMetaDefinition } from './ngx-meta-meta-definition'\n\n/**\n * Creates a {@link NgxMetaMetaDefinition} for its use with {@link NgxMetaMetaService}\n * by understanding `<meta>` elements as key / value pair elements.\n *\n * @remarks\n *\n * One can think about some `<meta>` elements as key / value pairs.\n *\n * For instance `<meta name='description' content='Lorem ipsum'>` would\n * actually be a key / value pair meta where\n * - `description` is the key\n * - `Lorem ipsum` is the value\n * - `name` is the key's HTML attribute name\n * - `content`is the value's HTML attribute name\n *\n * Value is set by {@link NgxMetaMetaService.set} by providing this model and an\n * actual value\n *\n * @deprecated Use {@link NgxMetaElementsService} APIs instead.\n * See {@link https://ngx-meta.dev/migrations/01-meta-element-apis | migration guide} for more info\n *\n * @param keyName - Name of the key in the key/value meta definition\n * @param options - Specifies HTML attribute names and extras of the definition if any\n *\n * @public\n */\nexport const makeKeyValMetaDefinition = (\n keyName: string,\n /* istanbul ignore next - quite simple */\n options: MakeKeyValMetaDefinitionOptions = {},\n): NgxMetaMetaDefinition => {\n /* istanbul ignore next - quite simple */\n const keyAttr = options.keyAttr ?? 'name'\n /* istanbul ignore next - quite simple */\n const valAttr = options.valAttr ?? 'content'\n return {\n withContent: (value) => ({\n [keyAttr]: keyName,\n [valAttr]: value,\n ...options.extras,\n }),\n attrSelector: `${keyAttr}='${keyName}'`,\n }\n}\n\n/**\n * Options argument object for {@link makeKeyValMetaDefinition}\n *\n * @deprecated Use {@link NgxMetaElementsService} APIs instead.\n * See {@link https://ngx-meta.dev/migrations/01-meta-element-apis | migration guide} for more info\n *\n * @public\n */\nexport interface MakeKeyValMetaDefinitionOptions {\n /**\n * Name of the `<meta>` attribute that will hold the key\n *\n * Default value is `name`\n */\n keyAttr?: string\n /**\n * Name of the `<meta>` attribute that will hold the value\n *\n * Default value is `content`\n */\n valAttr?: string\n /**\n * Extra contents for the meta definition\n *\n * Default value is `undefined`\n */\n extras?: MetaDefinition\n}\n","// noinspection JSDeprecatedSymbols\n\nimport {\n makeKeyValMetaDefinition,\n MakeKeyValMetaDefinitionOptions,\n} from './make-key-val-meta-definition'\nimport { NgxMetaMetaDefinition } from './ngx-meta-meta-definition'\n\n/**\n * Creates a key / value meta definition ({@link NgxMetaMetaDefinition})\n * where the key name is composed by several strings joined by a separator.\n *\n * See also {@link makeKeyValMetaDefinition}\n *\n * @example\n * For instance, Open Graph's meta definition for property `og:title` (hence\n * element `<meta property='og:title'>`) is composed of `og` and `title`.\n * Its {@link NgxMetaMetaDefinition} could be created with:\n *\n * ```typescript\n * const ogTitleMetaDefinition = makeComposedKeyValMetaDefinition(\n * ['og', 'title'],\n * {\n * keyAttr: 'property',\n * separator: ':', // Could be omitted, as it's the default one\n * }\n * )\n * ```\n *\n * @deprecated Use {@link NgxMetaElementsService} APIs instead.\n * See {@link https://ngx-meta.dev/migrations/01-meta-element-apis | migration guide} for more info\n *\n * @param names - Names to create they key name\n * @param options - Options object\n * @public\n */\n/* istanbul ignore next - quite simple */\nexport const makeComposedKeyValMetaDefinition = (\n names: readonly string[],\n options: MakeComposedKeyValMetaDefinitionOptions = {},\n): NgxMetaMetaDefinition =>\n makeKeyValMetaDefinition(names.join(options.separator ?? ':'), options)\n\n/**\n * Options argument object for {@link makeComposedKeyValMetaDefinition}\n *\n * @deprecated Use {@link NgxMetaElementsService} APIs instead.\n * See {@link https://ngx-meta.dev/migrations/01-meta-element-apis | migration guide} for more info\n *\n * @public\n */\nexport interface MakeComposedKeyValMetaDefinitionOptions\n extends MakeKeyValMetaDefinitionOptions {\n /**\n * Character to use to join key strings\n *\n * Default value is `:`\n */\n separator?: string\n}\n","// noinspection JSDeprecatedSymbols\n\nimport { Injectable } from '@angular/core'\nimport { Meta } from '@angular/platform-browser'\nimport { NgxMetaMetaDefinition } from './ngx-meta-meta-definition'\nimport { NgxMetaMetaContent } from './ngx-meta-meta-content'\n\n/**\n * Creates, updates or removes `<meta>` elements.\n *\n * Uses Angular {@link https://angular.dev/api/platform-browser/Meta | Meta} APIs under the hood.\n *\n * @deprecated Use {@link NgxMetaElementsService} APIs instead.\n * See {@link https://ngx-meta.dev/migrations/01-meta-element-apis | migration guide} for more info\n *\n * @public\n */\n@Injectable({ providedIn: 'root' })\nexport class NgxMetaMetaService {\n constructor(private readonly meta: Meta) {}\n\n /**\n * Creates, updates or removes a specific `<meta>` element.\n *\n * The element is modeled using a {@link NgxMetaMetaDefinition} object.\n *\n * The element is created with the provided content. If no content is given, element is removed.\n *\n * @deprecated Use {@link NgxMetaElementsService} APIs instead.\n * See {@link https://ngx-meta.dev/migrations/01-meta-element-apis | migration guide} for more info\n *\n * @param definition - `<meta>` element to create, update or remove\n * @param content - Content value to create or update the `<meta>` element.\n * Use `null` or `undefined` to remove the element from the page.\n */\n set(definition: NgxMetaMetaDefinition, content: NgxMetaMetaContent) {\n switch (content) {\n case undefined:\n case null:\n this.meta.removeTag(definition.attrSelector)\n return\n default:\n this.meta.updateTag(definition.withContent(content))\n }\n }\n}\n","import { NgxMetaElementAttributes } from './ngx-meta-element-attributes'\nimport { Meta } from '@angular/platform-browser'\nimport { Injectable } from '@angular/core'\nimport { NgxMetaElementNameAttribute } from './ngx-meta-element-name-attribute'\n\n/**\n * Manages `<meta>` elements inside `<head>`\n *\n * @public\n */\n@Injectable({ providedIn: 'root' })\nexport class NgxMetaElementsService {\n constructor(private meta: Meta) {}\n\n /**\n * Creates, updates or removes some kind of `<meta>` elements inside `<head>` in a declarative fashion.\n *\n * Kind of `<meta>` elements to manage are identified by an HTML attribute providing its metadata name.\n * For instance, to manage description metadata elements (`<meta name=\"description\">`) on the page, the\n * `name` attribute with `description` value identifies them.\n *\n * Then, contents for those can be specified. In the shape of a key/value JSON object declaring each element's\n * additional attributes. Mainly `content` named attributes. See {@link NgxMetaElementAttributes}.\n * If no contents are provided, all `<meta>` elements of that kind will be removed.\n * An array of contents may be given to create multiple `<meta>` elements with same kind.\n *\n * @example\n * <b>Setting `<meta name=\"description\" content=\"Cool page\"/>`</b>\n *\n * ```typescript\n * ngxMetaElementsService.set(\n * withNameAttribute('description'), // same as `['name','description']`\n * withContent('Cool page'), // same as `{content:'Cool page'}`\n * )\n * ```\n *\n * Utility functions {@link withNameAttribute} and {@link withContentAttribute} help creating the\n * name attribute identifying the kind of meta elements and the contents to provide for it.\n *\n * {@link withContentAttribute} helps to create the attributes key / value object.\n *\n * <b>Removing any `<meta name=\"description\"/>` existing elements</b>\n *\n * ```typescript\n * ngxMetaElementsService.set(\n * withNameAttribute('description'), // same as `['name','description']`\n * undefined, // same as `withContent(undefined)`\n * )\n * ```\n *\n * <b>Setting many `<meta name=\"theme-color\"/>` elements</b>\n *\n * ```typescript\n * ngxMetaElementsService.set(\n * withNameAttribute('theme-color'), // same as `['name','theme-color']`\n * [\n * withContent('darkblue', { media: \"(prefers-color-scheme: dark)\" }),\n * withContent('lightblue') // same as `{content:'lightblue'}`\n * ]\n * )\n * ```\n *\n * <b>Removing any `<meta name=\"theme-color\"/>` existing elements</b>\n *\n * ```typescript\n * ngxMetaElementsService.set(\n * withNameAttribute('theme-color'), // same as `['name','theme-color']`\n * [], // `undefined` is valid too\n * )\n * ```\n *\n * Attribute name helpers:\n *\n * - {@link withNameAttribute}\n *\n * - {@link withPropertyAttribute}\n *\n * Content helpers:\n *\n * - {@link withContentAttribute}\n *\n * @param nameAttribute - Attribute use to identify which kind of `<meta>` elements to manage.\n * As an array with the attribute name in first position and attribute value in second one.\n * Utility functions exist to generate arrays for common name attributes.\n * See {@link withNameAttribute} and {@link withPropertyAttribute} helpers to create those\n * arrays without repeating attribute names around.\n *\n * @param content - Content(s) attributes to set for this `<meta>` elements kind.\n * Or the lack of them to remove all `<meta>` elements of this kind.\n * See {@link withContentAttribute} helper for creating content objects.\n */\n set(\n nameAttribute: NgxMetaElementNameAttribute,\n content:\n | readonly NgxMetaElementAttributes[]\n | NgxMetaElementAttributes\n | undefined,\n ): void {\n const [nameAttributeName, nameAttributeValue] = nameAttribute\n const attrSelector = `${nameAttributeName}=\"${nameAttributeValue}\"`\n this.meta.getTags(attrSelector).forEach((tag) => tag.remove())\n /* istanbul ignore next https://github.com/istanbuljs/istanbuljs/issues/719 */\n if (!content) {\n return\n }\n const contents = (Array.isArray as isContentsArray)(content)\n ? content\n : [content]\n this.meta.addTags(\n contents.map((content) => ({\n [nameAttributeName]: nameAttributeValue,\n ...content,\n })),\n )\n }\n}\n\ntype isContentsArray = (\n contentOrContents:\n | readonly NgxMetaElementAttributes[]\n | NgxMetaElementAttributes,\n) => contentOrContents is readonly NgxMetaElementAttributes[]\n","/**\n * Creates an attribute name/value identifying a `<meta name=\"{value}\">` element kind.\n *\n * See {@link NgxMetaElementsService.set}.\n *\n * @param value - Value for the `name` attribute of the `<meta>` element\n *\n * @public\n */\nexport const withNameAttribute = (value: string) => ['name', value] as const\n","/**\n * Creates an attribute name/value identifying a `<meta property=\"{value}\">` element kind.\n *\n * See {@link NgxMetaElementsService.set}.\n *\n * @param value - Value for the `property` attribute of the `<meta>` element\n *\n * @public\n */\nexport const withPropertyAttribute = (value: string) =>\n ['property', value] as const\n","import { NgxMetaElementAttributes } from './ngx-meta-element-attributes'\n\n/**\n * Creates an {@link NgxMetaElementAttributes} object specifying the `content` attribute to the\n * given `value`. Plus optional `extras`.\n *\n * Unless given `value` is `null` or `undefined`. In that case, `undefined` is returned.\n *\n * See {@link NgxMetaElementsService.set}\n *\n * @param content - Value for the `property` attribute of the `<meta>` element\n * @param extras - Extra attributes to include in the object if `content` is defined.\n *\n * @public\n */\nexport const withContentAttribute = ((\n content: string | null | undefined,\n extras?: NgxMetaElementAttributes,\n) => (content ? { content, ...extras } : undefined)) as {\n (content: null | undefined, extras?: NgxMetaElementAttributes): undefined\n (content: string, extras?: NgxMetaElementAttributes): NgxMetaElementAttributes\n (\n content: string | null | undefined,\n extras?: NgxMetaElementAttributes,\n ): NgxMetaElementAttributes | undefined\n}\n","/**\n * @internal\n */\nexport const _composedMetadataName = (...names: readonly string[]) =>\n names.join(':')\n","import {\n _ProvideNgxMetaManagerOptions,\n provideNgxMetaManager,\n withManagerDeps,\n withManagerGlobal,\n withManagerJsonPath,\n} from './provide-ngx-meta-manager'\nimport {\n NgxMetaElementNameAttribute,\n NgxMetaElementsService,\n withContentAttribute,\n withNameAttribute,\n} from '../../../meta-elements'\nimport { MetadataSetterFactory } from '../metadata-setter-factory'\nimport { withOptions } from '../../../utils'\nimport { StringKeyOf } from '../../../utils/string-key-of'\n\n/**\n * @internal\n */\nexport const _provideNgxMetaModuleManager = <\n Type extends object,\n Key extends StringKeyOf<Type>,\n>(\n key: Key,\n scope: readonly string[],\n options: _ProvideNgxMetaModuleManagerOptions<Type[Key]>,\n) =>\n provideNgxMetaManager(\n withManagerJsonPath(...scope, key),\n options.f ??\n ((metaElementsService: NgxMetaElementsService) => (value) =>\n metaElementsService.set(\n options.n ?? withNameAttribute(key),\n withContentAttribute(value as string | null | undefined),\n )),\n withOptions(\n withManagerDeps(options.d ?? [NgxMetaElementsService]),\n options.k ? withManagerGlobal(key) : {},\n options,\n ),\n )\n\n/**\n * @internal\n */\nexport type _ProvideNgxMetaModuleManagerOptions<T> = Partial<{\n f: MetadataSetterFactory<T>\n n: NgxMetaElementNameAttribute\n k: true\n}> &\n _ProvideNgxMetaManagerOptions\n\n/**\n * @internal\n */\nexport const _withModuleManagerSetterFactory = <T>(\n setterFactory: _ProvideNgxMetaModuleManagerOptions<T>['f'],\n): _ProvideNgxMetaModuleManagerOptions<T> => ({\n f: setterFactory,\n})\n\n/**\n * @internal\n */\nexport const _withModuleManagerNameAttribute = <T>(\n nameAttribute: _ProvideNgxMetaModuleManagerOptions<T>['n'],\n): _ProvideNgxMetaModuleManagerOptions<T> => ({\n n: nameAttribute,\n})\n\n/**\n * @internal\n */\nexport const _withModuleManagerSameGlobalKey = <\n T,\n>(): _ProvideNgxMetaModuleManagerOptions<T> => ({\n k: true,\n})\n","import { EnvironmentProviders, makeEnvironmentProviders } from '@angular/core'\nimport { CoreFeatures, providersFromCoreFeatures } from './core-feature'\n\n/**\n * Provides `ngx-meta`'s core library services.\n *\n