@things-factory/shell 10.1.106 → 10.1.122

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@things-factory/shell",
3
- "version": "10.1.106",
3
+ "version": "10.1.122",
4
4
  "description": "Core module for framework",
5
5
  "bin": {
6
6
  "things-factory": "bin/things-factory",
@@ -56,7 +56,7 @@
56
56
  "@things-factory/ejs-remote": "^10.1.20",
57
57
  "@things-factory/env": "^10.1.20",
58
58
  "@things-factory/operato-license-checker": "^4.0.4",
59
- "@things-factory/styles": "^10.1.20",
59
+ "@things-factory/styles": "^10.1.122",
60
60
  "@things-factory/utils": "^10.1.20",
61
61
  "@types/koa": "^3.0.1",
62
62
  "@types/koa-bodyparser": "^4.3.13",
@@ -126,5 +126,5 @@
126
126
  "pg": "^8.7.3",
127
127
  "sqlite3": "^5.0.8"
128
128
  },
129
- "gitHead": "8d78c14708420773ec32d18b8dd44c300771c44d"
129
+ "gitHead": "a66715e94ef6064cade05229de57d0fe5798d1fb"
130
130
  }
@@ -0,0 +1,75 @@
1
+ import { spawnSync } from 'child_process'
2
+ import { readdirSync, readFileSync, statSync } from 'fs'
3
+ import path from 'path'
4
+ import ts from 'typescript'
5
+
6
+ /*
7
+ * @things-factory/styles is published as source: no build, no compiler. A backtick in a comment inside a
8
+ * css`` template ends the template early, and nothing catches it until an app bundles the file -
9
+ * 10.1.121 shipped that way (surface-styles.js, a path written in backticks in a comment), and every
10
+ * app that loads the package failed to bundle (2026-10-05, ADR-0117).
11
+ *
12
+ * Each style file is loaded by node on its own. index.js is left out: it imports without extensions,
13
+ * which the bundler resolves and node does not.
14
+ */
15
+ const SRC = path.resolve(__dirname, '../../styles/src')
16
+
17
+ const styleFiles = () => readdirSync(SRC).filter(name => name.endsWith('.js') && name !== 'index.js')
18
+
19
+ describe('@things-factory/styles sources', () => {
20
+ it('has style files to load - an empty list would make the check below pass on nothing', () => {
21
+ expect(styleFiles().length).toBeGreaterThan(3)
22
+ })
23
+
24
+ it.each(styleFiles())('%s loads as a module', name => {
25
+ const file = path.join(SRC, name)
26
+ const run = spawnSync(process.execPath, ['--input-type=module', '-e', `await import(${JSON.stringify(file)})`], {
27
+ cwd: SRC,
28
+ encoding: 'utf8'
29
+ })
30
+ expect(run.stderr.split('\n').filter(line => /Error|Unexpected/.test(line))).toEqual([])
31
+ expect(run.status).toBe(0)
32
+ })
33
+ })
34
+
35
+ /*
36
+ * The same hole elsewhere (counted 2026-10-05): files that go out with no compiler reading them before
37
+ * publish - component-ui has no build script at all (its .ts is compiled only inside each app's bundle),
38
+ * and two .js entries that the packages' tsc does not read. They are parsed here for syntax; a template
39
+ * cut short by a backtick is a syntax error to the parser.
40
+ */
41
+ const PACKAGES = path.resolve(__dirname, '../..')
42
+
43
+ function filesUnder(dir: string): string[] {
44
+ const out: string[] = []
45
+ for (const name of readdirSync(dir)) {
46
+ if (name === 'node_modules' || name.startsWith('dist')) continue
47
+ const full = path.join(dir, name)
48
+ if (statSync(full).isDirectory()) out.push(...filesUnder(full))
49
+ else if (/\.(ts|js)$/.test(name) && !name.endsWith('.d.ts')) out.push(full)
50
+ }
51
+ return out
52
+ }
53
+
54
+ const UNCOMPILED = [
55
+ ...filesUnder(path.join(PACKAGES, 'component-ui/client')),
56
+ path.join(PACKAGES, 'board-service/client/entries/headless-scene-components.js'),
57
+ path.join(PACKAGES, 'shell/client/entries/public/home.js')
58
+ ]
59
+
60
+ describe('client files no compiler reads before publish', () => {
61
+ it('found the files - an empty list would pass on nothing', () => {
62
+ expect(UNCOMPILED.length).toBeGreaterThan(5)
63
+ })
64
+
65
+ it.each(UNCOMPILED.map(file => path.relative(PACKAGES, file)))('%s parses', relative => {
66
+ const file = path.join(PACKAGES, relative)
67
+ const result = ts.transpileModule(readFileSync(file, 'utf8'), {
68
+ fileName: file,
69
+ reportDiagnostics: true,
70
+ compilerOptions: { target: ts.ScriptTarget.ES2022, module: ts.ModuleKind.ESNext, experimentalDecorators: true, allowJs: true }
71
+ })
72
+ const syntax = (result.diagnostics ?? []).map(d => ts.flattenDiagnosticMessageText(d.messageText, '\n'))
73
+ expect(syntax).toEqual([])
74
+ })
75
+ })