@ossy/app 1.21.4 → 1.22.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.
- package/cli/build.task.js +16 -8
- package/cli/get-platform-files.task.js +76 -5
- package/cli/manifest-plugin.js +1 -1
- package/package.json +14 -14
package/cli/build.task.js
CHANGED
|
@@ -54,14 +54,21 @@ function ensureDir (dir) {
|
|
|
54
54
|
// folders (e.g. `apps/home.page.jsx` and `analytics/home.page.jsx`) from
|
|
55
55
|
// colliding on the Rollup input map — which the filesystem already
|
|
56
56
|
// guarantees can't happen at the relative-path level.
|
|
57
|
-
|
|
57
|
+
//
|
|
58
|
+
// For installed-package entries, `packageName` is provided and used as a
|
|
59
|
+
// prefix so that e.g. `@ossy/authentication/sign-in.page.jsx` becomes
|
|
60
|
+
// `ossy__authentication__sign-in.page` and never collides with a local file.
|
|
61
|
+
function entryNameFromSource (sourcePath, srcDir, packageName) {
|
|
58
62
|
const rel = path.relative(srcDir, sourcePath).replace(/\\/g, '/')
|
|
59
|
-
|
|
63
|
+
const flat = rel.replace(/\//g, '__').replace(/\.(jsx?|tsx?|mjs|cjs)$/, '')
|
|
64
|
+
if (!packageName) return flat
|
|
65
|
+
const pkgPrefix = packageName.replace(/^@/, '').replace(/\//g, '__').replace(/[^a-zA-Z0-9_-]/g, '_')
|
|
66
|
+
return `${pkgPrefix}__${flat}`
|
|
60
67
|
}
|
|
61
68
|
|
|
62
|
-
function stubFileNameFor (kind, sourcePath, srcDir) {
|
|
69
|
+
function stubFileNameFor (kind, sourcePath, srcDir, packageName) {
|
|
63
70
|
const ext = kind === 'page' ? '.entry.jsx' : '.entry.js'
|
|
64
|
-
return entryNameFromSource(sourcePath, srcDir) + ext
|
|
71
|
+
return entryNameFromSource(sourcePath, srcDir, packageName) + ext
|
|
65
72
|
}
|
|
66
73
|
|
|
67
74
|
function relImport (fromAbs, toAbs) {
|
|
@@ -176,12 +183,13 @@ export async function build (cliArgs = []) {
|
|
|
176
183
|
const stubInputMap = {}
|
|
177
184
|
|
|
178
185
|
for (const entry of allEntries) {
|
|
179
|
-
const { kind, sourcePath } = entry
|
|
180
|
-
const
|
|
181
|
-
const
|
|
186
|
+
const { kind, sourcePath, packageName, packageSrcDir } = entry
|
|
187
|
+
const effectiveSrcDir = packageSrcDir || srcDir
|
|
188
|
+
const inputName = entryNameFromSource(sourcePath, effectiveSrcDir, packageName)
|
|
189
|
+
const stubAbs = path.join(stubDir, stubFileNameFor(kind, sourcePath, effectiveSrcDir, packageName))
|
|
182
190
|
fs.writeFileSync(stubAbs, stubFor(kind, { stubAbs, sourceAbs: sourcePath }), 'utf8')
|
|
183
191
|
stubInputMap[inputName] = stubAbs
|
|
184
|
-
entriesByStub.set(stubAbs, { kind, sourcePath })
|
|
192
|
+
entriesByStub.set(stubAbs, { kind, sourcePath, packageName, packageSrcDir })
|
|
185
193
|
}
|
|
186
194
|
|
|
187
195
|
const configPath = path.resolve(srcDir, 'config.js')
|
|
@@ -10,8 +10,10 @@ export const RESOURCE_FILE_PATTERN = /\.resource\.(mjs|cjs|js)$/
|
|
|
10
10
|
* @typedef {'page' | 'api' | 'task' | 'resource'} EntryKind
|
|
11
11
|
*
|
|
12
12
|
* @typedef {object} PlatformEntry
|
|
13
|
-
* @property {EntryKind} kind
|
|
14
|
-
* @property {string} sourcePath
|
|
13
|
+
* @property {EntryKind} kind Which bucket this entry lives in.
|
|
14
|
+
* @property {string} sourcePath Absolute path to the user-authored source file.
|
|
15
|
+
* @property {string} [packageName] npm package name, set only for installed-package entries.
|
|
16
|
+
* @property {string} [packageSrcDir] Absolute path to the package's `src/` dir, set only for installed-package entries.
|
|
15
17
|
*
|
|
16
18
|
* @typedef {object} PlatformFiles
|
|
17
19
|
* @property {PlatformEntry[]} pages Discovered `*.page.{jsx,tsx,...}` entries.
|
|
@@ -76,11 +78,72 @@ export function filePathToRoute (absPath, srcDir) {
|
|
|
76
78
|
return { id, path: defaultPageRoute(id) }
|
|
77
79
|
}
|
|
78
80
|
|
|
81
|
+
/**
|
|
82
|
+
* Walks `node_modules/` in `projectRoot` looking for packages that declare an
|
|
83
|
+
* `"ossy": { "src": "./src" }` field in their `package.json`. Returns entries
|
|
84
|
+
* from those packages' source trees, tagged with `packageName` and
|
|
85
|
+
* `packageSrcDir` so the build pipeline can namespace them correctly.
|
|
86
|
+
*
|
|
87
|
+
* Handles both flat packages (`node_modules/foo`) and scoped packages
|
|
88
|
+
* (`node_modules/@scope/foo`).
|
|
89
|
+
*
|
|
90
|
+
* @param {string} projectRoot Absolute path to the consuming project root (parent of `src/`).
|
|
91
|
+
* @returns {PlatformEntry[]}
|
|
92
|
+
*/
|
|
93
|
+
export function discoverInstalledPackageEntries (projectRoot) {
|
|
94
|
+
const nmDir = path.join(projectRoot, 'node_modules')
|
|
95
|
+
if (!fs.existsSync(nmDir) || !fs.statSync(nmDir).isDirectory()) return []
|
|
96
|
+
|
|
97
|
+
const entries = []
|
|
98
|
+
|
|
99
|
+
const tryPackageDir = (pkgDir) => {
|
|
100
|
+
const pkgJsonPath = path.join(pkgDir, 'package.json')
|
|
101
|
+
if (!fs.existsSync(pkgJsonPath)) return
|
|
102
|
+
let pkg
|
|
103
|
+
try { pkg = JSON.parse(fs.readFileSync(pkgJsonPath, 'utf8')) } catch { return }
|
|
104
|
+
if (!pkg.ossy?.src) return
|
|
105
|
+
|
|
106
|
+
const packageSrcDir = path.resolve(pkgDir, pkg.ossy.src)
|
|
107
|
+
const files = [
|
|
108
|
+
...discoverFilesByPattern(packageSrcDir, PAGE_FILE_PATTERN),
|
|
109
|
+
...discoverFilesByPattern(packageSrcDir, API_FILE_PATTERN),
|
|
110
|
+
...discoverFilesByPattern(packageSrcDir, TASK_FILE_PATTERN),
|
|
111
|
+
...discoverFilesByPattern(packageSrcDir, RESOURCE_FILE_PATTERN),
|
|
112
|
+
]
|
|
113
|
+
for (const sourcePath of files) {
|
|
114
|
+
const stat = fs.statSync(sourcePath)
|
|
115
|
+
if (!stat.isFile() || stat.size === 0) continue
|
|
116
|
+
const kind = classifyFile(sourcePath)
|
|
117
|
+
if (!kind) continue
|
|
118
|
+
entries.push({ kind, sourcePath, packageName: pkg.name, packageSrcDir })
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
for (const entry of fs.readdirSync(nmDir, { withFileTypes: true })) {
|
|
123
|
+
if (!entry.isDirectory() && !entry.isSymbolicLink()) continue
|
|
124
|
+
if (entry.name.startsWith('@')) {
|
|
125
|
+
const scopeDir = path.join(nmDir, entry.name)
|
|
126
|
+
for (const scoped of fs.readdirSync(scopeDir, { withFileTypes: true })) {
|
|
127
|
+
if (scoped.isDirectory() || scoped.isSymbolicLink()) {
|
|
128
|
+
tryPackageDir(path.join(scopeDir, scoped.name))
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
} else {
|
|
132
|
+
tryPackageDir(path.join(nmDir, entry.name))
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
return entries
|
|
137
|
+
}
|
|
138
|
+
|
|
79
139
|
/**
|
|
80
140
|
* Walks `srcDir` and returns the user-authored entries the platform cares
|
|
81
141
|
* about, bucketed by kind. Empty (zero-byte) source files are skipped — we
|
|
82
142
|
* treat them as placeholders the user is mid-creating.
|
|
83
143
|
*
|
|
144
|
+
* Also scans installed npm packages that declare an `"ossy": { "src" }` field
|
|
145
|
+
* in their `package.json`, merging their entries into the same output buckets.
|
|
146
|
+
*
|
|
84
147
|
* Metadata isn't read here on purpose: the build pipeline reads it from the
|
|
85
148
|
* bundled output instead, which lets users compute `metadata.path` (and
|
|
86
149
|
* anything else) from imports, config, env vars, etc.
|
|
@@ -90,19 +153,27 @@ export function filePathToRoute (absPath, srcDir) {
|
|
|
90
153
|
*/
|
|
91
154
|
export default async function getPlatformFiles (srcDir) {
|
|
92
155
|
const out = { pages: [], apis: [], tasks: [], resources: [] }
|
|
93
|
-
const
|
|
156
|
+
const bucketByKind = { page: 'pages', api: 'apis', task: 'tasks', resource: 'resources' }
|
|
157
|
+
|
|
158
|
+
const localFiles = [
|
|
94
159
|
...discoverFilesByPattern(srcDir, PAGE_FILE_PATTERN),
|
|
95
160
|
...discoverFilesByPattern(srcDir, API_FILE_PATTERN),
|
|
96
161
|
...discoverFilesByPattern(srcDir, TASK_FILE_PATTERN),
|
|
97
162
|
...discoverFilesByPattern(srcDir, RESOURCE_FILE_PATTERN),
|
|
98
163
|
]
|
|
99
|
-
const
|
|
100
|
-
for (const sourcePath of all) {
|
|
164
|
+
for (const sourcePath of localFiles) {
|
|
101
165
|
const stat = fs.statSync(sourcePath)
|
|
102
166
|
if (!stat.isFile() || stat.size === 0) continue
|
|
103
167
|
const kind = classifyFile(sourcePath)
|
|
104
168
|
if (!kind) continue
|
|
105
169
|
out[bucketByKind[kind]].push({ kind, sourcePath })
|
|
106
170
|
}
|
|
171
|
+
|
|
172
|
+
const projectRoot = path.dirname(srcDir)
|
|
173
|
+
const packageEntries = discoverInstalledPackageEntries(projectRoot)
|
|
174
|
+
for (const entry of packageEntries) {
|
|
175
|
+
out[bucketByKind[entry.kind]].push(entry)
|
|
176
|
+
}
|
|
177
|
+
|
|
107
178
|
return out
|
|
108
179
|
}
|
package/cli/manifest-plugin.js
CHANGED
|
@@ -138,7 +138,7 @@ export function manifestPlugin ({ entriesByStub, srcDir, staticOutDir, configVal
|
|
|
138
138
|
}
|
|
139
139
|
|
|
140
140
|
const rawMeta = (mod && mod.metadata) || {}
|
|
141
|
-
const id = rawMeta.id || metadataIdFromFile(entryInfo.sourcePath, srcDir)
|
|
141
|
+
const id = rawMeta.id || metadataIdFromFile(entryInfo.sourcePath, entryInfo.packageSrcDir || srcDir)
|
|
142
142
|
if (!id) {
|
|
143
143
|
this.error(`[@ossy/app][build] ${entryInfo.kind} entry missing metadata.id: ${entryInfo.sourcePath}`)
|
|
144
144
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ossy/app",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.22.1",
|
|
4
4
|
"description": "",
|
|
5
5
|
"source": "./src/index.js",
|
|
6
6
|
"main": "./src/index.js",
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
"devDependencies": {
|
|
26
26
|
"@jest/globals": "^30.2.0",
|
|
27
27
|
"jest": "^30.2.0",
|
|
28
|
-
"typescript": "^
|
|
28
|
+
"typescript": "^6.0.3"
|
|
29
29
|
},
|
|
30
30
|
"dependencies": {
|
|
31
31
|
"@babel/cli": "^7.26.4",
|
|
@@ -33,17 +33,17 @@
|
|
|
33
33
|
"@babel/eslint-parser": "^7.15.8",
|
|
34
34
|
"@babel/preset-react": "^7.26.3",
|
|
35
35
|
"@babel/register": "^7.25.9",
|
|
36
|
-
"@ossy/connected-components": "^1.
|
|
37
|
-
"@ossy/design-system": "^1.
|
|
38
|
-
"@ossy/pages": "^1.
|
|
39
|
-
"@ossy/platform": "^1.
|
|
40
|
-
"@ossy/router": "^1.
|
|
41
|
-
"@ossy/router-react": "^1.
|
|
42
|
-
"@ossy/sdk": "^1.
|
|
43
|
-
"@ossy/sdk-react": "^1.
|
|
44
|
-
"@ossy/themes": "^1.
|
|
36
|
+
"@ossy/connected-components": "^1.22.1",
|
|
37
|
+
"@ossy/design-system": "^1.22.1",
|
|
38
|
+
"@ossy/pages": "^1.22.1",
|
|
39
|
+
"@ossy/platform": "^1.21.1",
|
|
40
|
+
"@ossy/router": "^1.22.1",
|
|
41
|
+
"@ossy/router-react": "^1.22.1",
|
|
42
|
+
"@ossy/sdk": "^1.22.1",
|
|
43
|
+
"@ossy/sdk-react": "^1.22.1",
|
|
44
|
+
"@ossy/themes": "^1.22.1",
|
|
45
45
|
"@rollup/plugin-alias": "^6.0.0",
|
|
46
|
-
"@rollup/plugin-babel": "
|
|
46
|
+
"@rollup/plugin-babel": "^7.0.0",
|
|
47
47
|
"@rollup/plugin-commonjs": "^29.0.0",
|
|
48
48
|
"@rollup/plugin-inject": "^5.0.5",
|
|
49
49
|
"@rollup/plugin-json": "^6.1.0",
|
|
@@ -61,7 +61,7 @@
|
|
|
61
61
|
"rollup-plugin-copy": "^3.5.0",
|
|
62
62
|
"rollup-plugin-delete": "^3.0.2",
|
|
63
63
|
"rollup-plugin-dts": "^6.1.0",
|
|
64
|
-
"rollup-plugin-node-externals": "^
|
|
64
|
+
"rollup-plugin-node-externals": "^9.0.1",
|
|
65
65
|
"rollup-plugin-peer-deps-external": "^2.2.4",
|
|
66
66
|
"rollup-plugin-postcss-modules": "^2.1.1",
|
|
67
67
|
"rollup-plugin-preserve-directives": "^0.4.0",
|
|
@@ -75,5 +75,5 @@
|
|
|
75
75
|
"README.md",
|
|
76
76
|
"tsconfig.json"
|
|
77
77
|
],
|
|
78
|
-
"gitHead": "
|
|
78
|
+
"gitHead": "8e757fb891965b78be752b9c7db72cf45470144d"
|
|
79
79
|
}
|