@chill-sharp/ui-core 1.1.12 → 1.1.15

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.
Files changed (69) hide show
  1. package/README.md +103 -103
  2. package/fesm2022/chill-sharp-ui-core.mjs +2446 -2446
  3. package/fesm2022/chill-sharp-ui-core.mjs.map +1 -1
  4. package/lib/lib/chill-form.component.d.ts +1 -1
  5. package/package.json +3 -3
  6. package/service-worker/chill-sharp-service-worker.js +166 -166
  7. package/styles/core-theme.scss +1235 -1235
  8. package/.agents/skills/chillsharp-current-user-preferences/SKILL.md +0 -70
  9. package/.agents/skills/chillsharp-ui-template/SKILL.md +0 -18
  10. package/doc/AIAssistedDevelopment/README.md +0 -185
  11. package/doc/AttachmentModel/README.md +0 -173
  12. package/doc/AuthenticationModel/README.md +0 -213
  13. package/doc/AuthenticationModel/how-to-integreate-auth-minimal-api.md +0 -293
  14. package/doc/ChillSharpClient.md +0 -464
  15. package/doc/ClientGeneration/README.md +0 -172
  16. package/doc/ComplianceGuide/README.md +0 -178
  17. package/doc/Configuration/README.md +0 -94
  18. package/doc/CurrentUserPreferences.md +0 -114
  19. package/doc/DateTimePolicy/README.md +0 -154
  20. package/doc/DateTimeSerialization.md +0 -423
  21. package/doc/Endpoints.md +0 -260
  22. package/doc/HowTo/01-simple-blog-sqlite.md +0 -153
  23. package/doc/HowTo/02-blog-schema-labels.md +0 -140
  24. package/doc/HowTo/03-authentication.md +0 -218
  25. package/doc/HowTo/04-blog-posts-one-to-many.md +0 -194
  26. package/doc/HowTo/05-docker-env-variables.md +0 -274
  27. package/doc/HowTo/06-chunk-transactions-autocomplete.md +0 -196
  28. package/doc/Mcp/ChatGPT.md +0 -291
  29. package/doc/Mcp/README.md +0 -799
  30. package/doc/MenuGuide/README.md +0 -49
  31. package/doc/ModelPreparation.md +0 -255
  32. package/doc/PermissionModel/README.md +0 -277
  33. package/doc/README.md +0 -228
  34. package/doc/ReferenceExistence.md +0 -130
  35. package/doc/RegisterContext.md +0 -217
  36. package/doc/UiCore/CRUD.md +0 -170
  37. package/doc/UiCore/README.md +0 -13
  38. package/doc/ValidationModel/README.md +0 -117
  39. package/doc/it/AIAssistedDevelopment/README.md +0 -185
  40. package/doc/it/AttachmentModel/README.md +0 -173
  41. package/doc/it/AuthenticationModel/README.md +0 -171
  42. package/doc/it/AuthenticationModel/how-to-integreate-auth-minimal-api.md +0 -292
  43. package/doc/it/ChillSharpClient.md +0 -464
  44. package/doc/it/ClientGeneration/README.md +0 -152
  45. package/doc/it/ComplianceGuide/README.md +0 -178
  46. package/doc/it/Configuration/README.md +0 -94
  47. package/doc/it/CurrentUserPreferences.md +0 -114
  48. package/doc/it/DateTimePolicy/README.md +0 -154
  49. package/doc/it/DateTimeSerialization.md +0 -423
  50. package/doc/it/Endpoints.md +0 -260
  51. package/doc/it/HowTo/01-simple-blog-sqlite.md +0 -152
  52. package/doc/it/HowTo/02-blog-schema-labels.md +0 -139
  53. package/doc/it/HowTo/03-authentication.md +0 -221
  54. package/doc/it/HowTo/04-blog-posts-one-to-many.md +0 -193
  55. package/doc/it/HowTo/05-docker-env-variables.md +0 -268
  56. package/doc/it/HowTo/06-chunk-transactions-autocomplete.md +0 -196
  57. package/doc/it/Mcp/ChatGPT.md +0 -291
  58. package/doc/it/Mcp/README.md +0 -799
  59. package/doc/it/MenuGuide/README.md +0 -49
  60. package/doc/it/ModelPreparation.md +0 -254
  61. package/doc/it/PermissionModel/README.md +0 -190
  62. package/doc/it/README.md +0 -172
  63. package/doc/it/ReferenceExistence.md +0 -130
  64. package/doc/it/RegisterContext.md +0 -218
  65. package/doc/it/UiCore/CRUD.md +0 -170
  66. package/doc/it/UiCore/README.md +0 -13
  67. package/doc/it/ValidationModel/README.md +0 -117
  68. package/template-customization/upgrade.ps1.template +0 -342
  69. package/template-customization/upgrade.sh.template +0 -271
