@yahoo/uds-create-loader 4.46.1 → 4.47.0

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": "@yahoo/uds-create-loader",
3
- "version": "4.46.1",
3
+ "version": "4.47.0",
4
4
  "type": "module",
5
5
  "private": false,
6
6
  "files": [
@@ -38,7 +38,7 @@
38
38
  "test:update": "bun test src/ --update-snapshots"
39
39
  },
40
40
  "dependencies": {
41
- "@yahoo/uds-create-config": "4.46.1",
41
+ "@yahoo/uds-create-config": "4.47.0",
42
42
  "@babel/parser": "^7.29.0",
43
43
  "@babel/traverse": "^7.29.0",
44
44
  "@babel/types": "^7.29.0",
@@ -63,5 +63,5 @@
63
63
  "optional": true
64
64
  }
65
65
  },
66
- "udsSchemaVersion": 20260929161433
66
+ "udsSchemaVersion": 20260930153059
67
67
  }
@@ -88,6 +88,41 @@ export function Demo() {
88
88
  expect(output).not.toContain("from '@/uds/components/box'");
89
89
  });
90
90
 
91
+ it("runs a linked system's source import as the module the build emitted for it", () => {
92
+ const source = `
93
+ import { Avatar } from '@/uds/registry/yos/avatar';
94
+ import { useTone } from "@/uds/registry/yahoo-os-v3-bridge/hooks/use-tone";
95
+
96
+ export function Demo() {
97
+ return <Avatar tone={useTone()} />;
98
+ }
99
+ `;
100
+ const output = runLoader(source, makeEmptyConfig());
101
+
102
+ expect(output).toContain("from '#uds/components/_linked/yos/avatar'");
103
+ expect(output).toContain(
104
+ 'from "#uds/components/_linked/yahoo-os-v3-bridge/hooks/use-tone"',
105
+ );
106
+ expect(output).not.toContain('@/uds/registry/');
107
+ });
108
+
109
+ it('follows the aliases the system declares', () => {
110
+ const config = new System()
111
+ .register({
112
+ settings: { build: { sourceAlias: '~/ds', outputAlias: '#ds' } },
113
+ })
114
+ .toJSON() as SerializedConfig;
115
+ const source = `
116
+ import { Avatar } from '~/ds/registry/yos/avatar';
117
+ import { Stale } from '@/uds/registry/yos/stale';
118
+ `;
119
+ const output = runLoader(source, config);
120
+
121
+ expect(output).toContain("from '#ds/components/_linked/yos/avatar'");
122
+ // Not this system's alias, so not this loader's to rewrite.
123
+ expect(output).toContain("from '@/uds/registry/yos/stale'");
124
+ });
125
+
91
126
  it('does not rewrite relative imports', () => {
92
127
  const config = makeBoxConfig();
93
128
  const source = `
package/src/loader.ts CHANGED
@@ -1,6 +1,10 @@
1
1
  import { parse } from '@babel/parser';
2
2
  import _traverse from '@babel/traverse';
3
- import { resolveRegistryDir } from '@yahoo/uds-create-config';
3
+ import {
4
+ resolveOutputAlias,
5
+ resolveRegistryDir,
6
+ resolveSourceAlias,
7
+ } from '@yahoo/uds-create-config';
4
8
  import type { LoaderDefinitionFunction } from 'webpack';
5
9
  import {
6
10
  getLoaderProjection,
@@ -72,17 +76,23 @@ const transformLoader: LoaderDefinitionFunction = function (source) {
72
76
 
73
77
  // Configurable registry location (`build.registryDir`) — same skip rationale as above. The
74
78
  // settings are one item of the `settings` kind in a serialized config, keyed by the kind.
75
- const registryRel = resolveRegistryDir(
76
- (
77
- config as {
78
- items?: {
79
+ const build = (
80
+ config as {
81
+ items?: {
82
+ settings?: {
79
83
  settings?: {
80
- settings?: { build?: Parameters<typeof resolveRegistryDir>[0] };
84
+ build?: Parameters<typeof resolveRegistryDir>[0] &
85
+ Parameters<typeof resolveSourceAlias>[0];
81
86
  };
82
87
  };
83
- }
84
- ).items?.settings?.settings?.build,
85
- );
88
+ };
89
+ }
90
+ ).items?.settings?.settings?.build;
91
+ const registryRel = resolveRegistryDir(build);
92
+ // The prefixes the system declares: its sources' (`@/uds`) and its build output's (`#uds`). A linked
93
+ // system's source is imported beneath the first, `<sourceAlias>/registry/<slug>/…`.
94
+ const outputAlias = resolveOutputAlias(build);
95
+ const linkedAlias = `${resolveSourceAlias(build)}/registry/`;
86
96
  if (resourcePath.replace(/\\/g, '/').includes(`/${registryRel}/`)) {
87
97
  return source;
88
98
  }
@@ -92,7 +102,7 @@ const transformLoader: LoaderDefinitionFunction = function (source) {
92
102
  // Cheap pre-filter: only parse files that look like they import or
93
103
  // reference a UDS component. Avoids babel overhead on the bulk of
94
104
  // application files.
95
- let hasComponentReference = false;
105
+ let hasComponentReference = source.includes(linkedAlias);
96
106
  for (const name of projection.componentNames) {
97
107
  if (source.includes(name)) {
98
108
  hasComponentReference = true;
@@ -142,6 +152,25 @@ const transformLoader: LoaderDefinitionFunction = function (source) {
142
152
  const importSource: string | undefined = nodePath.node.source?.value;
143
153
  if (!importSource) return;
144
154
 
155
+ // A linked system's source, imported by its alias for the types (`@/uds/registry/yos/avatar`),
156
+ // runs as the module the build emitted from it — the same path under `components/_linked/`.
157
+ if (importSource.startsWith(linkedAlias)) {
158
+ const sourceNode = nodePath.node.source;
159
+ if (
160
+ typeof sourceNode.start !== 'number' ||
161
+ typeof sourceNode.end !== 'number'
162
+ ) {
163
+ return;
164
+ }
165
+ const quote = source[sourceNode.start] ?? "'";
166
+ edits.push({
167
+ start: sourceNode.start,
168
+ end: sourceNode.end,
169
+ value: `${quote}${outputAlias}/components/_linked/${importSource.slice(linkedAlias.length)}${quote}`,
170
+ });
171
+ return;
172
+ }
173
+
145
174
  // Only rewrite alias-prefixed local imports (e.g.
146
175
  // `@/uds/components/<name>`, `~/uds/components/<name>`).
147
176
  // Relative imports (`./text`, `../box`) belong to the authoring
@@ -213,7 +242,7 @@ const transformLoader: LoaderDefinitionFunction = function (source) {
213
242
  edits.push({
214
243
  start: sourceNode.start,
215
244
  end: sourceNode.end,
216
- value: `${quote}#uds/components/${segmentMatch[1]}${quote}`,
245
+ value: `${quote}${outputAlias}/components/${segmentMatch[1]}${quote}`,
217
246
  });
218
247
  }
219
248
  },
package/src/next.test.ts CHANGED
@@ -6,7 +6,8 @@ import { withUds } from './next';
6
6
  // Repo rule: test artifacts under the package's dist/.test-tmp.
7
7
  const TMP = path.join(import.meta.dir, '../dist/.test-tmp/next-registry-deps');
8
8
 
9
- const REGISTRY_REL = '.uds-registry';
9
+ // The default registry, beside the conventional components root.
10
+ const REGISTRY_REL = 'src/uds/registry';
10
11
 
11
12
  function writeFixture(args: {
12
13
  registryDeps?: Record<string, string>;