From 61eb7c7576e6252b369e70e6d4eba6217c12b95a Mon Sep 17 00:00:00 2001 From: erdemcaygor Date: Mon, 14 Apr 2025 18:48:13 +0300 Subject: [PATCH] Refactor schematics:create-lib command to align with the standalone template structure. --- .../src/commands/change-theme/index.ts | 15 +++- .../.eslintrc.json.template | 44 ++++++++++ .../config/ng-package.json.template | 7 ++ .../config/src/enums/index.ts.template | 1 + .../config/src/enums/route-names.ts.template | 3 + .../config/src/providers/index.ts.template | 1 + .../src/providers/route.provider.ts.template | 25 ++++++ .../config/src/public-api.ts.template | 2 + .../karma.conf.js.template | 44 ++++++++++ .../ng-package.json.template | 7 ++ .../package.json.template | 11 +++ .../__libraryName@kebab__-routing.ts.template | 9 ++ ..._libraryName@kebab__.component.ts.template | 11 +++ .../src/lib/index.ts.template | 1 + .../src/public-api.ts.template | 4 + .../src/test.ts.template | 26 ++++++ .../tsconfig.lib.json.template | 20 +++++ .../tsconfig.lib.prod.json.template | 10 +++ .../tsconfig.spec.json.template | 17 ++++ .../ng-package.json.template | 6 ++ ...@kebab__-__libraryName@kebab__.ts.template | 7 ++ .../src/lib/index.ts.template | 1 + .../src/public-api.ts.template | 1 + .../src/commands/create-lib/index.ts | 88 ++++++++++++++++--- .../create-lib/models/generate-lib-schema.ts | 4 + .../src/commands/create-lib/schema.json | 11 ++- .../schematics/src/utils/angular/ast-utils.ts | 9 +- .../schematics/src/utils/workspace.ts | 11 +++ 28 files changed, 377 insertions(+), 19 deletions(-) create mode 100644 npm/ng-packs/packages/schematics/src/commands/create-lib/files-package-standalone/__libraryName@kebab__/.eslintrc.json.template create mode 100644 npm/ng-packs/packages/schematics/src/commands/create-lib/files-package-standalone/__libraryName@kebab__/config/ng-package.json.template create mode 100644 npm/ng-packs/packages/schematics/src/commands/create-lib/files-package-standalone/__libraryName@kebab__/config/src/enums/index.ts.template create mode 100644 npm/ng-packs/packages/schematics/src/commands/create-lib/files-package-standalone/__libraryName@kebab__/config/src/enums/route-names.ts.template create mode 100644 npm/ng-packs/packages/schematics/src/commands/create-lib/files-package-standalone/__libraryName@kebab__/config/src/providers/index.ts.template create mode 100644 npm/ng-packs/packages/schematics/src/commands/create-lib/files-package-standalone/__libraryName@kebab__/config/src/providers/route.provider.ts.template create mode 100644 npm/ng-packs/packages/schematics/src/commands/create-lib/files-package-standalone/__libraryName@kebab__/config/src/public-api.ts.template create mode 100644 npm/ng-packs/packages/schematics/src/commands/create-lib/files-package-standalone/__libraryName@kebab__/karma.conf.js.template create mode 100644 npm/ng-packs/packages/schematics/src/commands/create-lib/files-package-standalone/__libraryName@kebab__/ng-package.json.template create mode 100644 npm/ng-packs/packages/schematics/src/commands/create-lib/files-package-standalone/__libraryName@kebab__/package.json.template create mode 100644 npm/ng-packs/packages/schematics/src/commands/create-lib/files-package-standalone/__libraryName@kebab__/src/lib/__libraryName@kebab__-routing.ts.template create mode 100644 npm/ng-packs/packages/schematics/src/commands/create-lib/files-package-standalone/__libraryName@kebab__/src/lib/__libraryName@kebab__.component.ts.template create mode 100644 npm/ng-packs/packages/schematics/src/commands/create-lib/files-package-standalone/__libraryName@kebab__/src/lib/index.ts.template create mode 100644 npm/ng-packs/packages/schematics/src/commands/create-lib/files-package-standalone/__libraryName@kebab__/src/public-api.ts.template create mode 100644 npm/ng-packs/packages/schematics/src/commands/create-lib/files-package-standalone/__libraryName@kebab__/src/test.ts.template create mode 100644 npm/ng-packs/packages/schematics/src/commands/create-lib/files-package-standalone/__libraryName@kebab__/tsconfig.lib.json.template create mode 100644 npm/ng-packs/packages/schematics/src/commands/create-lib/files-package-standalone/__libraryName@kebab__/tsconfig.lib.prod.json.template create mode 100644 npm/ng-packs/packages/schematics/src/commands/create-lib/files-package-standalone/__libraryName@kebab__/tsconfig.spec.json.template create mode 100644 npm/ng-packs/packages/schematics/src/commands/create-lib/files-secondary-entrypoint-standalone/__libraryName@kebab__/ng-package.json.template create mode 100644 npm/ng-packs/packages/schematics/src/commands/create-lib/files-secondary-entrypoint-standalone/__libraryName@kebab__/src/lib/__target@kebab__-__libraryName@kebab__.ts.template create mode 100644 npm/ng-packs/packages/schematics/src/commands/create-lib/files-secondary-entrypoint-standalone/__libraryName@kebab__/src/lib/index.ts.template create mode 100644 npm/ng-packs/packages/schematics/src/commands/create-lib/files-secondary-entrypoint-standalone/__libraryName@kebab__/src/public-api.ts.template diff --git a/npm/ng-packs/packages/schematics/src/commands/change-theme/index.ts b/npm/ng-packs/packages/schematics/src/commands/change-theme/index.ts index de0c75c2ef..56e80a0762 100644 --- a/npm/ng-packs/packages/schematics/src/commands/change-theme/index.ts +++ b/npm/ng-packs/packages/schematics/src/commands/change-theme/index.ts @@ -5,6 +5,7 @@ import * as ts from 'typescript'; import { allStyles, importMap, styleMap } from './style-map'; import { ChangeThemeOptions } from './model'; import { + applicationHasStandaloneTemplate, Change, createDefaultPath, InsertChange, @@ -68,13 +69,15 @@ function updateProjectStyle( function updateAppModule(selectedProject: string, targetThemeName: ThemeOptionsEnum): Rule { return async (host: Tree) => { - const appModulePath = (await createDefaultPath(host, selectedProject)) + '/app.module.ts'; + const isStandalone = applicationHasStandaloneTemplate(host, selectedProject); + const defaultPath = await createDefaultPath(host, selectedProject); + const appModulePath = defaultPath + `${isStandalone ? '/app.component.ts' : '/app.module.ts'}`; return chain([ removeImportPath(appModulePath, targetThemeName), removeImportFromNgModuleMetadata(appModulePath, targetThemeName), removeProviderFromNgModuleMetadata(appModulePath, targetThemeName), - insertImports(appModulePath, targetThemeName), + insertImports(appModulePath, targetThemeName, isStandalone), insertProviders(appModulePath, targetThemeName), ]); }; @@ -192,7 +195,11 @@ export function removeProviderFromNgModuleMetadata( }; } -export function insertImports(appModulePath: string, selectedTheme: ThemeOptionsEnum): Rule { +export function insertImports( + appModulePath: string, + selectedTheme: ThemeOptionsEnum, + isStandalone = false, +): Rule { return (host: Tree) => { const recorder = host.beginUpdate(appModulePath); const source = createSourceFile(host, appModulePath); @@ -205,7 +212,7 @@ export function insertImports(appModulePath: string, selectedTheme: ThemeOptions const changes: Change[] = []; selected.map(({ importName, path }) => - changes.push(...addImportToModule(source, appModulePath, importName, path)), + changes.push(...addImportToModule(source, appModulePath, importName, path, isStandalone)), ); if (changes.length > 0) { diff --git a/npm/ng-packs/packages/schematics/src/commands/create-lib/files-package-standalone/__libraryName@kebab__/.eslintrc.json.template b/npm/ng-packs/packages/schematics/src/commands/create-lib/files-package-standalone/__libraryName@kebab__/.eslintrc.json.template new file mode 100644 index 0000000000..de84cad019 --- /dev/null +++ b/npm/ng-packs/packages/schematics/src/commands/create-lib/files-package-standalone/__libraryName@kebab__/.eslintrc.json.template @@ -0,0 +1,44 @@ +{ + "extends": "../../.eslintrc.json", + "ignorePatterns": [ + "!**/*" + ], + "overrides": [ + { + "files": [ + "*.ts" + ], + "parserOptions": { + "project": [ + "projects/<%= kebab(libraryName) %>/tsconfig.lib.json", + "projects/<%= kebab(libraryName) %>/tsconfig.spec.json" + ], + "createDefaultProgram": true + }, + "rules": { + "@angular-eslint/directive-selector": [ + "error", + { + "type": "attribute", + "prefix": "lib", + "style": "camelCase" + } + ], + "@angular-eslint/component-selector": [ + "error", + { + "type": "element", + "prefix": "lib", + "style": "kebab-case" + } + ] + } + }, + { + "files": [ + "*.html" + ], + "rules": {} + } + ] +} diff --git a/npm/ng-packs/packages/schematics/src/commands/create-lib/files-package-standalone/__libraryName@kebab__/config/ng-package.json.template b/npm/ng-packs/packages/schematics/src/commands/create-lib/files-package-standalone/__libraryName@kebab__/config/ng-package.json.template new file mode 100644 index 0000000000..6cf8e96f64 --- /dev/null +++ b/npm/ng-packs/packages/schematics/src/commands/create-lib/files-package-standalone/__libraryName@kebab__/config/ng-package.json.template @@ -0,0 +1,7 @@ +{ + "$schema": "../../../node_modules/ng-packagr/ng-entrypoint.schema.json", + "dest": "../../dist/<%= kebab(libraryName) %>/config", + "lib": { + "entryFile": "src/public-api.ts" + } +} diff --git a/npm/ng-packs/packages/schematics/src/commands/create-lib/files-package-standalone/__libraryName@kebab__/config/src/enums/index.ts.template b/npm/ng-packs/packages/schematics/src/commands/create-lib/files-package-standalone/__libraryName@kebab__/config/src/enums/index.ts.template new file mode 100644 index 0000000000..3bda94b078 --- /dev/null +++ b/npm/ng-packs/packages/schematics/src/commands/create-lib/files-package-standalone/__libraryName@kebab__/config/src/enums/index.ts.template @@ -0,0 +1 @@ +export * from './route-names'; diff --git a/npm/ng-packs/packages/schematics/src/commands/create-lib/files-package-standalone/__libraryName@kebab__/config/src/enums/route-names.ts.template b/npm/ng-packs/packages/schematics/src/commands/create-lib/files-package-standalone/__libraryName@kebab__/config/src/enums/route-names.ts.template new file mode 100644 index 0000000000..3bbb75be52 --- /dev/null +++ b/npm/ng-packs/packages/schematics/src/commands/create-lib/files-package-standalone/__libraryName@kebab__/config/src/enums/route-names.ts.template @@ -0,0 +1,3 @@ +export const enum e<%= pascal(libraryName) %>RouteNames { + <%= pascal(libraryName) %> = '<%= pascal(libraryName) %>', +} diff --git a/npm/ng-packs/packages/schematics/src/commands/create-lib/files-package-standalone/__libraryName@kebab__/config/src/providers/index.ts.template b/npm/ng-packs/packages/schematics/src/commands/create-lib/files-package-standalone/__libraryName@kebab__/config/src/providers/index.ts.template new file mode 100644 index 0000000000..fe08efba8c --- /dev/null +++ b/npm/ng-packs/packages/schematics/src/commands/create-lib/files-package-standalone/__libraryName@kebab__/config/src/providers/index.ts.template @@ -0,0 +1 @@ +export * from './route.provider'; diff --git a/npm/ng-packs/packages/schematics/src/commands/create-lib/files-package-standalone/__libraryName@kebab__/config/src/providers/route.provider.ts.template b/npm/ng-packs/packages/schematics/src/commands/create-lib/files-package-standalone/__libraryName@kebab__/config/src/providers/route.provider.ts.template new file mode 100644 index 0000000000..91b2d7545c --- /dev/null +++ b/npm/ng-packs/packages/schematics/src/commands/create-lib/files-package-standalone/__libraryName@kebab__/config/src/providers/route.provider.ts.template @@ -0,0 +1,25 @@ +import { APP_INITIALIZER, Provider } from '@angular/core'; +import { eLayoutType, RoutesService } from '@abp/ng.core'; +import { e<%= pascal(libraryName) %>RouteNames } from '../enums/route-names'; +import { makeEnvironmentProviders, provideAppInitializer, inject } from '@angular/core'; + +export function configureRoutes() { + const routes = inject(RoutesService); + routes.add([ + { + path: '/<%= kebab(libraryName) %>', + name: e<%= pascal(libraryName) %>RouteNames.<%= pascal(libraryName) %>, + iconClass: 'fas fa-book', + layout: eLayoutType.application, + order: 3, + }, + ]); +} + +export function provide<%= pascal(libraryName) %>Config() { + return makeEnvironmentProviders([ + provideAppInitializer(() => { + configureRoutes(); + }), + ]); +} diff --git a/npm/ng-packs/packages/schematics/src/commands/create-lib/files-package-standalone/__libraryName@kebab__/config/src/public-api.ts.template b/npm/ng-packs/packages/schematics/src/commands/create-lib/files-package-standalone/__libraryName@kebab__/config/src/public-api.ts.template new file mode 100644 index 0000000000..0003cebbef --- /dev/null +++ b/npm/ng-packs/packages/schematics/src/commands/create-lib/files-package-standalone/__libraryName@kebab__/config/src/public-api.ts.template @@ -0,0 +1,2 @@ +export * from './enums'; +export * from './providers'; diff --git a/npm/ng-packs/packages/schematics/src/commands/create-lib/files-package-standalone/__libraryName@kebab__/karma.conf.js.template b/npm/ng-packs/packages/schematics/src/commands/create-lib/files-package-standalone/__libraryName@kebab__/karma.conf.js.template new file mode 100644 index 0000000000..e181d4088d --- /dev/null +++ b/npm/ng-packs/packages/schematics/src/commands/create-lib/files-package-standalone/__libraryName@kebab__/karma.conf.js.template @@ -0,0 +1,44 @@ +// Karma configuration file, see link for more information +// https://karma-runner.github.io/1.0/config/configuration-file.html + +module.exports = function (config) { + config.set({ + basePath: '', + frameworks: ['jasmine', '@angular-devkit/build-angular'], + plugins: [ + require('karma-jasmine'), + require('karma-chrome-launcher'), + require('karma-jasmine-html-reporter'), + require('karma-coverage'), + require('@angular-devkit/build-angular/plugins/karma') + ], + client: { + jasmine: { + // you can add configuration options for Jasmine here + // the possible options are listed at https://jasmine.github.io/api/edge/Configuration.html + // for example, you can disable the random execution with `random: false` + // or set a specific seed with `seed: 4321` + }, + clearContext: false // leave Jasmine Spec Runner output visible in browser + }, + jasmineHtmlReporter: { + suppressAll: true // removes the duplicated traces + }, + coverageReporter: { + dir: require('path').join(__dirname, '../../coverage/<%= kebab(libraryName) %>'), + subdir: '.', + reporters: [ + { type: 'html' }, + { type: 'text-summary' } + ] + }, + reporters: ['progress', 'kjhtml'], + port: 9876, + colors: true, + logLevel: config.LOG_INFO, + autoWatch: true, + browsers: ['Chrome'], + singleRun: false, + restartOnFileChange: true + }); +}; diff --git a/npm/ng-packs/packages/schematics/src/commands/create-lib/files-package-standalone/__libraryName@kebab__/ng-package.json.template b/npm/ng-packs/packages/schematics/src/commands/create-lib/files-package-standalone/__libraryName@kebab__/ng-package.json.template new file mode 100644 index 0000000000..fd8e55d798 --- /dev/null +++ b/npm/ng-packs/packages/schematics/src/commands/create-lib/files-package-standalone/__libraryName@kebab__/ng-package.json.template @@ -0,0 +1,7 @@ +{ + "$schema": "../../node_modules/ng-packagr/ng-package.schema.json", + "dest": "../../dist/<%= kebab(libraryName) %>", + "lib": { + "entryFile": "src/public-api.ts" + } +} diff --git a/npm/ng-packs/packages/schematics/src/commands/create-lib/files-package-standalone/__libraryName@kebab__/package.json.template b/npm/ng-packs/packages/schematics/src/commands/create-lib/files-package-standalone/__libraryName@kebab__/package.json.template new file mode 100644 index 0000000000..c4d36a8576 --- /dev/null +++ b/npm/ng-packs/packages/schematics/src/commands/create-lib/files-package-standalone/__libraryName@kebab__/package.json.template @@ -0,0 +1,11 @@ +{ + "name": "@<%= kebab(libraryName) %>/<%= kebab(libraryName) %>", + "version": "0.0.1", + "peerDependencies": { + "@abp/ng.core": "<%= abpVersion %>", + "@abp/ng.theme.shared": "<%= abpVersion %>" + }, + "dependencies": { + "tslib": "^2.1.0" + } +} diff --git a/npm/ng-packs/packages/schematics/src/commands/create-lib/files-package-standalone/__libraryName@kebab__/src/lib/__libraryName@kebab__-routing.ts.template b/npm/ng-packs/packages/schematics/src/commands/create-lib/files-package-standalone/__libraryName@kebab__/src/lib/__libraryName@kebab__-routing.ts.template new file mode 100644 index 0000000000..fba42c7882 --- /dev/null +++ b/npm/ng-packs/packages/schematics/src/commands/create-lib/files-package-standalone/__libraryName@kebab__/src/lib/__libraryName@kebab__-routing.ts.template @@ -0,0 +1,9 @@ +import { Routes } from '@angular/router'; + +export const <%= pascal(libraryName) %>Routes: Routes = [ + { + path: '', + loadComponent: () => + import('./<%= kebab(libraryName) %>.component').then(m => m.<%= pascal(libraryName) %>HomeComponent), + }, +]; diff --git a/npm/ng-packs/packages/schematics/src/commands/create-lib/files-package-standalone/__libraryName@kebab__/src/lib/__libraryName@kebab__.component.ts.template b/npm/ng-packs/packages/schematics/src/commands/create-lib/files-package-standalone/__libraryName@kebab__/src/lib/__libraryName@kebab__.component.ts.template new file mode 100644 index 0000000000..78dae13b85 --- /dev/null +++ b/npm/ng-packs/packages/schematics/src/commands/create-lib/files-package-standalone/__libraryName@kebab__/src/lib/__libraryName@kebab__.component.ts.template @@ -0,0 +1,11 @@ +import { Component } from '@angular/core'; +import {CoreModule} from "@abp/ng.core"; +import {ThemeSharedModule} from "@abp/ng.theme.shared"; + +@Component({ + standalone: true, + selector: '<%= camel(libraryName) %>-home', + template: `

Lazy Loaded Test Component

`, + imports: [CoreModule, ThemeSharedModule], +}) +export class <%= pascal(libraryName) %>HomeComponent {} diff --git a/npm/ng-packs/packages/schematics/src/commands/create-lib/files-package-standalone/__libraryName@kebab__/src/lib/index.ts.template b/npm/ng-packs/packages/schematics/src/commands/create-lib/files-package-standalone/__libraryName@kebab__/src/lib/index.ts.template new file mode 100644 index 0000000000..aee9705b6f --- /dev/null +++ b/npm/ng-packs/packages/schematics/src/commands/create-lib/files-package-standalone/__libraryName@kebab__/src/lib/index.ts.template @@ -0,0 +1 @@ +export * from './<%= kebab(libraryName) %>-routing'; diff --git a/npm/ng-packs/packages/schematics/src/commands/create-lib/files-package-standalone/__libraryName@kebab__/src/public-api.ts.template b/npm/ng-packs/packages/schematics/src/commands/create-lib/files-package-standalone/__libraryName@kebab__/src/public-api.ts.template new file mode 100644 index 0000000000..5fa8ee704c --- /dev/null +++ b/npm/ng-packs/packages/schematics/src/commands/create-lib/files-package-standalone/__libraryName@kebab__/src/public-api.ts.template @@ -0,0 +1,4 @@ +/* + * Public API Surface of my-project-name + */ +export * from './lib'; diff --git a/npm/ng-packs/packages/schematics/src/commands/create-lib/files-package-standalone/__libraryName@kebab__/src/test.ts.template b/npm/ng-packs/packages/schematics/src/commands/create-lib/files-package-standalone/__libraryName@kebab__/src/test.ts.template new file mode 100644 index 0000000000..52e55168eb --- /dev/null +++ b/npm/ng-packs/packages/schematics/src/commands/create-lib/files-package-standalone/__libraryName@kebab__/src/test.ts.template @@ -0,0 +1,26 @@ +// This file is required by karma.conf.js and loads recursively all the .spec and framework files + +import 'zone.js'; +import 'zone.js/testing'; +import { getTestBed } from '@angular/core/testing'; +import { + BrowserDynamicTestingModule, + platformBrowserDynamicTesting +} from '@angular/platform-browser-dynamic/testing'; + +declare const require: { + context(path: string, deep?: boolean, filter?: RegExp): { + keys(): string[]; + (id: string): T; + }; +}; + +// First, initialize the Angular testing environment. +getTestBed().initTestEnvironment( + BrowserDynamicTestingModule, + platformBrowserDynamicTesting() +); +// Then we find all the tests. +const context = require.context('./', true, /\.spec\.ts$/); +// And load the modules. +context.keys().map(context); diff --git a/npm/ng-packs/packages/schematics/src/commands/create-lib/files-package-standalone/__libraryName@kebab__/tsconfig.lib.json.template b/npm/ng-packs/packages/schematics/src/commands/create-lib/files-package-standalone/__libraryName@kebab__/tsconfig.lib.json.template new file mode 100644 index 0000000000..5b574d313d --- /dev/null +++ b/npm/ng-packs/packages/schematics/src/commands/create-lib/files-package-standalone/__libraryName@kebab__/tsconfig.lib.json.template @@ -0,0 +1,20 @@ +/* To learn more about this file see: https://angular.io/config/tsconfig. */ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "outDir": "../../out-tsc/lib", + "target": "es2020", + "declaration": true, + "declarationMap": true, + "inlineSources": true, + "types": [], + "lib": [ + "dom", + "es2018" + ] + }, + "exclude": [ + "src/test.ts", + "**/*.spec.ts" + ] +} diff --git a/npm/ng-packs/packages/schematics/src/commands/create-lib/files-package-standalone/__libraryName@kebab__/tsconfig.lib.prod.json.template b/npm/ng-packs/packages/schematics/src/commands/create-lib/files-package-standalone/__libraryName@kebab__/tsconfig.lib.prod.json.template new file mode 100644 index 0000000000..06de549e10 --- /dev/null +++ b/npm/ng-packs/packages/schematics/src/commands/create-lib/files-package-standalone/__libraryName@kebab__/tsconfig.lib.prod.json.template @@ -0,0 +1,10 @@ +/* To learn more about this file see: https://angular.io/config/tsconfig. */ +{ + "extends": "./tsconfig.lib.json", + "compilerOptions": { + "declarationMap": false + }, + "angularCompilerOptions": { + "compilationMode": "partial" + } +} diff --git a/npm/ng-packs/packages/schematics/src/commands/create-lib/files-package-standalone/__libraryName@kebab__/tsconfig.spec.json.template b/npm/ng-packs/packages/schematics/src/commands/create-lib/files-package-standalone/__libraryName@kebab__/tsconfig.spec.json.template new file mode 100644 index 0000000000..715dd0a5d2 --- /dev/null +++ b/npm/ng-packs/packages/schematics/src/commands/create-lib/files-package-standalone/__libraryName@kebab__/tsconfig.spec.json.template @@ -0,0 +1,17 @@ +/* To learn more about this file see: https://angular.io/config/tsconfig. */ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "outDir": "../../out-tsc/spec", + "types": [ + "jasmine" + ] + }, + "files": [ + "src/test.ts" + ], + "include": [ + "**/*.spec.ts", + "**/*.d.ts" + ] +} diff --git a/npm/ng-packs/packages/schematics/src/commands/create-lib/files-secondary-entrypoint-standalone/__libraryName@kebab__/ng-package.json.template b/npm/ng-packs/packages/schematics/src/commands/create-lib/files-secondary-entrypoint-standalone/__libraryName@kebab__/ng-package.json.template new file mode 100644 index 0000000000..e09fb3fd03 --- /dev/null +++ b/npm/ng-packs/packages/schematics/src/commands/create-lib/files-secondary-entrypoint-standalone/__libraryName@kebab__/ng-package.json.template @@ -0,0 +1,6 @@ +{ + "$schema": "../../../node_modules/ng-packagr/ng-entrypoint.schema.json", + "lib": { + "entryFile": "src/public-api.ts" + } +} diff --git a/npm/ng-packs/packages/schematics/src/commands/create-lib/files-secondary-entrypoint-standalone/__libraryName@kebab__/src/lib/__target@kebab__-__libraryName@kebab__.ts.template b/npm/ng-packs/packages/schematics/src/commands/create-lib/files-secondary-entrypoint-standalone/__libraryName@kebab__/src/lib/__target@kebab__-__libraryName@kebab__.ts.template new file mode 100644 index 0000000000..a6b4121de5 --- /dev/null +++ b/npm/ng-packs/packages/schematics/src/commands/create-lib/files-secondary-entrypoint-standalone/__libraryName@kebab__/src/lib/__target@kebab__-__libraryName@kebab__.ts.template @@ -0,0 +1,7 @@ +import { Provider } from '@angular/core'; + +export function provide<%= pascal(target) %><%= pascal(libraryName) %>(): Provider[] { + return [ + // Add your providers here + ]; +} diff --git a/npm/ng-packs/packages/schematics/src/commands/create-lib/files-secondary-entrypoint-standalone/__libraryName@kebab__/src/lib/index.ts.template b/npm/ng-packs/packages/schematics/src/commands/create-lib/files-secondary-entrypoint-standalone/__libraryName@kebab__/src/lib/index.ts.template new file mode 100644 index 0000000000..b8bd795229 --- /dev/null +++ b/npm/ng-packs/packages/schematics/src/commands/create-lib/files-secondary-entrypoint-standalone/__libraryName@kebab__/src/lib/index.ts.template @@ -0,0 +1 @@ +export * from './<%= kebab(target) %>-<%= kebab(libraryName) %>'; diff --git a/npm/ng-packs/packages/schematics/src/commands/create-lib/files-secondary-entrypoint-standalone/__libraryName@kebab__/src/public-api.ts.template b/npm/ng-packs/packages/schematics/src/commands/create-lib/files-secondary-entrypoint-standalone/__libraryName@kebab__/src/public-api.ts.template new file mode 100644 index 0000000000..11aece60c4 --- /dev/null +++ b/npm/ng-packs/packages/schematics/src/commands/create-lib/files-secondary-entrypoint-standalone/__libraryName@kebab__/src/public-api.ts.template @@ -0,0 +1 @@ +export * from './lib/index'; diff --git a/npm/ng-packs/packages/schematics/src/commands/create-lib/index.ts b/npm/ng-packs/packages/schematics/src/commands/create-lib/index.ts index f353845880..78a7d2e904 100644 --- a/npm/ng-packs/packages/schematics/src/commands/create-lib/index.ts +++ b/npm/ng-packs/packages/schematics/src/commands/create-lib/index.ts @@ -68,10 +68,18 @@ function createLibrary(options: GenerateLibSchema): Rule { const target = await resolveProject(tree, options.packageName, null); if (!target || options.override) { if (options.isModuleTemplate) { - return createLibFromModuleTemplate(tree, options); + if (options.isStandaloneTemplate) { + return createLibFromModuleStandaloneTemplate(tree, options); + } else { + return createLibFromModuleTemplate(tree, options); + } } if (options.isSecondaryEntrypoint) { - return createLibSecondaryEntry(tree, options); + if (options.isStandaloneTemplate) { + return createLibSecondaryEntryWithStandaloneTemplate(tree, options); + } else { + return createLibSecondaryEntry(tree, options); + } } } else { throw new SchematicsException( @@ -109,14 +117,32 @@ async function createLibFromModuleTemplate(tree: Tree, options: GenerateLibSchem }), move(normalize(packagesDir)), ]), - addLibToWorkspaceIfNotExist(options.packageName, packagesDir), + addLibToWorkspaceIfNotExist(options, packagesDir), ]); } -export function addLibToWorkspaceIfNotExist(name: string, packagesDir: string): Rule { +async function createLibFromModuleStandaloneTemplate(tree: Tree, options: GenerateLibSchema) { + const packagesDir = await resolvePackagesDirFromAngularJson(tree); + const packageJson = JSON.parse(tree.read('./package.json')!.toString()); + const abpVersion = packageJson.dependencies['@abp/ng.core']; + + return chain([ + applyWithOverwrite(url('./files-package-standalone'), [ + applyTemplates({ + ...cases, + libraryName: options.packageName, + abpVersion, + }), + move(normalize(packagesDir)), + ]), + addLibToWorkspaceIfNotExist(options, packagesDir), + ]); +} + +export function addLibToWorkspaceIfNotExist(options: GenerateLibSchema, packagesDir: string): Rule { return async (tree: Tree) => { const workspace = await getWorkspace(tree); - const packageName = kebab(name); + const packageName = kebab(options.packageName); const isProjectExist = workspace.projects.has(packageName); const projectRoot = join(normalize(packagesDir), packageName); @@ -130,8 +156,8 @@ export function addLibToWorkspaceIfNotExist(name: string, packagesDir: string): : noop(), addLibToWorkspaceFile(projectRoot, packageName), updateTsConfig(packageName, pathImportLib), - importConfigModuleToDefaultProjectAppModule(workspace, packageName), - addRoutingToAppRoutingModule(workspace, packageName), + importConfigModuleToDefaultProjectAppModule(workspace, packageName, options), + addRoutingToAppRoutingModule(workspace, packageName, options), ]); }; } @@ -169,9 +195,30 @@ export async function createLibSecondaryEntry(tree: Tree, options: GenerateLibSc ]); } +export async function createLibSecondaryEntryWithStandaloneTemplate( + tree: Tree, + options: GenerateLibSchema, +) { + const targetLib = await resolveProject(tree, options.target); + const packageName = `${kebab(targetLib.name)}/${kebab(options.packageName)}`; + const importPath = `${targetLib.definition.root}/${kebab(options.packageName)}`; + return chain([ + applyWithOverwrite(url('./files-secondary-entrypoint-standalone'), [ + applyTemplates({ + ...cases, + libraryName: options.packageName, + target: targetLib.name, + }), + move(normalize(targetLib.definition.root)), + updateTsConfig(packageName, importPath), + ]), + ]); +} + export function importConfigModuleToDefaultProjectAppModule( workspace: WorkspaceDefinition, packageName: string, + options: GenerateLibSchema, ) { return (tree: Tree) => { const projectName = readWorkspaceSchema(tree).defaultProject || getFirstApplication(tree).name!; @@ -182,17 +229,25 @@ export function importConfigModuleToDefaultProjectAppModule( return; } const appModuleContent = appModule.toString(); - if (appModuleContent.includes(`${camel(packageName)}ConfigModule`)) { + if ( + appModuleContent.includes( + options.isStandaloneTemplate + ? `provide${pascal(packageName)}Config` + : `${camel(packageName)}ConfigModule`, + ) + ) { return; } - const forRootStatement = `${pascal(packageName)}ConfigModule.forRoot()`; + const rootConfigStatement = options.isStandaloneTemplate + ? `provide${pascal(packageName)}Config()` + : `${pascal(packageName)}ConfigModule.forRoot()`; const text = tree.read(appModulePath); if (!text) { return; } const sourceText = text.toString(); - if (sourceText.includes(forRootStatement)) { + if (sourceText.includes(rootConfigStatement)) { return; } const source = ts.createSourceFile(appModulePath, sourceText, ts.ScriptTarget.Latest, true); @@ -200,8 +255,9 @@ export function importConfigModuleToDefaultProjectAppModule( const changes = addImportToModule( source, appModulePath, - forRootStatement, + rootConfigStatement, `${kebab(packageName)}/config`, + options.isStandaloneTemplate, ); const recorder = tree.beginUpdate(appModulePath); for (const change of changes) { @@ -215,7 +271,11 @@ export function importConfigModuleToDefaultProjectAppModule( }; } -export function addRoutingToAppRoutingModule(workspace: WorkspaceDefinition, packageName: string) { +export function addRoutingToAppRoutingModule( + workspace: WorkspaceDefinition, + packageName: string, + options: GenerateLibSchema, +) { return (tree: Tree) => { const projectName = readWorkspaceSchema(tree).defaultProject || getFirstApplication(tree).name!; const project = workspace.projects.get(projectName); @@ -237,7 +297,9 @@ export function addRoutingToAppRoutingModule(workspace: WorkspaceDefinition, pac true, ); const importPath = `${kebab(packageName)}`; - const importStatement = `() => import('${importPath}').then(m => m.${moduleName}.forLazy())`; + const importStatement = options.isStandaloneTemplate + ? `() => import('${importPath}').then(m => m.${pascal(packageName)}Routes)` + : `() => import('${importPath}').then(m => m.${moduleName}.forLazy())`; const routeDefinition = `{ path: '${kebab(packageName)}', loadChildren: ${importStatement} }`; const change = addRouteDeclarationToModule(source, `${kebab(packageName)}`, routeDefinition); diff --git a/npm/ng-packs/packages/schematics/src/commands/create-lib/models/generate-lib-schema.ts b/npm/ng-packs/packages/schematics/src/commands/create-lib/models/generate-lib-schema.ts index f3c6e5b97f..a6d32e1da0 100644 --- a/npm/ng-packs/packages/schematics/src/commands/create-lib/models/generate-lib-schema.ts +++ b/npm/ng-packs/packages/schematics/src/commands/create-lib/models/generate-lib-schema.ts @@ -8,6 +8,10 @@ export interface GenerateLibSchema { * İs the package a library or a library module */ isSecondaryEntrypoint: boolean; + /** + * İs the package has standalone template + */ + isStandaloneTemplate: boolean; isModuleTemplate: boolean; diff --git a/npm/ng-packs/packages/schematics/src/commands/create-lib/schema.json b/npm/ng-packs/packages/schematics/src/commands/create-lib/schema.json index 19df1a5427..19de7420ae 100644 --- a/npm/ng-packs/packages/schematics/src/commands/create-lib/schema.json +++ b/npm/ng-packs/packages/schematics/src/commands/create-lib/schema.json @@ -31,12 +31,21 @@ }, "x-prompt": "Is module template?" }, + "isStandaloneTemplate": { + "description": "Is standalone template", + "type": "boolean", + "$default": { + "$source": "argv", + "index": 3 + }, + "x-prompt": "Is standalone template?" + }, "override": { "description": "Override existing files", "type": "boolean", "$default": { "$source": "argv", - "index": 3 + "index": 4 }, "x-prompt": "Override existing files?" } diff --git a/npm/ng-packs/packages/schematics/src/utils/angular/ast-utils.ts b/npm/ng-packs/packages/schematics/src/utils/angular/ast-utils.ts index d435b90c85..97eaa2e630 100644 --- a/npm/ng-packs/packages/schematics/src/utils/angular/ast-utils.ts +++ b/npm/ng-packs/packages/schematics/src/utils/angular/ast-utils.ts @@ -493,8 +493,15 @@ export function addImportToModule( modulePath: string, classifiedName: string, importPath: string, + isStandalone = false, ): Change[] { - return addSymbolToNgModuleMetadata(source, modulePath, 'imports', classifiedName, importPath); + return addSymbolToNgModuleMetadata( + source, + modulePath, + isStandalone ? 'providers' : 'imports', + classifiedName, + importPath, + ); } /** diff --git a/npm/ng-packs/packages/schematics/src/utils/workspace.ts b/npm/ng-packs/packages/schematics/src/utils/workspace.ts index ed53e482e8..6218bc038e 100644 --- a/npm/ng-packs/packages/schematics/src/utils/workspace.ts +++ b/npm/ng-packs/packages/schematics/src/utils/workspace.ts @@ -13,6 +13,17 @@ export function isLibrary(project: workspaces.ProjectDefinition): boolean { return project.extensions['projectType'] === ProjectType.Library; } +export function applicationHasStandaloneTemplate(tree: Tree, selectedProject?: string): boolean { + const workspace = readWorkspaceSchema(tree); + const project = workspace.projects[selectedProject ?? 0]; + + const mainPath = project.sourceRoot + '/main.ts'; + const mainSource = readFileInTree(tree, mainPath); + const mainContent = mainSource.toString(); + + return mainContent.includes('bootstrapComponent'); +} + export function readEnvironment(tree: Tree, project: workspaces.ProjectDefinition) { if (isLibrary(project)) return undefined;