@open-rlb/ng-app 3.1.110 → 3.1.112
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/fesm2022/open-rlb-ng-app.mjs +1 -0
- package/fesm2022/open-rlb-ng-app.mjs.map +1 -1
- package/package.json +10 -2
- package/schematics/collection.json +10 -0
- package/schematics/ng-add/claude-skills/rlb-app-apps/SKILL.md +110 -0
- package/schematics/ng-add/claude-skills/rlb-app-auth-acl/SKILL.md +82 -0
- package/schematics/ng-add/claude-skills/rlb-app-config/SKILL.md +67 -0
- package/schematics/ng-add/claude-skills/rlb-app-shell/SKILL.md +69 -0
- package/schematics/ng-add/claude-skills/rlb-app-store/SKILL.md +49 -0
- package/schematics/ng-add/files/app/app-init-acl.provider.ts.template +54 -0
- package/schematics/ng-add/files/app/app.component.ts.template +44 -0
- package/schematics/ng-add/files/app/app.config.ts.template +17 -0
- package/schematics/ng-add/files/app/app.describer.ts.template +30 -0
- package/schematics/ng-add/files/app/app.routes.ts.template +21 -0
- package/schematics/ng-add/files/app/home/home.component.html.template +4 -0
- package/schematics/ng-add/files/app/home/home.component.ts.template +13 -0
- package/schematics/ng-add/files/assets/i18n/en.json +106 -0
- package/schematics/ng-add/files/assets/i18n/it.json +101 -0
- package/schematics/ng-add/files/environments/environment.ts.template +86 -0
- package/schematics/ng-add/files/main.ts.template +5 -0
- package/schematics/ng-add/index.js +157 -0
- package/schematics/ng-add/schema.js +2 -0
- package/schematics/ng-add/schema.json +26 -0
- package/schematics/package.json +3 -0
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
{
|
|
2
|
+
"common": {
|
|
3
|
+
"ok": "Ok",
|
|
4
|
+
"cancel": "Cancel",
|
|
5
|
+
"close": "Close",
|
|
6
|
+
"save": "Save",
|
|
7
|
+
"delete": "Delete",
|
|
8
|
+
"add": "Add",
|
|
9
|
+
"edit": "Edit",
|
|
10
|
+
"name": "Name",
|
|
11
|
+
"description": "Description",
|
|
12
|
+
"search": "Search",
|
|
13
|
+
"searching": "Searching...",
|
|
14
|
+
"noResults": "No results",
|
|
15
|
+
"loading": "Loading...",
|
|
16
|
+
"yes": "Yes",
|
|
17
|
+
"no": "No"
|
|
18
|
+
},
|
|
19
|
+
"core": {
|
|
20
|
+
"apps": {
|
|
21
|
+
"button": "Apps",
|
|
22
|
+
"title": "Riolabs Apps"
|
|
23
|
+
},
|
|
24
|
+
"settings": {
|
|
25
|
+
"title": "Settings",
|
|
26
|
+
"generalTitle": "General settings",
|
|
27
|
+
"generalDescription": "Manage general settings of applications",
|
|
28
|
+
"support": "Support",
|
|
29
|
+
"privacy": "Privacy",
|
|
30
|
+
"cookies": "Cookies",
|
|
31
|
+
"legal": "Legal",
|
|
32
|
+
"status": "Status",
|
|
33
|
+
"logger": "Logger"
|
|
34
|
+
},
|
|
35
|
+
"account": {
|
|
36
|
+
"title": "Account",
|
|
37
|
+
"email": "Email",
|
|
38
|
+
"changePassword": "Change password",
|
|
39
|
+
"firstName": "First name",
|
|
40
|
+
"lastName": "Last name",
|
|
41
|
+
"login": "Login",
|
|
42
|
+
"logout": "Logout",
|
|
43
|
+
"username": "Username",
|
|
44
|
+
"session": {
|
|
45
|
+
"title": "Sessions",
|
|
46
|
+
"current": "Current session",
|
|
47
|
+
"ip": "IP",
|
|
48
|
+
"applications": "Applications",
|
|
49
|
+
"lastAccess": "Last access",
|
|
50
|
+
"started": "Started",
|
|
51
|
+
"expires": "Expires"
|
|
52
|
+
},
|
|
53
|
+
"credentials": {
|
|
54
|
+
"title": "Credentials",
|
|
55
|
+
"password": "Password",
|
|
56
|
+
"otp": "One-time password",
|
|
57
|
+
"name": "Name",
|
|
58
|
+
"created": "Created",
|
|
59
|
+
"actions": "Actions",
|
|
60
|
+
"update": "Update",
|
|
61
|
+
"delete": "Delete",
|
|
62
|
+
"noCredentials": "No credentials found for this section",
|
|
63
|
+
"addOTP": "Configure OTP",
|
|
64
|
+
"deleteTitle": "Delete credential",
|
|
65
|
+
"deleteHeader": "Delete credential confirmation",
|
|
66
|
+
"deleteMessage": "Are you sure you want to delete this credential?"
|
|
67
|
+
},
|
|
68
|
+
"settings": {
|
|
69
|
+
"title": "Account settings",
|
|
70
|
+
"showMore": "Show more"
|
|
71
|
+
}
|
|
72
|
+
},
|
|
73
|
+
"pwa": {
|
|
74
|
+
"newVersionAvailable": "New version available",
|
|
75
|
+
"updateNow": "Update now",
|
|
76
|
+
"updateMessage": "A new version of the application is available. Do you want to update it now?",
|
|
77
|
+
"later": "Later",
|
|
78
|
+
"update": "Update"
|
|
79
|
+
}
|
|
80
|
+
},
|
|
81
|
+
"pages": {
|
|
82
|
+
"notFound": {
|
|
83
|
+
"title": "Page not found",
|
|
84
|
+
"content": "The page you are looking for does not exist.",
|
|
85
|
+
"button": "Go to home page"
|
|
86
|
+
},
|
|
87
|
+
"forbidden": {
|
|
88
|
+
"title": "Access forbidden",
|
|
89
|
+
"content": "You do not have permission to access this page.",
|
|
90
|
+
"button": "Go to home page"
|
|
91
|
+
},
|
|
92
|
+
|
|
93
|
+
"support": {
|
|
94
|
+
"title": "Support",
|
|
95
|
+
"legal": "Legal",
|
|
96
|
+
"name": "Name",
|
|
97
|
+
"email": "Email",
|
|
98
|
+
"subject": "Subject",
|
|
99
|
+
"message": "Message",
|
|
100
|
+
"send": "Send",
|
|
101
|
+
"success": "Your message has been sent successfully.",
|
|
102
|
+
"error": "An error occurred while sending your message.",
|
|
103
|
+
"infoPage": "For more information, please visit our legal page"
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
{
|
|
2
|
+
"common": {
|
|
3
|
+
"ok": "Ok",
|
|
4
|
+
"cancel": "Annulla",
|
|
5
|
+
"close": "Chiudi",
|
|
6
|
+
"save": "Salva",
|
|
7
|
+
"delete": "Elimina",
|
|
8
|
+
"add": "Aggiungi",
|
|
9
|
+
"edit": "Modifica",
|
|
10
|
+
"name": "Nome",
|
|
11
|
+
"description": "Descrizione",
|
|
12
|
+
"search": "Cerca",
|
|
13
|
+
"searching": "Ricerca in corso...",
|
|
14
|
+
"noResults": "Nessun risultato",
|
|
15
|
+
"loading": "Caricamento...",
|
|
16
|
+
"yes": "Sì",
|
|
17
|
+
"no": "No"
|
|
18
|
+
},
|
|
19
|
+
"core": {
|
|
20
|
+
"apps": {
|
|
21
|
+
"button": "Applicazioni",
|
|
22
|
+
"title": "App di Riolabs"
|
|
23
|
+
},
|
|
24
|
+
"settings": {
|
|
25
|
+
"title": "Impostazioni",
|
|
26
|
+
"generalTitle": "Impostazioni generali",
|
|
27
|
+
"generalDescription": "Gestisci le impostazioni generali delle applicazioni",
|
|
28
|
+
"support": "Supporto",
|
|
29
|
+
"privacy": "Privacy",
|
|
30
|
+
"cookies": "Cookie",
|
|
31
|
+
"legal": "Legale",
|
|
32
|
+
"status": "Stato",
|
|
33
|
+
"logger": "Logger"
|
|
34
|
+
},
|
|
35
|
+
"account": {
|
|
36
|
+
"title": "Account",
|
|
37
|
+
"email": "Email",
|
|
38
|
+
"changePassword": "Cambia password",
|
|
39
|
+
"firstName": "Nome",
|
|
40
|
+
"lastName": "Cognome",
|
|
41
|
+
"login": "Accesso",
|
|
42
|
+
"logout": "Esci",
|
|
43
|
+
"username": "Nome utente",
|
|
44
|
+
"session": {
|
|
45
|
+
"title": "Sessioni",
|
|
46
|
+
"current": "Sessione corrente",
|
|
47
|
+
"ip": "IP",
|
|
48
|
+
"applications": "Applicazioni",
|
|
49
|
+
"lastAccess": "Ultimo accesso",
|
|
50
|
+
"started": "Iniziata",
|
|
51
|
+
"expires": "Scade il"
|
|
52
|
+
},
|
|
53
|
+
"credentials": {
|
|
54
|
+
"title": "Credenziali",
|
|
55
|
+
"password": "Password",
|
|
56
|
+
"otp": "Password monouso",
|
|
57
|
+
"name": "Nome",
|
|
58
|
+
"created": "Creato",
|
|
59
|
+
"actions": "Azioni",
|
|
60
|
+
"update": "Aggiorna",
|
|
61
|
+
"delete": "Elimina",
|
|
62
|
+
"noCredentials": "Nessuna credenziale trovata per questa sezione",
|
|
63
|
+
"addOTP": "Configura OTP",
|
|
64
|
+
"deleteTitle": "Elimina credenziale",
|
|
65
|
+
"deleteHeader": "Conferma eliminazione credenziale",
|
|
66
|
+
"deleteMessage": "Sei sicuro di voler eliminare questa credenziale?"
|
|
67
|
+
}
|
|
68
|
+
},
|
|
69
|
+
"pwa": {
|
|
70
|
+
"newVersionAvailable": "Nuova versione disponibile",
|
|
71
|
+
"updateNow": "Aggiorna ora",
|
|
72
|
+
"updateMessage": "È disponibile una nuova versione dell'applicazione. Vuoi aggiornarla ora?",
|
|
73
|
+
"later": "Dopo",
|
|
74
|
+
"update": "Aggiorna"
|
|
75
|
+
}
|
|
76
|
+
},
|
|
77
|
+
"pages": {
|
|
78
|
+
"notFound": {
|
|
79
|
+
"title": "Pagina non trovata",
|
|
80
|
+
"content": "La pagina che stai cercando non esiste.",
|
|
81
|
+
"button": "Vai alla home page"
|
|
82
|
+
},
|
|
83
|
+
"forbidden": {
|
|
84
|
+
"title": "Accesso negato",
|
|
85
|
+
"content": "Non hai i permessi necessari per accedere a questa pagina.",
|
|
86
|
+
"button": "Vai alla home page"
|
|
87
|
+
},
|
|
88
|
+
"support": {
|
|
89
|
+
"title": "Supporto",
|
|
90
|
+
"legal": "Legale",
|
|
91
|
+
"name": "Nome",
|
|
92
|
+
"email": "Email",
|
|
93
|
+
"subject": "Oggetto",
|
|
94
|
+
"message": "Messaggio",
|
|
95
|
+
"send": "Invia",
|
|
96
|
+
"success": "Il tuo messaggio è stato inviato con successo.",
|
|
97
|
+
"error": "Si è verificato un errore durante l'invio del messaggio.",
|
|
98
|
+
"infoPage": "Per maggiori informazioni, visita la nostra pagina legale"
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { ProjectConfiguration } from '@open-rlb/ng-app';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Application configuration consumed by `provideRlbConfig(environment)`.
|
|
5
|
+
*
|
|
6
|
+
* ⚠ Replace the placeholder values below with your real settings:
|
|
7
|
+
* - auth.providers[].authority / clientId / redirectUrl / postLogoutRedirectUri
|
|
8
|
+
* - auth.allowedUrls and endpoints[].baseUrl (your API gateway URLs)
|
|
9
|
+
*/
|
|
10
|
+
export const environment: ProjectConfiguration = {
|
|
11
|
+
production: false,
|
|
12
|
+
environment: {
|
|
13
|
+
baseUrl: 'http://localhost:4200',
|
|
14
|
+
ssr: false,
|
|
15
|
+
phone: false,
|
|
16
|
+
appLogo: '', // set to your logo path, e.g. 'assets/logo.svg' (place the file under src/assets)
|
|
17
|
+
appTitle: 'My App',
|
|
18
|
+
navbarDisabled: false,
|
|
19
|
+
errorDialogName: 'error-modal-component',
|
|
20
|
+
pwaUpdateEnabled: true,
|
|
21
|
+
errorDialogSize: 'md',
|
|
22
|
+
logLevel: 'log',
|
|
23
|
+
},
|
|
24
|
+
i18n: {
|
|
25
|
+
availableLangs: ['en', 'it'],
|
|
26
|
+
defaultLanguage: 'en',
|
|
27
|
+
useLanguageBrowser: true,
|
|
28
|
+
storeSelectedLanguage: true,
|
|
29
|
+
cookieStoreName: 'language',
|
|
30
|
+
},
|
|
31
|
+
auth: {
|
|
32
|
+
protocol: 'oauth',
|
|
33
|
+
storage: 'localStorage',
|
|
34
|
+
interceptor: 'oauth-code-ep',
|
|
35
|
+
allowedUrls: ['https://api.example.com'],
|
|
36
|
+
enableCompanyInterceptor: true,
|
|
37
|
+
providers: [
|
|
38
|
+
{
|
|
39
|
+
configId: 'default',
|
|
40
|
+
authority: 'https://login.example.com/realms/your-realm',
|
|
41
|
+
domains: ['localhost'],
|
|
42
|
+
redirectUrl: 'http://localhost:4200',
|
|
43
|
+
postLogoutRedirectUri: 'http://localhost:4200',
|
|
44
|
+
clientId: 'your-client-id',
|
|
45
|
+
scope: 'openid profile offline_access',
|
|
46
|
+
logLevel: 2,
|
|
47
|
+
acl: {
|
|
48
|
+
endpointKey: 'http-gateway',
|
|
49
|
+
path: 'admin/acl/resources',
|
|
50
|
+
},
|
|
51
|
+
},
|
|
52
|
+
],
|
|
53
|
+
},
|
|
54
|
+
pages: {
|
|
55
|
+
content: { path: 'content' },
|
|
56
|
+
cookies: { path: 'cookies' },
|
|
57
|
+
notFound: { path: 'not-found' },
|
|
58
|
+
forbidden: { path: 'forbidden' },
|
|
59
|
+
privacy: { path: 'privacy' },
|
|
60
|
+
support: { path: 'support' },
|
|
61
|
+
terms: { path: 'terms' },
|
|
62
|
+
status: { path: 'status' },
|
|
63
|
+
logger: { path: 'logger' },
|
|
64
|
+
},
|
|
65
|
+
endpoints: {
|
|
66
|
+
'http-gateway': {
|
|
67
|
+
baseUrl: 'https://api.example.com',
|
|
68
|
+
auth: true,
|
|
69
|
+
healthPath: 'health',
|
|
70
|
+
wss: false,
|
|
71
|
+
},
|
|
72
|
+
'ws-gateway': {
|
|
73
|
+
baseUrl: 'wss://api.example.com',
|
|
74
|
+
healthPath: 'health',
|
|
75
|
+
auth: true,
|
|
76
|
+
wss: true,
|
|
77
|
+
},
|
|
78
|
+
},
|
|
79
|
+
acl: {
|
|
80
|
+
businessIdKey: 'businessId',
|
|
81
|
+
resourceIdKey: 'resourceId',
|
|
82
|
+
interceptorMapping: {
|
|
83
|
+
companyId: 'companyId',
|
|
84
|
+
},
|
|
85
|
+
},
|
|
86
|
+
};
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ngAdd = ngAdd;
|
|
4
|
+
const core_1 = require("@angular-devkit/core");
|
|
5
|
+
const schematics_1 = require("@angular-devkit/schematics");
|
|
6
|
+
const utility_1 = require("@schematics/angular/utility");
|
|
7
|
+
/**
|
|
8
|
+
* Dependencies the library needs at the consumer side. `@angular/{core,common,forms,router}`
|
|
9
|
+
* and `rxjs` are intentionally omitted: every Angular app already provides them. Versions mirror
|
|
10
|
+
* the ranges declared in the library's `peerDependencies`.
|
|
11
|
+
*/
|
|
12
|
+
const DEPENDENCIES = [
|
|
13
|
+
{ name: '@open-rlb/ng-bootstrap', version: '^3.0.1', type: utility_1.DependencyType.Default },
|
|
14
|
+
{ name: '@open-rlb/date-tz', version: '^2.1.1', type: utility_1.DependencyType.Default },
|
|
15
|
+
{ name: '@ngrx/store', version: '^21.0.0', type: utility_1.DependencyType.Default },
|
|
16
|
+
{ name: '@ngrx/effects', version: '^21.0.0', type: utility_1.DependencyType.Default },
|
|
17
|
+
{ name: '@ngrx/operators', version: '^21.0.0', type: utility_1.DependencyType.Default },
|
|
18
|
+
{ name: '@ngrx/signals', version: '^21.0.0', type: utility_1.DependencyType.Default },
|
|
19
|
+
{ name: '@ngx-translate/core', version: '^17.0.0', type: utility_1.DependencyType.Default },
|
|
20
|
+
{ name: '@ngx-translate/http-loader', version: '^17.0.0', type: utility_1.DependencyType.Default },
|
|
21
|
+
{ name: 'angular-auth-oidc-client', version: '^19.0.1', type: utility_1.DependencyType.Default },
|
|
22
|
+
{ name: 'ngx-cookie-service', version: '^21.1.0', type: utility_1.DependencyType.Default },
|
|
23
|
+
{ name: 'ngx-cookie-service-ssr', version: '^21.1.0', type: utility_1.DependencyType.Default },
|
|
24
|
+
{ name: '@angular/service-worker', version: '^21.0.0', type: utility_1.DependencyType.Default },
|
|
25
|
+
{ name: 'bootstrap-icons', version: '^1.13.1', type: utility_1.DependencyType.Default },
|
|
26
|
+
{ name: '@types/bootstrap', version: '^5.2.10', type: utility_1.DependencyType.Dev },
|
|
27
|
+
];
|
|
28
|
+
/** Global styles required for the Bootstrap + @open-rlb/ng-bootstrap look & feel. */
|
|
29
|
+
const STYLE_PATHS = [
|
|
30
|
+
'node_modules/bootstrap-icons/font/bootstrap-icons.css',
|
|
31
|
+
'node_modules/@open-rlb/ng-bootstrap/assets/scss/app.scss',
|
|
32
|
+
'node_modules/@open-rlb/ng-bootstrap/assets/scss/icons.scss',
|
|
33
|
+
];
|
|
34
|
+
/** SCSS `@use`/`@import` resolution root needed by the ng-bootstrap stylesheets. */
|
|
35
|
+
const STYLE_INCLUDE_PATH = 'node_modules';
|
|
36
|
+
/** Source folder for the scaffolded runtime assets (i18n JSON, logo), served at `/assets`. */
|
|
37
|
+
const ASSETS_INPUT = 'src/assets';
|
|
38
|
+
function ngAdd(options) {
|
|
39
|
+
return async (tree, _context) => {
|
|
40
|
+
const project = await resolveProject(tree, options.project);
|
|
41
|
+
return (0, schematics_1.chain)([
|
|
42
|
+
// 1. Install dependencies (a single npm install is scheduled automatically).
|
|
43
|
+
...DEPENDENCIES.map(dep => (0, utility_1.addDependency)(dep.name, dep.version, { type: dep.type })),
|
|
44
|
+
// 2. Register Bootstrap + ng-bootstrap global styles and the SCSS include path in angular.json.
|
|
45
|
+
addBootstrapStyles(project),
|
|
46
|
+
// 3. Scaffold the runnable application shell (providers, environment, app component, routes).
|
|
47
|
+
options.skipShell ? noop : scaffoldShell(tree, project),
|
|
48
|
+
// 4. Optionally copy the bundled Claude skills into .claude/skills.
|
|
49
|
+
options.skipSkills ? noop : copyClaudeSkills(),
|
|
50
|
+
// 5. Print next steps.
|
|
51
|
+
logNextSteps(project, options),
|
|
52
|
+
]);
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
/** Resolves the target project: the provided name, else the first application, else the first project. */
|
|
56
|
+
async function resolveProject(tree, name) {
|
|
57
|
+
const workspace = await (0, utility_1.readWorkspace)(tree);
|
|
58
|
+
if (name) {
|
|
59
|
+
if (!workspace.projects.has(name)) {
|
|
60
|
+
throw new schematics_1.SchematicsException(`Project "${name}" was not found in the workspace.`);
|
|
61
|
+
}
|
|
62
|
+
return name;
|
|
63
|
+
}
|
|
64
|
+
for (const [projectName, project] of workspace.projects) {
|
|
65
|
+
if (project.extensions['projectType'] === 'application') {
|
|
66
|
+
return projectName;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
const first = workspace.projects.keys().next().value;
|
|
70
|
+
if (!first) {
|
|
71
|
+
throw new schematics_1.SchematicsException('No project found in the workspace to add @open-rlb/ng-app to.');
|
|
72
|
+
}
|
|
73
|
+
return first;
|
|
74
|
+
}
|
|
75
|
+
function addBootstrapStyles(project) {
|
|
76
|
+
return (0, utility_1.updateWorkspace)(workspace => {
|
|
77
|
+
const target = workspace.projects.get(project)?.targets.get('build');
|
|
78
|
+
if (!target) {
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
target.options ??= {};
|
|
82
|
+
const styles = target.options['styles'] ?? [];
|
|
83
|
+
for (const style of STYLE_PATHS) {
|
|
84
|
+
const present = styles.some(s => (typeof s === 'string' ? s : s.input) === style);
|
|
85
|
+
if (!present) {
|
|
86
|
+
styles.unshift(style);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
target.options['styles'] = styles;
|
|
90
|
+
const preprocessor = target.options['stylePreprocessorOptions'] ?? {};
|
|
91
|
+
const includePaths = preprocessor.includePaths ?? [];
|
|
92
|
+
if (!includePaths.includes(STYLE_INCLUDE_PATH)) {
|
|
93
|
+
includePaths.push(STYLE_INCLUDE_PATH);
|
|
94
|
+
}
|
|
95
|
+
preprocessor.includePaths = includePaths;
|
|
96
|
+
target.options['stylePreprocessorOptions'] = preprocessor;
|
|
97
|
+
const assets = target.options['assets'] ?? [];
|
|
98
|
+
const servesAssets = assets.some(a => {
|
|
99
|
+
const input = typeof a === 'string' ? a : a.input;
|
|
100
|
+
return input === ASSETS_INPUT;
|
|
101
|
+
});
|
|
102
|
+
if (!servesAssets) {
|
|
103
|
+
assets.push({ glob: '**/*', input: ASSETS_INPUT, output: 'assets' });
|
|
104
|
+
}
|
|
105
|
+
target.options['assets'] = assets;
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
function scaffoldShell(tree, project) {
|
|
109
|
+
return async () => {
|
|
110
|
+
const workspace = await (0, utility_1.readWorkspace)(tree);
|
|
111
|
+
const def = workspace.projects.get(project);
|
|
112
|
+
const sourceRoot = def?.sourceRoot ?? (def ? `${def.root}/src` : 'src');
|
|
113
|
+
const templates = (0, schematics_1.apply)((0, schematics_1.url)('./files'), [
|
|
114
|
+
(0, schematics_1.applyTemplates)({ ...core_1.strings }),
|
|
115
|
+
(0, schematics_1.move)(sourceRoot),
|
|
116
|
+
]);
|
|
117
|
+
// Overwrite the core shell files: ng add assumes a fresh/near-fresh app and the shell is the
|
|
118
|
+
// deliverable. Existing files (e.g. the default app.config.ts from `ng new`) are replaced.
|
|
119
|
+
return (0, schematics_1.mergeWith)(templates, schematics_1.MergeStrategy.Overwrite);
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Copies the Claude skills bundled with the package into the consumer's
|
|
124
|
+
* `.claude/skills` folder. Library-authored skills are authoritative, so existing
|
|
125
|
+
* copies are overwritten to stay in sync with the installed version.
|
|
126
|
+
*/
|
|
127
|
+
function copyClaudeSkills() {
|
|
128
|
+
const skills = (0, schematics_1.apply)((0, schematics_1.url)('./claude-skills'), [(0, schematics_1.move)('.claude/skills')]);
|
|
129
|
+
return (0, schematics_1.mergeWith)(skills, schematics_1.MergeStrategy.Overwrite);
|
|
130
|
+
}
|
|
131
|
+
function logNextSteps(project, options) {
|
|
132
|
+
return (_tree, context) => {
|
|
133
|
+
const log = context.logger;
|
|
134
|
+
log.info('');
|
|
135
|
+
log.info('✅ @open-rlb/ng-app added successfully.');
|
|
136
|
+
log.info(' • Dependencies installed and added to package.json');
|
|
137
|
+
log.info(' • Bootstrap + ng-bootstrap styles registered in angular.json');
|
|
138
|
+
if (!options.skipShell) {
|
|
139
|
+
log.info(` • Application shell scaffolded into the "${project}" app:`);
|
|
140
|
+
log.info(' - src/main.ts bootstraps the AppComponent shell');
|
|
141
|
+
log.info(' - src/environments/environment.ts (config: auth, endpoints, i18n, pages, acl)');
|
|
142
|
+
log.info(' - src/app/app.config.ts (provideRlbConfig + provideApp + RLB_INIT_PROVIDER)');
|
|
143
|
+
log.info(' - src/app/app.component.ts (<rlb-app-container> shell), app.describer.ts, routes, home');
|
|
144
|
+
log.info(' A default root component from `ng new` (e.g. src/app/app.ts) is now unused and can be deleted.');
|
|
145
|
+
}
|
|
146
|
+
if (!options.skipSkills) {
|
|
147
|
+
log.info(' • Claude skills copied to .claude/skills/ (rlb-app-* guides)');
|
|
148
|
+
}
|
|
149
|
+
log.info('');
|
|
150
|
+
log.info('⚠ Before running: edit src/environments/environment.ts and replace the placeholder');
|
|
151
|
+
log.info(' OIDC authority/clientId/redirectUrl and endpoint baseUrls with your real values.');
|
|
152
|
+
log.info(' Then start the app with: ng serve');
|
|
153
|
+
log.info('');
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
/** A no-op rule. */
|
|
157
|
+
const noop = tree => tree;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "http://json-schema.org/draft-07/schema",
|
|
3
|
+
"$id": "OpenRlbNgAppNgAdd",
|
|
4
|
+
"title": "@open-rlb/ng-app ng-add schematic",
|
|
5
|
+
"type": "object",
|
|
6
|
+
"properties": {
|
|
7
|
+
"project": {
|
|
8
|
+
"type": "string",
|
|
9
|
+
"description": "The name of the project to add the library to.",
|
|
10
|
+
"$default": {
|
|
11
|
+
"$source": "projectName"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"skipShell": {
|
|
15
|
+
"type": "boolean",
|
|
16
|
+
"default": false,
|
|
17
|
+
"description": "Do not scaffold the application shell (environment, providers, app component, routes, home)."
|
|
18
|
+
},
|
|
19
|
+
"skipSkills": {
|
|
20
|
+
"type": "boolean",
|
|
21
|
+
"default": false,
|
|
22
|
+
"description": "Do not copy the bundled Claude skills into .claude/skills."
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
"required": []
|
|
26
|
+
}
|