@@ -72,7 +72,7 @@ export declare class ChillFormComponent implements OnDestroy {
72
72
  private autocompleteRequestSequence;
73
73
  private pendingAutocompletePromise;
74
74
  readonly mode: import("@angular/core").Signal<"entity" | "query">;
75
- readonly source: import("@angular/core").Signal<ChillQuery | ChillEntity | null>;
75
+ readonly source: import("@angular/core").Signal<ChillEntity | ChillQuery | null>;
76
76
  readonly hasCustomSubmitHandler: import("@angular/core").Signal<boolean>;
77
77
  readonly properties: import("@angular/core").Signal<ChillPropertySchema[]>;
78
78
  readonly layoutItems: import("@angular/core").Signal<ResolvedFormLayoutItem[]>;
package/package.json CHANGED
@@ -5,7 +5,7 @@
5
5
  "url": "git+https://github.com/e-500/chill-sharp.git",
6
6
  "directory": "extra/chill-sharp-ui-core"
7
7
  },
8
- "version": "1.1.12",
8
+ "version": "1.1.15",
9
9
  "description": "Shared Angular UI core for ChillSharp applications.",
10
10
  "keywords": [
11
11
  "angular",
@@ -44,8 +44,8 @@
44
44
  "zone.js": "~0.15.0"
45
45
  },
46
46
  "dependencies": {
47
- "@chill-sharp/ng-client": "^1.1.12",
48
- "@chill-sharp/ts-client": "^1.1.12",
47
+ "@chill-sharp/ng-client": "^1.1.15",
48
+ "@chill-sharp/ts-client": "^1.1.15",
49
49
  "monaco-editor": "^0.52.2",
50
50
  "tslib": "^2.3.0"
51
51
  },
