fyn 2.1.3 → 2.1.4

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 (3) hide show
  1. package/README.md +161 -0
  2. package/dist/fyn.js +1042 -156
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -77,6 +77,167 @@ production=false
77
77
  centralStore=false
78
78
  ```
79
79
 
80
+ ### Local source exports (`fyn.localExports`)
81
+
82
+ A package can expose local development directories by declaring them in its
83
+ `package.json`:
84
+
85
+ ```json
86
+ {
87
+ "name": "@acme/ui",
88
+ "fyn": {
89
+ "localExports": {
90
+ "src": "./src"
91
+ }
92
+ }
93
+ }
94
+ ```
95
+
96
+ Values are producer-relative directories. The merged `package-fyn.json` may
97
+ override this configuration; `false` disables either one named export or the
98
+ entire `localExports` field.
99
+
100
+ When the package is a fynpo package or resolves from a `file:`, `link:`, or
101
+ explicit filesystem path dependency, fyn creates each live directory link at
102
+ `<dir>/<package>/<export>` in the consuming package, where `<dir>` defaults to
103
+ `_fyn`; the example above creates `_fyn/@acme/ui/src`. Registry, Git, and URL
104
+ dependencies never create local exports, even if their package metadata declares
105
+ them.
106
+
107
+ #### Configuring the export directory
108
+
109
+ The export directory is owned and configured by the **consuming** package, in
110
+ its `package.json` (or merged `package-fyn.json`) `fyn` section:
111
+
112
+ ```json
113
+ {
114
+ "fyn": {
115
+ "localExportsDir": "_fyn",
116
+ "localExportsDirs": {
117
+ "@acme/ui": "_ui",
118
+ "tools": "vendor/tools"
119
+ }
120
+ }
121
+ }
122
+ ```
123
+
124
+ - `localExportsDir` sets the default directory for all producers; it defaults to
125
+ `_fyn` when omitted.
126
+ - `localExportsDirs` overrides the directory per producer package name.
127
+
128
+ With the example above, `@acme/ui` exports land under `_ui/@acme/ui/...` and
129
+ `tools` under `vendor/tools/tools/...`, while every other producer uses the
130
+ `_fyn` default. Directories must be relative paths inside the consumer; absolute
131
+ paths, `..` escapes, `node_modules`, `.git`, and nested export directories are
132
+ rejected. Producers cannot choose where their exports are written.
133
+
134
+ Each configured directory is generated, disposable content. Exclude it from Git,
135
+ package publication, and fynpo build-cache inputs. Fyn creates the source
136
+ surface only; the consumer remains responsible for configuring Vite aliases,
137
+ TypeScript paths, or equivalent tool settings to use it.
138
+
139
+ ### Lifecycle script allow list (`fyn.allowScripts`)
140
+
141
+ As a security hardening measure, `fyn` does **not** run a package's npm lifecycle
142
+ scripts (`preinstall`, `install`, `postinstall`) during install unless the package
143
+ came from a configured registry (the primary `registry` or a `@scope:registry`) or
144
+ is a local `file:`/`link:`/symlink dependency.
145
+
146
+ Packages pulled from other sources — `github:`, git URLs (`git+https`, `git+ssh`,
147
+ …), and `http(s)` tarball URLs — have their lifecycle scripts **skipped by default**,
148
+ and `fyn` prints a warning showing how to allow them.
149
+
150
+ To allow specific scripts for such a package, add a `fyn.allowScripts` map to your
151
+ `package.json`. Each key is `name@<spec-or-version>` and the value is the list of
152
+ allowed script names:
153
+
154
+ ```json
155
+ {
156
+ "fyn": {
157
+ "allowScripts": {
158
+ "foo@github:user/foo#v1": ["install", "postinstall"],
159
+ "bar@2.3.0": ["preinstall"]
160
+ }
161
+ }
162
+ }
163
+ ```
164
+
165
+ - The key matches **either** the original dependency spec (e.g. `foo@github:user/foo#v1`)
166
+ **or** the resolved version (e.g. `bar@2.3.0`).
167
+ - Script names are matched case-insensitively.
168
+ - Use `["*"]` (or `true`) as the value to allow all lifecycle scripts for that package.
169
+
170
+ #### Trusting direct dependencies (`fyn.allowTopLevelScripts`)
171
+
172
+ Maintaining per-package `allowScripts` entries is tedious when you have several
173
+ non-registry dependencies you control (e.g. private `github:`/git deps with a
174
+ build step). As an **opt-in** convenience, you can trust the lifecycle scripts of
175
+ any non-registry package that is declared **directly** in your top-level
176
+ `package.json` — without listing each one:
177
+
178
+ ```json
179
+ {
180
+ "fyn": {
181
+ "allowTopLevelScripts": true
182
+ }
183
+ }
184
+ ```
185
+
186
+ - This is **off by default**; the deny-by-default policy above is unchanged.
187
+ - It only applies to dependencies you declared directly in the top-level
188
+ `package.json`. Non-registry packages pulled in **transitively** stay blocked
189
+ and still require an explicit `fyn.allowScripts` entry.
190
+ - `true` (or `"*"`) allows all lifecycle scripts; an array such as
191
+ `["install", "postinstall"]` restricts it to those script names for all direct
192
+ non-registry deps.
193
+ - Allowances combine with `fyn.allowScripts`: a per-package entry can grant
194
+ additional scripts on top of what `allowTopLevelScripts` permits.
195
+
196
+ > ⚠️ A direct `github:`/git dependency on a branch or tag still runs whatever code
197
+ > has been pushed there. Declaring it in your `package.json` is an explicit trust
198
+ > decision — pin to a commit/tarball you've reviewed when that matters.
199
+
200
+ ### Registry-only transitive dependencies (`fyn.enforceRegistryDeps`)
201
+
202
+ By default, `fyn` requires that **transitive** (non-top-level) dependencies
203
+ resolve from a published registry. This blocks a transitive dependency from
204
+ quietly pulling code off `github:`/git/URL sources that you never chose — only
205
+ the top-level `package.json` is allowed to declare such sources.
206
+
207
+ - **On by default.** A transitive dependency from a non-registry source
208
+ (`github:`, `git+ssh`/`https`/`http`/`file`, `git:`, `http(s)` tarball) — or
209
+ one with an unparseable version selector — causes `fyn` to **abort the
210
+ install** with an error naming the offending package and its parent.
211
+ - **Top-level `package.json` is unrestricted** — you may still declare `github:`,
212
+ git, URL, and local dependencies for your own project.
213
+ - **Accepted for transitive deps:** registry semver/ranges/dist-tags
214
+ (`^1.2.3`, `1.x`, `latest`, `*`), `npm:` aliases (registry-backed), and local
215
+ `file:`/`link:`/symlink deps — including monorepo siblings linked by `fynpo`.
216
+
217
+ To **disable** the policy (e.g. you genuinely need a transitive git/URL dep),
218
+ turn it off in `package.json`:
219
+
220
+ ```json
221
+ {
222
+ "fyn": {
223
+ "enforceRegistryDeps": false
224
+ }
225
+ }
226
+ ```
227
+
228
+ or per-invocation on the command line:
229
+
230
+ ```sh
231
+ fyn install --no-enforce-registry-deps
232
+ ```
233
+
234
+ The CLI flag takes precedence over the `package.json` setting, which takes
235
+ precedence over the default (on).
236
+
237
+ This is independent of the lifecycle-script controls above: `allowScripts` /
238
+ `allowTopLevelScripts` decide whether *scripts run*, while `enforceRegistryDeps`
239
+ decides whether a transitive package is *allowed at all*.
240
+
80
241
  ### Thank you `npm`
81
242
 
82
243
  Node Package Manager is a very large and complex piece of software. Developing `fyn` was 10 times easier because of the generous open source software from the community, especially the individual packages that are part of `npm`.