@yahoo/uds-create-loader 2.45.0 → 3.0.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": "2.45.0",
3
+ "version": "3.0.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": "2.45.0",
41
+ "@yahoo/uds-create-config": "3.0.0",
42
42
  "@babel/parser": "^7.29.0",
43
43
  "@babel/traverse": "^7.29.0",
44
44
  "@babel/types": "^7.29.0",
@@ -62,5 +62,6 @@
62
62
  "webpack": {
63
63
  "optional": true
64
64
  }
65
- }
65
+ },
66
+ "udsSchemaVersion": 20260910212453
66
67
  }
@@ -104,7 +104,10 @@ export function getLoaderProjection(
104
104
  const cached = projectionCache.get(config);
105
105
  if (cached) return cached;
106
106
 
107
- const components = (config.components ?? {}) as Record<string, unknown>;
107
+ // Items are grouped BY KIND in a serialized config; a top-level `components` map is the shape the
108
+ // old artifact had. Read the old way it answered `{}`, so `componentNames` was empty and the
109
+ // loader's pre-filter concluded no file referenced a UDS component — it transformed nothing at all.
110
+ const components = config.items?.component ?? {};
108
111
  const componentNames = new Set<string>(Object.keys(components));
109
112
 
110
113
  const projection: LoaderProjection = { componentNames };
@@ -1,22 +1,18 @@
1
1
  /**
2
2
  * Unit tests for the trimmed `transformLoader`.
3
3
  *
4
- * Fixtures use the public authoring API (`defineComponent`,
5
- * `defineStyleProp`, `uds.register*`) and call `Config.toJSON()` so the
6
- * loader sees exactly the serialized-config shape it would in production.
7
- * Avoids coupling tests to internal serialized layer / marker shape —
8
- * those shapes can evolve without touching this file.
4
+ * Fixtures are built through the public entity API (`System.register`,
5
+ * `Component.item`, `StyleProperty.item`) and serialized with `toJSON()`, so the
6
+ * loader sees exactly the shape it would in production. Avoids coupling tests to
7
+ * the internal serialized layer / prop shape — those can evolve without touching
8
+ * this file.
9
9
  */
10
10
 
11
11
  import { describe, expect, it } from 'bun:test';
12
12
  import path from 'node:path';
13
13
  import { parse } from '@babel/parser';
14
14
  import type { SerializedConfig } from '@yahoo/uds-create-config';
15
- import {
16
- Config,
17
- defineComponent,
18
- defineStyleProp,
19
- } from '@yahoo/uds-create-config';
15
+ import { Component, StyleProperty, System } from '@yahoo/uds-create-config';
20
16
  import transformLoader from './loader';
21
17
  import { seedUdsConfig } from './loader/artifacts';
22
18
 
@@ -47,35 +43,33 @@ function runLoader(
47
43
  // Shared config factories — authoring-API based
48
44
  // ---------------------------------------------------------------------------
49
45
 
50
- const bg = defineStyleProp({
51
- cssProperty: 'background-color',
52
- classPrefix: 'bg',
53
- values: [],
54
- });
55
-
56
- const padding = defineStyleProp({
57
- cssProperty: 'padding',
58
- classPrefix: 'p',
59
- values: [],
60
- });
61
-
62
46
  /** Single-layer primitive `<Box>` with two style-prop bindings. Lowerable. */
63
47
  function makeBoxConfig(): SerializedConfig {
64
- const Box = defineComponent('div').config(({ styleProp }) => ({
65
- props: {
66
- bg: styleProp('bg'),
67
- padding: styleProp('padding'),
68
- },
69
- }));
70
- const config = new Config()
71
- .registerStyleProps({ bg, padding })
72
- .registerComponents({ Box });
73
- return config.toJSON();
48
+ return new System()
49
+ .register({
50
+ styleProps: {
51
+ bg: StyleProperty.item({ properties: ['background-color'] }),
52
+ padding: StyleProperty.item({ properties: ['padding'] }),
53
+ },
54
+ components: {
55
+ Box: Component.item({
56
+ layers: { root: 'div' },
57
+ props: {
58
+ bg: { type: 'styleProperty', value: StyleProperty.ref('bg') },
59
+ padding: {
60
+ type: 'styleProperty',
61
+ value: StyleProperty.ref('padding'),
62
+ },
63
+ },
64
+ }),
65
+ },
66
+ })
67
+ .toJSON() as SerializedConfig;
74
68
  }
75
69
 
76
70
  /** Empty config — no registered components. */
77
71
  function makeEmptyConfig(): SerializedConfig {
78
- return new Config().toJSON();
72
+ return new System().toJSON() as SerializedConfig;
79
73
  }
80
74
 
81
75
  describe('loader — new-API import rewrite', () => {
@@ -265,32 +259,14 @@ export function Demo() {
265
259
  expect(output).toBe(source);
266
260
  });
267
261
 
268
- it('skips the default registry location under componentsDir', () => {
269
- const config = {
270
- ...makeBoxConfig(),
271
- buildOptions: { componentsDir: 'src/uds' },
272
- };
273
- const source = `
274
- import { Box } from '@/uds/components/box';
275
-
276
- export function Demo() {
277
- return <Box bg="brand">hi</Box>;
278
- }
279
- `;
280
- const output = runLoader(source, config, {
281
- resourcePath: path.join(
282
- process.cwd(),
283
- 'src/uds/registry/aaaaaaaa-1111-4111-8111-111111111111@1.0.0/src/uds/components/demo.tsx',
284
- ),
285
- });
286
-
287
- expect(output).toBe(source);
288
- });
289
-
290
- it('skips an explicit buildOptions.registryDir', () => {
262
+ it('skips an explicit build.registryDir', () => {
263
+ const box = makeBoxConfig();
291
264
  const config = {
292
- ...makeBoxConfig(),
293
- buildOptions: { registryDir: 'vendor/linked' },
265
+ ...box,
266
+ items: {
267
+ ...box.items,
268
+ settings: { settings: { build: { registryDir: 'vendor/linked' } } },
269
+ },
294
270
  };
295
271
  const source = `
296
272
  import { Box } from '@/uds/components/box';
package/src/loader.ts CHANGED
@@ -70,9 +70,19 @@ const transformLoader: LoaderDefinitionFunction = function (source) {
70
70
  const config = loadUdsConfig(dataPath, isDev);
71
71
  if (!config) return source;
72
72
 
73
- // Configurable registry location (`buildOptions.registryDir`, defaulting
74
- // to `<componentsDir>/registry`) — same skip rationale as above.
75
- const registryRel = resolveRegistryDir(config.buildOptions);
73
+ // Configurable registry location (`build.registryDir`) — same skip rationale as above. The
74
+ // 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
+ settings?: {
80
+ settings?: { build?: Parameters<typeof resolveRegistryDir>[0] };
81
+ };
82
+ };
83
+ }
84
+ ).items?.settings?.settings?.build,
85
+ );
76
86
  if (resourcePath.replace(/\\/g, '/').includes(`/${registryRel}/`)) {
77
87
  return source;
78
88
  }
package/src/next.test.ts CHANGED
@@ -6,12 +6,12 @@ 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 = 'src/uds/registry';
9
+ const REGISTRY_REL = '.uds-registry';
10
10
 
11
11
  function writeFixture(args: {
12
12
  registryDeps?: Record<string, string>;
13
13
  consumerHas?: string[];
14
- buildOptions?: { componentsDir?: string; registryDir?: string };
14
+ build?: { registryDir?: string };
15
15
  }): string {
16
16
  const root = path.join(TMP, `proj-${Math.random().toString(36).slice(2, 8)}`);
17
17
 
@@ -19,12 +19,15 @@ function writeFixture(args: {
19
19
  writeFileSync(
20
20
  path.join(root, '.uds/config.json'),
21
21
  JSON.stringify({
22
- buildOptions: args.buildOptions ?? { componentsDir: 'src/uds' },
22
+ items: { settings: { settings: { build: args.build ?? {} } } },
23
23
  }),
24
24
  );
25
25
 
26
26
  if (args.registryDeps) {
27
- const registryDir = path.join(root, REGISTRY_REL);
27
+ const registryDir = path.join(
28
+ root,
29
+ args.build?.registryDir ?? REGISTRY_REL,
30
+ );
28
31
  mkdirSync(path.join(registryDir, 'node_modules'), { recursive: true });
29
32
  writeFileSync(
30
33
  path.join(registryDir, 'package.json'),
@@ -141,10 +144,10 @@ describe('withUds — linked-registry dependency resolution', () => {
141
144
  ).toBeUndefined();
142
145
  });
143
146
 
144
- it('honors a custom buildOptions.registryDir', () => {
147
+ it('honors a custom build.registryDir', () => {
145
148
  const root = writeFixture({
146
149
  registryDeps: { clsx: '^2.0.0' },
147
- buildOptions: { registryDir: 'src/uds/registry' },
150
+ build: { registryDir: 'src/uds/registry' },
148
151
  });
149
152
 
150
153
  const config = applyIn(root, () => withUds({}));
package/src/next.ts CHANGED
@@ -27,9 +27,7 @@ function resolveLoaderPath(): string {
27
27
  function readRegistryDeps(
28
28
  outputDir: string,
29
29
  ): { registryDirRel: string; nodeModules: string; deps: string[] } | null {
30
- let buildOptions:
31
- | { componentsDir?: string; registryDir?: string }
32
- | undefined;
30
+ let buildOptions: { registryDir?: string } | undefined;
33
31
  try {
34
32
  buildOptions = (
35
33
  JSON.parse(
@@ -37,8 +35,10 @@ function readRegistryDeps(
37
35
  path.resolve(process.cwd(), outputDir, 'config.json'),
38
36
  'utf-8',
39
37
  ),
40
- ) as { buildOptions?: typeof buildOptions }
41
- ).buildOptions;
38
+ ) as {
39
+ items?: { settings?: { settings?: { build?: typeof buildOptions } } };
40
+ }
41
+ ).items?.settings?.settings?.build;
42
42
  } catch {
43
43
  return null;
44
44
  }
@@ -1,63 +0,0 @@
1
- import fs from 'node:fs';
2
- import path from 'node:path';
3
- import { pathToFileURL } from 'node:url';
4
- import { runLoaderTransform } from './transform-runner';
5
- function readFlag(flag) {
6
- const index = process.argv.indexOf(flag);
7
- if (index === -1)
8
- return null;
9
- const value = process.argv[index + 1];
10
- if (!value || value.startsWith('-'))
11
- return null;
12
- return value;
13
- }
14
- function printUsage() {
15
- console.error([
16
- 'Usage:',
17
- ' bun run src/inspect-transform.ts --file <path-to-tsx> --config <path-to-uds.config.ts>',
18
- '',
19
- 'Example:',
20
- ' bun run --filter @yahoo/uds-create-loader inspect:transform -- --file packages/components/src/accordion.tsx --config apps/studio/uds.config.ts',
21
- ].join('\n'));
22
- process.exit(1);
23
- }
24
- async function loadUdsConfig(configPath) {
25
- const resolvedPath = path.resolve(configPath);
26
- const configUrl = pathToFileURL(resolvedPath).href;
27
- const module = (await import(configUrl));
28
- if (module.default !== undefined) {
29
- return module.default;
30
- }
31
- if (module.udsConfig !== undefined) {
32
- return module.udsConfig;
33
- }
34
- return module;
35
- }
36
- async function main() {
37
- const sourcePath = readFlag('--file');
38
- const configPath = readFlag('--config');
39
- if (!sourcePath || !configPath) {
40
- printUsage();
41
- }
42
- const sourceAbsolutePath = path.resolve(sourcePath);
43
- if (!fs.existsSync(sourceAbsolutePath)) {
44
- throw new Error(`Source file not found: ${sourceAbsolutePath}`);
45
- }
46
- const rawConfig = await loadUdsConfig(configPath);
47
- const config = rawConfig.toJSON();
48
- const source = fs.readFileSync(sourceAbsolutePath, 'utf8');
49
- const result = runLoaderTransform(source, {
50
- config,
51
- resourcePath: sourceAbsolutePath,
52
- isDev: false,
53
- });
54
- if ('error' in result) {
55
- throw new Error(result.error);
56
- }
57
- process.stdout.write(result.output);
58
- }
59
- void main().catch((error) => {
60
- const message = error instanceof Error ? error.message : String(error);
61
- console.error(`[inspect-transform] ${message}`);
62
- process.exit(1);
63
- });