@deshlo/nextjs 0.1.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.
@@ -0,0 +1,5 @@
1
+ export { withSourceInspectorWebpack } from "@deshlo/react/webpack";
2
+ export type { SourceInspectorAdapterOptions, WebpackLikeConfig } from "@deshlo/core";
3
+ export { applySourceInspectorTurbopack, createSourceInspectorTurbopackRules, } from "./turbopack";
4
+ export type { LegacyTurboConfig, NextJsLikeConfig, NextTurbopackConfig, NextjsTurbopackOptions, TurbopackLoader, TurbopackRule, TurbopackRules, } from "./turbopack";
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,0BAA0B,EAAE,MAAM,uBAAuB,CAAC;AACnE,YAAY,EAAE,6BAA6B,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACrF,OAAO,EACL,6BAA6B,EAC7B,mCAAmC,GACpC,MAAM,aAAa,CAAC;AACrB,YAAY,EACV,iBAAiB,EACjB,gBAAgB,EAChB,mBAAmB,EACnB,sBAAsB,EACtB,eAAe,EACf,aAAa,EACb,cAAc,GACf,MAAM,aAAa,CAAC"}
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createSourceInspectorTurbopackRules = exports.applySourceInspectorTurbopack = exports.withSourceInspectorWebpack = void 0;
4
+ var webpack_1 = require("@deshlo/react/webpack");
5
+ Object.defineProperty(exports, "withSourceInspectorWebpack", { enumerable: true, get: function () { return webpack_1.withSourceInspectorWebpack; } });
6
+ var turbopack_1 = require("./turbopack");
7
+ Object.defineProperty(exports, "applySourceInspectorTurbopack", { enumerable: true, get: function () { return turbopack_1.applySourceInspectorTurbopack; } });
8
+ Object.defineProperty(exports, "createSourceInspectorTurbopackRules", { enumerable: true, get: function () { return turbopack_1.createSourceInspectorTurbopackRules; } });
@@ -0,0 +1,2 @@
1
+ export { OverlayGate, type OverlayGateProps, type TriggerKey, } from "@deshlo/react/overlay";
2
+ //# sourceMappingURL=overlay.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"overlay.d.ts","sourceRoot":"","sources":["../../src/overlay.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,WAAW,EACX,KAAK,gBAAgB,EACrB,KAAK,UAAU,GAChB,MAAM,uBAAuB,CAAC"}
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.OverlayGate = void 0;
4
+ var overlay_1 = require("@deshlo/react/overlay");
5
+ Object.defineProperty(exports, "OverlayGate", { enumerable: true, get: function () { return overlay_1.OverlayGate; } });
@@ -0,0 +1,37 @@
1
+ import { type SourceInspectorAdapterOptions } from "@deshlo/core";
2
+ export interface NextJsLikeConfig {
3
+ webpack?: (config: any, context: any) => any;
4
+ turbopack?: NextTurbopackConfig;
5
+ experimental?: {
6
+ turbo?: LegacyTurboConfig;
7
+ [key: string]: unknown;
8
+ };
9
+ [key: string]: unknown;
10
+ }
11
+ export interface NextjsTurbopackOptions extends SourceInspectorAdapterOptions {
12
+ cwd?: string;
13
+ }
14
+ export type TurbopackLoader = string | {
15
+ loader: string;
16
+ options?: unknown;
17
+ };
18
+ export interface TurbopackRule {
19
+ loaders: TurbopackLoader[];
20
+ as?: string;
21
+ condition?: unknown;
22
+ }
23
+ export type TurbopackRules = Record<string, TurbopackRule | TurbopackRule[]>;
24
+ export interface NextTurbopackConfig {
25
+ root?: string;
26
+ rules?: TurbopackRules;
27
+ [key: string]: unknown;
28
+ }
29
+ export interface LegacyTurboConfig {
30
+ root?: string;
31
+ rules?: TurbopackRules;
32
+ loaders?: Record<string, TurbopackLoader[]>;
33
+ [key: string]: unknown;
34
+ }
35
+ export declare function createSourceInspectorTurbopackRules(options?: NextjsTurbopackOptions, cwd?: string, rootDir?: string): TurbopackRules;
36
+ export declare function applySourceInspectorTurbopack<TConfig extends NextJsLikeConfig>(nextConfig: TConfig, options?: NextjsTurbopackOptions): TConfig & NextJsLikeConfig;
37
+ //# sourceMappingURL=turbopack.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"turbopack.d.ts","sourceRoot":"","sources":["../../src/turbopack.ts"],"names":[],"mappings":"AAGA,OAAO,EAGL,KAAK,6BAA6B,EACnC,MAAM,cAAc,CAAC;AAEtB,MAAM,WAAW,gBAAgB;IAC/B,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,KAAK,GAAG,CAAC;IAC7C,SAAS,CAAC,EAAE,mBAAmB,CAAC;IAChC,YAAY,CAAC,EAAE;QACb,KAAK,CAAC,EAAE,iBAAiB,CAAC;QAC1B,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;KACxB,CAAC;IACF,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,sBAAuB,SAAQ,6BAA6B;IAC3E,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,MAAM,MAAM,eAAe,GAAG,MAAM,GAAG;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC;AAE7E,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,eAAe,EAAE,CAAC;IAC3B,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,MAAM,cAAc,GAAG,MAAM,CAAC,MAAM,EAAE,aAAa,GAAG,aAAa,EAAE,CAAC,CAAC;AAE7E,MAAM,WAAW,mBAAmB;IAClC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,cAAc,CAAC;IACvB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,cAAc,CAAC;IACvB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,EAAE,CAAC,CAAC;IAC5C,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AA+GD,wBAAgB,mCAAmC,CACjD,OAAO,GAAE,sBAA2B,EACpC,GAAG,GAAE,MAAqC,EAC1C,OAAO,GAAE,MAA+B,GACvC,cAAc,CAyBhB;AAED,wBAAgB,6BAA6B,CAAC,OAAO,SAAS,gBAAgB,EAC5E,UAAU,EAAE,OAAO,EACnB,OAAO,GAAE,sBAA2B,GACnC,OAAO,GAAG,gBAAgB,CAgE5B"}
@@ -0,0 +1,173 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.createSourceInspectorTurbopackRules = createSourceInspectorTurbopackRules;
7
+ exports.applySourceInspectorTurbopack = applySourceInspectorTurbopack;
8
+ const node_fs_1 = require("node:fs");
9
+ const node_path_1 = __importDefault(require("node:path"));
10
+ const core_1 = require("@deshlo/core");
11
+ const TURBOPACK_EXTENSIONS = [".js", ".jsx", ".ts", ".tsx"];
12
+ const SOURCE_INSPECTOR_LOADER = "@deshlo/loader";
13
+ const ROOT_MARKER_FILES = [
14
+ "yarn.lock",
15
+ "pnpm-lock.yaml",
16
+ "package-lock.json",
17
+ "bun.lock",
18
+ "bun.lockb",
19
+ ];
20
+ function toPosixPath(value) {
21
+ return value.replace(/\\/g, "/");
22
+ }
23
+ function toTurbopackGlob(includePath, rootDir, extension) {
24
+ const relativePath = toPosixPath(node_path_1.default.relative(rootDir, includePath)).replace(/^\.\/+/, "");
25
+ if (relativePath.length === 0 || relativePath === ".") {
26
+ return `*${extension}`;
27
+ }
28
+ if (relativePath.startsWith("../")) {
29
+ return `**/*${extension}`;
30
+ }
31
+ return `${relativePath}/**/*${extension}`;
32
+ }
33
+ function findWorkspaceRoot(cwd) {
34
+ const startDir = node_path_1.default.resolve(cwd);
35
+ let currentDir = startDir;
36
+ while (true) {
37
+ const hasRootMarker = ROOT_MARKER_FILES.some((fileName) => (0, node_fs_1.existsSync)(node_path_1.default.join(currentDir, fileName)));
38
+ if (hasRootMarker) {
39
+ return currentDir;
40
+ }
41
+ const parentDir = node_path_1.default.dirname(currentDir);
42
+ if (parentDir === currentDir) {
43
+ return startDir;
44
+ }
45
+ currentDir = parentDir;
46
+ }
47
+ }
48
+ function normalizeRootPath(rootPath, cwd) {
49
+ if (typeof rootPath !== "string" || rootPath.trim().length === 0) {
50
+ return undefined;
51
+ }
52
+ return node_path_1.default.resolve(cwd, rootPath);
53
+ }
54
+ function resolveTurbopackRoot(nextConfig, cwd) {
55
+ const configuredRoot = normalizeRootPath(nextConfig.turbopack?.root, cwd) ??
56
+ normalizeRootPath(nextConfig.experimental?.turbo?.root, cwd);
57
+ return configuredRoot ?? findWorkspaceRoot(cwd);
58
+ }
59
+ function mergeRuleEntry(existing, incoming) {
60
+ if (!existing) {
61
+ return incoming;
62
+ }
63
+ if (Array.isArray(existing)) {
64
+ return [...existing, incoming];
65
+ }
66
+ return [existing, incoming];
67
+ }
68
+ function mergeRules(currentRules, incomingRules) {
69
+ const merged = {
70
+ ...(currentRules ?? {}),
71
+ };
72
+ for (const [glob, rule] of Object.entries(incomingRules)) {
73
+ if (Array.isArray(rule)) {
74
+ for (const ruleEntry of rule) {
75
+ merged[glob] = mergeRuleEntry(merged[glob], ruleEntry);
76
+ }
77
+ continue;
78
+ }
79
+ merged[glob] = mergeRuleEntry(merged[glob], rule);
80
+ }
81
+ return merged;
82
+ }
83
+ function createLegacyTurboLoaders(options, cwd) {
84
+ const loaderOptions = (0, core_1.buildSourceInspectorLoaderOptions)(options, cwd);
85
+ const loader = {
86
+ loader: SOURCE_INSPECTOR_LOADER,
87
+ options: loaderOptions,
88
+ };
89
+ return TURBOPACK_EXTENSIONS.reduce((acc, extension) => {
90
+ acc[extension] = [loader];
91
+ return acc;
92
+ }, {});
93
+ }
94
+ function createSourceInspectorTurbopackRules(options = {}, cwd = options.cwd ?? process.cwd(), rootDir = findWorkspaceRoot(cwd)) {
95
+ if (!(0, core_1.isSourceInspectorEnabled)(options)) {
96
+ return {};
97
+ }
98
+ const loaderOptions = (0, core_1.buildSourceInspectorLoaderOptions)(options, cwd);
99
+ const loader = {
100
+ loader: SOURCE_INSPECTOR_LOADER,
101
+ options: loaderOptions,
102
+ };
103
+ const rules = {};
104
+ for (const includePath of loaderOptions.includePaths) {
105
+ for (const extension of TURBOPACK_EXTENSIONS) {
106
+ const glob = toTurbopackGlob(includePath, rootDir, extension);
107
+ const incomingRule = {
108
+ condition: { not: "foreign" },
109
+ loaders: [loader],
110
+ as: "*.js",
111
+ };
112
+ rules[glob] = mergeRuleEntry(rules[glob], incomingRule);
113
+ }
114
+ }
115
+ return rules;
116
+ }
117
+ function applySourceInspectorTurbopack(nextConfig, options = {}) {
118
+ if (!(0, core_1.isSourceInspectorEnabled)(options)) {
119
+ return nextConfig;
120
+ }
121
+ const cwd = options.cwd ?? process.cwd();
122
+ const resolvedRoot = resolveTurbopackRoot(nextConfig, cwd);
123
+ const rules = createSourceInspectorTurbopackRules(options, cwd, resolvedRoot);
124
+ if (Object.keys(rules).length === 0) {
125
+ return nextConfig;
126
+ }
127
+ if (nextConfig.turbopack) {
128
+ return {
129
+ ...nextConfig,
130
+ turbopack: {
131
+ ...nextConfig.turbopack,
132
+ root: nextConfig.turbopack.root ?? resolvedRoot,
133
+ rules: mergeRules(nextConfig.turbopack.rules, rules),
134
+ },
135
+ };
136
+ }
137
+ if (nextConfig.experimental?.turbo) {
138
+ const legacyTurbo = nextConfig.experimental.turbo;
139
+ const hasLegacyLoaders = legacyTurbo &&
140
+ typeof legacyTurbo === "object" &&
141
+ "loaders" in legacyTurbo &&
142
+ typeof legacyTurbo.loaders === "object" &&
143
+ legacyTurbo.loaders !== null;
144
+ const mergedTurbo = hasLegacyLoaders
145
+ ? {
146
+ ...legacyTurbo,
147
+ root: legacyTurbo.root ?? resolvedRoot,
148
+ loaders: {
149
+ ...legacyTurbo.loaders,
150
+ ...createLegacyTurboLoaders(options, cwd),
151
+ },
152
+ }
153
+ : {
154
+ ...legacyTurbo,
155
+ root: legacyTurbo.root ?? resolvedRoot,
156
+ rules: mergeRules(legacyTurbo.rules, rules),
157
+ };
158
+ return {
159
+ ...nextConfig,
160
+ experimental: {
161
+ ...nextConfig.experimental,
162
+ turbo: mergedTurbo,
163
+ },
164
+ };
165
+ }
166
+ return {
167
+ ...nextConfig,
168
+ turbopack: {
169
+ root: resolvedRoot,
170
+ rules,
171
+ },
172
+ };
173
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=turbopack.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"turbopack.test.d.ts","sourceRoot":"","sources":["../../src/turbopack.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,117 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const node_path_1 = __importDefault(require("node:path"));
7
+ const vitest_1 = require("vitest");
8
+ const turbopack_1 = require("./turbopack");
9
+ const CWD = "/repo";
10
+ (0, vitest_1.describe)("applySourceInspectorTurbopack", () => {
11
+ (0, vitest_1.it)("creates turbopack rules when config has no turbopack section", () => {
12
+ const result = (0, turbopack_1.applySourceInspectorTurbopack)({
13
+ reactStrictMode: true,
14
+ }, {
15
+ enabled: true,
16
+ include: ["app", "components"],
17
+ wrapLooseTextNodes: true,
18
+ annotateLeafNodesOnly: true,
19
+ cwd: CWD,
20
+ });
21
+ (0, vitest_1.expect)(result.turbopack?.rules).toBeDefined();
22
+ (0, vitest_1.expect)(Object.keys(result.turbopack?.rules ?? {})).toEqual(vitest_1.expect.arrayContaining([
23
+ "app/**/*.js",
24
+ "app/**/*.jsx",
25
+ "app/**/*.ts",
26
+ "app/**/*.tsx",
27
+ "components/**/*.js",
28
+ "components/**/*.jsx",
29
+ "components/**/*.ts",
30
+ "components/**/*.tsx",
31
+ ]));
32
+ const appRule = result.turbopack?.rules?.["app/**/*.tsx"];
33
+ const firstRule = Array.isArray(appRule) ? appRule[0] : appRule;
34
+ const firstLoader = firstRule && firstRule.loaders.length > 0 ? firstRule.loaders[0] : undefined;
35
+ (0, vitest_1.expect)(firstRule).toMatchObject({
36
+ as: "*.js",
37
+ condition: { not: "foreign" },
38
+ });
39
+ (0, vitest_1.expect)(firstLoader).toMatchObject({
40
+ loader: "@deshlo/loader",
41
+ options: {
42
+ attributeName: "data-src-loc",
43
+ wrapLooseTextNodes: true,
44
+ annotateLeafNodesOnly: true,
45
+ includePaths: [node_path_1.default.resolve(CWD, "app"), node_path_1.default.resolve(CWD, "components")],
46
+ },
47
+ });
48
+ (0, vitest_1.expect)(result.turbopack?.root).toBe(CWD);
49
+ });
50
+ (0, vitest_1.it)("merges into existing turbopack rules", () => {
51
+ const result = (0, turbopack_1.applySourceInspectorTurbopack)({
52
+ turbopack: {
53
+ rules: {
54
+ "*.mdx": {
55
+ loaders: ["mdx-loader"],
56
+ as: "*.js",
57
+ },
58
+ },
59
+ },
60
+ }, {
61
+ enabled: true,
62
+ include: ["app"],
63
+ cwd: CWD,
64
+ });
65
+ const rules = result.turbopack?.rules;
66
+ (0, vitest_1.expect)(rules?.["*.mdx"]).toBeDefined();
67
+ (0, vitest_1.expect)(rules?.["app/**/*.tsx"]).toBeDefined();
68
+ });
69
+ (0, vitest_1.it)("merges into legacy experimental turbo config", () => {
70
+ const result = (0, turbopack_1.applySourceInspectorTurbopack)({
71
+ experimental: {
72
+ turbo: {
73
+ loaders: {
74
+ ".mdx": ["mdx-loader"],
75
+ },
76
+ },
77
+ },
78
+ }, {
79
+ enabled: true,
80
+ include: ["app"],
81
+ cwd: CWD,
82
+ });
83
+ const loaders = result.experimental?.turbo?.loaders;
84
+ (0, vitest_1.expect)(loaders?.[".mdx"]).toEqual(["mdx-loader"]);
85
+ (0, vitest_1.expect)(loaders?.[".tsx"]).toBeDefined();
86
+ (0, vitest_1.expect)(loaders?.[".tsx"]?.[0]).toMatchObject({
87
+ loader: "@deshlo/loader",
88
+ });
89
+ });
90
+ (0, vitest_1.it)("does nothing when disabled", () => {
91
+ const nextConfig = {
92
+ reactStrictMode: true,
93
+ };
94
+ const result = (0, turbopack_1.applySourceInspectorTurbopack)(nextConfig, {
95
+ enabled: false,
96
+ include: ["app"],
97
+ cwd: CWD,
98
+ });
99
+ (0, vitest_1.expect)(result).toBe(nextConfig);
100
+ });
101
+ (0, vitest_1.it)("builds include globs relative to workspace root in monorepos", () => {
102
+ const workspaceRoot = "/repo";
103
+ const appDir = "/repo/apps/next-test-app";
104
+ const result = (0, turbopack_1.applySourceInspectorTurbopack)({
105
+ reactStrictMode: true,
106
+ turbopack: {
107
+ root: workspaceRoot,
108
+ },
109
+ }, {
110
+ enabled: true,
111
+ include: ["app"],
112
+ cwd: appDir,
113
+ });
114
+ (0, vitest_1.expect)(result.turbopack?.root).toBe(workspaceRoot);
115
+ (0, vitest_1.expect)(result.turbopack?.rules?.["apps/next-test-app/app/**/*.tsx"]).toBeDefined();
116
+ });
117
+ });
package/package.json ADDED
@@ -0,0 +1,51 @@
1
+ {
2
+ "name": "@deshlo/nextjs",
3
+ "version": "0.1.0",
4
+ "description": "Next.js source inspector bundler utilities",
5
+ "main": "build/src/index.js",
6
+ "module": "build/src/index.js",
7
+ "types": "build/src/index.d.ts",
8
+ "sideEffects": false,
9
+ "exports": {
10
+ ".": {
11
+ "types": "./build/src/index.d.ts",
12
+ "require": "./build/src/index.js",
13
+ "import": "./build/src/index.js"
14
+ },
15
+ "./overlay": {
16
+ "types": "./build/src/overlay.d.ts",
17
+ "require": "./build/src/overlay.js",
18
+ "import": "./build/src/overlay.js"
19
+ }
20
+ },
21
+ "files": [
22
+ "build"
23
+ ],
24
+ "scripts": {
25
+ "clean": "rm -rf build",
26
+ "build": "tsc -p tsconfig.json",
27
+ "test": "vitest run"
28
+ },
29
+ "keywords": [
30
+ "nextjs",
31
+ "source-map",
32
+ "debug",
33
+ "inspector"
34
+ ],
35
+ "author": "Nikos Gerontakis",
36
+ "license": "MIT",
37
+ "dependencies": {
38
+ "@deshlo/core": "0.1.0",
39
+ "@deshlo/react": "0.1.0"
40
+ },
41
+ "peerDependencies": {
42
+ "next": ">=14",
43
+ "react": ">=18",
44
+ "react-dom": ">=18"
45
+ },
46
+ "devDependencies": {
47
+ "@types/node": "^24.10.1",
48
+ "@types/react": "^19.2.2",
49
+ "vitest": "^3.2.4"
50
+ }
51
+ }