@alloy-js/core 0.20.0-dev.8 → 0.20.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.
@@ -1,21 +1,7 @@
1
1
  import { createNamedContext, useContext } from "../context.js";
2
+ import { PrintTreeOptions } from "../render.js";
2
3
 
3
- export interface CommonFormatOptions {
4
- /**
5
- * The number of characters the printer will wrap on.
6
- */
7
- printWidth?: number;
8
-
9
- /**
10
- * Whether to use tabs instead of spaces for indentation.
11
- */
12
- useTabs?: boolean;
13
-
14
- /**
15
- * The number of spaces to use for indentation.
16
- */
17
- tabWidth?: number;
18
- }
4
+ export interface CommonFormatOptions extends PrintTreeOptions {}
19
5
 
20
6
  export const { Provider: FormatOptions, useFormatOptions } =
21
7
  createFormatOptionsContextFor<CommonFormatOptions>("*");
package/src/render.ts CHANGED
@@ -261,6 +261,10 @@ export function sourceFilesForTree(
261
261
  options?.printWidth ?? context.meta?.printOptions?.printWidth,
262
262
  tabWidth: options?.tabWidth ?? context.meta?.printOptions?.tabWidth,
263
263
  useTabs: options?.useTabs ?? context.meta?.printOptions?.useTabs,
264
+ insertFinalNewLine:
265
+ options?.insertFinalNewLine ??
266
+ context.meta?.printOptions?.insertFinalNewLine ??
267
+ true,
264
268
  }),
265
269
  };
266
270
 
@@ -590,6 +594,12 @@ export interface PrintTreeOptions {
590
594
  * The number of spaces to use for indentation. Defaults to 2 spaces.
591
595
  */
592
596
  tabWidth?: number;
597
+
598
+ /**
599
+ * If files should end with a final new line.
600
+ * @default true
601
+ */
602
+ insertFinalNewLine?: boolean;
593
603
  }
594
604
 
