diff --git a/.bazelrc b/.bazelrc new file mode 100644 index 0000000000..9fb7a90afe --- /dev/null +++ b/.bazelrc @@ -0,0 +1,10 @@ +# Print all the options that apply to the build. +# This helps us diagnose which options override others +# (e.g. /etc/bazel.bazelrc vs. tools/bazel.rc) +build --announce_rc + +# More details on failures +build --verbose_failures=true + +# CI supports colors but Bazel does not detect it. +common --color=yes diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000000..86dd5ef968 --- /dev/null +++ b/.prettierignore @@ -0,0 +1,4 @@ +*.md + +origin + diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000000..dc2fb828f0 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,3 @@ +{ + "singleQuote": true +} \ No newline at end of file diff --git a/adev-ja/_headers b/adev-ja/_headers new file mode 100644 index 0000000000..279a4600c9 --- /dev/null +++ b/adev-ja/_headers @@ -0,0 +1,7 @@ +# Headers for Cloudflare Pages +# https://developers.cloudflare.com/pages/configuration/headers/ + +# Enable site isolation for all resources +/* + Cross-Origin-Embedder-Policy: require-corp + Cross-Origin-Opener-Policy: same-origin diff --git a/adev-ja/src/app/sub-navigation-data.en.ts b/adev-ja/src/app/sub-navigation-data.en.ts new file mode 100644 index 0000000000..896057d6e5 --- /dev/null +++ b/adev-ja/src/app/sub-navigation-data.en.ts @@ -0,0 +1,1569 @@ +/*! + * @license + * Copyright Google LLC All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.dev/license + */ + +import {NavigationItem} from '@angular/docs'; + +// These 2 imports are expected to be red because they are generated a build time +import FIRST_APP_TUTORIAL_NAV_DATA from '../../src/assets/tutorials/first-app/routes.json'; +import LEARN_ANGULAR_TUTORIAL_NAV_DATA from '../../src/assets/tutorials/learn-angular/routes.json'; + +import {DefaultPage} from './core/enums/pages'; +import {getApiNavigationItems} from './features/references/helpers/manifest.helper'; + +interface SubNavigationData { + docs: NavigationItem[]; + reference: NavigationItem[]; + tutorials: NavigationItem[]; + footer: NavigationItem[]; +} + +const DOCS_SUB_NAVIGATION_DATA: NavigationItem[] = [ + { + label: 'Introduction', + children: [ + { + label: 'What is Angular?', + path: 'overview', + contentPath: 'introduction/what-is-angular', + }, + { + label: 'Essentials', + children: [ + { + label: 'Overview', + path: 'essentials', + contentPath: 'introduction/essentials/overview', + }, + { + label: 'Composing with Components', + path: 'essentials/components', + contentPath: 'introduction/essentials/components', + }, + { + label: 'Managing Dynamic Data', + path: 'essentials/managing-dynamic-data', + contentPath: 'introduction/essentials/managing-dynamic-data', + }, + { + label: 'Rendering Dynamic Templates', + path: 'essentials/rendering-dynamic-templates', + contentPath: 'introduction/essentials/rendering-dynamic-templates', + }, + { + label: 'Conditionals and Loops', + path: 'essentials/conditionals-and-loops', + contentPath: 'introduction/essentials/conditionals-and-loops', + }, + { + label: 'Handling User Interaction', + path: 'essentials/handling-user-interaction', + contentPath: 'introduction/essentials/handling-user-interaction', + }, + { + label: 'Sharing Logic', + path: 'essentials/sharing-logic', + contentPath: 'introduction/essentials/sharing-logic', + }, + { + label: 'Next Steps', + path: 'essentials/next-steps', + contentPath: 'introduction/essentials/next-steps', + }, + ], + }, + { + label: 'Start coding! 🚀', + path: 'tutorials/learn-angular', + }, + ], + }, + { + label: 'In-depth Guides', + children: [ + { + label: 'Components', + children: [ + { + label: 'Anatomy of components', + path: 'guide/components', + contentPath: 'guide/components/anatomy-of-components', + }, + { + label: 'Importing and using components', + path: 'guide/components/importing', + contentPath: 'guide/components/importing', + }, + { + label: 'Selectors', + path: 'guide/components/selectors', + contentPath: 'guide/components/selectors', + }, + { + label: 'Styling', + path: 'guide/components/styling', + contentPath: 'guide/components/styling', + }, + { + label: 'Accepting data with input properties', + path: 'guide/components/inputs', + contentPath: 'guide/components/inputs', + }, + { + label: 'Custom events with outputs', + path: 'guide/components/outputs', + contentPath: 'guide/components/outputs', + }, + { + label: 'output() function', + path: 'guide/components/output-fn', + contentPath: 'guide/components/output-function', + }, + { + label: 'Content projection with ng-content', + path: 'guide/components/content-projection', + contentPath: 'guide/components/content-projection', + }, + { + label: 'Host elements', + path: 'guide/components/host-elements', + contentPath: 'guide/components/host-elements', + }, + { + label: 'Lifecycle', + path: 'guide/components/lifecycle', + contentPath: 'guide/components/lifecycle', + }, + { + label: 'Referencing component children with queries', + path: 'guide/components/queries', + contentPath: 'guide/components/queries', + }, + { + label: 'Using DOM APIs', + path: 'guide/components/dom-apis', + contentPath: 'guide/components/dom-apis', + }, + { + label: 'Inheritance', + path: 'guide/components/inheritance', + contentPath: 'guide/components/inheritance', + }, + { + label: 'Programmatically rendering components', + path: 'guide/components/programmatic-rendering', + contentPath: 'guide/components/programmatic-rendering', + }, + { + label: 'Advanced configuration', + path: 'guide/components/advanced-configuration', + contentPath: 'guide/components/advanced-configuration', + }, + { + label: 'Custom Elements', + path: 'guide/elements', + contentPath: 'guide/elements', + }, + ], + }, + { + label: 'Template Syntax', + children: [ + { + label: 'Overview', + path: 'guide/templates', + contentPath: 'guide/templates/overview', + }, + { + label: 'Text interpolation', + path: 'guide/templates/interpolation', + contentPath: 'guide/templates/interpolation', + }, + { + label: 'Template statements', + path: 'guide/templates/template-statements', + contentPath: 'guide/templates/template-statements', + }, + { + label: 'Understanding binding', + path: 'guide/templates/binding', + contentPath: 'guide/templates/binding', + }, + { + label: 'Property binding', + path: 'guide/templates/property-binding', + contentPath: 'guide/templates/property-binding', + }, + { + label: 'Property binding best practices', + path: 'guide/templates/property-binding-best-practices', + contentPath: 'guide/templates/property-binding-best-practices', + }, + { + label: 'Attribute binding', + path: 'guide/templates/attribute-binding', + contentPath: 'guide/templates/attribute-binding', + }, + { + label: 'Class and style binding', + path: 'guide/templates/class-binding', + contentPath: 'guide/templates/class-binding', + }, + { + label: 'Event binding', + path: 'guide/templates/event-binding', + contentPath: 'guide/templates/event-binding', + }, + { + label: 'Two-way binding', + path: 'guide/templates/two-way-binding', + contentPath: 'guide/templates/two-way-binding', + }, + { + label: 'Control flow', + path: 'guide/templates/control-flow', + contentPath: 'guide/templates/control-flow', + }, + { + label: 'Local template variables with @let', + path: 'guide/templates/let-template-variables', + contentPath: 'guide/templates/let-template-variables', + }, + { + label: 'Pipes', + children: [ + { + label: 'Overview', + path: 'guide/pipes', + contentPath: 'guide/pipes/overview', + }, + { + label: 'Using a pipe in a template', + path: 'guide/pipes/template', + contentPath: 'guide/pipes/template', + }, + { + label: 'Custom pipes', + path: 'guide/pipes/transform-data', + contentPath: 'guide/pipes/transform-data', + }, + { + label: 'Pipe precedence in expressions', + path: 'guide/pipes/precedence', + contentPath: 'guide/pipes/precedence', + }, + { + label: 'Change detection with pipes', + path: 'guide/pipes/change-detection', + contentPath: 'guide/pipes/change-detection', + }, + { + label: 'Unwrapping data from an observable', + path: 'guide/pipes/unwrapping-data-observables', + contentPath: 'guide/pipes/unwrapping-data-observables', + }, + ], + }, + { + label: 'Template reference variables', + path: 'guide/templates/reference-variables', + contentPath: 'guide/templates/reference-variables', + }, + { + label: 'SVG as templates', + path: 'guide/templates/svg-in-templates', + contentPath: 'guide/templates/svg-in-templates', + }, + ], + }, + { + label: 'Directives', + children: [ + { + label: 'Overview', + path: 'guide/directives', + contentPath: 'guide/directives/overview', + }, + { + label: 'Attribute directives', + path: 'guide/directives/attribute-directives', + contentPath: 'guide/directives/attribute-directives', + }, + { + label: 'Structural directives', + path: 'guide/directives/structural-directives', + contentPath: 'guide/directives/structural-directives', + }, + { + label: 'Directive composition API', + path: 'guide/directives/directive-composition-api', + contentPath: 'guide/directives/directive-composition-api', + }, + ], + }, + { + label: 'Dependency Injection', + children: [ + { + label: 'Overview', + path: 'guide/di', + contentPath: 'guide/di/overview', + }, + { + label: 'Understanding dependency injection', + path: 'guide/di/dependency-injection', + contentPath: 'guide/di/dependency-injection', + }, + { + label: 'Creating an injectable service', + path: 'guide/di/creating-injectable-service', + contentPath: 'guide/di/creating-injectable-service', + }, + { + label: 'Defining dependency providers', + path: 'guide/di/dependency-injection-providers', + contentPath: 'guide/di/dependency-injection-providers', + }, + { + label: 'Injection context', + path: 'guide/di/dependency-injection-context', + contentPath: 'guide/di/dependency-injection-context', + }, + { + label: 'Hierarchical injectors', + path: 'guide/di/hierarchical-dependency-injection', + contentPath: 'guide/di/hierarchical-dependency-injection', + }, + { + label: 'Optimizing injection tokens', + path: 'guide/di/lightweight-injection-tokens', + contentPath: 'guide/di/lightweight-injection-tokens', + }, + { + label: 'DI in action', + path: 'guide/di/di-in-action', + contentPath: 'guide/di/di-in-action', + }, + ], + }, + { + label: 'Signals', + children: [ + { + label: 'Overview', + path: 'guide/signals', + contentPath: 'guide/signals/overview', + }, + { + label: 'RxJS Interop', + path: 'guide/signals/rxjs-interop', + contentPath: 'guide/signals/rxjs-interop', + }, + { + label: 'Inputs as signals', + path: 'guide/signals/inputs', + contentPath: 'guide/signals/inputs', + }, + { + label: 'Model inputs', + path: 'guide/signals/model', + contentPath: 'guide/signals/model', + }, + { + label: 'Queries as signals', + path: 'guide/signals/queries', + contentPath: 'guide/signals/queries', + }, + ], + }, + { + label: 'Routing', + children: [ + { + label: 'Overview', + path: 'guide/routing', + contentPath: 'guide/routing/overview', + }, + { + label: 'Common routing tasks', + path: 'guide/routing/common-router-tasks', + contentPath: 'guide/routing/common-router-tasks', + }, + { + label: 'Routing in single-page applications', + path: 'guide/routing/router-tutorial', + contentPath: 'guide/routing/router-tutorial', + }, + { + label: 'Creating custom route matches', + path: 'guide/routing/routing-with-urlmatcher', + contentPath: 'guide/routing/routing-with-urlmatcher', + }, + { + label: 'Router reference', + path: 'guide/routing/router-reference', + contentPath: 'guide/routing/router-reference', + }, + ], + }, + { + label: 'Forms', + children: [ + { + label: 'Overview', + path: 'guide/forms', + contentPath: 'guide/forms/overview', + }, + { + label: 'Reactive forms', + path: 'guide/forms/reactive-forms', + contentPath: 'guide/forms/reactive-forms', + }, + { + label: 'Strictly typed reactive forms', + path: 'guide/forms/typed-forms', + contentPath: 'guide/forms/typed-forms', + }, + { + label: 'Template-driven forms', + path: 'guide/forms/template-driven-forms', + contentPath: 'guide/forms/template-driven-forms', + }, + { + label: 'Validate form input', + path: 'guide/forms/form-validation', + contentPath: 'guide/forms/form-validation', + }, + { + label: 'Building dynamic forms', + path: 'guide/forms/dynamic-forms', + contentPath: 'guide/forms/dynamic-forms', + }, + ], + }, + { + label: 'HTTP Client', + children: [ + { + label: 'Overview', + path: 'guide/http', + contentPath: 'guide/http/overview', + }, + { + label: 'Setting up HttpClient', + path: 'guide/http/setup', + contentPath: 'guide/http/setup', + }, + { + label: 'Making requests', + path: 'guide/http/making-requests', + contentPath: 'guide/http/making-requests', + }, + { + label: 'Intercepting requests and responses', + path: 'guide/http/interceptors', + contentPath: 'guide/http/interceptors', + }, + { + label: 'Testing', + path: 'guide/http/testing', + contentPath: 'guide/http/testing', + }, + ], + }, + { + label: 'Performance', + children: [ + { + label: 'Deferrable views', + path: 'guide/defer', + contentPath: 'guide/defer', + }, + { + label: 'Image Optimization', + path: 'guide/image-optimization', + contentPath: 'guide/image-optimization', + }, + { + label: 'Server-side Rendering', + path: 'guide/ssr', + contentPath: 'guide/ssr', + }, + { + label: 'Build-time prerendering', + path: 'guide/prerendering', + contentPath: 'guide/prerendering', + }, + { + label: 'Hydration', + path: 'guide/hydration', + contentPath: 'guide/hydration', + }, + ], + }, + { + label: 'Testing', + children: [ + { + label: 'Overview', + path: 'guide/testing', + contentPath: 'guide/testing/overview', + }, + { + label: 'Code coverage', + path: 'guide/testing/code-coverage', + contentPath: 'guide/testing/code-coverage', + }, + { + label: 'Testing services', + path: 'guide/testing/services', + contentPath: 'guide/testing/services', + }, + { + label: 'Basics of testing components', + path: 'guide/testing/components-basics', + contentPath: 'guide/testing/components-basics', + }, + { + label: 'Component testing scenarios', + path: 'guide/testing/components-scenarios', + contentPath: 'guide/testing/components-scenarios', + }, + { + label: 'Testing attribute directives', + path: 'guide/testing/attribute-directives', + contentPath: 'guide/testing/attribute-directives', + }, + { + label: 'Testing pipes', + path: 'guide/testing/pipes', + contentPath: 'guide/testing/pipes', + }, + { + label: 'Debugging tests', + path: 'guide/testing/debugging', + contentPath: 'guide/testing/debugging', + }, + { + label: 'Testing utility APIs', + path: 'guide/testing/utility-apis', + contentPath: 'guide/testing/utility-apis', + }, + ], + }, + { + label: 'Internationalization', + children: [ + { + label: 'Overview', + path: 'guide/i18n', + contentPath: 'guide/i18n/overview', + }, + { + label: 'Add the localize package', + path: 'guide/i18n/add-package', + contentPath: 'guide/i18n/add-package', + }, + { + label: 'Refer to locales by ID', + path: 'guide/i18n/locale-id', + contentPath: 'guide/i18n/locale-id', + }, + { + label: 'Format data based on locale', + path: 'guide/i18n/format-data-locale', + contentPath: 'guide/i18n/format-data-locale', + }, + { + label: 'Prepare component for translation', + path: 'guide/i18n/prepare', + contentPath: 'guide/i18n/prepare', + }, + { + label: 'Work with translation files', + path: 'guide/i18n/translation-files', + contentPath: 'guide/i18n/translation-files', + }, + { + label: 'Merge translations into the app', + path: 'guide/i18n/merge', + contentPath: 'guide/i18n/merge', + }, + { + label: 'Deploy multiple locales', + path: 'guide/i18n/deploy', + contentPath: 'guide/i18n/deploy', + }, + { + label: 'Import global variants of the locale data', + path: 'guide/i18n/import-global-variants', + contentPath: 'guide/i18n/import-global-variants', + }, + { + label: 'Manage marked text with custom IDs', + path: 'guide/i18n/manage-marked-text', + contentPath: 'guide/i18n/manage-marked-text', + }, + { + label: 'Example Angular application', + path: 'guide/i18n/example', + contentPath: 'guide/i18n/example', + }, + ], + }, + { + label: 'Animations', + children: [ + { + label: 'Overview', + path: 'guide/animations', + contentPath: 'guide/animations/overview', + }, + { + label: 'Transition and Triggers', + path: 'guide/animations/transition-and-triggers', + contentPath: 'guide/animations/transition-and-triggers', + }, + { + label: 'Complex Sequences', + path: 'guide/animations/complex-sequences', + contentPath: 'guide/animations/complex-sequences', + }, + { + label: 'Reusable Animations', + path: 'guide/animations/reusable-animations', + contentPath: 'guide/animations/reusable-animations', + }, + { + label: 'Route transition animations', + path: 'guide/animations/route-animations', + contentPath: 'guide/animations/route-animations', + }, + ], + }, + { + label: 'Experimental features', + children: [ + {label: 'Zoneless', path: 'guide/experimental/zoneless', contentPath: 'guide/zoneless'}, + ], + }, + ], + }, + { + label: 'Developer Tools', + children: [ + { + label: 'Angular CLI', + children: [ + { + label: 'Overview', + path: 'tools/cli', + contentPath: 'tools/cli/overview', + }, + { + label: 'Local set-up', + path: 'tools/cli/setup-local', + contentPath: 'tools/cli/setup-local', + }, + { + label: 'Building Angular apps', + path: 'tools/cli/build', + contentPath: 'tools/cli/build', + }, + { + label: 'Serving Angular apps for development', + path: 'tools/cli/serve', + contentPath: 'tools/cli/serve', + }, + { + label: 'Deployment', + path: 'tools/cli/deployment', + contentPath: 'tools/cli/deployment', + }, + { + label: 'End-to-End Testing', + path: 'tools/cli/end-to-end', + contentPath: 'tools/cli/end-to-end', + }, + { + label: 'Migrating to new build system', + path: 'tools/cli/build-system-migration', + contentPath: 'tools/cli/build-system-migration', + }, + { + label: 'Build environments', + path: 'tools/cli/environments', + contentPath: 'tools/cli/environments', + }, + { + label: 'Angular CLI builders', + path: 'tools/cli/cli-builder', + contentPath: 'tools/cli/cli-builder', + }, + { + label: 'Generating code using schematics', + path: 'tools/cli/schematics', + contentPath: 'tools/cli/schematics', + }, + { + label: 'Authoring schematics', + path: 'tools/cli/schematics-authoring', + contentPath: 'tools/cli/schematics-authoring', + }, + { + label: 'Schematics for libraries', + path: 'tools/cli/schematics-for-libraries', + contentPath: 'tools/cli/schematics-for-libraries', + }, + { + label: 'Template type checking', + path: 'tools/cli/template-typecheck', + contentPath: 'tools/cli/template-typecheck', + }, + { + label: 'Ahead-of-time (AOT) compilation', + path: 'tools/cli/aot-compiler', + contentPath: 'tools/cli/aot-compiler', + }, + { + label: 'AOT metadata errors', + path: 'tools/cli/aot-metadata-errors', + contentPath: 'tools/cli/aot-metadata-errors', + }, + ], + }, + { + label: 'Libraries', + children: [ + { + label: 'Overview', + path: 'tools/libraries', + contentPath: 'tools/libraries/overview', + }, + { + label: 'Creating Libraries', + path: 'tools/libraries/creating-libraries', + contentPath: 'tools/libraries/creating-libraries', + }, + { + label: 'Using Libraries', + path: 'tools/libraries/using-libraries', + contentPath: 'tools/libraries/using-libraries', + }, + { + label: 'Angular Package Format', + path: 'tools/libraries/angular-package-format', + contentPath: 'tools/libraries/angular-package-format', + }, + ], + }, + { + label: 'DevTools', + path: 'tools/devtools', + contentPath: 'tools/devtools', + }, + { + label: 'Language Service', + path: 'tools/language-service', + contentPath: 'tools/language-service', + }, + ], + }, + { + label: 'Best Practices', + children: [ + { + label: 'Style Guide', + path: 'style-guide', + contentPath: 'best-practices/style-guide', + }, + { + label: 'Security', + path: 'best-practices/security', + contentPath: 'guide/security', // Have not refactored due to build issues + }, + { + label: 'Accessibility', + path: 'best-practices/a11y', + contentPath: 'best-practices/a11y', + }, + { + label: 'Performance', + children: [ + { + label: 'Overview', + path: 'best-practices/runtime-performance', + contentPath: 'best-practices/runtime-performance/overview', + }, + { + label: 'Zone pollution', + path: 'best-practices/zone-pollution', + contentPath: 'best-practices/runtime-performance/zone-pollution', + }, + { + label: 'Slow computations', + path: 'best-practices/slow-computations', + contentPath: 'best-practices/runtime-performance/slow-computations', + }, + { + label: 'Skipping component subtrees', + path: 'best-practices/skipping-subtrees', + contentPath: 'best-practices/runtime-performance/skipping-subtrees', + }, + ], + }, + { + label: 'Keeping up-to-date', + path: 'update', + contentPath: 'best-practices/update', + }, + ], + }, + { + label: 'Extended Ecosystem', + children: [ + { + label: 'Service Workers & PWAs', + children: [ + { + label: 'Overview', + path: 'ecosystem/service-workers', + contentPath: 'ecosystem/service-workers/overview', + }, + { + label: 'Getting started', + path: 'ecosystem/service-workers/getting-started', + contentPath: 'ecosystem/service-workers/getting-started', + }, + { + label: 'Configuration file', + path: 'ecosystem/service-workers/config', + contentPath: 'ecosystem/service-workers/config', + }, + { + label: 'Communicating with the service worker', + path: 'ecosystem/service-workers/communications', + contentPath: 'ecosystem/service-workers/communications', + }, + { + label: 'Push notifications', + path: 'ecosystem/service-workers/push-notifications', + contentPath: 'ecosystem/service-workers/push-notifications', + }, + { + label: 'Service worker devops', + path: 'ecosystem/service-workers/devops', + contentPath: 'ecosystem/service-workers/devops', + }, + { + label: 'App shell pattern', + path: 'ecosystem/service-workers/app-shell', + contentPath: 'ecosystem/service-workers/app-shell', + }, + ], + }, + { + label: 'Web workers', + path: 'ecosystem/web-workers', + contentPath: 'ecosystem/web-workers', + }, + { + label: 'Angular Fire', + path: 'https://github.com/angular/angularfire#readme', + }, + { + label: 'Google Maps', + path: 'https://github.com/angular/components/tree/main/src/google-maps#readme', + }, + { + label: 'Google Pay', + path: 'https://github.com/google-pay/google-pay-button#angular', + }, + { + label: 'YouTube player', + path: 'https://github.com/angular/components/blob/main/src/youtube-player/README.md', + }, + { + label: 'Angular CDK', + path: 'https://material.angular.io/cdk/categories', + }, + { + label: 'Angular Material', + path: 'https://material.angular.io/', + }, + ], + }, +]; + +export const TUTORIALS_SUB_NAVIGATION_DATA: NavigationItem[] = [ + FIRST_APP_TUTORIAL_NAV_DATA, + LEARN_ANGULAR_TUTORIAL_NAV_DATA, + { + path: DefaultPage.TUTORIALS, + contentPath: 'tutorials/home', + label: 'Tutorials', + }, +]; + +const REFERENCE_SUB_NAVIGATION_DATA: NavigationItem[] = [ + { + label: 'Roadmap', + path: 'roadmap', + contentPath: 'reference/roadmap', + }, + { + label: 'Get involved', + path: 'https://github.com/angular/angular/blob/main/CONTRIBUTING.md', + }, + { + label: 'API Reference', + children: [ + { + label: 'Overview', + path: 'api', + }, + ...getApiNavigationItems(), + ], + }, + { + label: 'CLI Reference', + children: [ + { + label: 'Overview', + path: 'cli', + contentPath: 'reference/cli', + }, + { + label: 'ng add', + path: 'cli/add', + }, + { + label: 'ng analytics', + children: [ + { + label: 'Overview', + path: 'cli/analytics', + }, + { + label: 'disable', + path: 'cli/analytics/disable', + }, + { + label: 'enable', + path: 'cli/analytics/enable', + }, + { + label: 'info', + path: 'cli/analytics/info', + }, + { + label: 'prompt', + path: 'cli/analytics/prompt', + }, + ], + }, + { + label: 'ng build', + path: 'cli/build', + }, + { + label: 'ng cache', + children: [ + { + label: 'Overview', + path: 'cli/cache', + }, + { + label: 'clear', + path: 'cli/cache/clean', + }, + { + label: 'disable', + path: 'cli/cache/disable', + }, + { + label: 'enable', + path: 'cli/cache/enable', + }, + { + label: 'info', + path: 'cli/cache/info', + }, + ], + }, + { + label: 'ng completion', + children: [ + { + label: 'Overview', + path: 'cli/completion', + }, + { + label: 'script', + path: 'cli/completion/script', + }, + ], + }, + { + label: 'ng config', + path: 'cli/config', + }, + { + label: 'ng deploy', + path: 'cli/deploy', + }, + { + label: 'ng e2e', + path: 'cli/e2e', + }, + { + label: 'ng extract-i18n', + path: 'cli/extract-i18n', + }, + { + label: 'ng generate', + children: [ + { + label: 'Overview', + path: 'cli/generate', + }, + { + label: 'app-shell', + path: 'cli/generate/app-shell', + }, + { + label: 'application', + path: 'cli/generate/application', + }, + { + label: 'class', + path: 'cli/generate/class', + }, + { + label: 'component', + path: 'cli/generate/component', + }, + { + label: 'config', + path: 'cli/generate/config', + }, + { + label: 'directive', + path: 'cli/generate/directive', + }, + { + label: 'enum', + path: 'cli/generate/enum', + }, + { + label: 'environments', + path: 'cli/generate/environments', + }, + { + label: 'guard', + path: 'cli/generate/guard', + }, + { + label: 'interceptor', + path: 'cli/generate/interceptor', + }, + { + label: 'interface', + path: 'cli/generate/interface', + }, + { + label: 'library', + path: 'cli/generate/library', + }, + { + label: 'module', + path: 'cli/generate/module', + }, + { + label: 'pipe', + path: 'cli/generate/pipe', + }, + { + label: 'resolver', + path: 'cli/generate/resolver', + }, + { + label: 'service-worker', + path: 'cli/generate/service-worker', + }, + { + label: 'service', + path: 'cli/generate/service', + }, + { + label: 'web-worker', + path: 'cli/generate/web-worker', + }, + ], + }, + { + label: 'ng lint', + path: 'cli/lint', + }, + { + label: 'ng new', + path: 'cli/new', + }, + { + label: 'ng run', + path: 'cli/run', + }, + { + label: 'ng serve', + path: 'cli/serve', + }, + { + label: 'ng test', + path: 'cli/test', + }, + { + label: 'ng update', + path: 'cli/update', + }, + { + label: 'ng version', + path: 'cli/version', + }, + ], + }, + { + label: 'Error Encyclopedia', + children: [ + { + label: 'Overview', + path: 'errors', + contentPath: 'reference/errors/overview', + }, + { + label: 'NG0100: Expression Changed After Checked', + path: 'errors/NG0100', + contentPath: 'reference/errors/NG0100', + }, + { + label: 'NG01101: Wrong Async Validator Return Type', + path: 'errors/NG01101', + contentPath: 'reference/errors/NG01101', + }, + { + label: 'NG01203: Missing value accessor', + path: 'errors/NG01203', + contentPath: 'reference/errors/NG01203', + }, + { + label: 'NG0200: Circular Dependency in DI', + path: 'errors/NG0200', + contentPath: 'reference/errors/NG0200', + }, + { + label: 'NG0201: No Provider Found', + path: 'errors/NG0201', + contentPath: 'reference/errors/NG0201', + }, + { + label: 'NG0203: `inject()` must be called from an injection context', + path: 'errors/NG0203', + contentPath: 'reference/errors/NG0203', + }, + { + label: 'NG0209: Invalid multi provider', + path: 'errors/NG0209', + contentPath: 'reference/errors/NG0209', + }, + { + label: 'NG02200: Missing Iterable Differ', + path: 'errors/NG02200', + contentPath: 'reference/errors/NG02200', + }, + { + label: 'NG02800: JSONP support in HttpClient configuration', + path: 'errors/NG02800', + contentPath: 'reference/errors/NG02800', + }, + { + label: 'NG0300: Selector Collision', + path: 'errors/NG0300', + contentPath: 'reference/errors/NG0300', + }, + { + label: 'NG0301: Export Not Found', + path: 'errors/NG0301', + contentPath: 'reference/errors/NG0301', + }, + { + label: 'NG0302: Pipe Not Found', + path: 'errors/NG0302', + contentPath: 'reference/errors/NG0302', + }, + { + label: `NG0403: Bootstrapped NgModule doesn't specify which component to initialize`, + path: 'errors/NG0403', + contentPath: 'reference/errors/NG0403', + }, + { + label: 'NG0500: Hydration Node Mismatch', + path: 'errors/NG0500', + contentPath: 'reference/errors/NG0500', + }, + { + label: 'NG0501: Hydration Missing Siblings', + path: 'errors/NG0501', + contentPath: 'reference/errors/NG0501', + }, + { + label: 'NG0502: Hydration Missing Node', + path: 'errors/NG0502', + contentPath: 'reference/errors/NG0502', + }, + { + label: 'NG0503: Hydration Unsupported Projection of DOM Nodes', + path: 'errors/NG0503', + contentPath: 'reference/errors/NG0503', + }, + { + label: 'NG0504: Skip hydration flag is applied to an invalid node', + path: 'errors/NG0504', + contentPath: 'reference/errors/NG0504', + }, + { + label: 'NG0505: No hydration info in server response', + path: 'errors/NG0505', + contentPath: 'reference/errors/NG0505', + }, + { + label: 'NG0506: NgZone remains unstable', + path: 'errors/NG0506', + contentPath: 'reference/errors/NG0506', + }, + { + label: 'NG0507: HTML content was altered after server-side rendering', + path: 'errors/NG0507', + contentPath: 'reference/errors/NG0507', + }, + { + label: 'NG0602: HTML content was altered after server-side rendering', + path: 'errors/NG0602', + contentPath: 'reference/errors/NG0602', + }, + { + label: 'NG05104: Root element was not found', + path: 'errors/NG05104', + contentPath: 'reference/errors/NG05104', + }, + { + label: 'NG0910: Unsafe bindings on an iframe element', + path: 'errors/NG0910', + contentPath: 'reference/errors/NG0910', + }, + { + label: 'NG0912: Component ID generation collision', + path: 'errors/NG0912', + contentPath: 'reference/errors/NG0912', + }, + { + label: 'NG0913: Runtime Performance Warnings', + path: 'errors/NG0913', + contentPath: 'reference/errors/NG0913', + }, + { + label: 'NG0950: Required input is accessed before a value is set.', + path: 'errors/NG0950', + contentPath: 'reference/errors/NG0950', + }, + { + label: 'NG0951: Child query result is required but no value is available.', + path: 'errors/NG0951', + contentPath: 'reference/errors/NG0951', + }, + { + label: 'NG0955: Track expression resulted in duplicated keys for a given collection', + path: 'errors/NG0955', + contentPath: 'reference/errors/NG0955', + }, + { + label: 'NG0956: Tracking expression caused re-creation of the DOM structure', + path: 'errors/NG0956', + contentPath: 'reference/errors/NG0956', + }, + { + label: 'NG1001: Argument Not Literal', + path: 'errors/NG1001', + contentPath: 'reference/errors/NG1001', + }, + { + label: 'NG2003: Missing Token', + path: 'errors/NG2003', + contentPath: 'reference/errors/NG2003', + }, + { + label: 'NG2009: Invalid Shadow DOM selector', + path: 'errors/NG2009', + contentPath: 'reference/errors/NG2009', + }, + { + label: 'NG3003: Import Cycle Detected', + path: 'errors/NG3003', + contentPath: 'reference/errors/NG3003', + }, + { + label: 'NG05000: Hydration with unsupported Zone.js instance.', + path: 'errors/NG05000', + contentPath: 'reference/errors/NG05000', + }, + { + label: 'NG6100: NgModule.id Set to module.id anti-pattern', + path: 'errors/NG6100', + contentPath: 'reference/errors/NG6100', + }, + { + label: 'NG8001: Invalid Element', + path: 'errors/NG8001', + contentPath: 'reference/errors/NG8001', + }, + { + label: 'NG8002: Invalid Attribute', + path: 'errors/NG8002', + contentPath: 'reference/errors/NG8002', + }, + { + label: 'NG8003: Missing Reference Target', + path: 'errors/NG8003', + contentPath: 'reference/errors/NG8003', + }, + ], + }, + { + label: 'Extended Diagnostics', + children: [ + { + label: 'Overview', + path: 'extended-diagnostics', + contentPath: 'reference/extended-diagnostics/overview', + }, + { + label: 'NG8101: Invalid Banana-in-Box', + path: 'extended-diagnostics/NG8101', + contentPath: 'reference/extended-diagnostics/NG8101', + }, + { + label: 'NG8102: Nullish coalescing not nullable', + path: 'extended-diagnostics/NG8102', + contentPath: 'reference/extended-diagnostics/NG8102', + }, + { + label: 'NG8103: Missing control flow directive', + path: 'extended-diagnostics/NG8103', + contentPath: 'reference/extended-diagnostics/NG8103', + }, + { + label: 'NG8104: Text attribute not binding', + path: 'extended-diagnostics/NG8104', + contentPath: 'reference/extended-diagnostics/NG8104', + }, + { + label: 'NG8105: Missing `let` keyword in an *ngFor expression', + path: 'extended-diagnostics/NG8105', + contentPath: 'reference/extended-diagnostics/NG8105', + }, + { + label: 'NG8106: Suffix not supported', + path: 'extended-diagnostics/NG8106', + contentPath: 'reference/extended-diagnostics/NG8106', + }, + { + label: 'NG8107: Optional chain not nullable', + path: 'extended-diagnostics/NG8107', + contentPath: 'reference/extended-diagnostics/NG8107', + }, + { + label: 'NG8108: ngSkipHydration should be a static attribute', + path: 'extended-diagnostics/NG8108', + contentPath: 'reference/extended-diagnostics/NG8108', + }, + { + label: 'NG8109: Signals must be invoked in template interpolations', + path: 'extended-diagnostics/NG8109', + contentPath: 'reference/extended-diagnostics/NG8109', + }, + { + label: 'NG8111: Functions must be invoked in event bindings', + path: 'extended-diagnostics/NG8111', + contentPath: 'reference/extended-diagnostics/NG8111', + }, + ], + }, + { + label: 'Versioning and releases', + path: 'reference/releases', + contentPath: 'reference/releases', + }, + { + label: 'Version compatibility', + path: 'reference/versions', + contentPath: 'reference/versions', + }, + { + label: 'Update guide', + path: 'update-guide', + }, + { + label: 'Configurations', + children: [ + { + label: 'File structure', + path: 'reference/configs/file-structure', + contentPath: 'reference/configs/file-structure', + }, + { + label: 'Workspace configuration', + path: 'reference/configs/workspace-config', + contentPath: 'reference/configs/workspace-config', + }, + { + label: 'Angular compiler options', + path: 'reference/configs/angular-compiler-options', + contentPath: 'reference/configs/angular-compiler-options', + }, + { + label: 'npm dependencies', + path: 'reference/configs/npm-packages', + contentPath: 'reference/configs/npm-packages', + }, + ], + }, + { + label: 'Migrations', + children: [ + { + label: 'Overview', + path: 'reference/migrations', + contentPath: 'reference/migrations/overview', + }, + { + label: 'Standalone', + path: 'reference/migrations/standalone', + contentPath: 'reference/migrations/standalone', + }, + { + label: 'ModuleWithProviders', + path: 'reference/migrations/module-with-providers', + contentPath: 'reference/migrations/module-with-providers', + }, + { + label: 'Typed Forms', + path: 'reference/migrations/typed-forms', + contentPath: 'reference/migrations/typed-forms', + }, + { + label: 'Control Flow Syntax', + path: 'reference/migrations/control-flow', + contentPath: 'reference/migrations/control-flow', + }, + ], + }, + { + label: 'Concepts', + children: [ + { + label: 'Overview', + path: 'reference/concepts', + contentPath: 'reference/concepts/overview', + }, + { + label: 'NgModule', + children: [ + { + label: 'Overview', + path: 'guide/ngmodules', + contentPath: 'guide/ngmodules/overview', + }, + { + label: 'JS Modules vs NgModules', + path: 'guide/ngmodules/vs-jsmodule', + contentPath: 'guide/ngmodules/vs-jsmodule', + }, + { + label: 'Launching your app with a root module', + path: 'guide/ngmodules/bootstrapping', + contentPath: 'guide/ngmodules/bootstrapping', + }, + { + label: 'Sharing NgModules', + path: 'guide/ngmodules/sharing', + contentPath: 'guide/ngmodules/sharing', + }, + { + label: 'Frequently used NgModules', + path: 'guide/ngmodules/frequent', + contentPath: 'guide/ngmodules/frequent', + }, + { + label: 'Feature modules', + path: 'guide/ngmodules/feature-modules', + contentPath: 'guide/ngmodules/feature-modules', + }, + { + label: 'Types of feature modules', + path: 'guide/ngmodules/module-types', + contentPath: 'guide/ngmodules/module-types', + }, + { + label: 'Providing dependencies', + path: 'guide/ngmodules/providers', + contentPath: 'guide/ngmodules/providers', + }, + { + label: 'Singleton services', + path: 'guide/ngmodules/singleton-services', + contentPath: 'guide/ngmodules/singleton-services', + }, + { + label: 'Lazy-loading feature modules', + path: 'guide/ngmodules/lazy-loading', + contentPath: 'guide/ngmodules/lazy-loading', + }, + { + label: 'NgModule API', + path: 'guide/ngmodules/api', + contentPath: 'guide/ngmodules/api', + }, + { + label: 'NgModule FAQs', + path: 'guide/ngmodules/faq', + contentPath: 'guide/ngmodules/faq', + }, + ], + }, + ], + }, +]; + +const FOOTER_NAVIGATION_DATA: NavigationItem[] = [ + { + label: 'Press Kit', + path: 'press-kit', + contentPath: 'reference/press-kit', + }, + { + label: 'License', + path: 'license', + contentPath: 'reference/license', + }, +]; + +// Docs navigation data structure, it's used to display structure in +// navigation-list component And build the routing table for content pages. +export const SUB_NAVIGATION_DATA: SubNavigationData = { + docs: DOCS_SUB_NAVIGATION_DATA, + reference: REFERENCE_SUB_NAVIGATION_DATA, + tutorials: TUTORIALS_SUB_NAVIGATION_DATA, + footer: FOOTER_NAVIGATION_DATA, +}; diff --git a/adev-ja/src/app/sub-navigation-data.ts b/adev-ja/src/app/sub-navigation-data.ts new file mode 100644 index 0000000000..80b9952ee3 --- /dev/null +++ b/adev-ja/src/app/sub-navigation-data.ts @@ -0,0 +1,1569 @@ +/*! + * @license + * Copyright Google LLC All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.dev/license + */ + +import {NavigationItem} from '@angular/docs'; + +// These 2 imports are expected to be red because they are generated a build time +import FIRST_APP_TUTORIAL_NAV_DATA from '../../src/assets/tutorials/first-app/routes.json'; +import LEARN_ANGULAR_TUTORIAL_NAV_DATA from '../../src/assets/tutorials/learn-angular/routes.json'; + +import {DefaultPage} from './core/enums/pages'; +import {getApiNavigationItems} from './features/references/helpers/manifest.helper'; + +interface SubNavigationData { + docs: NavigationItem[]; + reference: NavigationItem[]; + tutorials: NavigationItem[]; + footer: NavigationItem[]; +} + +const DOCS_SUB_NAVIGATION_DATA: NavigationItem[] = [ + { + label: '入門', + children: [ + { + label: 'Angularずは', + path: 'overview', + contentPath: 'introduction/what-is-angular', + }, + { + label: '基本芁玠', + children: [ + { + label: 'Overview', + path: 'essentials', + contentPath: 'introduction/essentials/overview', + }, + { + label: 'Composing with Components', + path: 'essentials/components', + contentPath: 'introduction/essentials/components', + }, + { + label: 'Managing Dynamic Data', + path: 'essentials/managing-dynamic-data', + contentPath: 'introduction/essentials/managing-dynamic-data', + }, + { + label: 'Rendering Dynamic Templates', + path: 'essentials/rendering-dynamic-templates', + contentPath: 'introduction/essentials/rendering-dynamic-templates', + }, + { + label: 'Conditionals and Loops', + path: 'essentials/conditionals-and-loops', + contentPath: 'introduction/essentials/conditionals-and-loops', + }, + { + label: 'Handling User Interaction', + path: 'essentials/handling-user-interaction', + contentPath: 'introduction/essentials/handling-user-interaction', + }, + { + label: 'Sharing Logic', + path: 'essentials/sharing-logic', + contentPath: 'introduction/essentials/sharing-logic', + }, + { + label: 'Next Steps', + path: 'essentials/next-steps', + contentPath: 'introduction/essentials/next-steps', + }, + ], + }, + { + label: '䜜っおみよう 🚀', + path: 'tutorials/learn-angular', + }, + ], + }, + { + label: 'In-depth Guides', + children: [ + { + label: 'Components', + children: [ + { + label: 'Anatomy of components', + path: 'guide/components', + contentPath: 'guide/components/anatomy-of-components', + }, + { + label: 'Importing and using components', + path: 'guide/components/importing', + contentPath: 'guide/components/importing', + }, + { + label: 'Selectors', + path: 'guide/components/selectors', + contentPath: 'guide/components/selectors', + }, + { + label: 'Styling', + path: 'guide/components/styling', + contentPath: 'guide/components/styling', + }, + { + label: 'Accepting data with input properties', + path: 'guide/components/inputs', + contentPath: 'guide/components/inputs', + }, + { + label: 'Custom events with outputs', + path: 'guide/components/outputs', + contentPath: 'guide/components/outputs', + }, + { + label: 'output() function', + path: 'guide/components/output-fn', + contentPath: 'guide/components/output-function', + }, + { + label: 'Content projection with ng-content', + path: 'guide/components/content-projection', + contentPath: 'guide/components/content-projection', + }, + { + label: 'Host elements', + path: 'guide/components/host-elements', + contentPath: 'guide/components/host-elements', + }, + { + label: 'Lifecycle', + path: 'guide/components/lifecycle', + contentPath: 'guide/components/lifecycle', + }, + { + label: 'Referencing component children with queries', + path: 'guide/components/queries', + contentPath: 'guide/components/queries', + }, + { + label: 'Using DOM APIs', + path: 'guide/components/dom-apis', + contentPath: 'guide/components/dom-apis', + }, + { + label: 'Inheritance', + path: 'guide/components/inheritance', + contentPath: 'guide/components/inheritance', + }, + { + label: 'Programmatically rendering components', + path: 'guide/components/programmatic-rendering', + contentPath: 'guide/components/programmatic-rendering', + }, + { + label: 'Advanced configuration', + path: 'guide/components/advanced-configuration', + contentPath: 'guide/components/advanced-configuration', + }, + { + label: 'Custom Elements', + path: 'guide/elements', + contentPath: 'guide/elements', + }, + ], + }, + { + label: 'Template Syntax', + children: [ + { + label: 'Overview', + path: 'guide/templates', + contentPath: 'guide/templates/overview', + }, + { + label: 'Text interpolation', + path: 'guide/templates/interpolation', + contentPath: 'guide/templates/interpolation', + }, + { + label: 'Template statements', + path: 'guide/templates/template-statements', + contentPath: 'guide/templates/template-statements', + }, + { + label: 'Understanding binding', + path: 'guide/templates/binding', + contentPath: 'guide/templates/binding', + }, + { + label: 'Property binding', + path: 'guide/templates/property-binding', + contentPath: 'guide/templates/property-binding', + }, + { + label: 'Property binding best practices', + path: 'guide/templates/property-binding-best-practices', + contentPath: 'guide/templates/property-binding-best-practices', + }, + { + label: 'Attribute binding', + path: 'guide/templates/attribute-binding', + contentPath: 'guide/templates/attribute-binding', + }, + { + label: 'Class and style binding', + path: 'guide/templates/class-binding', + contentPath: 'guide/templates/class-binding', + }, + { + label: 'Event binding', + path: 'guide/templates/event-binding', + contentPath: 'guide/templates/event-binding', + }, + { + label: 'Two-way binding', + path: 'guide/templates/two-way-binding', + contentPath: 'guide/templates/two-way-binding', + }, + { + label: 'Control flow', + path: 'guide/templates/control-flow', + contentPath: 'guide/templates/control-flow', + }, + { + label: 'Local template variables with @let', + path: 'guide/templates/let-template-variables', + contentPath: 'guide/templates/let-template-variables', + }, + { + label: 'Pipes', + children: [ + { + label: 'Overview', + path: 'guide/pipes', + contentPath: 'guide/pipes/overview', + }, + { + label: 'Using a pipe in a template', + path: 'guide/pipes/template', + contentPath: 'guide/pipes/template', + }, + { + label: 'Custom pipes', + path: 'guide/pipes/transform-data', + contentPath: 'guide/pipes/transform-data', + }, + { + label: 'Pipe precedence in expressions', + path: 'guide/pipes/precedence', + contentPath: 'guide/pipes/precedence', + }, + { + label: 'Change detection with pipes', + path: 'guide/pipes/change-detection', + contentPath: 'guide/pipes/change-detection', + }, + { + label: 'Unwrapping data from an observable', + path: 'guide/pipes/unwrapping-data-observables', + contentPath: 'guide/pipes/unwrapping-data-observables', + }, + ], + }, + { + label: 'Template reference variables', + path: 'guide/templates/reference-variables', + contentPath: 'guide/templates/reference-variables', + }, + { + label: 'SVG as templates', + path: 'guide/templates/svg-in-templates', + contentPath: 'guide/templates/svg-in-templates', + }, + ], + }, + { + label: 'Directives', + children: [ + { + label: 'Overview', + path: 'guide/directives', + contentPath: 'guide/directives/overview', + }, + { + label: 'Attribute directives', + path: 'guide/directives/attribute-directives', + contentPath: 'guide/directives/attribute-directives', + }, + { + label: 'Structural directives', + path: 'guide/directives/structural-directives', + contentPath: 'guide/directives/structural-directives', + }, + { + label: 'Directive composition API', + path: 'guide/directives/directive-composition-api', + contentPath: 'guide/directives/directive-composition-api', + }, + ], + }, + { + label: 'Dependency Injection', + children: [ + { + label: 'Overview', + path: 'guide/di', + contentPath: 'guide/di/overview', + }, + { + label: 'Understanding dependency injection', + path: 'guide/di/dependency-injection', + contentPath: 'guide/di/dependency-injection', + }, + { + label: 'Creating an injectable service', + path: 'guide/di/creating-injectable-service', + contentPath: 'guide/di/creating-injectable-service', + }, + { + label: 'Defining dependency providers', + path: 'guide/di/dependency-injection-providers', + contentPath: 'guide/di/dependency-injection-providers', + }, + { + label: 'Injection context', + path: 'guide/di/dependency-injection-context', + contentPath: 'guide/di/dependency-injection-context', + }, + { + label: 'Hierarchical injectors', + path: 'guide/di/hierarchical-dependency-injection', + contentPath: 'guide/di/hierarchical-dependency-injection', + }, + { + label: 'Optimizing injection tokens', + path: 'guide/di/lightweight-injection-tokens', + contentPath: 'guide/di/lightweight-injection-tokens', + }, + { + label: 'DI in action', + path: 'guide/di/di-in-action', + contentPath: 'guide/di/di-in-action', + }, + ], + }, + { + label: 'Signals', + children: [ + { + label: 'Overview', + path: 'guide/signals', + contentPath: 'guide/signals/overview', + }, + { + label: 'RxJS Interop', + path: 'guide/signals/rxjs-interop', + contentPath: 'guide/signals/rxjs-interop', + }, + { + label: 'Inputs as signals', + path: 'guide/signals/inputs', + contentPath: 'guide/signals/inputs', + }, + { + label: 'Model inputs', + path: 'guide/signals/model', + contentPath: 'guide/signals/model', + }, + { + label: 'Queries as signals', + path: 'guide/signals/queries', + contentPath: 'guide/signals/queries', + }, + ], + }, + { + label: 'Routing', + children: [ + { + label: 'Overview', + path: 'guide/routing', + contentPath: 'guide/routing/overview', + }, + { + label: 'Common routing tasks', + path: 'guide/routing/common-router-tasks', + contentPath: 'guide/routing/common-router-tasks', + }, + { + label: 'Routing in single-page applications', + path: 'guide/routing/router-tutorial', + contentPath: 'guide/routing/router-tutorial', + }, + { + label: 'Creating custom route matches', + path: 'guide/routing/routing-with-urlmatcher', + contentPath: 'guide/routing/routing-with-urlmatcher', + }, + { + label: 'Router reference', + path: 'guide/routing/router-reference', + contentPath: 'guide/routing/router-reference', + }, + ], + }, + { + label: 'Forms', + children: [ + { + label: 'Overview', + path: 'guide/forms', + contentPath: 'guide/forms/overview', + }, + { + label: 'Reactive forms', + path: 'guide/forms/reactive-forms', + contentPath: 'guide/forms/reactive-forms', + }, + { + label: 'Strictly typed reactive forms', + path: 'guide/forms/typed-forms', + contentPath: 'guide/forms/typed-forms', + }, + { + label: 'Template-driven forms', + path: 'guide/forms/template-driven-forms', + contentPath: 'guide/forms/template-driven-forms', + }, + { + label: 'Validate form input', + path: 'guide/forms/form-validation', + contentPath: 'guide/forms/form-validation', + }, + { + label: 'Building dynamic forms', + path: 'guide/forms/dynamic-forms', + contentPath: 'guide/forms/dynamic-forms', + }, + ], + }, + { + label: 'HTTP Client', + children: [ + { + label: 'Overview', + path: 'guide/http', + contentPath: 'guide/http/overview', + }, + { + label: 'Setting up HttpClient', + path: 'guide/http/setup', + contentPath: 'guide/http/setup', + }, + { + label: 'Making requests', + path: 'guide/http/making-requests', + contentPath: 'guide/http/making-requests', + }, + { + label: 'Intercepting requests and responses', + path: 'guide/http/interceptors', + contentPath: 'guide/http/interceptors', + }, + { + label: 'Testing', + path: 'guide/http/testing', + contentPath: 'guide/http/testing', + }, + ], + }, + { + label: 'Performance', + children: [ + { + label: 'Deferrable views', + path: 'guide/defer', + contentPath: 'guide/defer', + }, + { + label: 'Image Optimization', + path: 'guide/image-optimization', + contentPath: 'guide/image-optimization', + }, + { + label: 'Server-side Rendering', + path: 'guide/ssr', + contentPath: 'guide/ssr', + }, + { + label: 'Build-time prerendering', + path: 'guide/prerendering', + contentPath: 'guide/prerendering', + }, + { + label: 'Hydration', + path: 'guide/hydration', + contentPath: 'guide/hydration', + }, + ], + }, + { + label: 'Testing', + children: [ + { + label: 'Overview', + path: 'guide/testing', + contentPath: 'guide/testing/overview', + }, + { + label: 'Code coverage', + path: 'guide/testing/code-coverage', + contentPath: 'guide/testing/code-coverage', + }, + { + label: 'Testing services', + path: 'guide/testing/services', + contentPath: 'guide/testing/services', + }, + { + label: 'Basics of testing components', + path: 'guide/testing/components-basics', + contentPath: 'guide/testing/components-basics', + }, + { + label: 'Component testing scenarios', + path: 'guide/testing/components-scenarios', + contentPath: 'guide/testing/components-scenarios', + }, + { + label: 'Testing attribute directives', + path: 'guide/testing/attribute-directives', + contentPath: 'guide/testing/attribute-directives', + }, + { + label: 'Testing pipes', + path: 'guide/testing/pipes', + contentPath: 'guide/testing/pipes', + }, + { + label: 'Debugging tests', + path: 'guide/testing/debugging', + contentPath: 'guide/testing/debugging', + }, + { + label: 'Testing utility APIs', + path: 'guide/testing/utility-apis', + contentPath: 'guide/testing/utility-apis', + }, + ], + }, + { + label: 'Internationalization', + children: [ + { + label: 'Overview', + path: 'guide/i18n', + contentPath: 'guide/i18n/overview', + }, + { + label: 'Add the localize package', + path: 'guide/i18n/add-package', + contentPath: 'guide/i18n/add-package', + }, + { + label: 'Refer to locales by ID', + path: 'guide/i18n/locale-id', + contentPath: 'guide/i18n/locale-id', + }, + { + label: 'Format data based on locale', + path: 'guide/i18n/format-data-locale', + contentPath: 'guide/i18n/format-data-locale', + }, + { + label: 'Prepare component for translation', + path: 'guide/i18n/prepare', + contentPath: 'guide/i18n/prepare', + }, + { + label: 'Work with translation files', + path: 'guide/i18n/translation-files', + contentPath: 'guide/i18n/translation-files', + }, + { + label: 'Merge translations into the app', + path: 'guide/i18n/merge', + contentPath: 'guide/i18n/merge', + }, + { + label: 'Deploy multiple locales', + path: 'guide/i18n/deploy', + contentPath: 'guide/i18n/deploy', + }, + { + label: 'Import global variants of the locale data', + path: 'guide/i18n/import-global-variants', + contentPath: 'guide/i18n/import-global-variants', + }, + { + label: 'Manage marked text with custom IDs', + path: 'guide/i18n/manage-marked-text', + contentPath: 'guide/i18n/manage-marked-text', + }, + { + label: 'Example Angular application', + path: 'guide/i18n/example', + contentPath: 'guide/i18n/example', + }, + ], + }, + { + label: 'Animations', + children: [ + { + label: 'Overview', + path: 'guide/animations', + contentPath: 'guide/animations/overview', + }, + { + label: 'Transition and Triggers', + path: 'guide/animations/transition-and-triggers', + contentPath: 'guide/animations/transition-and-triggers', + }, + { + label: 'Complex Sequences', + path: 'guide/animations/complex-sequences', + contentPath: 'guide/animations/complex-sequences', + }, + { + label: 'Reusable Animations', + path: 'guide/animations/reusable-animations', + contentPath: 'guide/animations/reusable-animations', + }, + { + label: 'Route transition animations', + path: 'guide/animations/route-animations', + contentPath: 'guide/animations/route-animations', + }, + ], + }, + { + label: 'Experimental features', + children: [ + {label: 'Zoneless', path: 'guide/experimental/zoneless', contentPath: 'guide/zoneless'}, + ], + }, + ], + }, + { + label: 'Developer Tools', + children: [ + { + label: 'Angular CLI', + children: [ + { + label: 'Overview', + path: 'tools/cli', + contentPath: 'tools/cli/overview', + }, + { + label: 'Local set-up', + path: 'tools/cli/setup-local', + contentPath: 'tools/cli/setup-local', + }, + { + label: 'Building Angular apps', + path: 'tools/cli/build', + contentPath: 'tools/cli/build', + }, + { + label: 'Serving Angular apps for development', + path: 'tools/cli/serve', + contentPath: 'tools/cli/serve', + }, + { + label: 'Deployment', + path: 'tools/cli/deployment', + contentPath: 'tools/cli/deployment', + }, + { + label: 'End-to-End Testing', + path: 'tools/cli/end-to-end', + contentPath: 'tools/cli/end-to-end', + }, + { + label: 'Migrating to new build system', + path: 'tools/cli/build-system-migration', + contentPath: 'tools/cli/build-system-migration', + }, + { + label: 'Build environments', + path: 'tools/cli/environments', + contentPath: 'tools/cli/environments', + }, + { + label: 'Angular CLI builders', + path: 'tools/cli/cli-builder', + contentPath: 'tools/cli/cli-builder', + }, + { + label: 'Generating code using schematics', + path: 'tools/cli/schematics', + contentPath: 'tools/cli/schematics', + }, + { + label: 'Authoring schematics', + path: 'tools/cli/schematics-authoring', + contentPath: 'tools/cli/schematics-authoring', + }, + { + label: 'Schematics for libraries', + path: 'tools/cli/schematics-for-libraries', + contentPath: 'tools/cli/schematics-for-libraries', + }, + { + label: 'Template type checking', + path: 'tools/cli/template-typecheck', + contentPath: 'tools/cli/template-typecheck', + }, + { + label: 'Ahead-of-time (AOT) compilation', + path: 'tools/cli/aot-compiler', + contentPath: 'tools/cli/aot-compiler', + }, + { + label: 'AOT metadata errors', + path: 'tools/cli/aot-metadata-errors', + contentPath: 'tools/cli/aot-metadata-errors', + }, + ], + }, + { + label: 'Libraries', + children: [ + { + label: 'Overview', + path: 'tools/libraries', + contentPath: 'tools/libraries/overview', + }, + { + label: 'Creating Libraries', + path: 'tools/libraries/creating-libraries', + contentPath: 'tools/libraries/creating-libraries', + }, + { + label: 'Using Libraries', + path: 'tools/libraries/using-libraries', + contentPath: 'tools/libraries/using-libraries', + }, + { + label: 'Angular Package Format', + path: 'tools/libraries/angular-package-format', + contentPath: 'tools/libraries/angular-package-format', + }, + ], + }, + { + label: 'DevTools', + path: 'tools/devtools', + contentPath: 'tools/devtools', + }, + { + label: 'Language Service', + path: 'tools/language-service', + contentPath: 'tools/language-service', + }, + ], + }, + { + label: 'Best Practices', + children: [ + { + label: 'Style Guide', + path: 'style-guide', + contentPath: 'best-practices/style-guide', + }, + { + label: 'Security', + path: 'best-practices/security', + contentPath: 'guide/security', // Have not refactored due to build issues + }, + { + label: 'Accessibility', + path: 'best-practices/a11y', + contentPath: 'best-practices/a11y', + }, + { + label: 'Performance', + children: [ + { + label: 'Overview', + path: 'best-practices/runtime-performance', + contentPath: 'best-practices/runtime-performance/overview', + }, + { + label: 'Zone pollution', + path: 'best-practices/zone-pollution', + contentPath: 'best-practices/runtime-performance/zone-pollution', + }, + { + label: 'Slow computations', + path: 'best-practices/slow-computations', + contentPath: 'best-practices/runtime-performance/slow-computations', + }, + { + label: 'Skipping component subtrees', + path: 'best-practices/skipping-subtrees', + contentPath: 'best-practices/runtime-performance/skipping-subtrees', + }, + ], + }, + { + label: 'Keeping up-to-date', + path: 'update', + contentPath: 'best-practices/update', + }, + ], + }, + { + label: 'Extended Ecosystem', + children: [ + { + label: 'Service Workers & PWAs', + children: [ + { + label: 'Overview', + path: 'ecosystem/service-workers', + contentPath: 'ecosystem/service-workers/overview', + }, + { + label: 'Getting started', + path: 'ecosystem/service-workers/getting-started', + contentPath: 'ecosystem/service-workers/getting-started', + }, + { + label: 'Configuration file', + path: 'ecosystem/service-workers/config', + contentPath: 'ecosystem/service-workers/config', + }, + { + label: 'Communicating with the service worker', + path: 'ecosystem/service-workers/communications', + contentPath: 'ecosystem/service-workers/communications', + }, + { + label: 'Push notifications', + path: 'ecosystem/service-workers/push-notifications', + contentPath: 'ecosystem/service-workers/push-notifications', + }, + { + label: 'Service worker devops', + path: 'ecosystem/service-workers/devops', + contentPath: 'ecosystem/service-workers/devops', + }, + { + label: 'App shell pattern', + path: 'ecosystem/service-workers/app-shell', + contentPath: 'ecosystem/service-workers/app-shell', + }, + ], + }, + { + label: 'Web workers', + path: 'ecosystem/web-workers', + contentPath: 'ecosystem/web-workers', + }, + { + label: 'Angular Fire', + path: 'https://github.com/angular/angularfire#readme', + }, + { + label: 'Google Maps', + path: 'https://github.com/angular/components/tree/main/src/google-maps#readme', + }, + { + label: 'Google Pay', + path: 'https://github.com/google-pay/google-pay-button#angular', + }, + { + label: 'YouTube player', + path: 'https://github.com/angular/components/blob/main/src/youtube-player/README.md', + }, + { + label: 'Angular CDK', + path: 'https://material.angular.io/cdk/categories', + }, + { + label: 'Angular Material', + path: 'https://material.angular.io/', + }, + ], + }, +]; + +export const TUTORIALS_SUB_NAVIGATION_DATA: NavigationItem[] = [ + FIRST_APP_TUTORIAL_NAV_DATA, + LEARN_ANGULAR_TUTORIAL_NAV_DATA, + { + path: DefaultPage.TUTORIALS, + contentPath: 'tutorials/home', + label: 'Tutorials', + }, +]; + +const REFERENCE_SUB_NAVIGATION_DATA: NavigationItem[] = [ + { + label: 'Roadmap', + path: 'roadmap', + contentPath: 'reference/roadmap', + }, + { + label: 'Get involved', + path: 'https://github.com/angular/angular/blob/main/CONTRIBUTING.md', + }, + { + label: 'API Reference', + children: [ + { + label: 'Overview', + path: 'api', + }, + ...getApiNavigationItems(), + ], + }, + { + label: 'CLI Reference', + children: [ + { + label: 'Overview', + path: 'cli', + contentPath: 'reference/cli', + }, + { + label: 'ng add', + path: 'cli/add', + }, + { + label: 'ng analytics', + children: [ + { + label: 'Overview', + path: 'cli/analytics', + }, + { + label: 'disable', + path: 'cli/analytics/disable', + }, + { + label: 'enable', + path: 'cli/analytics/enable', + }, + { + label: 'info', + path: 'cli/analytics/info', + }, + { + label: 'prompt', + path: 'cli/analytics/prompt', + }, + ], + }, + { + label: 'ng build', + path: 'cli/build', + }, + { + label: 'ng cache', + children: [ + { + label: 'Overview', + path: 'cli/cache', + }, + { + label: 'clear', + path: 'cli/cache/clean', + }, + { + label: 'disable', + path: 'cli/cache/disable', + }, + { + label: 'enable', + path: 'cli/cache/enable', + }, + { + label: 'info', + path: 'cli/cache/info', + }, + ], + }, + { + label: 'ng completion', + children: [ + { + label: 'Overview', + path: 'cli/completion', + }, + { + label: 'script', + path: 'cli/completion/script', + }, + ], + }, + { + label: 'ng config', + path: 'cli/config', + }, + { + label: 'ng deploy', + path: 'cli/deploy', + }, + { + label: 'ng e2e', + path: 'cli/e2e', + }, + { + label: 'ng extract-i18n', + path: 'cli/extract-i18n', + }, + { + label: 'ng generate', + children: [ + { + label: 'Overview', + path: 'cli/generate', + }, + { + label: 'app-shell', + path: 'cli/generate/app-shell', + }, + { + label: 'application', + path: 'cli/generate/application', + }, + { + label: 'class', + path: 'cli/generate/class', + }, + { + label: 'component', + path: 'cli/generate/component', + }, + { + label: 'config', + path: 'cli/generate/config', + }, + { + label: 'directive', + path: 'cli/generate/directive', + }, + { + label: 'enum', + path: 'cli/generate/enum', + }, + { + label: 'environments', + path: 'cli/generate/environments', + }, + { + label: 'guard', + path: 'cli/generate/guard', + }, + { + label: 'interceptor', + path: 'cli/generate/interceptor', + }, + { + label: 'interface', + path: 'cli/generate/interface', + }, + { + label: 'library', + path: 'cli/generate/library', + }, + { + label: 'module', + path: 'cli/generate/module', + }, + { + label: 'pipe', + path: 'cli/generate/pipe', + }, + { + label: 'resolver', + path: 'cli/generate/resolver', + }, + { + label: 'service-worker', + path: 'cli/generate/service-worker', + }, + { + label: 'service', + path: 'cli/generate/service', + }, + { + label: 'web-worker', + path: 'cli/generate/web-worker', + }, + ], + }, + { + label: 'ng lint', + path: 'cli/lint', + }, + { + label: 'ng new', + path: 'cli/new', + }, + { + label: 'ng run', + path: 'cli/run', + }, + { + label: 'ng serve', + path: 'cli/serve', + }, + { + label: 'ng test', + path: 'cli/test', + }, + { + label: 'ng update', + path: 'cli/update', + }, + { + label: 'ng version', + path: 'cli/version', + }, + ], + }, + { + label: 'Error Encyclopedia', + children: [ + { + label: 'Overview', + path: 'errors', + contentPath: 'reference/errors/overview', + }, + { + label: 'NG0100: Expression Changed After Checked', + path: 'errors/NG0100', + contentPath: 'reference/errors/NG0100', + }, + { + label: 'NG01101: Wrong Async Validator Return Type', + path: 'errors/NG01101', + contentPath: 'reference/errors/NG01101', + }, + { + label: 'NG01203: Missing value accessor', + path: 'errors/NG01203', + contentPath: 'reference/errors/NG01203', + }, + { + label: 'NG0200: Circular Dependency in DI', + path: 'errors/NG0200', + contentPath: 'reference/errors/NG0200', + }, + { + label: 'NG0201: No Provider Found', + path: 'errors/NG0201', + contentPath: 'reference/errors/NG0201', + }, + { + label: 'NG0203: `inject()` must be called from an injection context', + path: 'errors/NG0203', + contentPath: 'reference/errors/NG0203', + }, + { + label: 'NG0209: Invalid multi provider', + path: 'errors/NG0209', + contentPath: 'reference/errors/NG0209', + }, + { + label: 'NG02200: Missing Iterable Differ', + path: 'errors/NG02200', + contentPath: 'reference/errors/NG02200', + }, + { + label: 'NG02800: JSONP support in HttpClient configuration', + path: 'errors/NG02800', + contentPath: 'reference/errors/NG02800', + }, + { + label: 'NG0300: Selector Collision', + path: 'errors/NG0300', + contentPath: 'reference/errors/NG0300', + }, + { + label: 'NG0301: Export Not Found', + path: 'errors/NG0301', + contentPath: 'reference/errors/NG0301', + }, + { + label: 'NG0302: Pipe Not Found', + path: 'errors/NG0302', + contentPath: 'reference/errors/NG0302', + }, + { + label: `NG0403: Bootstrapped NgModule doesn't specify which component to initialize`, + path: 'errors/NG0403', + contentPath: 'reference/errors/NG0403', + }, + { + label: 'NG0500: Hydration Node Mismatch', + path: 'errors/NG0500', + contentPath: 'reference/errors/NG0500', + }, + { + label: 'NG0501: Hydration Missing Siblings', + path: 'errors/NG0501', + contentPath: 'reference/errors/NG0501', + }, + { + label: 'NG0502: Hydration Missing Node', + path: 'errors/NG0502', + contentPath: 'reference/errors/NG0502', + }, + { + label: 'NG0503: Hydration Unsupported Projection of DOM Nodes', + path: 'errors/NG0503', + contentPath: 'reference/errors/NG0503', + }, + { + label: 'NG0504: Skip hydration flag is applied to an invalid node', + path: 'errors/NG0504', + contentPath: 'reference/errors/NG0504', + }, + { + label: 'NG0505: No hydration info in server response', + path: 'errors/NG0505', + contentPath: 'reference/errors/NG0505', + }, + { + label: 'NG0506: NgZone remains unstable', + path: 'errors/NG0506', + contentPath: 'reference/errors/NG0506', + }, + { + label: 'NG0507: HTML content was altered after server-side rendering', + path: 'errors/NG0507', + contentPath: 'reference/errors/NG0507', + }, + { + label: 'NG0602: HTML content was altered after server-side rendering', + path: 'errors/NG0602', + contentPath: 'reference/errors/NG0602', + }, + { + label: 'NG05104: Root element was not found', + path: 'errors/NG05104', + contentPath: 'reference/errors/NG05104', + }, + { + label: 'NG0910: Unsafe bindings on an iframe element', + path: 'errors/NG0910', + contentPath: 'reference/errors/NG0910', + }, + { + label: 'NG0912: Component ID generation collision', + path: 'errors/NG0912', + contentPath: 'reference/errors/NG0912', + }, + { + label: 'NG0913: Runtime Performance Warnings', + path: 'errors/NG0913', + contentPath: 'reference/errors/NG0913', + }, + { + label: 'NG0950: Required input is accessed before a value is set.', + path: 'errors/NG0950', + contentPath: 'reference/errors/NG0950', + }, + { + label: 'NG0951: Child query result is required but no value is available.', + path: 'errors/NG0951', + contentPath: 'reference/errors/NG0951', + }, + { + label: 'NG0955: Track expression resulted in duplicated keys for a given collection', + path: 'errors/NG0955', + contentPath: 'reference/errors/NG0955', + }, + { + label: 'NG0956: Tracking expression caused re-creation of the DOM structure', + path: 'errors/NG0956', + contentPath: 'reference/errors/NG0956', + }, + { + label: 'NG1001: Argument Not Literal', + path: 'errors/NG1001', + contentPath: 'reference/errors/NG1001', + }, + { + label: 'NG2003: Missing Token', + path: 'errors/NG2003', + contentPath: 'reference/errors/NG2003', + }, + { + label: 'NG2009: Invalid Shadow DOM selector', + path: 'errors/NG2009', + contentPath: 'reference/errors/NG2009', + }, + { + label: 'NG3003: Import Cycle Detected', + path: 'errors/NG3003', + contentPath: 'reference/errors/NG3003', + }, + { + label: 'NG05000: Hydration with unsupported Zone.js instance.', + path: 'errors/NG05000', + contentPath: 'reference/errors/NG05000', + }, + { + label: 'NG6100: NgModule.id Set to module.id anti-pattern', + path: 'errors/NG6100', + contentPath: 'reference/errors/NG6100', + }, + { + label: 'NG8001: Invalid Element', + path: 'errors/NG8001', + contentPath: 'reference/errors/NG8001', + }, + { + label: 'NG8002: Invalid Attribute', + path: 'errors/NG8002', + contentPath: 'reference/errors/NG8002', + }, + { + label: 'NG8003: Missing Reference Target', + path: 'errors/NG8003', + contentPath: 'reference/errors/NG8003', + }, + ], + }, + { + label: 'Extended Diagnostics', + children: [ + { + label: 'Overview', + path: 'extended-diagnostics', + contentPath: 'reference/extended-diagnostics/overview', + }, + { + label: 'NG8101: Invalid Banana-in-Box', + path: 'extended-diagnostics/NG8101', + contentPath: 'reference/extended-diagnostics/NG8101', + }, + { + label: 'NG8102: Nullish coalescing not nullable', + path: 'extended-diagnostics/NG8102', + contentPath: 'reference/extended-diagnostics/NG8102', + }, + { + label: 'NG8103: Missing control flow directive', + path: 'extended-diagnostics/NG8103', + contentPath: 'reference/extended-diagnostics/NG8103', + }, + { + label: 'NG8104: Text attribute not binding', + path: 'extended-diagnostics/NG8104', + contentPath: 'reference/extended-diagnostics/NG8104', + }, + { + label: 'NG8105: Missing `let` keyword in an *ngFor expression', + path: 'extended-diagnostics/NG8105', + contentPath: 'reference/extended-diagnostics/NG8105', + }, + { + label: 'NG8106: Suffix not supported', + path: 'extended-diagnostics/NG8106', + contentPath: 'reference/extended-diagnostics/NG8106', + }, + { + label: 'NG8107: Optional chain not nullable', + path: 'extended-diagnostics/NG8107', + contentPath: 'reference/extended-diagnostics/NG8107', + }, + { + label: 'NG8108: ngSkipHydration should be a static attribute', + path: 'extended-diagnostics/NG8108', + contentPath: 'reference/extended-diagnostics/NG8108', + }, + { + label: 'NG8109: Signals must be invoked in template interpolations', + path: 'extended-diagnostics/NG8109', + contentPath: 'reference/extended-diagnostics/NG8109', + }, + { + label: 'NG8111: Functions must be invoked in event bindings', + path: 'extended-diagnostics/NG8111', + contentPath: 'reference/extended-diagnostics/NG8111', + }, + ], + }, + { + label: 'Versioning and releases', + path: 'reference/releases', + contentPath: 'reference/releases', + }, + { + label: 'Version compatibility', + path: 'reference/versions', + contentPath: 'reference/versions', + }, + { + label: 'Update guide', + path: 'update-guide', + }, + { + label: 'Configurations', + children: [ + { + label: 'File structure', + path: 'reference/configs/file-structure', + contentPath: 'reference/configs/file-structure', + }, + { + label: 'Workspace configuration', + path: 'reference/configs/workspace-config', + contentPath: 'reference/configs/workspace-config', + }, + { + label: 'Angular compiler options', + path: 'reference/configs/angular-compiler-options', + contentPath: 'reference/configs/angular-compiler-options', + }, + { + label: 'npm dependencies', + path: 'reference/configs/npm-packages', + contentPath: 'reference/configs/npm-packages', + }, + ], + }, + { + label: 'Migrations', + children: [ + { + label: 'Overview', + path: 'reference/migrations', + contentPath: 'reference/migrations/overview', + }, + { + label: 'Standalone', + path: 'reference/migrations/standalone', + contentPath: 'reference/migrations/standalone', + }, + { + label: 'ModuleWithProviders', + path: 'reference/migrations/module-with-providers', + contentPath: 'reference/migrations/module-with-providers', + }, + { + label: 'Typed Forms', + path: 'reference/migrations/typed-forms', + contentPath: 'reference/migrations/typed-forms', + }, + { + label: 'Control Flow Syntax', + path: 'reference/migrations/control-flow', + contentPath: 'reference/migrations/control-flow', + }, + ], + }, + { + label: 'Concepts', + children: [ + { + label: 'Overview', + path: 'reference/concepts', + contentPath: 'reference/concepts/overview', + }, + { + label: 'NgModule', + children: [ + { + label: 'Overview', + path: 'guide/ngmodules', + contentPath: 'guide/ngmodules/overview', + }, + { + label: 'JS Modules vs NgModules', + path: 'guide/ngmodules/vs-jsmodule', + contentPath: 'guide/ngmodules/vs-jsmodule', + }, + { + label: 'Launching your app with a root module', + path: 'guide/ngmodules/bootstrapping', + contentPath: 'guide/ngmodules/bootstrapping', + }, + { + label: 'Sharing NgModules', + path: 'guide/ngmodules/sharing', + contentPath: 'guide/ngmodules/sharing', + }, + { + label: 'Frequently used NgModules', + path: 'guide/ngmodules/frequent', + contentPath: 'guide/ngmodules/frequent', + }, + { + label: 'Feature modules', + path: 'guide/ngmodules/feature-modules', + contentPath: 'guide/ngmodules/feature-modules', + }, + { + label: 'Types of feature modules', + path: 'guide/ngmodules/module-types', + contentPath: 'guide/ngmodules/module-types', + }, + { + label: 'Providing dependencies', + path: 'guide/ngmodules/providers', + contentPath: 'guide/ngmodules/providers', + }, + { + label: 'Singleton services', + path: 'guide/ngmodules/singleton-services', + contentPath: 'guide/ngmodules/singleton-services', + }, + { + label: 'Lazy-loading feature modules', + path: 'guide/ngmodules/lazy-loading', + contentPath: 'guide/ngmodules/lazy-loading', + }, + { + label: 'NgModule API', + path: 'guide/ngmodules/api', + contentPath: 'guide/ngmodules/api', + }, + { + label: 'NgModule FAQs', + path: 'guide/ngmodules/faq', + contentPath: 'guide/ngmodules/faq', + }, + ], + }, + ], + }, +]; + +const FOOTER_NAVIGATION_DATA: NavigationItem[] = [ + { + label: 'Press Kit', + path: 'press-kit', + contentPath: 'reference/press-kit', + }, + { + label: 'License', + path: 'license', + contentPath: 'reference/license', + }, +]; + +// Docs navigation data structure, it's used to display structure in +// navigation-list component And build the routing table for content pages. +export const SUB_NAVIGATION_DATA: SubNavigationData = { + docs: DOCS_SUB_NAVIGATION_DATA, + reference: REFERENCE_SUB_NAVIGATION_DATA, + tutorials: TUTORIALS_SUB_NAVIGATION_DATA, + footer: FOOTER_NAVIGATION_DATA, +}; diff --git a/adev-ja/src/content/introduction/what-is-angular.en.md b/adev-ja/src/content/introduction/what-is-angular.en.md new file mode 100644 index 0000000000..bfb75fcf63 --- /dev/null +++ b/adev-ja/src/content/introduction/what-is-angular.en.md @@ -0,0 +1,152 @@ + + + + +Angular is a web framework that empowers developers to build fast, reliable applications. + + +Maintained by a dedicated team at Google, Angular provides a broad suite of tools, APIs, and +libraries to simplify and streamline your development workflow. Angular gives you +a solid platform on which to build fast, reliable applications that scale with both the size of +your team and the size of your codebase. + +**Want to see some code?** Jump over to our [Essentials](essentials) for a quick overview of +what it's like to use Angular, or get started in the [Tutorial](tutorials/learn-angular) if you +prefer following step-by-step instructions. + +## Features that power your development + + + + Angular components make it easy to split your code into well-encapsulated parts. + + The versatile dependency injection helps you keep your code modular, loosely-coupled, and + testable. + + + Our fine-grained reactivity model, combined with compile-time optimizations, simplifies development and helps build faster apps by default. + + Granularly track how and where state is used throughout an application, giving the framework the power to render fast updates via highly optimized instructions. + + + Angular supports both server-side rendering (SSR) and static site generation (SSG) along + with full DOM hydration. `@defer` blocks in templates make it simple to declaratively divide + your templates into lazy-loadable parts. + + + [Angular's router](guide/routing) provides a feature-rich navigation toolkit, including support + for route guards, data resolution, lazy-loading, and much more. + + [Angular's forms module](guide/forms) provides a standardized system for form participation and validation. + + + +## Develop applications faster than ever + + + + Angular CLI gets your project running in under a minute with the commands you need to + grow into a deployed production application. + + + Angular DevTools sits alongside your browser's developer tools. It helps debug and analyze your + app, including a component tree inspector, dependency injection tree view, + and custom performance profiling flame chart. + + + Angular CLI's `ng update` runs automated code transformations that automatically handle routine + breaking changes, dramatically simplifying major version updates. Keeping up with the latest + version keeps your app as fast and secure as possible. + + + Angular's IDE language services powers code completion, navigation, refactoring, and real-time + diagnostics in your favorite editor. + + + +## Ship with confidence + + + + Every Angular commit is checked against _hundreds of thousands_ of tests in Google's internal code + repository, representing countless real-world scenarios. + + Angular is committed to stability for some of Google’s largest products, including Google Cloud. + This commitment ensures changes are well-tested, backwards compatible, and include migration tools + whenever possible. + + + Angular's predictable, time-based release schedule gives your organization confidence in the + stability and backwards compatibility of the framework. Long Term Support (LTS) windows make sure + you get critical security fixes when you need them. First-party update tools, guides and automated + migration schematics help keep your apps up-to-date with the latest advancements to the framework + and the web platform. + + + +## Works at any scale + + + + Angular's internationalization features handle message translations and formatting, including + support for unicode standard ICU syntax. + + + In collaboration with Google's world-class security engineers, Angular aims to make development + safe by default. Built-in security features, including HTML sanitization and + trusted type support, help protect your users from common vulnerabilities like + cross-site scripting and cross-site request forgery. + + + Angular CLI includes a fast, modern build pipeline using Vite and ESBuild. Developers report + building projects with hundreds of thousands of lines of code in less than a minute. + + + Large Google products build on top of Angular's architecture and help develop new features that + further improve Angular's scalability, from [Google Fonts](https://fonts.google.com/) to [Google Cloud](https://console.cloud.google.com). + + + +## Open-source first + + + + Curious what we’re working on? Every PR and commit is available on our GitHub. Run into an issue or bug? We triage GitHub issues regularly to ensure we’re responsive and engaged with our community, and solving the real world problems you’re facing. + + + Our team publishes a public roadmap of our current and future work and values your feedback. We publish Request for Comments (RFCs) to collect feedback on larger feature changes and ensure the community voice is heard while shaping the future direction of Angular. + + + +## A thriving community + + + + Our community is composed of talented developers, writers, instructors, podcasters, and more. The Google for Developers library is just a sample of the high quality resources available for new and experienced developers to continue developing. + + + We are thankful for the open source contributors who make Angular a better framework for everyone. From fixing a typo in the docs, to adding major features, we encourage anyone interested to get started on our GitHub. + + + Our team partners with individuals, educators, and enterprises to ensure we consistently are supporting developers. Angular Google Developer Experts (GDEs) represent community leaders around the world educating, organizing, and developing with Angular. Enterprise partnerships help ensure that Angular scales well for technology industry leaders. + + + Angular partners closely with other Google technologies and teams to improve the web. + + Our ongoing partnership with Chrome’s Aurora actively explores improvements to user experience across the web, developing built-in performance optimizations like NgOptimizedImage and improvements to Angular’s Core Web Vitals. + + We are also working with [Firebase](https://firebase.google.com/), [Tensorflow](https://www.tensorflow.org/), [Flutter](https://flutter.dev/), [Material Design](https://m3.material.io/), and [Google Cloud](https://cloud.google.com/) to ensure we provide meaningful integrations across the developer workflow. + + + + + + + + + + + + diff --git a/adev-ja/src/content/introduction/what-is-angular.md b/adev-ja/src/content/introduction/what-is-angular.md new file mode 100644 index 0000000000..fc16bff2fd --- /dev/null +++ b/adev-ja/src/content/introduction/what-is-angular.md @@ -0,0 +1,152 @@ + + + + +Angularは、開発者が高速で信頌性の高いアプリケヌションを構築できるようにするWebフレヌムワヌクです。 + + +Googleの専門チヌムによっお管理されおいるAngularは、 +開発ワヌクフロヌを簡玠化し効率化するためのツヌル、API、ラむブラリの幅広いスむヌトを提䟛したす。 +Angularは、チヌムの芏暡やコヌドベヌスの芏暡に合わせお拡匵できる、 +高速で信頌性の高いアプリケヌションを構築するための堅牢なプラットフォヌムを提䟛したす。 + +**コヌドを確認したいですか** Angular の䜿い方の抂芁を簡単に確認するには、 +[基本芁玠](essentials)にアクセスしおください。 +ステップバむステップの手順に埓いたい堎合は、[チュヌトリアル](tutorials/learn-angular)で始めるこずができたす。 + +## 開発を匷力にサポヌトする機胜 + + + + Angularのコンポヌネントを䜿甚するず、コヌドをうたくカプセル化しお簡単に分割できたす。 + + 汎甚性の高い䟝存性の泚入により、コヌドをモゞュヌル化し、 + 疎結合か぀テスト可胜に保぀こずができたす。 + + + コンパむル時の最適化ず組み合わせたきめ现かなリアクティビティモデルは、開発を簡玠化し、より高速なアプリの構築をデフォルトで支揎したす。 + + アプリケヌション党䜓で状態がどのように、どこで䜿甚されおいるかを詳现に远跡し、高床に最適化された呜什を通じおフレヌムワヌクが高速な曎新をレンダリングできるようにしたす。 + + + Angular は、完党なDOMハむドレヌションず䞊んで、サヌバヌサむドレンダリング (SSR) ず + 静的サむト生成 (SSG) の䞡方をサポヌトしたす。テンプレヌト内の `@defer` ブロックを䜿甚しお、 + テンプレヌトを遅延読み蟌み可胜な郚分ぞ宣蚀的に分割するこずが簡単にできたす。 + + + [Angularのルヌタヌ](guide/routing)は、ルヌト保護、デヌタ解決、遅延読み蟌みなど、 + 機胜豊富なナビゲヌションツヌルキットを提䟛したす。 + + [Angularのフォヌムモゞュヌル](guide/forms)は、 + カスタムフォヌム芁玠ずバリデヌションのための暙準化されたシステムを提䟛したす。 + + + +## これたでにない開発速床 + + + + Angular CLI を䜿甚するず、 + 本番アプリケヌションをデプロむするのに必芁なコマンドでプロゞェクトをあっずいう間に実行できたす。 + + + Angular DevToolsはブラりザの開発者ツヌルず䞀緒に䜿甚できたす。 + コンポヌネントツリヌむンスペクタヌ、䟝存性の泚入ツリヌビュヌ、独自のパフォヌマンスプロファむリングフレヌムチャヌトなど、 + アプリのデバッグず分析に圹立ちたす。 + + + Angular CLIの `ng update` は、芏則的な砎壊的倉曎を自動的に凊理する自動コヌド倉換を実行し、 + メゞャヌバヌゞョンアップデヌトを倧幅に簡玠化したす。 + 最新バヌゞョンを維持するこずで、アプリをできるだけ高速か぀安党に保぀こずができたす。 + + + AngularのIDE蚀語サヌビスは、お気に入りの゚ディタでのコヌド補完、ナビゲヌション、 + リファクタリング、リアルタむム蚺断を匷化したす。 + + + +## 自信を持っおリリヌス + + + + Angularのすべおのコミットは、Googleの内郚コヌドリポゞトリにある、 + 数え切れない珟実䞖界のシナリオを衚す_数十䞇_のテストでチェックされおたす。 + + Angularは、Google Cloudを含むGoogleの最倧玚の補品の安定性にコミットしおいたす。 + このコミットメントにより、倉曎点が十分にテストされ、埌方互換性があり、 + 可胜な限り移行ツヌルが含たれるこずが保蚌されたす。 + + + Angularの予枬可胜な時間ベヌスのリリヌススケゞュヌルにより、 + 組織はフレヌムワヌクの安定性ず埌方互換性に぀いお自信を持぀こずができたす。 + 長期サポヌト (LTS) りィンドりにより、必芁なずきに重芁なセキュリティ修正を入手できたす。 + ファヌストパヌティの曎新ツヌルやガむド、自動移行Schematicsは、 + アプリをフレヌムワヌクずWebプラットフォヌムの最新の発展に合わせお最新の状態に保぀のに圹立ちたす。 + + + +## あらゆる芏暡で機胜する + + + + Angularの囜際化機胜は、メッセヌゞの翻蚳ずフォヌマットを凊理し、 + Unicode暙準のICU構文のサポヌトを含みたす。 + + + Googleの䞖界クラスのセキュリティ゚ンゞニアずのコラボレヌションにより、 + Angularはデフォルトで安党な開発を目指しおいたす。 + HTMLサニタむズやTrusted Typesサポヌトなどの組み蟌みセキュリティ機胜により、 + クロスサむトスクリプティングやクロスサむトリク゚ストフォヌゞェリなどの䞀般的な脆匱性からナヌザヌを保護したす。 + + + Angular CLIには、ViteずESBuildを䜿甚した高速で最新のビルドパむプラむンが含たれおいたす。 + 開発者は、数十䞇行のコヌドを含むプロゞェクトを1分未満でビルドしおいるず報告しおいたす。 + + + Googleの倧芏暡なプロダクトはAngularのアヌキテクチャに基づいお構築されおおり、[Google Fonts](https://fonts.google.com/)から[Google Cloud](https://console.cloud.google.com)たで、 + Angularのスケヌラビリティをさらに向䞊させる新機胜の開発に圹立っおいたす。 + + + +## オヌプン゜ヌスファヌスト + + + + 私たちが䜕に取り組んでいるのか興味がありたすか すべおのPRずコミットはGitHubで公開されおいたす。問題やバグに遭遇したしたかGitHubのむシュヌを定期的に分類しお、コミュニティに反応し、関わりを持ち、盎面しおいる珟実䞖界の問題を解決できるようにしおいたす。 + + + 私たちのチヌムは、珟圚および将来の䜜業のロヌドマップを公開しおおり、あなたのフィヌドバックを倧切にしおいたす。倧きな機胜倉曎に関するフィヌドバックを収集し、コミュニティの声を聞きながらAngularの将来の方向性を圢䜜るために、Request for Comments (RFC) を公開しおいたす。 + + + +## 掻気のあるコミュニティ + + + + 私たちのコミュニティには才胜ある開発者、ラむタヌ、むンストラクタヌ、ポッドキャスタヌなどがいたす。Google for Developersのラむブラリは、新人から経隓豊富な開発者たでが継続的に開発するための高品質なリ゜ヌスのほんの䞀䟋です。 + + + 私たちは、Angularをすべおの人に適したフレヌムワヌクにするオヌプン゜ヌスコントリビュヌタヌに感謝しおいたす。ドキュメントのタむプミスを修正するこずから䞻芁な機胜を远加するこずたで、興味のある方は誰でもGitHubで始めるこずを歓迎したす。 + + + 私たちのチヌムは、個人、教育者、䌁業ず提携しお、開発者を垞にサポヌトできるようにしおいたす。AngularのGoogle Developer Experts (GDE) は、䞖界䞭のコミュニティリヌダヌを代衚しお、Angularでの教育、組織化、開発を行っおいたす。゚ンタヌプラむズパヌトナヌシップは、Angularがテクノロゞヌ業界のリヌダヌにずっお優れたスケヌラビリティを実珟できるようにしたす。 + + + Angularは、他のGoogleテクノロゞヌやチヌムず緊密に連携しおWebを改善しおいたす。 + + ChromeのAuroraずの継続的なパヌトナヌシップにより、NgOptimizedImageなどの組み蟌みパフォヌマンス最適化や Angular のCore Web Vitalsの改善など、Web 党䜓でのナヌザヌ゚クスペリ゚ンスの向䞊を積極的に探求しおいたす。 + + たた、[Firebase](https://firebase.google.com/)、[Tensorflow](https://www.tensorflow.org/)、[Flutter](https://flutter.dev/)、[Material Design](https://m3.material.io/)、[Google Cloud](https://cloud.google.com/) ず連携しお、開発者ワヌクフロヌ党䜓で有意矩な統合を提䟛しおいたす。 + + + + + + + + + + + + diff --git a/package.json b/package.json index b0a6ba7e29..05b60ecc57 100644 --- a/package.json +++ b/package.json @@ -18,10 +18,12 @@ "packageManager": "yarn@1.22.10", "devDependencies": { "chokidar": "3.6.0", + "execa": "^9.3.0", "prh-rules": "prh/rules", "textlint": "^14.0.4", "textlint-filter-rule-comments": "^1.2.2", "textlint-rule-prh": "^6.0.0", + "tree-kill": "^1.2.2", "zx": "8.1.3" } } diff --git a/tools/build.mjs b/tools/build.mjs index 13ea735f3c..8fb319bf42 100644 --- a/tools/build.mjs +++ b/tools/build.mjs @@ -9,6 +9,8 @@ import { copyRobots, modifySitemap, resetBuildDir, + copyStaticFiles, + replaceAdevGitHubEditLinks, } from './lib/common.mjs'; // `init` is true by default, use `--no-init` flag to skip initialization. @@ -34,9 +36,8 @@ async function setup({ init }) { async function preBuild({ init }) { if (init) { - // copy translated files - // console.log(chalk.cyan('Copy localized files...')); - // await copyLocalizedFiles(); + console.log(chalk.cyan('Copy localized files...')); + await copyLocalizedFiles(); // apply patches console.log(chalk.cyan('Apply patches...')); @@ -49,7 +50,10 @@ async function build() { } async function postBuild() { - // await copyRobots(); + console.log(chalk.cyan('Copy static files...')); + await copyStaticFiles(); + console.log(chalk.cyan('Replace GitHub edit links...')); + await replaceAdevGitHubEditLinks(); // await remove404HTML(); // await modifySitemap(); } diff --git a/tools/lib/common.mjs b/tools/lib/common.mjs index 9103c9fc3b..f9cd315109 100644 --- a/tools/lib/common.mjs +++ b/tools/lib/common.mjs @@ -1,11 +1,24 @@ import { watch } from 'chokidar'; -import { resolve } from 'node:path'; +import { resolve, basename } from 'node:path'; +import { execa } from 'execa'; +// TODO: replace $ to execa import { $, cd, chalk, glob, within } from 'zx'; +import kill from 'tree-kill'; import { cpRf, exists, initDir, rename, sed } from './fileutils.mjs'; +const $$ = execa({ + stdin: 'inherit', + stdout: 'inherit', + stderr: 'inherit', + preferLocal: true, + verbose: 'short', +}); + const rootDir = resolve(__dirname, '../'); +const adevJaDir = resolve(rootDir, 'adev-ja'); const aiojaDir = resolve(rootDir, 'aio-ja'); -const outDir = resolve(rootDir, 'build'); +const buildDir = resolve(rootDir, 'build'); +const buildOutputDir = resolve(buildDir, 'dist/bin/adev/build/browser'); export async function resetBuildDir({ init = false }) { if (init) { @@ -13,65 +26,90 @@ export async function resetBuildDir({ init = false }) { await syncSubmodule(); } - const buildDirExists = await exists(outDir); + const buildDirExists = await exists(buildDir); if (init || !buildDirExists) { console.log(chalk.cyan('removing build directory...')); - await initDir(outDir); + await initDir(buildDir); console.log(chalk.cyan('copying origin files to build directory...')); - await cpRf(resolve(rootDir, 'origin'), outDir); + await cpRf(resolve(rootDir, 'origin'), buildDir); + console.log(chalk.cyan('copying .bazelrc to build directory...')); + await cpRf( + resolve(rootDir, '.bazelrc'), + resolve(buildDir, '.bazelrc.user') + ); } } export async function buildAdev() { - await within(async () => { - cd(`${outDir}`); - await $`yarn install --frozen-lockfile`; - await $`yarn bazel build //adev:build`; - }); + await $$({ cwd: buildDir })`yarn install --frozen-lockfile`; + await $$({ cwd: buildDir })`yarn bazel build //adev:build`; } -export async function watchAIO() { - await within(async () => { - cd(`${outDir}`); - await $`yarn docs`; +export function serveAdev() { + const p = $$({ + cwd: buildDir, + reject: false, + })`npx bazel run //adev:serve --fast_adev`; + console.debug(chalk.gray('adev process started.', p.pid)); + const abort = () => kill(p.pid); + p.finally(() => { + console.debug(chalk.gray('adev process exited.', p.pid)); }); + return { + cancel: async () => { + abort(); + return await p; + }, + }; } /** - * glob patterns of localized files in aio-ja + * 翻蚳甚ファむルのパタヌン + * このパタヌンに䞀臎するファむルがビルドディレクトリにコピヌされたす。 */ -const lozalizedFilePatterns = ['**/*', '!**/*.en.*', '!**/*.old']; +const localizedFilePatterns = ['**/*', '!**/*.en.*', '!**/*.old']; + +/** + * 翻蚳甚ファむルをビルドディレクトリにコピヌしたす。 + * + * @param {string} file + */ +async function copyLocalizedFile(file) { + const src = resolve(adevJaDir, file); + const dest = resolve(buildDir, 'adev', file); + return cpRf(src, dest); +} export async function copyLocalizedFiles() { - const jaFiles = await glob(lozalizedFilePatterns, { - cwd: aiojaDir, + const jaFiles = await glob(localizedFilePatterns, { + cwd: adevJaDir, }); - for (const file of jaFiles) { - const src = resolve(aiojaDir, file); - const dest = resolve(outDir, 'aio', file); - await cpRf(src, dest); - } + await Promise.all(jaFiles.map(copyLocalizedFile)); } /** - * - * @param {AbortSignal} signal + * @param {() => () => void} onChangeCallback */ -export async function watchLocalizedFiles(signal) { - const watcher = watch(lozalizedFilePatterns, { - cwd: aiojaDir, +export function watchLocalizedFiles(onChangeCallback) { + const watcher = watch(localizedFilePatterns, { + cwd: adevJaDir, + awaitWriteFinish: true, }); - watcher.on('change', (path) => { - const src = resolve(aiojaDir, path); - const dest = resolve(outDir, 'aio', path); - cpRf(src, dest); + watcher.on('change', async (file) => { + console.debug(chalk.gray(`File changed: ${file}`)); + await copyLocalizedFile(file); + onChangeCallback(); }); - signal.addEventListener('abort', () => watcher.close()); + return { + cancel: () => { + watcher.close(); + }, + }; } export async function applyPatches() { await within(async () => { - cd(outDir); + cd(buildDir); const patches = await glob('tools/adev-patches/*.patch', { cwd: rootDir }); for (const patch of patches) { const path = resolve(rootDir, patch); @@ -90,23 +128,51 @@ export async function syncSubmodule() { // copy robots.txt export async function copyRobots() { - await $`chmod -R +w ${resolve(outDir, 'dist/bin/aio/build')}`; + await $`chmod -R +w ${resolve(buildDir, 'dist/bin/aio/build')}`; const src = resolve(aiojaDir, 'src/robots.txt'); - const dest = resolve(outDir, 'dist/bin/aio/build/robots.txt'); + const dest = resolve(buildDir, 'dist/bin/aio/build/robots.txt'); await cpRf(src, dest); } +// Copy static files into build output directory +export async function copyStaticFiles() { + await $`chmod -R +w ${buildOutputDir}`; + const files = ['_headers']; + for (const file of files) { + const src = resolve(adevJaDir, file); + const dest = resolve(buildOutputDir, file); + await cpRf(src, dest); + } +} + +// Replace all links to GitHub edit page for adev contents. +export async function replaceAdevGitHubEditLinks() { + await $`chmod -R +w ${buildOutputDir}`; + const contentFiles = await glob(['**/*.html'], { cwd: buildOutputDir }); + const from = 'https://github.com/angular/angular/edit/main/adev/'; + const to = 'https://github.com/angular/angular-ja/edit/main/adev-ja/'; + await Promise.all( + contentFiles.map(async (file) => { + const path = resolve(buildOutputDir, file); + await sed(path, from, to); + }) + ); +} + // replace angular.io to angular.jp in sitemap.xml export async function modifySitemap() { - await $`chmod -R +w ${resolve(outDir, 'dist/bin/aio/build')}`; - const sitemapPath = resolve(outDir, 'dist/bin/aio/build/generated/sitemap.xml'); + await $`chmod -R +w ${resolve(buildDir, 'dist/bin/aio/build')}`; + const sitemapPath = resolve( + buildDir, + 'dist/bin/aio/build/generated/sitemap.xml' + ); await sed(sitemapPath, 'angular.io', 'angular.jp'); } // copy _redirects export async function remove404HTML() { - await $`chmod -R +w ${resolve(outDir, 'dist/bin/aio/build')}`; - const from = resolve(outDir, 'dist/bin/aio/build/404.html'); - const to = resolve(outDir, 'dist/bin/aio/build/_404.html'); + await $`chmod -R +w ${resolve(buildDir, 'dist/bin/aio/build')}`; + const from = resolve(buildDir, 'dist/bin/aio/build/404.html'); + const to = resolve(buildDir, 'dist/bin/aio/build/_404.html'); await rename(from, to); } diff --git a/tools/watch.mjs b/tools/watch.mjs index 6c502f3fa4..bdb85e5575 100644 --- a/tools/watch.mjs +++ b/tools/watch.mjs @@ -1,7 +1,12 @@ #!/usr/bin/env zx import { argv, chalk } from 'zx'; -import { applyPatches, copyLocalizedFiles, resetBuildDir, watchAIO, watchLocalizedFiles } from './lib/common.mjs'; +import { + applyPatches, + resetBuildDir, + serveAdev, + watchLocalizedFiles, +} from './lib/common.mjs'; try { const { init = false } = argv; @@ -19,11 +24,17 @@ try { async function setup({ init }) { console.log(''); - console.log(chalk.white('倉曎監芖の察象は、aio-ja 内のファむル ず build/aio 内の゜ヌスコヌドです。')); + console.log(chalk.white('倉曎監芖の察象は、adev-ja 内のファむルです')); if (init) { - console.log(chalk.yellow('build ディレクトリを初期化し、キャッシュを砎棄したす。')); + console.log( + chalk.yellow('build ディレクトリを初期化し、キャッシュを砎棄したす。') + ); } else { - console.log(chalk.white('build ディレクトリを初期化するには --init オプションを指定しおください。')); + console.log( + chalk.white( + 'build ディレクトリを初期化するには --init オプションを指定しおください。' + ) + ); } console.log(''); await resetBuildDir({ init }); @@ -31,23 +42,22 @@ async function setup({ init }) { async function preWatch({ init }) { if (init) { - // copy translated files console.log(chalk.cyan('Copy localized files...')); await copyLocalizedFiles(); - // apply patches console.log(chalk.cyan('Apply patches...')); await applyPatches(); } } async function watch() { - const ctrl = new AbortController(); - await watchLocalizedFiles(ctrl.signal); - try { - await watchAIO(); - } finally { - console.log(chalk.cyan('Abort watching...')); - ctrl.abort(); - } + let adevProcess = serveAdev(); + console.log(chalk.cyan('Start watching adev-ja files...')); + watchLocalizedFiles(async () => { + if (adevProcess != null) { + await adevProcess.cancel(); + } + console.log(chalk.cyan('Restarting adev...')); + adevProcess = serveAdev(); + }); } diff --git a/yarn.lock b/yarn.lock index a9fac0dda8..2d4b6f34bb 100644 --- a/yarn.lock +++ b/yarn.lock @@ -28,6 +28,16 @@ resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.24.7.tgz#9a5226f92f0c5c8ead550b750f5608e766c8ce85" integrity sha512-9uUYRm6OqQrCqQdG1iCBwBPZgN8ciDBro2nIOFaiRz1/BCxaI7CNvQbDHvsArAC7Tw9Hda/B3U+6ui9u4HWXPw== +"@sec-ant/readable-stream@^0.4.1": + version "0.4.1" + resolved "https://registry.yarnpkg.com/@sec-ant/readable-stream/-/readable-stream-0.4.1.tgz#60de891bb126abfdc5410fdc6166aca065f10a0c" + integrity sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg== + +"@sindresorhus/merge-streams@^4.0.0": + version "4.0.0" + resolved "https://registry.yarnpkg.com/@sindresorhus/merge-streams/-/merge-streams-4.0.0.tgz#abb11d99aeb6d27f1b563c38147a72d50058e339" + integrity sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ== + "@textlint/ast-node-types@^13.4.1": version "13.4.1" resolved "https://registry.yarnpkg.com/@textlint/ast-node-types/-/ast-node-types-13.4.1.tgz#00424f7b9bc6fe15cf6a78468ffe1e5d1adce5b2" @@ -404,11 +414,6 @@ color-name@~1.1.4: resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== -commandpost@^1.0.1: - version "1.4.0" - resolved "https://registry.yarnpkg.com/commandpost/-/commandpost-1.4.0.tgz#89218012089dfc9b67a337ba162f15c88e0f1048" - integrity sha512-aE2Y4MTFJ870NuB/+2z1cXBhSBBzRydVVjzhFC4gtenEhpnj15yu0qptWGJsO9YGrcPZ3ezX8AWb1VA391MKpQ== - commandpost@^1.2.1: version "1.3.0" resolved "https://registry.yarnpkg.com/commandpost/-/commandpost-1.3.0.tgz#e0654e4933abf58406c7d3b77ce747083da178c4" @@ -418,6 +423,15 @@ concat-map@0.0.1: resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= +cross-spawn@^7.0.3: + version "7.0.3" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" + integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== + dependencies: + path-key "^3.1.0" + shebang-command "^2.0.0" + which "^2.0.1" + crypt@0.0.2: version "0.0.2" resolved "https://registry.yarnpkg.com/crypt/-/crypt-0.0.2.tgz#88d7ff7ec0dfb86f713dc87bbb42d044d3e6c41b" @@ -600,6 +614,24 @@ esprima@^4.0.0: resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== +execa@^9.3.0: + version "9.3.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-9.3.0.tgz#b10b70f52c1a978985e8492cc1fa74795c59963c" + integrity sha512-l6JFbqnHEadBoVAVpN5dl2yCyfX28WoBAGaoQcNmLLSedOxTxcn2Qa83s8I/PA5i56vWru2OHOtrwF7Om2vqlg== + dependencies: + "@sindresorhus/merge-streams" "^4.0.0" + cross-spawn "^7.0.3" + figures "^6.1.0" + get-stream "^9.0.0" + human-signals "^7.0.0" + is-plain-obj "^4.1.0" + is-stream "^4.0.1" + npm-run-path "^5.2.0" + pretty-ms "^9.0.0" + signal-exit "^4.1.0" + strip-final-newline "^4.0.0" + yoctocolors "^2.0.0" + extend@^3.0.0: version "3.0.2" resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" @@ -627,6 +659,13 @@ fault@^1.0.0: dependencies: format "^0.2.0" +figures@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/figures/-/figures-6.1.0.tgz#935479f51865fa7479f6fa94fc6fc7ac14e62c4a" + integrity sha512-d+l3qxjSesT4V7v2fh+QnmFnUWv9lSpjarhShNTgBOfA0ttejbQUAlHLitbjkoRiDulW0OPoQPYIGhIC8ohejg== + dependencies: + is-unicode-supported "^2.0.0" + file-entry-cache@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-5.0.1.tgz#ca0f6efa6dd3d561333fb14515065c2fafdf439c" @@ -718,6 +757,14 @@ get-stdin@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-5.0.1.tgz#122e161591e21ff4c52530305693f20e6393a398" +get-stream@^9.0.0: + version "9.0.1" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-9.0.1.tgz#95157d21df8eb90d1647102b63039b1df60ebd27" + integrity sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA== + dependencies: + "@sec-ant/readable-stream" "^0.4.1" + is-stream "^4.0.1" + get-symbol-description@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/get-symbol-description/-/get-symbol-description-1.0.2.tgz#533744d5aa20aca4e079c8e5daf7fd44202821f5" @@ -812,6 +859,11 @@ hosted-git-info@^2.1.4: resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.9.tgz#dffc0bf9a21c02209090f2aa69429e1414daf3f9" integrity sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw== +human-signals@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-7.0.0.tgz#93e58e0c19cfec1dded4af10cd4969f5ab75f6c8" + integrity sha512-74kytxOUSvNbjrT9KisAbaTZ/eJwD/LrbM/kh5j0IhPuJzwuA19dWvniFGwBzN9rVjg+O/e+F310PjObDXS+9Q== + inflight@^1.0.4: version "1.0.6" resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" @@ -962,6 +1014,11 @@ is-plain-obj@^2.0.0: resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-2.1.0.tgz#45e42e37fccf1f40da8e5f76ee21515840c09287" integrity sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA== +is-plain-obj@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-4.1.0.tgz#d65025edec3657ce032fd7db63c97883eaed71f0" + integrity sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg== + is-regex@^1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.4.tgz#eef5663cd59fa4c0ae339505323df6854bb15958" @@ -977,6 +1034,11 @@ is-shared-array-buffer@^1.0.2, is-shared-array-buffer@^1.0.3: dependencies: call-bind "^1.0.7" +is-stream@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-4.0.1.tgz#375cf891e16d2e4baec250b85926cffc14720d9b" + integrity sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A== + is-string@^1.0.5, is-string@^1.0.7: version "1.0.7" resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.7.tgz#0dd12bf2006f255bb58f695110eff7491eebc0fd" @@ -998,6 +1060,11 @@ is-typed-array@^1.1.13: dependencies: which-typed-array "^1.1.14" +is-unicode-supported@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-2.0.0.tgz#fdf32df9ae98ff6ab2cedc155a5a6e895701c451" + integrity sha512-FRdAyx5lusK1iHG0TWpVtk9+1i+GjrzRffhDg4ovQ7mcidMQ6mj+MhKPmvh7Xwyv5gIS06ns49CA7Sqg7lC22Q== + is-utf8@^0.2.0: version "0.2.1" resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" @@ -1014,7 +1081,12 @@ isarray@^2.0.5: resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.5.tgz#8af1e4c1221244cc62459faf38940d4e644a5723" integrity sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw== -js-yaml@^3.14.1, js-yaml@^3.6.1: +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== + +js-yaml@^3.14.1: version "3.14.1" resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.1.tgz#dae812fdb3825fa306609a8717383c50c36a0537" integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g== @@ -1316,6 +1388,13 @@ normalize-path@^3.0.0, normalize-path@~3.0.0: resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== +npm-run-path@^5.2.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-5.3.0.tgz#e23353d0ebb9317f174e93417e4a4d82d0249e9f" + integrity sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ== + dependencies: + path-key "^4.0.0" + object-inspect@^1.13.1: version "1.13.1" resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.13.1.tgz#b96c6109324ccfef6b12216a956ca4dc2ff94bc2" @@ -1399,6 +1478,11 @@ parse-json@^4.0.0: error-ex "^1.3.1" json-parse-better-errors "^1.0.1" +parse-ms@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/parse-ms/-/parse-ms-4.0.0.tgz#c0c058edd47c2a590151a718990533fd62803df4" + integrity sha512-TXfryirbmq34y8QBwgqCVLi+8oA3oWx2eAnSn62ITyEhEYaWRlVZ2DvMM9eZbMs/RfxPu/PK/aBLyGj4IrqMHw== + path-exists@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" @@ -1409,6 +1493,16 @@ path-is-absolute@^1.0.0: resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= +path-key@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" + integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== + +path-key@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-4.0.0.tgz#295588dc3aee64154f877adb9d780b81c554bf18" + integrity sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ== + path-to-glob-pattern@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/path-to-glob-pattern/-/path-to-glob-pattern-2.0.1.tgz#d599efea51af1f3e97dcbf721ad8b7d2c40f4a53" @@ -1468,21 +1562,20 @@ prelude-ls@^1.2.1: resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== +pretty-ms@^9.0.0: + version "9.0.0" + resolved "https://registry.yarnpkg.com/pretty-ms/-/pretty-ms-9.0.0.tgz#53c57f81171c53be7ce3fd20bdd4265422bc5929" + integrity sha512-E9e9HJ9R9NasGOgPaPE8VMeiPKAyWR5jcFpNnwIejslIhWqdqOrb2wShBsncMPUb+BcCd2OPYfh7p2W6oemTng== + dependencies: + parse-ms "^4.0.0" + prh-rules@prh/rules: version "1.0.0" resolved "https://codeload.github.com/prh/rules/tar.gz/711e00793d9d69eeda04d68a796b6d9afb6d5748" dependencies: - prh "^1.0.3" + prh "^5.4.3" -prh@^1.0.3: - version "1.1.0" - resolved "https://registry.yarnpkg.com/prh/-/prh-1.1.0.tgz#1c22b2a1998daaa7445865e5c86fb30e5b8ebb33" - integrity sha512-eLYe7+E2lgYOOQMYL2WTJU7Qzu/ro4LyfcW7ZZXgbX+QkM7YQauHSFAq5VtmFV4MXwCMPcNi3xVNz0J4dPk9Vg== - dependencies: - commandpost "^1.0.1" - js-yaml "^3.6.1" - -prh@^5.4.4: +prh@^5.4.3, prh@^5.4.4: version "5.4.4" resolved "https://registry.yarnpkg.com/prh/-/prh-5.4.4.tgz#5b618213a187f3580f262f4e0f79e8e8561ea179" integrity sha512-UATF+R/2H8owxwPvF12Knihu9aYGTuZttGHrEEq5NBWz38mREh23+WvCVKX3fhnIZIMV7ye6E1fnqAl+V6WYEw== @@ -1639,6 +1732,18 @@ set-function-name@^2.0.1: functions-have-names "^1.2.3" has-property-descriptors "^1.0.2" +shebang-command@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" + integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== + dependencies: + shebang-regex "^3.0.0" + +shebang-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" + integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== + side-channel@^1.0.4: version "1.0.6" resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.6.tgz#abd25fb7cd24baf45466406b1096b7831c9215f2" @@ -1649,6 +1754,11 @@ side-channel@^1.0.4: get-intrinsic "^1.2.4" object-inspect "^1.13.1" +signal-exit@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-4.1.0.tgz#952188c1cbd546070e2dd20d0f41c0ae0530cb04" + integrity sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw== + slice-ansi@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-4.0.0.tgz#500e8dd0fd55b05815086255b3195adf2a45fe6b" @@ -1739,6 +1849,11 @@ strip-bom@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" +strip-final-newline@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-4.0.0.tgz#35a369ec2ac43df356e3edd5dcebb6429aa1fa5c" + integrity sha512-aulFJcD6YK8V1G7iRB5tigAP4TsHBZZrOV8pjV++zdUwmeV8uzbY7yn6h9MswN62adStNZFuCIx4haBnRuMDaw== + structured-source@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/structured-source/-/structured-source-4.0.0.tgz#0c9e59ee43dedd8fc60a63731f60e358102a4948" @@ -1838,6 +1953,11 @@ traverse@^0.6.8: typedarray.prototype.slice "^1.0.3" which-typed-array "^1.1.15" +tree-kill@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/tree-kill/-/tree-kill-1.2.2.tgz#4ca09a9092c88b73a7cdc5e8a01b507b0790a0cc" + integrity sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A== + trough@^1.0.0: version "1.0.3" resolved "https://registry.yarnpkg.com/trough/-/trough-1.0.3.tgz#e29bd1614c6458d44869fc28b255ab7857ef7c24" @@ -2023,6 +2143,13 @@ which-typed-array@^1.1.14, which-typed-array@^1.1.15: gopd "^1.0.1" has-tostringtag "^1.0.2" +which@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" + integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== + dependencies: + isexe "^2.0.0" + wrappy@1: version "1.0.2" resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" @@ -2035,6 +2162,11 @@ write@1.0.3: dependencies: mkdirp "^0.5.1" +yoctocolors@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/yoctocolors/-/yoctocolors-2.1.1.tgz#e0167474e9fbb9e8b3ecca738deaa61dd12e56fc" + integrity sha512-GQHQqAopRhwU8Kt1DDM8NjibDXHC8eoh1erhGAJPEyveY9qqVeXvVikNKrDz69sHowPMorbPUrH/mx8c50eiBQ== + zwitch@^1.0.0: version "1.0.5" resolved "https://registry.yarnpkg.com/zwitch/-/zwitch-1.0.5.tgz#d11d7381ffed16b742f6af7b3f223d5cd9fe9920"