@paramour-js/next 0.11.0 → 0.11.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/dist/app.js CHANGED
@@ -1,5 +1,11 @@
1
1
  "use client";
2
- import { useParams, usePathname, useRouter, useSearchParams, } from "next/navigation";
2
+ // Extensionful for the same reason as pages.ts's `next/router.js`: `next`
3
+ // ships no `exports` map, so wherever this package is loaded through Node's
4
+ // ESM resolver (Vitest externalizes node_modules) the bare `next/navigation`
5
+ // dies with ERR_MODULE_NOT_FOUND. The root stub `next/navigation.js` is the
6
+ // file the bare specifier resolves to, and Next's bundler aliases are keyed
7
+ // on that file, so bundles see the same module either way.
8
+ import { useParams, usePathname, useRouter, useSearchParams, } from "next/navigation.js";
3
9
  import { decodeParams, decodeSearch, ParamsDecodeError, safeDecodeParams, safeDecodeSearch, SearchDecodeError, } from "paramour";
4
10
  import { useContext } from "react";
5
11
  import { searchWireSnapshot } from "./devtools-emit.js";
package/dist/emit.d.ts CHANGED
@@ -6,11 +6,18 @@ export interface WriteIfChangedResult {
6
6
  */
7
7
  previousContent: null | string;
8
8
  /**
9
- * `false` on a byte-identical no-op — the signal `--check` and the watch
10
- * loop hang off.
9
+ * `false` on a no-op (identical up to line endings) — the signal `--check`
10
+ * and the watch loop hang off.
11
11
  */
12
12
  written: boolean;
13
13
  }
14
+ /**
15
+ * Content equality that ignores CRLF vs LF. A consumer repo with git
16
+ * `core.autocrlf=true` checks the committed LF artifact out as CRLF; that
17
+ * flip is not drift, and treating it as drift fails every strict build and
18
+ * `paramour check` on a fresh Windows checkout.
19
+ */
20
+ export declare function sameContent(a: string, b: string): boolean;
14
21
  /** Input of {@link emitArtifact} — one union per router. */
