slicejs-web-framework 3.4.4 → 3.5.1

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 (110) hide show
  1. package/Slice/Components/Structural/Controller/Controller.js +135 -0
  2. package/Slice/Components/Structural/EventManager/EventManager.js +289 -4
  3. package/Slice/Components/Structural/EventManager/EventManagerDebugger.js +368 -30
  4. package/Slice/Components/Structural/LeakInspector/LeakInspector.js +296 -0
  5. package/Slice/Components/Structural/StylesManager/ThemeManager/ThemeManager.js +56 -0
  6. package/Slice/Slice.js +14 -1
  7. package/Slice/tests/event-emitters.test.js +79 -0
  8. package/Slice/tests/event-registry.test.js +141 -0
  9. package/Slice/tests/leak-orphans.test.js +131 -0
  10. package/api/{middleware → framework}/securityMiddleware.js +18 -74
  11. package/api/framework/server.js +333 -0
  12. package/api/index.js +5 -279
  13. package/api/tests/public-env-resolver.test.js +1 -1
  14. package/package.json +4 -2
  15. package/sliceConfig.schema.json +10 -1
  16. package/src/App/index.html +31 -1
  17. package/src/manifest.json +15 -0
  18. package/src/robots.txt +4 -0
  19. package/src/sitemap.xml +8 -0
  20. package/src/sliceConfig.json +5 -1
  21. package/types/index.d.ts +12 -0
  22. package/slicejs-cli/.github/workflows/ci.yml +0 -43
  23. package/slicejs-cli/LICENSE +0 -21
  24. package/slicejs-cli/assets/Slice.js-logo.png +0 -0
  25. package/slicejs-cli/client.js +0 -740
  26. package/slicejs-cli/commands/Print.js +0 -164
  27. package/slicejs-cli/commands/Validations.js +0 -92
  28. package/slicejs-cli/commands/build/build.js +0 -40
  29. package/slicejs-cli/commands/buildProduction/buildProduction.js +0 -577
  30. package/slicejs-cli/commands/bundle/bundle.js +0 -236
  31. package/slicejs-cli/commands/createComponent/VisualComponentTemplate.js +0 -55
  32. package/slicejs-cli/commands/createComponent/createComponent.js +0 -128
  33. package/slicejs-cli/commands/deleteComponent/deleteComponent.js +0 -81
  34. package/slicejs-cli/commands/doctor/doctor.js +0 -516
  35. package/slicejs-cli/commands/getComponent/getComponent.js +0 -695
  36. package/slicejs-cli/commands/init/init.js +0 -473
  37. package/slicejs-cli/commands/listComponents/listComponents.js +0 -172
  38. package/slicejs-cli/commands/startServer/startServer.js +0 -240
  39. package/slicejs-cli/commands/startServer/watchServer.js +0 -66
  40. package/slicejs-cli/commands/types/types.js +0 -583
  41. package/slicejs-cli/commands/utils/LocalCliDelegation.js +0 -53
  42. package/slicejs-cli/commands/utils/PackageManager.js +0 -148
  43. package/slicejs-cli/commands/utils/PathHelper.js +0 -75
  44. package/slicejs-cli/commands/utils/VersionChecker.js +0 -169
  45. package/slicejs-cli/commands/utils/bundling/BundleGenerator.js +0 -2525
  46. package/slicejs-cli/commands/utils/bundling/DependencyAnalyzer.js +0 -933
  47. package/slicejs-cli/commands/utils/loadConfig.js +0 -31
  48. package/slicejs-cli/commands/utils/sliceScripts.js +0 -48
  49. package/slicejs-cli/commands/utils/updateManager.js +0 -471
  50. package/slicejs-cli/package.json +0 -71
  51. package/slicejs-cli/playwright.config.js +0 -51
  52. package/slicejs-cli/pnpm-lock.yaml +0 -1629
  53. package/slicejs-cli/tests/build-command-integration.test.js +0 -87
  54. package/slicejs-cli/tests/build-mangling-e2e.test.js +0 -290
  55. package/slicejs-cli/tests/build-production-e2e.test.js +0 -140
  56. package/slicejs-cli/tests/builder-edge-cases.test.js +0 -322
  57. package/slicejs-cli/tests/bundle-generate-e2e.test.js +0 -115
  58. package/slicejs-cli/tests/bundle-generator.test.js +0 -691
  59. package/slicejs-cli/tests/bundle-v2-register-output.test.js +0 -470
  60. package/slicejs-cli/tests/bundling-dependency-edges.test.js +0 -127
  61. package/slicejs-cli/tests/bundling-imports-unit.test.js +0 -267
  62. package/slicejs-cli/tests/client-launcher-contract.test.js +0 -211
  63. package/slicejs-cli/tests/commands-component-crud.test.js +0 -128
  64. package/slicejs-cli/tests/commands-doctor.test.js +0 -152
  65. package/slicejs-cli/tests/commands-version-checker.test.js +0 -37
  66. package/slicejs-cli/tests/component-registry-parse.test.js +0 -34
  67. package/slicejs-cli/tests/dependency-analyzer.test.js +0 -24
  68. package/slicejs-cli/tests/e2e/bundles.spec.js +0 -91
  69. package/slicejs-cli/tests/e2e/dependency-scenarios.spec.js +0 -56
  70. package/slicejs-cli/tests/e2e/fixtures/components/Service/FetchManager/FetchManager.js +0 -136
  71. package/slicejs-cli/tests/e2e/fixtures/components/Service/IndexedDbManager/IndexedDbManager.js +0 -149
  72. package/slicejs-cli/tests/e2e/fixtures/components/Service/LocalStorageManager/LocalStorageManager.js +0 -45
  73. package/slicejs-cli/tests/e2e/fixtures/components/Visual/Button/Button.css +0 -106
  74. package/slicejs-cli/tests/e2e/fixtures/components/Visual/Button/Button.html +0 -5
  75. package/slicejs-cli/tests/e2e/fixtures/components/Visual/Button/Button.js +0 -158
  76. package/slicejs-cli/tests/e2e/fixtures/components/Visual/Link/Link.js +0 -33
  77. package/slicejs-cli/tests/e2e/fixtures/components/Visual/Loading/Loading.css +0 -56
  78. package/slicejs-cli/tests/e2e/fixtures/components/Visual/Loading/Loading.html +0 -83
  79. package/slicejs-cli/tests/e2e/fixtures/components/Visual/Loading/Loading.js +0 -164
  80. package/slicejs-cli/tests/e2e/fixtures/components/Visual/MultiRoute/MultiRoute.js +0 -167
  81. package/slicejs-cli/tests/e2e/fixtures/components/Visual/Navbar/Navbar.css +0 -116
  82. package/slicejs-cli/tests/e2e/fixtures/components/Visual/Navbar/Navbar.html +0 -44
  83. package/slicejs-cli/tests/e2e/fixtures/components/Visual/Navbar/Navbar.js +0 -180
  84. package/slicejs-cli/tests/e2e/fixtures/components/Visual/NotFound/NotFound.js +0 -20
  85. package/slicejs-cli/tests/e2e/fixtures/components/Visual/Route/Route.js +0 -181
  86. package/slicejs-cli/tests/e2e/fixtures/components/registry.json +0 -12
  87. package/slicejs-cli/tests/e2e/fixtures/vendor-components.mjs +0 -65
  88. package/slicejs-cli/tests/e2e/navigation.spec.js +0 -44
  89. package/slicejs-cli/tests/e2e/render.spec.js +0 -34
  90. package/slicejs-cli/tests/e2e/serve.mjs +0 -264
  91. package/slicejs-cli/tests/e2e/shared-deps.spec.js +0 -61
  92. package/slicejs-cli/tests/e2e/unminified.spec.js +0 -33
  93. package/slicejs-cli/tests/e2e-serve.test.js +0 -148
  94. package/slicejs-cli/tests/fixtures/components.js +0 -8
  95. package/slicejs-cli/tests/fixtures/sliceConfig.json +0 -74
  96. package/slicejs-cli/tests/getcomponent.test.js +0 -435
  97. package/slicejs-cli/tests/helpers/setup.js +0 -102
  98. package/slicejs-cli/tests/init-command-contract.test.js +0 -101
  99. package/slicejs-cli/tests/init-e2e.test.js +0 -82
  100. package/slicejs-cli/tests/init-project-isolation.test.js +0 -98
  101. package/slicejs-cli/tests/local-cli-delegation.test.js +0 -81
  102. package/slicejs-cli/tests/package-manager.test.js +0 -127
  103. package/slicejs-cli/tests/path-helper.test.js +0 -206
  104. package/slicejs-cli/tests/perf-budget.test.js +0 -84
  105. package/slicejs-cli/tests/postinstall-command.test.js +0 -103
  106. package/slicejs-cli/tests/property-mangling-regression.test.js +0 -182
  107. package/slicejs-cli/tests/types-breakage.test.js +0 -491
  108. package/slicejs-cli/tests/types-generator-errors.test.js +0 -361
  109. package/slicejs-cli/tests/types-generator.test.js +0 -348
  110. /package/api/{utils → framework}/publicEnvResolver.js +0 -0
