@scania-nl/tegel-angular-extensions 0.0.4 → 0.0.5
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/README.md +291 -26
- package/docker/docker-entrypoint.sh +13 -0
- package/docker/extract-env-vars.sh +114 -0
- package/docker/nginx.conf +69 -0
- package/esm2022/index.mjs +16 -5
- package/esm2022/lib/env/angular/provide-runtime-config.mjs +161 -0
- package/esm2022/lib/env/angular/provide-static-config.mjs +44 -0
- package/esm2022/lib/env/core/create-env-kit.mjs +81 -0
- package/esm2022/lib/env/core/env-types.mjs +2 -0
- package/esm2022/lib/env/core/parse-env-file.mjs +140 -0
- package/index.d.ts +467 -4
- package/package.json +18 -6
- package/lib/toast/models/toast-state.enum.d.ts +0 -17
- package/lib/toast/models/toast-type.d.ts +0 -8
- package/lib/toast/models/toast.model.d.ts +0 -73
- package/lib/toast/provide-toast.d.ts +0 -3
- package/lib/toast/toast.component.d.ts +0 -24
- package/lib/toast/toast.config.d.ts +0 -35
- package/lib/toast/toast.service.d.ts +0 -98
- package/lib/utils/bootstrap-global-component.d.ts +0 -23
package/README.md
CHANGED
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+

|
|
2
|
+

|
|
3
|
+

|
|
4
|
+