15
22
  export interface EmitRoutes {
16
23
  appRoutes: readonly string[];
@@ -30,6 +37,8 @@ export declare function emitArtifact(routes: EmitRoutes): string;
30
37
  /**
31
38
  * Compare-before-write: a no-op regeneration must not touch the file — that
32
39
  * property is what prevents TS-server churn, watch-loop feedback, and
33
- * concurrent-generator races.
40
+ * concurrent-generator races. A file differing only in line endings is a
41
+ * no-op too, so a CRLF checkout keeps its endings and `git status` stays
42
+ * clean; a real change is written LF.
34
43
  */
35
44
  export declare function writeIfChanged(filePath: string, content: string): WriteIfChangedResult;
package/dist/emit.js CHANGED
@@ -1,5 +1,14 @@
1
1
  import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
2
2
  import { dirname } from "node:path";
3
+ /**
4
+ * Content equality that ignores CRLF vs LF. A consumer repo with git
5
+ * `core.autocrlf=true` checks the committed LF artifact out as CRLF; that
6
+ * flip is not drift, and treating it as drift fails every strict build and
7
+ * `paramour check` on a fresh Windows checkout.
8
+ */
9
+ export function sameContent(a, b) {
10
+ return a.replaceAll("\r\n", "\n") === b.replaceAll("\r\n", "\n");
11
+ }
3
12
  const HEADER = "// Generated by @paramour-js/next. Do not edit — regenerate with `paramour generate`.";
4
13
  /**
5
14
  * Artifact text for the per-router route unions: deterministic — sorted,
@@ -59,14 +68,17 @@ export function emitArtifact(routes) {
59
68
  /**
60
69
  * Compare-before-write: a no-op regeneration must not touch the file — that
61
70
  * property is what prevents TS-server churn, watch-loop feedback, and
62
- * concurrent-generator races.
71
+ * concurrent-generator races. A file differing only in line endings is a
72
+ * no-op too, so a CRLF checkout keeps its endings and `git status` stays
73
+ * clean; a real change is written LF.
63
74
  */
64
75
  export function writeIfChanged(filePath, content) {
65
76
  const previousContent = existsSync(filePath)
66
77
  ? readFileSync(filePath, "utf8")
67
78
  : null;
68
- if (previousContent === content)
79
+ if (previousContent !== null && sameContent(previousContent, content)) {
69
80
  return { previousContent, written: false };
81
+ }
70
82
  // The outFile escape hatch may point into a not-yet-existing directory.
71
83
  mkdirSync(dirname(filePath), { recursive: true });
72
84
  writeFileSync(filePath, content);
@@ -40,9 +40,10 @@ export interface RouterDrift {
40
40
  disappeared: string[];
41
41
  }
42
42
  /**
43
- * `--check`: scan to memory and byte-compare against disk — never writes. A
44
- * missing artifact is drift, not an error: that is exactly the
45
- * CI-degrades-to-world-A case the committed file exists to prevent.
43
+ * `--check`: scan to memory and compare against disk (line endings aside, as
44
+ * in {@link writeIfChanged}) — never writes. A missing artifact is drift, not
45
+ * an error: that is exactly the CI-degrades-to-world-A case the committed
46
+ * file exists to prevent.
46
47
  */
47
48
  export declare function checkArtifact(inputs: GenerateInputs): CheckResult;
48
49
  /**
package/dist/generate.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { existsSync, readFileSync } from "node:fs";
2
- import { emitArtifact, writeIfChanged } from "./emit.js";
2
+ import { emitArtifact, sameContent, writeIfChanged } from "./emit.js";
3
3
  import { scanRoutes } from "./scan.js";
4
4
  /**
5
5
  * Reads the per-router unions back out of a previously emitted artifact for
@@ -11,9 +11,10 @@ import { scanRoutes } from "./scan.js";
11
11
  const MEMBER_HEADER = /^\s*(appRoutes|pagesRoutes):\s*$/;
12
12
  const UNION_MEMBER = /^\s*\| "(.*)";?\s*$/;
13
13
  /**
14
- * `--check`: scan to memory and byte-compare against disk — never writes. A
15
- * missing artifact is drift, not an error: that is exactly the
16
- * CI-degrades-to-world-A case the committed file exists to prevent.
14
+ * `--check`: scan to memory and compare against disk (line endings aside, as
15
+ * in {@link writeIfChanged}) — never writes. A missing artifact is drift, not
16
+ * an error: that is exactly the CI-degrades-to-world-A case the committed
17
+ * file exists to prevent.
17
18
  */
18
19
  export function checkArtifact(inputs) {
19
20
  const routes = scanRoutes(inputs, inputs.pageExtensions);
@@ -21,7 +22,7 @@ export function checkArtifact(inputs) {
21
22
  const current = existsSync(inputs.artifactPath)
22
23
  ? readFileSync(inputs.artifactPath, "utf8")
23
24
  : null;
24
- if (current === expected) {
25
+ if (current !== null && sameContent(current, expected)) {
25
26
  return {
26
27
  app: { appeared: [], disappeared: [] },
27
28
  missingFile: false,
@@ -12,7 +12,7 @@ import type { ParamsSource } from "paramour";
12
12
  * (`useContext(ctx) ?? realAdapter`), so neither this module nor the
13
13
  * /testing entry ever drags a `next/*` specifier into its graph. The
14
14
  * dist.test.ts bundle-hygiene invariants (/app reaches only
15
- * `next/navigation`, /pages only `next/router.js`, /testing neither) depend
15
+ * `next/navigation.js`, /pages only `next/router.js`, /testing neither) depend
16
16
  * on exactly this split — a context whose DEFAULT VALUE were the real
17
17
  * adapter would break all three.
18
18
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@paramour-js/next",
3
- "version": "0.11.0",
3
+ "version": "0.11.1",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": {
@@ -51,7 +51,7 @@
51
51
  "react-dom": "^19.2.0",
52
52
  "typescript": "^6.0.3",
53
53
  "zod": "^4.4.3",
54
- "paramour": "0.11.0"
54
+ "paramour": "0.11.1"
55
55
  },
56
56
  "description": "Next.js integration for paramour: withTypedRoutes, App and Pages Router hooks, PageProps glue, and the codegen CLI.",
57
57
  "author": "Jason Paff <jasonpaff@gmail.com>",