@@ -1,166 +1,166 @@
1
- // Shared worker, loaded by the client-owned public/sw.js through importScripts().
2
- // Set self.CHILL_SHARP_SW_OPTIONS before importing to customize these defaults.
3
- const OPTIONS = {
4
- cachePrefix: 'chill-sharp-ui',
5
- cacheVersion: 'v2',
6
- cacheTimeoutMs: 10 * 60 * 1000,
7
- appShell: ['/', '/index.html'],
8
- legacyCacheNames: [],
9
- ...self.CHILL_SHARP_SW_OPTIONS
10
- };
11
-
12
- const SHELL_CACHE = `${OPTIONS.cachePrefix}-shell-${OPTIONS.cacheVersion}`;
13
- const METADATA_CACHE = `${OPTIONS.cachePrefix}-metadata-${OPTIONS.cacheVersion}`;
14
- const CACHED_AT = 'X-ChillSharp-Cached-At';
15
- const METADATA_READS = new Set(['get-schema', 'get-schema-list', 'get-entity-options']);
16
- const METADATA_WRITES = new Set(['set-schema', 'set-entity-options']);
17
- let metadataGeneration = 0;
18
- let pendingMutation = Promise.resolve();
19
- let cacheOperations = Promise.resolve();
20
-
21
- // Order cache writes/deletions so a pre-update fetch cannot refill an invalidated cache.
22
- function changeMetadataCache(action) {
23
- const operation = cacheOperations.then(action);
24
- cacheOperations = operation.catch(() => {});
25
- return operation;
26
- }
27
-
28
- function schemaAction(url) {
29
- const match = url.pathname.match(/\/chill-schema\/([^/]+)\/?$/i);
30
- return match ? match[1].toLowerCase() : '';
31
- }
32
-
33
- function isSchemaUpdate(url, action) {
34
- return action === 'get-schema' && [...url.searchParams].some(
35
- ([name, value]) => name.toLowerCase() === 'update' && value.toLowerCase() === 'true'
36
- );
37
- }
38
-
39
- async function freshCachedResponse(cacheName, request) {
40
- const cache = await caches.open(cacheName);
41
- const response = await cache.match(request);
42
- if (!response) return undefined;
43
- const cachedAt = Number(response.headers.get(CACHED_AT));
44
- const age = Date.now() - cachedAt;
45
- if (cachedAt > 0 && age >= 0 && age < OPTIONS.cacheTimeoutMs) return response;
46
- await cache.delete(request);
47
- return undefined;
48
- }
49
-
50
- async function storeResponse(cacheName, request, response) {
51
- if (!response.ok || [204, 205, 206].includes(response.status) || response.type === 'opaque' ||
52
- /\bno-store\b/i.test(response.headers.get('Cache-Control') || '') ||
53
- (response.headers.get('Vary') || '').split(',').some((name) => name.trim() === '*')) return;
54
-
55
- const headers = new Headers(response.headers);
56
- headers.set(CACHED_AT, String(Date.now()));
57
- // Cache API does not distinguish bearer tokens unless the response varies by them.
58
- const vary = new Set((headers.get('Vary') || '').split(',').map((v) => v.trim()).filter(Boolean));
59
- vary.add('Authorization');
60
- headers.set('Vary', [...vary].join(', '));
61
- const copy = new Response(await response.clone().blob(), {
62
- status: response.status, statusText: response.statusText, headers
63
- });
64
- await (await caches.open(cacheName)).put(request, copy);
65
- }
66
-
67
- function fetchFresh(request) {
68
- return fetch(new Request(request, { cache: 'no-store' }));
69
- }
70
-
71
- async function readMetadata(request) {
72
- await pendingMutation;
73
- const generation = metadataGeneration;
74
- const cached = await changeMetadataCache(() => freshCachedResponse(METADATA_CACHE, request)).catch(() => undefined);
75
- if (cached && generation === metadataGeneration) return cached;
76
- const response = await fetchFresh(request);
77
- await changeMetadataCache(async () => {
78
- if (generation === metadataGeneration) await storeResponse(METADATA_CACHE, request, response);
79
- }).catch(() => {}); // Storage quota errors must not discard a successful network response.
80
- return response;
81
- }
82
-
83
- function mutateMetadata(request) {
84
- metadataGeneration++;
85
- const operation = pendingMutation.then(async () => {
86
- await changeMetadataCache(() => caches.delete(METADATA_CACHE));
87
- try {
88
- // update=true must reach the server on every click, including repeated updates.
89
- return await fetchFresh(request);
90
- } finally {
91
- // Clear all types/views/cultures and entity options, including schema-list summaries.
92
- // Normal GETs after the update (also after a reload) must fetch the saved schema.
93
- await changeMetadataCache(() => caches.delete(METADATA_CACHE));
94
- }
95
- });
96
- pendingMutation = operation.then(() => {}, () => {});
97
- return operation;
98
- }
99
-
100
- self.addEventListener('install', (event) => {
101
- event.waitUntil((async () => {
102
- const cache = await caches.open(SHELL_CACHE);
103
- await cache.addAll(OPTIONS.appShell.map((url) => new Request(new URL(url, self.location.href), { cache: 'reload' })));
104
- await self.skipWaiting();
105
- })());
106
- });
107
-
108
- self.addEventListener('activate', (event) => {
109
- event.waitUntil((async () => {
110
- const current = new Set([SHELL_CACHE, METADATA_CACHE]);
111
- await Promise.all((await caches.keys())
112
- .filter((key) => OPTIONS.legacyCacheNames.includes(key) ||
113
- (key.startsWith(`${OPTIONS.cachePrefix}-`) && !current.has(key)))
114
- .map((key) => caches.delete(key)));
115
- await self.clients.claim();
116
- })());
117
- });
118
-
119
- self.addEventListener('fetch', (event) => {
120
- const request = event.request;
121
- const url = new URL(request.url);
122
- const action = schemaAction(url);
123
-
124
- if ((request.method === 'GET' && isSchemaUpdate(url, action)) ||
125
- (request.method === 'POST' && METADATA_WRITES.has(action))) {
126
- const response = mutateMetadata(request);
127
- event.respondWith(response);
128
- event.waitUntil(response.then(() => {}, () => {}));
129
- return;
130
- }
131
-
132
- if (request.method !== 'GET') return;
133
- if (METADATA_READS.has(action)) {
134
- const response = readMetadata(request);
135
- event.respondWith(response);
136
- event.waitUntil(response.then(() => {}, () => {}));
137
- return;
138
- }
139
-
140
- // Only metadata APIs above are cached. Other APIs and runtime settings stay fresh.
141
- if (action || /\/api(?:\/|$)/i.test(url.pathname) ||
142
- /\/(?:env|runtime-config|sw)\.js$/i.test(url.pathname)) {
143
- event.respondWith(fetchFresh(request));
144
- return;
145
- }
146
-
147
- if (url.origin !== self.location.origin || request.headers.has('Authorization')) return;
148
- if (request.mode === 'navigate') {
149
- event.respondWith(fetchFresh(request).catch(async () => {
150
- const shell = await (await caches.open(SHELL_CACHE)).match('/index.html');
151
- return shell || Response.error();
152
- }));
153
- return;
154
- }
155
-
156
- if (!['script', 'style', 'image', 'font', 'manifest'].includes(request.destination)) return;
157
- const response = (async () => {
158
- const cached = await freshCachedResponse(SHELL_CACHE, request);
159
- if (cached) return cached;
160
- const result = await fetchFresh(request);
161
- await storeResponse(SHELL_CACHE, request, result).catch(() => {});
162
- return result;
163
- })();
164
- event.respondWith(response);
165
- event.waitUntil(response.then(() => {}, () => {}));
166
- });
1
+ // Shared worker, loaded by the client-owned public/sw.js through importScripts().
2
+ // Set self.CHILL_SHARP_SW_OPTIONS before importing to customize these defaults.
3
+ const OPTIONS = {
4
+ cachePrefix: 'chill-sharp-ui',
5
+ cacheVersion: 'v2',
6
+ cacheTimeoutMs: 10 * 60 * 1000,
7
+ appShell: ['/', '/index.html'],
8
+ legacyCacheNames: [],
9
+ ...self.CHILL_SHARP_SW_OPTIONS
10
+ };
11
+
12
+ const SHELL_CACHE = `${OPTIONS.cachePrefix}-shell-${OPTIONS.cacheVersion}`;
13
+ const METADATA_CACHE = `${OPTIONS.cachePrefix}-metadata-${OPTIONS.cacheVersion}`;
14
+ const CACHED_AT = 'X-ChillSharp-Cached-At';
15
+ const METADATA_READS = new Set(['get-schema', 'get-schema-list', 'get-entity-options']);
16
+ const METADATA_WRITES = new Set(['set-schema', 'set-entity-options']);
17
+ let metadataGeneration = 0;
18
+ let pendingMutation = Promise.resolve();
19
+ let cacheOperations = Promise.resolve();
20
+
21
+ // Order cache writes/deletions so a pre-update fetch cannot refill an invalidated cache.
22
+ function changeMetadataCache(action) {
23
+ const operation = cacheOperations.then(action);
24
+ cacheOperations = operation.catch(() => {});
25
+ return operation;
26
+ }
27
+
28
+ function schemaAction(url) {
29
+ const match = url.pathname.match(/\/chill-schema\/([^/]+)\/?$/i);
30
+ return match ? match[1].toLowerCase() : '';
31
+ }
32
+
33
+ function isSchemaUpdate(url, action) {
34
+ return action === 'get-schema' && [...url.searchParams].some(
35
+ ([name, value]) => name.toLowerCase() === 'update' && value.toLowerCase() === 'true'
36
+ );
37
+ }
38
+
39
+ async function freshCachedResponse(cacheName, request) {
40
+ const cache = await caches.open(cacheName);
41
+ const response = await cache.match(request);
42
+ if (!response) return undefined;
43
+ const cachedAt = Number(response.headers.get(CACHED_AT));
44
+ const age = Date.now() - cachedAt;
45
+ if (cachedAt > 0 && age >= 0 && age < OPTIONS.cacheTimeoutMs) return response;
46
+ await cache.delete(request);
47
+ return undefined;
48
+ }
49
+
50
+ async function storeResponse(cacheName, request, response) {
51
+ if (!response.ok || [204, 205, 206].includes(response.status) || response.type === 'opaque' ||
52
+ /\bno-store\b/i.test(response.headers.get('Cache-Control') || '') ||
53
+ (response.headers.get('Vary') || '').split(',').some((name) => name.trim() === '*')) return;
54
+
55
+ const headers = new Headers(response.headers);
56
+ headers.set(CACHED_AT, String(Date.now()));
57
+ // Cache API does not distinguish bearer tokens unless the response varies by them.
58
+ const vary = new Set((headers.get('Vary') || '').split(',').map((v) => v.trim()).filter(Boolean));
59
+ vary.add('Authorization');
60
+ headers.set('Vary', [...vary].join(', '));
61
+ const copy = new Response(await response.clone().blob(), {
62
+ status: response.status, statusText: response.statusText, headers
63
+ });
64
+ await (await caches.open(cacheName)).put(request, copy);
65
+ }
66
+
67
+ function fetchFresh(request) {
68
+ return fetch(new Request(request, { cache: 'no-store' }));
69
+ }
70
+
71
+ async function readMetadata(request) {
72
+ await pendingMutation;
73
+ const generation = metadataGeneration;
74
+ const cached = await changeMetadataCache(() => freshCachedResponse(METADATA_CACHE, request)).catch(() => undefined);
75
+ if (cached && generation === metadataGeneration) return cached;
76
+ const response = await fetchFresh(request);
77
+ await changeMetadataCache(async () => {
78
+ if (generation === metadataGeneration) await storeResponse(METADATA_CACHE, request, response);
79
+ }).catch(() => {}); // Storage quota errors must not discard a successful network response.
80
+ return response;
81
+ }
82
+
83
+ function mutateMetadata(request) {
84
+ metadataGeneration++;
85
+ const operation = pendingMutation.then(async () => {
86
+ await changeMetadataCache(() => caches.delete(METADATA_CACHE));
87
+ try {
88
+ // update=true must reach the server on every click, including repeated updates.
89
+ return await fetchFresh(request);
90
+ } finally {
91
+ // Clear all types/views/cultures and entity options, including schema-list summaries.
92
+ // Normal GETs after the update (also after a reload) must fetch the saved schema.
93
+ await changeMetadataCache(() => caches.delete(METADATA_CACHE));
94
+ }
95
+ });
96
+ pendingMutation = operation.then(() => {}, () => {});
97
+ return operation;
98
+ }
99
+
100
+ self.addEventListener('install', (event) => {
101
+ event.waitUntil((async () => {
102
+ const cache = await caches.open(SHELL_CACHE);
103
+ await cache.addAll(OPTIONS.appShell.map((url) => new Request(new URL(url, self.location.href), { cache: 'reload' })));
104
+ await self.skipWaiting();
105
+ })());
106
+ });
107
+
108
+ self.addEventListener('activate', (event) => {
109
+ event.waitUntil((async () => {
110
+ const current = new Set([SHELL_CACHE, METADATA_CACHE]);
111
+ await Promise.all((await caches.keys())
112
+ .filter((key) => OPTIONS.legacyCacheNames.includes(key) ||
113
+ (key.startsWith(`${OPTIONS.cachePrefix}-`) && !current.has(key)))
114
+ .map((key) => caches.delete(key)));
115
+ await self.clients.claim();
116
+ })());
117
+ });
118
+
119
+ self.addEventListener('fetch', (event) => {
120
+ const request = event.request;
121
+ const url = new URL(request.url);
122
+ const action = schemaAction(url);
123
+
124
+ if ((request.method === 'GET' && isSchemaUpdate(url, action)) ||
125
+ (request.method === 'POST' && METADATA_WRITES.has(action))) {
126
+ const response = mutateMetadata(request);
127
+ event.respondWith(response);
128
+ event.waitUntil(response.then(() => {}, () => {}));
129
+ return;
130
+ }
131
+
132
+ if (request.method !== 'GET') return;
133
+ if (METADATA_READS.has(action)) {
134
+ const response = readMetadata(request);
135
+ event.respondWith(response);
136
+ event.waitUntil(response.then(() => {}, () => {}));
137
+ return;
138
+ }
139
+
140
+ // Only metadata APIs above are cached. Other APIs and runtime settings stay fresh.
141
+ if (action || /\/api(?:\/|$)/i.test(url.pathname) ||
142
+ /\/(?:env|runtime-config|sw)\.js$/i.test(url.pathname)) {
143
+ event.respondWith(fetchFresh(request));
144
+ return;
145
+ }
146
+
147
+ if (url.origin !== self.location.origin || request.headers.has('Authorization')) return;
148
+ if (request.mode === 'navigate') {
149
+ event.respondWith(fetchFresh(request).catch(async () => {
150
+ const shell = await (await caches.open(SHELL_CACHE)).match('/index.html');
151
+ return shell || Response.error();
152
+ }));
153
+ return;
154
+ }
155
+
156
+ if (!['script', 'style', 'image', 'font', 'manifest'].includes(request.destination)) return;
157
+ const response = (async () => {
158
+ const cached = await freshCachedResponse(SHELL_CACHE, request);
159
+ if (cached) return cached;
160
+ const result = await fetchFresh(request);
161
+ await storeResponse(SHELL_CACHE, request, result).catch(() => {});
162
+ return result;
163
+ })();
164
+ event.respondWith(response);
165
+ event.waitUntil(response.then(() => {}, () => {}));
166
+ });