|
|
5
|
+
|
|
1
6
|
# @scania-nl/tegel-angular-extensions
|
|
2
7
|
|
|
3
8
|
Angular services for working with the [Tegel Angular 17](https://www.npmjs.com/package/@scania/tegel-angular-17) component library.
|
|
@@ -7,38 +12,238 @@ Provides simple wrappers for toast and modal (TBC) functionality using Angular 1
|
|
|
7
12
|
|
|
8
13
|
## ✨ Features
|
|
9
14
|
|
|
10
|
-
|
|
11
|
-
-
|
|
12
|
-
-
|
|
13
|
-
-
|
|
15
|
+
1. **Runtime environment configuration**
|
|
16
|
+
- Schema-driven configuration and validation using Zod
|
|
17
|
+
- Deep-partial runtime overrides
|
|
18
|
+
- Runtime-required key enforcements
|
|
19
|
+
- Strong TypeScript inference
|
|
20
|
+
2. **ToastService**
|
|
21
|
+
- Drop-in UI integrations for Tegel Angular
|
|
22
|
+
- Signal-based `ToastService` for displaying toasts
|
|
23
|
+
- Customizable toast appearance and behavior
|
|
24
|
+
3. **Default Nginx config**
|
|
25
|
+
|
|
26
|
+
- Zero boilerplate - no Angular modules required
|
|
27
|
+
- Fully typed and configurable via DI
|
|
28
|
+
- Built for Angular 19+ standalone architecture
|
|
14
29
|
|
|
15
30
|
---
|
|
16
31
|
|
|
17
|
-
|
|
32
|
+
# 📘 Table of Contents
|
|
33
|
+
|
|
34
|
+
1. [Installation](#-installation)
|
|
35
|
+
2. [Environment Configuration Overview](#-environment-configuration-overview)
|
|
36
|
+
2.1. [Defining your schema with createEnvKit](#defining-your-schema-with-createenvkit)
|
|
37
|
+
2.2. [Defining Static Environments (Dev/Prod)](#defining-static-environments-devprod)
|
|
38
|
+
2.3. [Providing Runtime Configuration](#providing-runtime-configuration)
|
|
39
|
+
2.4. [Using the ENV_CONFIG Token](#using-the-env_config-token)
|
|
40
|
+
2.5. [Runtime Configuration Binaries](#runtime-configuration-binaries)
|
|
41
|
+
2.5.1. [`docker-entrypoint.sh`](#docker-entrypointsh)
|
|
42
|
+
2.5.2. [`extract-env-vars.sh`](#extract-env-varssh)
|
|
43
|
+
2.5.3. [`nginx.conf`](#nginxconf)
|
|
44
|
+
2.5.4. [Example Docker Commands](#example-docker-commands)
|
|
45
|
+
3. [Toasts](#-toasts)
|
|
46
|
+
3.1. [Quick Start](#-quick-start)
|
|
47
|
+
3.1.1. [Add Providers](#add-providers)
|
|
48
|
+
3.1.2. [Use in components](#use-in-components)
|
|
49
|
+
3.2. [Configuration Options](#️-configuration-options)
|
|
50
|
+
3.3. [ToastService API](#-toastservice-api)
|
|
51
|
+
3.3.1. [ToastService Properties](#-toastservice-properties)
|
|
52
|
+
3.3.2. [ToastService Methods](#-toastservice-methods)
|
|
53
|
+
3.3.3. [Toast Lifecycle Hooks](#-toast-lifecycle-hooks)
|
|
54
|
+
4. [Appendix](#appendix)
|
|
55
|
+
4.1. [Dockerfile Example](#runtime-config-dockerfile-example)
|
|
56
|
+
5. [License](#-license)
|
|
57
|
+
|
|
58
|
+
---
|
|
59
|
+
|
|
60
|
+
# 📦 Installation
|
|
18
61
|
|
|
19
62
|
```bash
|
|
20
|
-
npm install @scania-nl/tegel-angular-extensions @scania/tegel-angular-17
|
|
63
|
+
npm install @scania-nl/tegel-angular-extensions @scania/tegel-angular-17 @traversable/zod zod
|
|
21
64
|
```
|
|
22
65
|
|
|
23
|
-
> Note: `@scania/tegel-angular-17`
|
|
66
|
+
> Note: `@scania/tegel-angular-17`, `@traversable/zod`, and `zod` are peer dependencies and must be installed separately.
|
|
24
67
|
|
|
25
|
-
|
|
68
|
+
When creating an Angular project, the following dependencies already should have been installed:
|
|
26
69
|
|
|
27
70
|
```json
|
|
28
71
|
{
|
|
29
72
|
"@angular/common": "^19.0.0",
|
|
30
73
|
"@angular/core": "^19.0.0",
|
|
31
74
|
"@angular/router": "^19.0.0",
|
|
32
|
-
"rxjs": "
|
|
75
|
+
"rxjs": ">=7.8.0"
|
|
76
|
+
}
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
---
|
|
80
|
+
|
|
81
|
+
# 🌍 Environment Configuration Overview
|
|
82
|
+
|
|
83
|
+
The runtime-config system provides:
|
|
84
|
+
|
|
85
|
+
- Type-safe configuration via Zod schemas
|
|
86
|
+
- Static environment validation
|
|
87
|
+
- Runtime overrides via .env files (shell scripts included)
|
|
88
|
+
- Guaranteed config availability before app bootstrap
|
|
89
|
+
|
|
90
|
+
## Defining your schema with createEnvKit
|
|
91
|
+
|
|
92
|
+
Create a local file: `src/environments/environment-config.ts`
|
|
93
|
+
|
|
94
|
+
```ts
|
|
95
|
+
import { InjectionToken } from '@angular/core';
|
|
96
|
+
import { createEnvKit } from '@scania-nl/tegel-angular-extensions';
|
|
97
|
+
import { z } from 'zod';
|
|
98
|
+
|
|
99
|
+
// Create the EnvKit by defining a Zod-schema
|
|
100
|
+
export const EnvKit = createEnvKit({
|
|
101
|
+
schema: z
|
|
102
|
+
.object({
|
|
103
|
+
envType: z.enum(['dev', 'preprod', 'staging', 'prod']),
|
|
104
|
+
production: z.boolean(),
|
|
105
|
+
apiUrl: z.url(),
|
|
106
|
+
})
|
|
107
|
+
.strict(),
|
|
108
|
+
runtimeRequiredKeys: ['apiUrl'],
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
// Re-export for static env files
|
|
112
|
+
type EnvConfig = typeof EnvKit.types.EnvConfig;
|
|
113
|
+
export type StaticEnv = typeof EnvKit.types.StaticEnv;
|
|
114
|
+
|
|
115
|
+
// Injection Token for EnvConfig
|
|
116
|
+
export const ENV_CONFIG = new InjectionToken<EnvConfig>('ENV_CONFIG');
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
## Defining Static Environments (Dev/Prod)
|
|
121
|
+
|
|
122
|
+
Initialize the environments using Nx:
|
|
123
|
+
```bash
|
|
124
|
+
nx g environments
|
|
125
|
+
```
|
|
126
|
+
This will create two files: `environment.ts` for production environment configuration and `environment.development.ts` for the local development environment configuration.
|
|
127
|
+
|
|
128
|
+
`environment.development.ts`:
|
|
129
|
+
```ts
|
|
130
|
+
import { StaticEnv } from './environment-config';
|
|
131
|
+
|
|
132
|
+
export const environment: StaticEnv = {
|
|
133
|
+
envType: 'dev',
|
|
134
|
+
production: false,
|
|
135
|
+
apiUrl: 'https://www.company.com/api/'
|
|
136
|
+
} satisfies StaticEnv;
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
`environment.ts`:
|
|
140
|
+
```ts
|
|
141
|
+
import { StaticEnv } from './environment-config';
|
|
142
|
+
|
|
143
|
+
export const environment: StaticEnv = {
|
|
144
|
+
envType: 'prod',
|
|
145
|
+
production: true,
|
|
146
|
+
// apiUrl: 'https://www.company.com/api/' // apiUrl cannot be defined here
|
|
147
|
+
} satisfies StaticEnv;
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
## Providing Runtime Configuration
|
|
152
|
+
|
|
153
|
+
Add to `app.config.ts`:
|
|
154
|
+
|
|
155
|
+
```ts
|
|
156
|
+
import { provideRuntimeConfig } from '@scania-nl/tegel-angular-extensions';
|
|
157
|
+
import { EnvKit, ENV_CONFIG } from '../environments/environment-config';
|
|
158
|
+
import { environment } from '../environments/environment';
|
|
159
|
+
|
|
160
|
+
export const appConfig: ApplicationConfig = {
|
|
161
|
+
providers: [
|
|
162
|
+
// ...
|
|
163
|
+
provideRuntimeConfig(EnvKit, environment, {
|
|
164
|
+
envPath: '/env/runtime.env', // Default
|
|
165
|
+
debug: !isDevMode(), // Defaults to false
|
|
166
|
+
stopOnError: true, // Default
|
|
167
|
+
token: ENV_CONFIG,
|
|
168
|
+
}),
|
|
169
|
+
],
|
|
170
|
+
};
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
## Using the ENV_CONFIG Token
|
|
175
|
+
|
|
176
|
+
```ts
|
|
177
|
+
import { inject } from '@angular/core';
|
|
178
|
+
import { ENV_CONFIG } from '../environments/environment-config';
|
|
179
|
+
|
|
180
|
+
@Injectable()
|
|
181
|
+
export class ApiService {
|
|
182
|
+
private readonly envConfig = inject(ENV_CONFIG);
|
|
183
|
+
|
|
184
|
+
constructor() {
|
|
185
|
+
console.log('API base URL:', this.envConfig.apiUrl);
|
|
186
|
+
}
|
|
33
187
|
}
|
|
34
188
|
```
|
|
189
|
+
|
|
190
|
+
This setup involves several key steps:
|
|
191
|
+
|
|
192
|
+
- At application startup, the code loads `/env/runtime.env`, parses any overrides using Zod (via a deep-partial schema), and merges them with the static configuration.
|
|
193
|
+
- Required configuration keys are enforced **only** in production.
|
|
194
|
+
- The validated configuration is exposed through Angular DI using the `ENV_CONFIG` InjectionToken.
|
|
195
|
+
- The `environment` file is referenced directly here. Angular’s build process replaces the `development` environment with the `production` environment via file replacement based on the selected build configuration.
|
|
196
|
+
|
|
197
|
+
> The `/env/runtime.env` file must be generated by the container during startup.
|
|
198
|
+
> Shell script binaries to support this are included the package.
|
|
199
|
+
|
|
200
|
+
## Runtime Configuration Binaries
|
|
201
|
+
|
|
202
|
+
This package ships with two lightweight shell scripts used to generate a runtime configuration file inside the container. They enable true runtime configurability without rebuilding the Angular image. Additionally, the package contains a default `nginx.conf` optimized for Angular application. The files are located in the `/docker` directory.
|
|
203
|
+
|
|
204
|
+
### `docker-entrypoint.sh`
|
|
205
|
+
- Entry point executed every time the container starts
|
|
206
|
+
- Calls the `extract-env-vars.sh` to generate a fresh `runtime.env`
|
|
207
|
+
- Lastly, executes the provided Dockerfile `CMD`
|
|
208
|
+
|
|
209
|
+
### `extract-env-vars.sh`
|
|
210
|
+
- Reads all container environment variables matching a prefix (default: `NG__`)
|
|
211
|
+
- Strips the prefix and writes cleaned `KEY=VALUE` pairs to `runtime.env`
|
|
212
|
+
- Supports nested keys via __ (e.g., `NG__myFeature__myThreshold`)
|
|
213
|
+
- Defaults output to `/usr/share/nginx/html/env/runtime.env`
|
|
214
|
+
|
|
215
|
+
### `nginx.conf`
|
|
216
|
+
A default Nginx configuration optimized for Angular applications. It provides:
|
|
217
|
+
|
|
218
|
+
- Performance tuning for static file serving
|
|
219
|
+
- Browser caching of compiled assets
|
|
220
|
+
- Gzip compression where supported
|
|
221
|
+
- Automatic fallback to `index.html` for client-side routing
|
|
222
|
+
|
|
223
|
+
### **Example Docker Commands**
|
|
224
|
+
|
|
225
|
+
```Dockerfile
|
|
226
|
+
# Copy the shell scripts to /usr/local/bin
|
|
227
|
+
COPY --from=build /app/node_modules/@scania-nl/tegel-angular-extensions/docker/*.sh /usr/local/bin/
|
|
228
|
+
# Ensure they shell scripts are executable
|
|
229
|
+
RUN chmod +x /usr/local/bin/*
|
|
230
|
+
# Use the shared entrypoint from the @scania-nl/tegel-angular-extensions npm package
|
|
231
|
+
ENTRYPOINT ["/usr/local/bin/docker-entrypoint.sh"]
|
|
232
|
+
# Start the nginx web server in the foreground and keep it running
|
|
233
|
+
CMD ["nginx", "-g", "daemon off;"]
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
For a complete Dockerfile example with the shipped `nginx.conf` config, refer to [Runtime Config Dockerfile Example](#runtime-config-dockerfile-example)
|
|
35
237
|
|
|
36
238
|
---
|
|
37
239
|
|
|
240
|
+
# 🔔 Toasts
|
|
241
|
+
|
|
38
242
|
## 🚀 Quick Start
|
|
39
243
|
|
|
40
|
-
###
|
|
41
|
-
|
|
244
|
+
### Add Providers
|
|
245
|
+
|
|
246
|
+
In your `app.config.ts`, specify the provider with `provideToast()`:
|
|
42
247
|
|
|
43
248
|
```ts
|
|
44
249
|
import { provideToast } from '@scania-nl/tegel-angular-extensions';
|
|
@@ -46,19 +251,21 @@ import { provideToast } from '@scania-nl/tegel-angular-extensions';
|
|
|
46
251
|
export const appConfig: ApplicationConfig = {
|
|
47
252
|
providers: [
|
|
48
253
|
provideToast({
|
|
49
|
-
type: 'information',
|
|
50
|
-
title: 'Notification',
|
|
51
|
-
description: '',
|
|
52
|
-
duration: 7500,
|
|
53
|
-
closeDuration: 300,
|
|
54
|
-
closable: true,
|
|
254
|
+
type: 'information', // Default toast type
|
|
255
|
+
title: 'Notification', // Default title
|
|
256
|
+
description: '', // Default description
|
|
257
|
+
duration: 7500, // Auto-dismiss delay (ms)
|
|
258
|
+
closeDuration: 300, // Fade-out animation duration (ms)
|
|
259
|
+
closable: true, // Show a close button
|
|
55
260
|
}),
|
|
56
261
|
],
|
|
57
262
|
};
|
|
58
263
|
```
|
|
264
|
+
|
|
59
265
|
> Note: The configuration is optional, all values shown above are the default settings.
|
|
60
266
|
|
|
61
|
-
###
|
|
267
|
+
### Use in components
|
|
268
|
+
|
|
62
269
|
In any standalone component:
|
|
63
270
|
|
|
64
271
|
```ts
|
|
@@ -72,9 +279,9 @@ export class MyToastDemoComponent {
|
|
|
72
279
|
|
|
73
280
|
showToast() {
|
|
74
281
|
this.toastService.create({
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
282
|
+
type: 'success',
|
|
283
|
+
title: 'Hello Toast',
|
|
284
|
+
description: 'Toast created successfully!',
|
|
78
285
|
});
|
|
79
286
|
}
|
|
80
287
|
}
|
|
@@ -107,7 +314,7 @@ The `ToastService` provides a signal-based API to create, manage, and dismiss to
|
|
|
107
314
|
|
|
108
315
|
---
|
|
109
316
|
|
|
110
|
-
### 📦 Properties
|
|
317
|
+
### 📦 ToastService Properties
|
|
111
318
|
|
|
112
319
|
| Property | Type | Description |
|
|
113
320
|
| -------------- | ----------------- | ----------------------------------------------------- |
|
|
@@ -116,7 +323,7 @@ The `ToastService` provides a signal-based API to create, manage, and dismiss to
|
|
|
116
323
|
|
|
117
324
|
---
|
|
118
325
|
|
|
119
|
-
### 🔧 Methods
|
|
326
|
+
### 🔧 ToastService Methods
|
|
120
327
|
|
|
121
328
|
#### `create(toastOptions: Partial<ToastOptions>): number`
|
|
122
329
|
|
|
@@ -206,12 +413,70 @@ Example:
|
|
|
206
413
|
toastService.success({
|
|
207
414
|
title: 'Logged out',
|
|
208
415
|
duration: 5000,
|
|
209
|
-
onRemoved: (toast) => console.log(`Toast ${toast.id} removed`)
|
|
416
|
+
onRemoved: (toast) => console.log(`Toast ${toast.id} removed`),
|
|
210
417
|
});
|
|
211
418
|
```
|
|
212
419
|
|
|
420
|
+
# Appendix
|
|
421
|
+
|
|
422
|
+
## Runtime Config Dockerfile Example
|
|
423
|
+
|
|
424
|
+
```Dockerfile
|
|
425
|
+
ARG NODE_VERSION=25-alpine
|
|
426
|
+
ARG NGINX_VERSION=1.29.3-alpine
|
|
427
|
+
|
|
428
|
+
# Stage 1: Build the Angular Application
|
|
429
|
+
FROM node:${NODE_VERSION} AS build
|
|
430
|
+
|
|
431
|
+
WORKDIR /app
|
|
432
|
+
|
|
433
|
+
# Copy package-related files
|
|
434
|
+
COPY package*.json ./
|
|
435
|
+
|
|
436
|
+
# Install project dependencies using npm ci (ensures a clean, reproducible install)
|
|
437
|
+
RUN --mount=type=cache,target=/root/.npm npm ci
|
|
438
|
+
|
|
439
|
+
# Copy the rest of the application source code into the container
|
|
440
|
+
COPY . .
|
|
441
|
+
|
|
442
|
+
# Build the Angular application with the specified app version
|
|
443
|
+
RUN npm run build
|
|
444
|
+
|
|
445
|
+
|
|
446
|
+
# Stage 2: Prepare Nginx to Serve Static Files
|
|
447
|
+
FROM nginx:${NGINX_VERSION}
|
|
448
|
+
|
|
449
|
+
# Copy the static build output from the build stage to Nginx's default HTML serving directory
|
|
450
|
+
COPY --from=build /app/dist/*/browser /usr/share/nginx/html
|
|
451
|
+
|
|
452
|
+
# Copy the shell scripts from the @scania-nl/tegel-angular-extensions npm package
|
|
453
|
+
COPY --from=build /app/node_modules/@scania-nl/tegel-angular-extensions/docker/*.sh /usr/local/bin/
|
|
454
|
+
# Copy the custom Nginx configuration file from the @scania-nl/tegel-angular-extensions npm package
|
|
455
|
+
COPY --from=build /app/node_modules/@scania-nl/tegel-angular-extensions/docker/nginx.conf /etc/nginx/nginx.conf
|
|
456
|
+
|
|
457
|
+
# Ensure the shell scripts are executable
|
|
458
|
+
RUN chmod +x /usr/local/bin/*
|
|
459
|
+
|
|
460
|
+
# Expose ports 80 and 443 to allow HTTP and HTTPS traffic
|
|
461
|
+
EXPOSE 80 443
|
|
462
|
+
|
|
463
|
+
# Use the shared entrypoint from the @scania-nl/tegel-angular-extensions npm package
|
|
464
|
+
ENTRYPOINT ["/usr/local/bin/docker-entrypoint.sh"]
|
|
465
|
+
|
|
466
|
+
# Start the nginx web server with custom config in the foreground and keep it running
|
|
467
|
+
CMD ["nginx", "-c", "/etc/nginx/nginx.conf", "-g", "daemon off;"]
|
|
468
|
+
```
|
|
469
|
+
|
|
213
470
|
---
|
|
214
471
|
|
|
215
|
-
|
|
472
|
+
# 📄 License
|
|
473
|
+
|
|
474
|
+
Copyright 2025 Scania CV AB.
|
|
475
|
+
|
|
476
|
+
All files are available under the MIT license. The Scania brand identity, logos and photographs found in this repository are copyrighted Scania CV AB and are not available on an open source basis or to be used as examples or in any other way, if not specifically ordered by Scania CV AB.
|
|
477
|
+
|
|
478
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
479
|
+
|
|
480
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
216
481
|
|
|
217
|
-
|
|
482
|
+
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
#!/bin/sh
|
|
2
|
+
|
|
3
|
+
ENV_OUTPUT_PATH="/usr/share/nginx/html/env/runtime.env"
|
|
4
|
+
|
|
5
|
+
rm -f "$ENV_OUTPUT_PATH" # Remove the runtime config if it exists
|
|
6
|
+
|
|
7
|
+
# Generate the runtime config from env vars
|
|
8
|
+
if ! /usr/local/bin/extract-env-vars.sh "" "$ENV_OUTPUT_PATH"; then
|
|
9
|
+
echo "Failed to extract runtime environment variables, continuing with defaults..."
|
|
10
|
+
fi
|
|
11
|
+
|
|
12
|
+
# Then start Nginx
|
|
13
|
+
exec "$@"
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
#!/bin/sh
|
|
2
|
+
|
|
3
|
+
# --------------
|
|
4
|
+
# Configuration
|
|
5
|
+
# --------------
|
|
6
|
+
|
|
7
|
+
PREFIX="${1:-NG__}" # First argument = prefix, defaults to NG__
|
|
8
|
+
OUTPUT_FILE="${2:-./runtime.env}" # Second argument = output path, defaults to current dir
|
|
9
|
+
shift 2 # Remaining arguments = manual test vars like NG__key=value
|
|
10
|
+
|
|
11
|
+
OUTPUT_DIR=$(dirname "$OUTPUT_FILE") # Output directory
|
|
12
|
+
TMP_FILE="/tmp/runtime_env_$$.tmp" # Temp file for writing
|
|
13
|
+
: > "$TMP_FILE" # Create/empty the temp file
|
|
14
|
+
|
|
15
|
+
# --------------
|
|
16
|
+
# Logging Helpers
|
|
17
|
+
# --------------
|
|
18
|
+
|
|
19
|
+
log_info() { echo "[INFO] $*"; }
|
|
20
|
+
log_warn() { echo "[WARN] $*"; }
|
|
21
|
+
log_debug() { echo "[DEBUG] $*"; }
|
|
22
|
+
|
|
23
|
+
# --------------
|
|
24
|
+
# Validation
|
|
25
|
+
# --------------
|
|
26
|
+
|
|
27
|
+
validate_var() {
|
|
28
|
+
raw="$1"
|
|
29
|
+
key="${raw%%=*}"
|
|
30
|
+
|
|
31
|
+
# Must start with prefix
|
|
32
|
+
case "$key" in
|
|
33
|
+
"$PREFIX") return 1 ;; # only prefix, no key
|
|
34
|
+
"$PREFIX"*) ;;
|
|
35
|
+
*) return 1 ;;
|
|
36
|
+
esac
|
|
37
|
+
|
|
38
|
+
# Strip prefix
|
|
39
|
+
trimmed="${key#$PREFIX}"
|
|
40
|
+
|
|
41
|
+
# Key must not start with a digit
|
|
42
|
+
first_segment=$(printf '%s' "$trimmed" | cut -d'_' -f1)
|
|
43
|
+
case "$first_segment" in
|
|
44
|
+
[0-9]*)
|
|
45
|
+
return 1 ;;
|
|
46
|
+
esac
|
|
47
|
+
|
|
48
|
+
return 0
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
strip_prefix() {
|
|
52
|
+
printf '%s\n' "$1" | sed "s/^$PREFIX//"
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
# --------------
|
|
56
|
+
# Extract ENV vars
|
|
57
|
+
# --------------
|
|
58
|
+
|
|
59
|
+
log_info "Using prefix: '$PREFIX'"
|
|
60
|
+
log_info "Output file: $OUTPUT_FILE"
|
|
61
|
+
|
|
62
|
+
env | grep "^$PREFIX" | while IFS= read -r line; do
|
|
63
|
+
if validate_var "$line"; then
|
|
64
|
+
key="${line%%=*}"
|
|
65
|
+
val="${line#*=}"
|
|
66
|
+
clean_key=$(strip_prefix "$key")
|
|
67
|
+
printf '%s=%s\n' "$clean_key" "$val" >> "$TMP_FILE"
|
|
68
|
+
log_debug "Added from environment: $clean_key=$val"
|
|
69
|
+
else
|
|
70
|
+
log_warn "Skipped invalid env var: $line"
|
|
71
|
+
fi
|
|
72
|
+
done
|
|
73
|
+
|
|
74
|
+
# --------------
|
|
75
|
+
# Manual vars
|
|
76
|
+
# --------------
|
|
77
|
+
|
|
78
|
+
for var in "$@"; do
|
|
79
|
+
if validate_var "$var"; then
|
|
80
|
+
key="${var%%=*}"
|
|
81
|
+
val="${var#*=}"
|
|
82
|
+
clean_key=$(strip_prefix "$key")
|
|
83
|
+
printf '%s=%s\n' "$clean_key" "$val" >> "$TMP_FILE"
|
|
84
|
+
log_debug "Added from CLI: $clean_key=$val"
|
|
85
|
+
else
|
|
86
|
+
log_warn "Skipped invalid manual var: $var"
|
|
87
|
+
fi
|
|
88
|
+
done
|
|
89
|
+
|
|
90
|
+
# --------------
|
|
91
|
+
# Output
|
|
92
|
+
# --------------
|
|
93
|
+
# Ensure the output directory exists
|
|
94
|
+
if [ ! -d "$OUTPUT_DIR" ]; then
|
|
95
|
+
log_info "Creating output directory: $OUTPUT_DIR"
|
|
96
|
+
if ! mkdir -p "$OUTPUT_DIR"; then
|
|
97
|
+
log_warn "Failed to create directory '$OUTPUT_DIR'"
|
|
98
|
+
rm -f "$TMP_FILE"
|
|
99
|
+
exit 1
|
|
100
|
+
fi
|
|
101
|
+
fi
|
|
102
|
+
|
|
103
|
+
if [ -s "$TMP_FILE" ]; then
|
|
104
|
+
if mv "$TMP_FILE" "$OUTPUT_FILE"; then
|
|
105
|
+
log_info "Wrote cleaned env vars to $OUTPUT_FILE"
|
|
106
|
+
else
|
|
107
|
+
log_warn "Failed to move temp file to $OUTPUT_FILE"
|
|
108
|
+
rm -f "$TMP_FILE"
|
|
109
|
+
exit 1
|
|
110
|
+
fi
|
|
111
|
+
else
|
|
112
|
+
rm -f "$TMP_FILE"
|
|
113
|
+
log_warn "No valid env vars found with prefix '$PREFIX'. Skipping output."
|
|
114
|
+
fi
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
worker_processes auto;
|
|
2
|
+
|
|
3
|
+
pid /tmp/nginx.pid;
|
|
4
|
+
|
|
5
|
+
events {
|
|
6
|
+
worker_connections 1024;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
http {
|
|
10
|
+
include /etc/nginx/mime.types;
|
|
11
|
+
default_type application/octet-stream;
|
|
12
|
+
|
|
13
|
+
# Logging
|
|
14
|
+
access_log off;
|
|
15
|
+
error_log /dev/stderr warn;
|
|
16
|
+
|
|
17
|
+
# Performance
|
|
18
|
+
sendfile on;
|
|
19
|
+
tcp_nopush on;
|
|
20
|
+
tcp_nodelay on;
|
|
21
|
+
keepalive_timeout 65;
|
|
22
|
+
keepalive_requests 1000;
|
|
23
|
+
|
|
24
|
+
# Compression
|
|
25
|
+
gzip on;
|
|
26
|
+
gzip_vary on;
|
|
27
|
+
gzip_proxied any;
|
|
28
|
+
gzip_min_length 256;
|
|
29
|
+
gzip_comp_level 6;
|
|
30
|
+
gzip_types
|
|
31
|
+
text/plain
|
|
32
|
+
text/css
|
|
33
|
+
text/xml
|
|
34
|
+
text/javascript
|
|
35
|
+
application/javascript
|
|
36
|
+
application/x-javascript
|
|
37
|
+
application/json
|
|
38
|
+
application/xml
|
|
39
|
+
application/xml+rss
|
|
40
|
+
font/ttf
|
|
41
|
+
font/otf
|
|
42
|
+
image/svg+xml;
|
|
43
|
+
|
|
44
|
+
server {
|
|
45
|
+
# listen 8080;
|
|
46
|
+
server_name localhost;
|
|
47
|
+
|
|
48
|
+
root /usr/share/nginx/html;
|
|
49
|
+
index index.html;
|
|
50
|
+
|
|
51
|
+
# Angular Routing
|
|
52
|
+
location / {
|
|
53
|
+
try_files $uri $uri/ /index.html;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
# Static Assets Caching
|
|
57
|
+
location ~* \.(?:ico|css|js|gif|jpe?g|png|woff2?|eot|ttf|svg|map)$ {
|
|
58
|
+
expires 1y;
|
|
59
|
+
access_log off;
|
|
60
|
+
add_header Cache-Control "public, immutable";
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
# Optional: Explicit asset route
|
|
64
|
+
location /assets/ {
|
|
65
|
+
expires 1y;
|
|
66
|
+
add_header Cache-Control "public, immutable";
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
package/esm2022/index.mjs
CHANGED
|
@@ -1,5 +1,16 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
export
|
|
5
|
-
|
|
1
|
+
// --------------------------------------------------
|
|
2
|
+
// Toast Module Exports
|
|
3
|
+
// --------------------------------------------------
|
|
4
|
+
export { provideToast } from './lib/toast/provide-toast';
|
|
5
|
+
export { DEFAULT_TOAST_CONFIG, TOAST_CONFIG, } from './lib/toast/toast.config';
|
|
6
|
+
export { ToastService } from './lib/toast/toast.service';
|
|
7
|
+
// --------------------------------------------------
|
|
8
|
+
// Env Module Exports
|
|
9
|
+
// --------------------------------------------------
|
|
10
|
+
// Core
|
|
11
|
+
export { createEnvKit } from './lib/env/core/create-env-kit';
|
|
12
|
+
export { parseEnvFile } from './lib/env/core/parse-env-file';
|
|
13
|
+
// Angular
|
|
14
|
+
export { provideRuntimeConfig } from './lib/env/angular/provide-runtime-config';
|
|
15
|
+
export { provideStaticConfig } from './lib/env/angular/provide-static-config';
|
|
16
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9saWJzL3RlZ2VsLWFuZ3VsYXItZXh0ZW5zaW9ucy9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEscURBQXFEO0FBQ3JELHVCQUF1QjtBQUN2QixxREFBcUQ7QUFDckQsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBQ3pELE9BQU8sRUFDTCxvQkFBb0IsRUFDcEIsWUFBWSxHQUViLE1BQU0sMEJBQTBCLENBQUM7QUFDbEMsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBS3pELHFEQUFxRDtBQUNyRCxxQkFBcUI7QUFDckIscURBQXFEO0FBQ3JELE9BQU87QUFDUCxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sK0JBQStCLENBQUM7QUFDN0QsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLCtCQUErQixDQUFDO0FBRTdELFVBQVU7QUFDVixPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSwwQ0FBMEMsQ0FBQztBQUNoRixPQUFPLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSx5Q0FBeUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4vLyBUb2FzdCBNb2R1bGUgRXhwb3J0c1xuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbmV4cG9ydCB7IHByb3ZpZGVUb2FzdCB9IGZyb20gJy4vbGliL3RvYXN0L3Byb3ZpZGUtdG9hc3QnO1xuZXhwb3J0IHtcbiAgREVGQVVMVF9UT0FTVF9DT05GSUcsXG4gIFRPQVNUX0NPTkZJRyxcbiAgVG9hc3RDb25maWcsXG59IGZyb20gJy4vbGliL3RvYXN0L3RvYXN0LmNvbmZpZyc7XG5leHBvcnQgeyBUb2FzdFNlcnZpY2UgfSBmcm9tICcuL2xpYi90b2FzdC90b2FzdC5zZXJ2aWNlJztcblxuLy8gTW9kZWxzXG5leHBvcnQgeyBUb2FzdCwgVG9hc3RPcHRpb25zIH0gZnJvbSAnLi9saWIvdG9hc3QvbW9kZWxzL3RvYXN0Lm1vZGVsJztcblxuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbi8vIEVudiBNb2R1bGUgRXhwb3J0c1xuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbi8vIENvcmVcbmV4cG9ydCB7IGNyZWF0ZUVudktpdCB9IGZyb20gJy4vbGliL2Vudi9jb3JlL2NyZWF0ZS1lbnYta2l0JztcbmV4cG9ydCB7IHBhcnNlRW52RmlsZSB9IGZyb20gJy4vbGliL2Vudi9jb3JlL3BhcnNlLWVudi1maWxlJztcblxuLy8gQW5ndWxhclxuZXhwb3J0IHsgcHJvdmlkZVJ1bnRpbWVDb25maWcgfSBmcm9tICcuL2xpYi9lbnYvYW5ndWxhci9wcm92aWRlLXJ1bnRpbWUtY29uZmlnJztcbmV4cG9ydCB7IHByb3ZpZGVTdGF0aWNDb25maWcgfSBmcm9tICcuL2xpYi9lbnYvYW5ndWxhci9wcm92aWRlLXN0YXRpYy1jb25maWcnO1xuIl19
|