595
605
  const defaultPrintTreeOptions: PrintTreeOptions = {
@@ -609,8 +619,14 @@ export function printTree(tree: RenderedTextTree, options?: PrintTreeOptions) {
609
619
  flushJobs();
610
620
 
611
621
  const d = printTreeWorker(tree);
612
- return doc.printer.printDocToString(d, options as doc.printer.Options)
613
- .formatted;
622
+ const result = doc.printer.printDocToString(
623
+ d,
624
+ options as doc.printer.Options,
625
+ ).formatted;
626
+
627
+ return options.insertFinalNewLine && !result.endsWith("\n") ?
628
+ `${result}\n`
629
+ : result;
614
630
  }
615
631
 
616
632
  function printTreeWorker(tree: RenderedTextTree): Doc {
package/temp/api.json CHANGED
@@ -117,6 +117,10 @@
117
117
  {
118
118
  "tagName": "@reactive",
119
119
  "syntaxKind": "modifier"
120
+ },
121
+ {
122
+ "tagName": "@default",
123
+ "syntaxKind": "block"
120
124
  }
121
125
  ],
122
126
  "reportUnsupportedHtmlElements": false
@@ -2591,97 +2595,29 @@
2591
2595
  "excerptTokens": [
2592
2596
  {
2593
2597
  "kind": "Content",
2594
- "text": "export interface CommonFormatOptions "
2598
+ "text": "export interface CommonFormatOptions extends "
2599
+ },
2600
+ {
2601
+ "kind": "Reference",
2602
+ "text": "PrintTreeOptions",
2603
+ "canonicalReference": "@alloy-js/core!PrintTreeOptions:interface"
2604
+ },
2605
+ {
2606
+ "kind": "Content",
2607
+ "text": " "
2595
2608
  }
2596
2609
  ],
2597
2610
  "fileUrlPath": "src/context/format-options.ts",
2598
2611
  "releaseTag": "Public",
2599
2612
  "name": "CommonFormatOptions",
2600
2613
  "preserveMemberOrder": false,
2601
- "members": [
2602
- {
2603
- "kind": "PropertySignature",
2604
- "canonicalReference": "@alloy-js/core!CommonFormatOptions#printWidth:member",
2605
- "docComment": "/**\n * The number of characters the printer will wrap on.\n */\n",
2606
- "excerptTokens": [
2607
- {
2608
- "kind": "Content",
2609
- "text": "printWidth?: "
2610
- },
2611
- {
2612
- "kind": "Content",
2613
- "text": "number"
2614
- },
2615
- {
2616
- "kind": "Content",
2617
- "text": ";"
2618
- }
2619
- ],
2620
- "isReadonly": false,
2621
- "isOptional": true,
2622
- "releaseTag": "Public",
2623
- "name": "printWidth",
2624
- "propertyTypeTokenRange": {
2625
- "startIndex": 1,
2626
- "endIndex": 2
2627
- }
2628
- },
2629
- {
2630
- "kind": "PropertySignature",
2631
- "canonicalReference": "@alloy-js/core!CommonFormatOptions#tabWidth:member",
2632
- "docComment": "/**\n * The number of spaces to use for indentation.\n */\n",
2633
- "excerptTokens": [
2634
- {
2635
- "kind": "Content",
2636
- "text": "tabWidth?: "
2637
- },
2638
- {
2639
- "kind": "Content",
2640
- "text": "number"
2641
- },
2642
- {
2643
- "kind": "Content",
2644
- "text": ";"
2645
- }
2646
- ],
2647
- "isReadonly": false,
2648
- "isOptional": true,
2649
- "releaseTag": "Public",
2650
- "name": "tabWidth",
2651
- "propertyTypeTokenRange": {
2652
- "startIndex": 1,
2653
- "endIndex": 2
2654
- }
2655
- },
2614
+ "members": [],
2615
+ "extendsTokenRanges": [
2656
2616
  {
2657
- "kind": "PropertySignature",
2658
- "canonicalReference": "@alloy-js/core!CommonFormatOptions#useTabs:member",
2659
- "docComment": "/**\n * Whether to use tabs instead of spaces for indentation.\n */\n",
2660
- "excerptTokens": [
2661
- {
2662
- "kind": "Content",
2663
- "text": "useTabs?: "
2664
- },
2665
- {
2666
- "kind": "Content",
2667
- "text": "boolean"
2668
- },
2669
- {
2670
- "kind": "Content",
2671
- "text": ";"
2672
- }
2673
- ],
2674
- "isReadonly": false,
2675
- "isOptional": true,
2676
- "releaseTag": "Public",
2677
- "name": "useTabs",
2678
- "propertyTypeTokenRange": {
2679
- "startIndex": 1,
2680
- "endIndex": 2
2681
- }
2617
+ "startIndex": 1,
2618
+ "endIndex": 2
2682
2619
  }
2683
- ],
2684
- "extendsTokenRanges": []
2620
+ ]
2685
2621
  },