@@ -1,348 +0,0 @@
1
- import { test } from 'node:test';
2
- import assert from 'node:assert/strict';
3
- import fs from 'node:fs';
4
- import path from 'node:path';
5
- import { createTestProject, cleanupTestProject } from './helpers/setup.js';
6
-
7
- import {
8
- ensureEditorConfigForTypes,
9
- ensureNoCheckInPublicVendorFiles,
10
- extractStaticPropsFromSource,
11
- generateDeclarationContent,
12
- generateTypesFile
13
- } from '../commands/types/types.js';
14
-
15
- test('extractStaticPropsFromSource reads static props definitions', () => {
16
- const source = `
17
- export default class Button extends HTMLElement {
18
- static props = {
19
- value: { type: 'string', default: 'Button', allowedValues: ['Button', 'Submit'] },
20
- disabled: { type: 'boolean', default: false },
21
- size: { type: 'number', allowedValues: [12, 16, 20] },
22
- options: {
23
- type: 'object',
24
- schema: {
25
- theme: {
26
- type: 'object',
27
- schema: {
28
- mode: { type: 'string', allowedValues: ['light', 'dark'] }
29
- }
30
- }
31
- }
32
- },
33
- steps: {
34
- type: 'array',
35
- items: {
36
- type: 'object',
37
- schema: {
38
- id: { type: 'string', required: true },
39
- enabled: { type: 'boolean', default: true }
40
- }
41
- }
42
- },
43
- onClickCallback: { type: 'function', required: true }
44
- };
45
- }
46
- `;
47
-
48
- const result = extractStaticPropsFromSource(source);
49
-
50
- assert.deepEqual(result, {
51
- value: { type: 'string', required: false, allowedValues: ['Button', 'Submit'] },
52
- disabled: { type: 'boolean', required: false },
53
- size: { type: 'number', required: false, allowedValues: [12, 16, 20] },
54
- options: {
55
- type: 'object',
56
- required: false,
57
- schema: {
58
- theme: {
59
- type: 'object',
60
- required: false,
61
- schema: {
62
- mode: {
63
- type: 'string',
64
- required: false,
65
- allowedValues: ['light', 'dark']
66
- }
67
- }
68
- }
69
- }
70
- },
71
- steps: {
72
- type: 'array',
73
- required: false,
74
- items: {
75
- type: 'object',
76
- required: false,
77
- schema: {
78
- id: { type: 'string', required: true },
79
- enabled: { type: 'boolean', required: false }
80
- }
81
- }
82
- },
83
- onClickCallback: { type: 'function', required: true }
84
- });
85
- });
86
-
87
- test('generateDeclarationContent creates build typing map', () => {
88
- const content = generateDeclarationContent({
89
- Button: {
90
- value: { type: 'string', required: false, allowedValues: ['primary', 'secondary', 'danger'] },
91
- size: { type: 'number', required: false, allowedValues: [12, 16] },
92
- disabled: { type: 'boolean', required: false },
93
- status: { type: 'string', required: false, allowedValues: ['ok', 1] },
94
- options: {
95
- type: 'object',
96
- required: false,
97
- schema: {
98
- mode: { type: 'string', required: false, allowedValues: ['light', 'dark'] }
99
- }
100
- },
101
- steps: {
102
- type: 'array',
103
- required: false,
104
- items: {
105
- type: 'object',
106
- required: false,
107
- schema: {
108
- id: { type: 'string', required: true }
109
- }
110
- }
111
- }
112
- },
113
- FetchManager: {
114
- baseUrl: { type: 'string', required: true }
115
- }
116
- });
117
-
118
- assert.match(content, /export interface ButtonProps/);
119
- assert.match(content, /\[key: string\]: unknown;/);
120
- assert.match(content, /value\?: 'primary' \| 'secondary' \| 'danger';/);
121
- assert.match(content, /size\?: 12 \| 16;/);
122
- assert.match(content, /disabled\?: boolean;/);
123
- assert.match(content, /status\?: string;/);
124
- assert.match(content, /export interface FetchManagerProps/);
125
- assert.match(content, /baseUrl: string;/);
126
- assert.match(content, /export interface SliceComponentPropsMap/);
127
- assert.match(content, /Button: ButtonProps;/);
128
- assert.match(content, /FetchManager: FetchManagerProps;/);
129
- assert.match(content, /options\?: \{/);
130
- assert.match(content, /mode\?: 'light' \| 'dark';/);
131
- assert.match(content, /steps\?: \{/);
132
- assert.match(content, /id: string;/);
133
- assert.match(content, /}\[\];/);
134
- assert.match(content, /declare module 'slicejs-web-framework'/);
135
- assert.match(content, /interface SliceApi \{/);
136
- assert.match(content, /export type SliceDynamicElement = HTMLElement & Record<string, any>;/);
137
- assert.match(content, /build<K extends SliceComponentName>/);
138
- assert.match(content, /getComponent<K extends SliceComponentName>\(/);
139
- assert.match(content, /componentSliceId: K \|/);
140
- assert.match(content, /SliceDynamicElement \| undefined;/);
141
- assert.match(content, /getComponent<T extends SliceDynamicElement = SliceDynamicElement>\(/);
142
- assert.match(content, /\): T \| undefined;/);
143
- assert.match(content, /interface Element \{/);
144
- assert.match(content, /querySelector<E extends Element = HTMLElement>\(selectors: string\): E \| null;/);
145
- assert.match(content, /querySelectorAll<E extends Element = HTMLElement>\(selectors: string\): NodeListOf<E>;/);
146
- assert.match(content, /interface HTMLElement \{/);
147
- assert.match(content, /\[key: string\]: any;/);
148
- assert.match(content, /const slice: SliceBuildApi & Record<string, any>;/);
149
- assert.match(content, /interface EventTarget \{/);
150
- assert.match(content, /interface Event \{/);
151
- assert.match(content, /detail: any;/);
152
- assert.match(content, /currentTarget: any;/);
153
- });
154
-
155
- test('generateTypesFile creates declaration file from local components', async () => {
156
- const tmpRoot = await createTestProject();
157
- const srcDir = path.join(tmpRoot, 'src');
158
-
159
- try {
160
- const visualDir = path.join(srcDir, 'Components', 'Visual', 'Button');
161
- const noStaticDir = path.join(srcDir, 'Components', 'Visual', 'Tabs');
162
- const serviceDir = path.join(srcDir, 'Components', 'Service', 'FetchManager');
163
- const outputFile = path.join(srcDir, 'slice-build.generated.d.ts');
164
-
165
- fs.mkdirSync(visualDir, { recursive: true });
166
- fs.mkdirSync(noStaticDir, { recursive: true });
167
- fs.mkdirSync(serviceDir, { recursive: true });
168
-
169
- fs.writeFileSync(
170
- path.join(visualDir, 'Button.js'),
171
- `
172
- export default class Button extends HTMLElement {
173
- static props = {
174
- value: { type: 'string', default: 'Button', allowedValues: ['Button', 'Submit'] },
175
- size: { type: 'number', allowedValues: [12, 16] },
176
- disabled: { type: 'boolean', default: false }
177
- };
178
- }
179
- `,
180
- 'utf8'
181
- );
182
-
183
- fs.writeFileSync(
184
- path.join(noStaticDir, 'Tabs.js'),
185
- `
186
- export default class Tabs extends HTMLElement {
187
- constructor() {
188
- super();
189
- }
190
- }
191
- `,
192
- 'utf8'
193
- );
194
-
195
- fs.writeFileSync(
196
- path.join(serviceDir, 'FetchManager.js'),
197
- `
198
- export default class FetchManager extends HTMLElement {
199
- static props = {
200
- baseUrl: { type: 'string', required: true }
201
- };
202
- }
203
- `,
204
- 'utf8'
205
- );
206
-
207
- fs.writeFileSync(
208
- path.join(srcDir, 'Components', 'components.js'),
209
- 'const components = {"Button": "Visual", "Tabs": "Visual", "FetchManager": "Service"};\n\nexport default components;\n',
210
- 'utf8'
211
- );
212
-
213
- const result = await generateTypesFile({
214
- projectRoot: tmpRoot,
215
- outputPath: outputFile
216
- });
217
-
218
- assert.equal(result.componentsProcessed, 3);
219
- assert.equal(fs.existsSync(result.outputPath), true);
220
-
221
- const declaration = fs.readFileSync(result.outputPath, 'utf8');
222
- assert.match(declaration, /export interface ButtonProps/);
223
- assert.match(declaration, /value\?: 'Button' \| 'Submit';/);
224
- assert.match(declaration, /size\?: 12 \| 16;/);
225
- assert.match(declaration, /export interface TabsProps/);
226
- assert.match(declaration, /\[key: string\]: unknown;/);
227
- assert.match(declaration, /export interface FetchManagerProps/);
228
- assert.match(declaration, /Tabs: TabsProps;/);
229
- assert.match(declaration, /build<K extends SliceComponentName>/);
230
- } finally {
231
- await cleanupTestProject(tmpRoot);
232
- }
233
- });
234
-
235
- test('ensureEditorConfigForTypes creates jsconfig when missing', async () => {
236
- const tmpRoot = await createTestProject();
237
- const outputFile = path.join(tmpRoot, 'src', 'slice-build.generated.d.ts');
238
-
239
- try {
240
- fs.writeFileSync(outputFile, 'export {};\n', 'utf8');
241
-
242
- const result = await ensureEditorConfigForTypes({
243
- projectRoot: tmpRoot,
244
- outputPath: outputFile
245
- });
246
-
247
- assert.equal(result.mode, 'created_jsconfig');
248
-
249
- const jsconfigPath = path.join(tmpRoot, 'jsconfig.json');
250
- assert.equal(fs.existsSync(jsconfigPath), true);
251
-
252
- const jsconfig = JSON.parse(fs.readFileSync(jsconfigPath, 'utf8'));
253
- assert.equal(Array.isArray(jsconfig.include), true);
254
- assert.equal(jsconfig.include.includes('src/Components/**/*.js'), true);
255
- assert.equal(jsconfig.include.includes('src/**/*.d.ts'), true);
256
- assert.equal(jsconfig.include.includes('api/**/*.js'), false);
257
- assert.equal(jsconfig.include.includes('tests/**/*.js'), false);
258
- assert.equal(jsconfig.include.includes('src/**/*.js'), false);
259
- assert.equal(jsconfig.compilerOptions.checkJs, true);
260
- assert.equal(jsconfig.compilerOptions.strictNullChecks, false);
261
- assert.equal(jsconfig.compilerOptions.noImplicitAny, false);
262
- assert.equal(jsconfig.compilerOptions.strict, false);
263
- assert.equal(Array.isArray(jsconfig.exclude), true);
264
- assert.equal(jsconfig.exclude.includes('src/libs/**'), true);
265
- assert.equal(jsconfig.exclude.includes('tests/**'), true);
266
- } finally {
267
- await cleanupTestProject(tmpRoot);
268
- }
269
- });
270
-
271
- test('types functions use PathHelper with explicit projectRoot', async () => {
272
- const tmpRoot = await createTestProject({ visualComponents: ['Button'] });
273
- const srcDir = path.join(tmpRoot, 'src');
274
- const outputFile = path.join(srcDir, 'slice-build.generated.d.ts');
275
-
276
- try {
277
- const visualDir = path.join(srcDir, 'Components', 'Visual', 'Button');
278
- fs.writeFileSync(
279
- path.join(visualDir, 'Button.js'),
280
- `export default class Button extends HTMLElement {
281
- static props = { value: { type: 'string' } };
282
- }`,
283
- 'utf8'
284
- );
285
-
286
- const result = await generateTypesFile({
287
- projectRoot: tmpRoot,
288
- outputPath: outputFile
289
- });
290
-
291
- assert.equal(result.componentsProcessed, 1);
292
- assert.equal(fs.existsSync(result.outputPath), true);
293
-
294
- const declaration = fs.readFileSync(result.outputPath, 'utf8');
295
- assert.match(declaration, /export interface ButtonProps/);
296
- assert.match(declaration, /build<K extends SliceComponentName>/);
297
- } finally {
298
- await cleanupTestProject(tmpRoot);
299
- }
300
- });
301
-
302
- test('ensureEditorConfigForTypes augments existing jsconfig include list', async () => {
303
- const tmpRoot = await createTestProject();
304
- const outputFile = path.join(tmpRoot, 'src', 'slice-build.generated.d.ts');
305
- const jsconfigPath = path.join(tmpRoot, 'jsconfig.json');
306
-
307
- try {
308
- fs.writeFileSync(outputFile, 'export {};\n', 'utf8');
309
- fs.writeFileSync(
310
- jsconfigPath,
311
- JSON.stringify(
312
- {
313
- compilerOptions: {
314
- allowJs: true
315
- },
316
- include: ['src/Components/**/*.js', 'src/**/*.js', 'api/**/*.js', 'tests/**/*.js']
317
- },
318
- null,
319
- 2
320
- ),
321
- 'utf8'
322
- );
323
-
324
- const result = await ensureEditorConfigForTypes({
325
- projectRoot: tmpRoot,
326
- outputPath: outputFile
327
- });
328
-
329
- assert.equal(result.mode, 'updated_jsconfig');
330
-
331
- const jsconfig = JSON.parse(fs.readFileSync(jsconfigPath, 'utf8'));
332
- assert.equal(jsconfig.include.includes('src/Components/**/*.js'), true);
333
- assert.equal(jsconfig.include.includes('src/**/*.d.ts'), true);
334
- assert.equal(jsconfig.include.includes('src/**/*.js'), false);
335
- assert.equal(jsconfig.include.includes('api/**/*.js'), false);
336
- assert.equal(jsconfig.include.includes('tests/**/*.js'), false);
337
- assert.equal(jsconfig.compilerOptions.allowJs, true);
338
- assert.equal(jsconfig.compilerOptions.checkJs, true);
339
- assert.equal(jsconfig.compilerOptions.noImplicitAny, false);
340
- assert.equal(jsconfig.compilerOptions.strictNullChecks, false);
341
- assert.equal(jsconfig.compilerOptions.strict, false);
342
- assert.equal(Array.isArray(jsconfig.exclude), true);
343
- assert.equal(jsconfig.exclude.includes('src/libs/**'), true);
344
- assert.equal(jsconfig.exclude.includes('tests/**'), true);
345
- } finally {
346
- await cleanupTestProject(tmpRoot);
347
- }
348
- });
File without changes