2686
2622
  {
2687
2623
  "kind": "Interface",
@@ -16582,6 +16518,33 @@
16582
16518
  "name": "PrintTreeOptions",
16583
16519
  "preserveMemberOrder": false,
16584
16520
  "members": [
16521
+ {
16522
+ "kind": "PropertySignature",
16523
+ "canonicalReference": "@alloy-js/core!PrintTreeOptions#insertFinalNewLine:member",
16524
+ "docComment": "/**\n * If files should end with a final new line.\n *\n * @default\n *\n * true\n */\n",
16525
+ "excerptTokens": [
16526
+ {
16527
+ "kind": "Content",
16528
+ "text": "insertFinalNewLine?: "
16529
+ },
16530
+ {
16531
+ "kind": "Content",
16532
+ "text": "boolean"
16533
+ },
16534
+ {
16535
+ "kind": "Content",
16536
+ "text": ";"
16537
+ }
16538
+ ],
16539
+ "isReadonly": false,
16540
+ "isOptional": true,
16541
+ "releaseTag": "Public",
16542
+ "name": "insertFinalNewLine",
16543
+ "propertyTypeTokenRange": {
16544
+ "startIndex": 1,
16545
+ "endIndex": 2
16546
+ }
16547
+ },
16585
16548
  {
16586
16549
  "kind": "PropertySignature",
16587
16550
  "canonicalReference": "@alloy-js/core!PrintTreeOptions#printWidth:member",
@@ -47,34 +47,32 @@ it("has reactive context", () => {
47
47
  );
48
48
  }
49
49
 
50
- const tree = render(
50
+ expect(
51
51
  <Output>
52
52
  <SourceFile path="hi.txt" filetype="text">
53
53
  hello!
54
54
  </SourceFile>
55
55
  <TrackContents />
56
56
  </Output>,
57
- );
58
-
59
- expect((tree.contents[1] as ContentOutputFile).contents).toEqual(
60
- "hi.txt contents.txt",
61
- );
57
+ ).toRenderTo({
58
+ "hi.txt": "hello!",
59
+ "contents.txt": "hi.txt contents.txt",
60
+ });
62
61
  });
63
62
 
64
- it("Includes header", () => {
63
+ it("includes header", () => {
65
64
  const header = <># This is a header</>;
66
- const tree = render(
65
+
66
+ expect(
67
67
  <Output>
68
68
  <SourceFile path="hi.txt" filetype="text" header={header}>
69
69
  hello!
70
70
  </SourceFile>
71
71
  </Output>,
72
- );
73
-
74
- expect((tree.contents[0] as ContentOutputFile).contents).toEqual(d`
72
+ ).toRenderTo(`
75
73
  # This is a header
76
74
  hello!
77
- `);
75
+ `);
78
76
  });
79
77
 
80
78
  describe("format options", () => {
@@ -139,4 +137,35 @@ describe("format options", () => {
139
137
  indented 3 spaces
140
138
  `);
141
139
  });
140
+
141
+ describe("trailing line", () => {
142
+ function testRender(comp: any) {
143
+ const tree = render(<Output>{comp}</Output>);
144
+ return (tree.contents[0] as ContentOutputFile).contents;
145
+ }
146
+
147
+ it("add trailing new line by default", () => {
148
+ expect(
149
+ testRender(
150
+ <SourceFile filetype="text" path="abc.txt">
151
+ end with new line
152
+ </SourceFile>,
153
+ ),
154
+ ).toEqual(d`
155
+ end with new line
156
+
157
+ `);
158
+ });
159
+ it("add trailing new line by default", () => {
160
+ expect(
161
+ testRender(
162
+ <SourceFile filetype="text" path="abc.txt" insertFinalNewLine={false}>
163
+ end with no line
164
+ </SourceFile>,
165
+ ),
166
+ ).toEqual(d`
167
+ end with no line
168
+ `);
169
+ });
170
+ });
142
171
  });
@@ -467,6 +467,7 @@ it("formats based on the output component props", () => {
467
467
  4
468
468
  5
469
469
  6
470
+
470
471
  `);
471
472
  });
472
473
 
@@ -489,5 +490,6 @@ it("formats based on the source file component props", () => {
489
490
  4
490
491
  5
491
492
  6
493
+
492
494
  `);
493
495
  });
@@ -40,6 +40,12 @@ expect.extend({
40
40
  },
41
41
  });
42
42
 
43
+ function isAsymmetricMatcher(value: any): value is {
44
+ asymmetricMatch: (other: any) => boolean;
45
+ } {
46
+ return value.$$typeof === Symbol.for("jest.asymmetricMatcher");
47
+ }
48
+
43
49
  function validateRender(
44
50
  actual: string | Record<string, string>,
45
51
  expectedRaw: string | Record<string, string>,
@@ -73,12 +79,18 @@ function validateRender(
73
79
  const expected = expectedRaw;
74
80
  const dedentExpected: Record<string, string> = {};
75
81
  for (const [key, value] of Object.entries(expected)) {
76
- dedentExpected[key] = dedent(value);
82
+ if (isAsymmetricMatcher(value)) {
83
+ dedentExpected[key] = value;
84
+ } else {
85
+ dedentExpected[key] = dedent(value);
86
+ }
77
87
  }
78
88
  const pass =
79
89
  Object.keys(actual).length === Object.keys(expected).length &&
80
90
  Object.entries(actual).every(([key, value]) => {
81
- return dedentExpected[key] === value;
91
+ return isAsymmetricMatcher(dedentExpected[key]) ?
92
+ dedentExpected[key].asymmetricMatch(value)
93
+ : dedentExpected[key] === value;
82
94
  });
83
95
  return {
84
96
  pass,