@deshlo/core 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,7 @@
1
+ export { buildSourceInspectorLoaderOptions, DEFAULT_ATTRIBUTE_NAME, DEFAULT_REVISION_ATTRIBUTE_NAME, injectSourceInspectorLoader, isSourceInspectorEnabled, resolveIncludePaths, } from "./shared";
2
+ export { injectSourceAttributes } from "./transform";
3
+ export { buildOverlaySubmitInput, normalizeOverlayText, toOverlayErrorResult, } from "./overlay-plugin";
4
+ export type { SourceInspectorAdapter, SourceInspectorAdapterOptions, SourceInspectorLoaderOptions, WebpackLikeConfig, } from "./shared";
5
+ export type { InjectSourceAttributesOptions, InjectSourceAttributesResult } from "./transform";
6
+ export type { OverlayPlugin, OverlayPluginContext, OverlayResultLink, OverlaySelection, OverlaySubmitHandler, OverlaySubmitInput, OverlaySubmitResult, TriggerKey, } from "./overlay-plugin";
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,iCAAiC,EACjC,sBAAsB,EACtB,+BAA+B,EAC/B,2BAA2B,EAC3B,wBAAwB,EACxB,mBAAmB,GACpB,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AACrD,OAAO,EACL,uBAAuB,EACvB,oBAAoB,EACpB,oBAAoB,GACrB,MAAM,kBAAkB,CAAC;AAC1B,YAAY,EACV,sBAAsB,EACtB,6BAA6B,EAC7B,4BAA4B,EAC5B,iBAAiB,GAClB,MAAM,UAAU,CAAC;AAClB,YAAY,EAAE,6BAA6B,EAAE,4BAA4B,EAAE,MAAM,aAAa,CAAC;AAC/F,YAAY,EACV,aAAa,EACb,oBAAoB,EACpB,iBAAiB,EACjB,gBAAgB,EAChB,oBAAoB,EACpB,kBAAkB,EAClB,mBAAmB,EACnB,UAAU,GACX,MAAM,kBAAkB,CAAC"}
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.toOverlayErrorResult = exports.normalizeOverlayText = exports.buildOverlaySubmitInput = exports.injectSourceAttributes = exports.resolveIncludePaths = exports.isSourceInspectorEnabled = exports.injectSourceInspectorLoader = exports.DEFAULT_REVISION_ATTRIBUTE_NAME = exports.DEFAULT_ATTRIBUTE_NAME = exports.buildSourceInspectorLoaderOptions = void 0;
4
+ var shared_1 = require("./shared");
5
+ Object.defineProperty(exports, "buildSourceInspectorLoaderOptions", { enumerable: true, get: function () { return shared_1.buildSourceInspectorLoaderOptions; } });
6
+ Object.defineProperty(exports, "DEFAULT_ATTRIBUTE_NAME", { enumerable: true, get: function () { return shared_1.DEFAULT_ATTRIBUTE_NAME; } });
7
+ Object.defineProperty(exports, "DEFAULT_REVISION_ATTRIBUTE_NAME", { enumerable: true, get: function () { return shared_1.DEFAULT_REVISION_ATTRIBUTE_NAME; } });
8
+ Object.defineProperty(exports, "injectSourceInspectorLoader", { enumerable: true, get: function () { return shared_1.injectSourceInspectorLoader; } });
9
+ Object.defineProperty(exports, "isSourceInspectorEnabled", { enumerable: true, get: function () { return shared_1.isSourceInspectorEnabled; } });
10
+ Object.defineProperty(exports, "resolveIncludePaths", { enumerable: true, get: function () { return shared_1.resolveIncludePaths; } });
11
+ var transform_1 = require("./transform");
12
+ Object.defineProperty(exports, "injectSourceAttributes", { enumerable: true, get: function () { return transform_1.injectSourceAttributes; } });
13
+ var overlay_plugin_1 = require("./overlay-plugin");
14
+ Object.defineProperty(exports, "buildOverlaySubmitInput", { enumerable: true, get: function () { return overlay_plugin_1.buildOverlaySubmitInput; } });
15
+ Object.defineProperty(exports, "normalizeOverlayText", { enumerable: true, get: function () { return overlay_plugin_1.normalizeOverlayText; } });
16
+ Object.defineProperty(exports, "toOverlayErrorResult", { enumerable: true, get: function () { return overlay_plugin_1.toOverlayErrorResult; } });
@@ -0,0 +1,31 @@
1
+ export type TriggerKey = "alt" | "shift" | "meta" | "ctrl";
2
+ export interface OverlaySelection {
3
+ sourceLoc: string;
4
+ tagName: string;
5
+ selectedText: string;
6
+ commitSha?: string;
7
+ }
8
+ export interface OverlaySubmitInput extends OverlaySelection {
9
+ proposedText: string;
10
+ }
11
+ export interface OverlayResultLink {
12
+ label: string;
13
+ url: string;
14
+ }
15
+ export interface OverlaySubmitResult {
16
+ ok: boolean;
17
+ message: string;
18
+ links?: OverlayResultLink[];
19
+ }
20
+ export interface OverlayPluginContext {
21
+ host: string;
22
+ }
23
+ export type OverlaySubmitHandler = (input: OverlaySubmitInput, context: OverlayPluginContext) => Promise<OverlaySubmitResult> | OverlaySubmitResult;
24
+ export interface OverlayPlugin {
25
+ id: string;
26
+ submit: OverlaySubmitHandler;
27
+ }
28
+ export declare function normalizeOverlayText(value: string): string;
29
+ export declare function buildOverlaySubmitInput(selection: OverlaySelection, proposedText: string): OverlaySubmitInput;
30
+ export declare function toOverlayErrorResult(error: unknown): OverlaySubmitResult;
31
+ //# sourceMappingURL=overlay-plugin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"overlay-plugin.d.ts","sourceRoot":"","sources":["../../src/overlay-plugin.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,UAAU,GAAG,KAAK,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,CAAC;AAE3D,MAAM,WAAW,gBAAgB;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,kBAAmB,SAAQ,gBAAgB;IAC1D,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,OAAO,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,iBAAiB,EAAE,CAAC;CAC7B;AAED,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,MAAM,oBAAoB,GAAG,CACjC,KAAK,EAAE,kBAAkB,EACzB,OAAO,EAAE,oBAAoB,KAC1B,OAAO,CAAC,mBAAmB,CAAC,GAAG,mBAAmB,CAAC;AAExD,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,oBAAoB,CAAC;CAC9B;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAE1D;AAED,wBAAgB,uBAAuB,CACrC,SAAS,EAAE,gBAAgB,EAC3B,YAAY,EAAE,MAAM,GACnB,kBAAkB,CAQpB;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,OAAO,GAAG,mBAAmB,CAYxE"}
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.normalizeOverlayText = normalizeOverlayText;
4
+ exports.buildOverlaySubmitInput = buildOverlaySubmitInput;
5
+ exports.toOverlayErrorResult = toOverlayErrorResult;
6
+ function normalizeOverlayText(value) {
7
+ return value.replace(/\s+/g, " ").trim();
8
+ }
9
+ function buildOverlaySubmitInput(selection, proposedText) {
10
+ return {
11
+ sourceLoc: selection.sourceLoc,
12
+ tagName: selection.tagName,
13
+ selectedText: selection.selectedText,
14
+ commitSha: selection.commitSha ?? "unknown",
15
+ proposedText: proposedText.trim(),
16
+ };
17
+ }
18
+ function toOverlayErrorResult(error) {
19
+ if (error instanceof Error) {
20
+ return {
21
+ ok: false,
22
+ message: error.message,
23
+ };
24
+ }
25
+ return {
26
+ ok: false,
27
+ message: "Unexpected plugin error.",
28
+ };
29
+ }
@@ -0,0 +1,2 @@
1
+ export declare function resolveBuildCommitSha(): string;
2
+ //# sourceMappingURL=revision.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"revision.d.ts","sourceRoot":"","sources":["../../src/revision.ts"],"names":[],"mappings":"AAqCA,wBAAgB,qBAAqB,IAAI,MAAM,CAY9C"}
@@ -0,0 +1,45 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.resolveBuildCommitSha = resolveBuildCommitSha;
4
+ const node_child_process_1 = require("node:child_process");
5
+ const COMMIT_ENV_KEYS = [
6
+ "COMMIT_SHA",
7
+ "SOURCE_VERSION",
8
+ "GITHUB_SHA",
9
+ "CI_COMMIT_SHA",
10
+ "GIT_COMMIT",
11
+ "VERCEL_GIT_COMMIT_SHA",
12
+ "RENDER_GIT_COMMIT",
13
+ ];
14
+ let cachedCommitSha = null;
15
+ function resolveCommitFromEnv() {
16
+ for (const key of COMMIT_ENV_KEYS) {
17
+ const value = process.env[key]?.trim();
18
+ if (value) {
19
+ return value;
20
+ }
21
+ }
22
+ return null;
23
+ }
24
+ function resolveCommitFromGit() {
25
+ try {
26
+ const value = (0, node_child_process_1.execSync)("git rev-parse HEAD", {
27
+ encoding: "utf8",
28
+ stdio: ["ignore", "pipe", "ignore"],
29
+ }).trim();
30
+ return value.length > 0 ? value : null;
31
+ }
32
+ catch {
33
+ return null;
34
+ }
35
+ }
36
+ function resolveBuildCommitSha() {
37
+ if (cachedCommitSha) {
38
+ return cachedCommitSha;
39
+ }
40
+ const resolved = resolveCommitFromEnv() ??
41
+ resolveCommitFromGit() ??
42
+ "unknown";
43
+ cachedCommitSha = resolved;
44
+ return resolved;
45
+ }
@@ -0,0 +1,30 @@
1
+ export interface SourceInspectorAdapterOptions {
2
+ enabled?: boolean;
3
+ include?: string[];
4
+ attributeName?: string;
5
+ wrapLooseTextNodes?: boolean;
6
+ annotateLeafNodesOnly?: boolean;
7
+ }
8
+ export interface SourceInspectorLoaderOptions {
9
+ attributeName: string;
10
+ wrapLooseTextNodes: boolean;
11
+ annotateLeafNodesOnly: boolean;
12
+ includePaths: string[];
13
+ }
14
+ export interface WebpackLikeConfig {
15
+ module?: {
16
+ rules?: unknown[];
17
+ };
18
+ [key: string]: unknown;
19
+ }
20
+ export interface SourceInspectorAdapter<TConfig = unknown> {
21
+ id: string;
22
+ apply: (config: TConfig, options?: SourceInspectorAdapterOptions) => TConfig;
23
+ }
24
+ export declare const DEFAULT_ATTRIBUTE_NAME = "data-src-loc";
25
+ export declare const DEFAULT_REVISION_ATTRIBUTE_NAME = "data-src-rev";
26
+ export declare function buildSourceInspectorLoaderOptions(options?: SourceInspectorAdapterOptions, cwd?: string): SourceInspectorLoaderOptions;
27
+ export declare function isSourceInspectorEnabled(options: SourceInspectorAdapterOptions): boolean;
28
+ export declare function resolveIncludePaths(include: string[] | undefined, cwd?: string): string[];
29
+ export declare function injectSourceInspectorLoader<TConfig extends WebpackLikeConfig>(webpackConfig: TConfig, options?: SourceInspectorAdapterOptions, cwd?: string): TConfig;
30
+ //# sourceMappingURL=shared.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../../src/shared.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,6BAA6B;IAC5C,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,qBAAqB,CAAC,EAAE,OAAO,CAAC;CACjC;AAED,MAAM,WAAW,4BAA4B;IAC3C,aAAa,EAAE,MAAM,CAAC;IACtB,kBAAkB,EAAE,OAAO,CAAC;IAC5B,qBAAqB,EAAE,OAAO,CAAC;IAC/B,YAAY,EAAE,MAAM,EAAE,CAAC;CACxB;AAED,MAAM,WAAW,iBAAiB;IAChC,MAAM,CAAC,EAAE;QACP,KAAK,CAAC,EAAE,OAAO,EAAE,CAAC;KACnB,CAAC;IACF,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,sBAAsB,CAAC,OAAO,GAAG,OAAO;IACvD,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,6BAA6B,KAAK,OAAO,CAAC;CAC9E;AAED,eAAO,MAAM,sBAAsB,iBAAiB,CAAC;AACrD,eAAO,MAAM,+BAA+B,iBAAiB,CAAC;AAE9D,wBAAgB,iCAAiC,CAC/C,OAAO,GAAE,6BAAkC,EAC3C,GAAG,GAAE,MAAsB,GAC1B,4BAA4B,CAO9B;AAED,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,6BAA6B,GAAG,OAAO,CAUxF;AAED,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,MAAM,EAAE,GAAG,SAAS,EAC7B,GAAG,GAAE,MAAsB,GAC1B,MAAM,EAAE,CAGV;AAED,wBAAgB,2BAA2B,CAAC,OAAO,SAAS,iBAAiB,EAC3E,aAAa,EAAE,OAAO,EACtB,OAAO,GAAE,6BAAkC,EAC3C,GAAG,GAAE,MAAsB,GAC1B,OAAO,CAoBT"}
@@ -0,0 +1,52 @@
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.DEFAULT_REVISION_ATTRIBUTE_NAME = exports.DEFAULT_ATTRIBUTE_NAME = void 0;
7
+ exports.buildSourceInspectorLoaderOptions = buildSourceInspectorLoaderOptions;
8
+ exports.isSourceInspectorEnabled = isSourceInspectorEnabled;
9
+ exports.resolveIncludePaths = resolveIncludePaths;
10
+ exports.injectSourceInspectorLoader = injectSourceInspectorLoader;
11
+ const node_path_1 = __importDefault(require("node:path"));
12
+ exports.DEFAULT_ATTRIBUTE_NAME = "data-src-loc";
13
+ exports.DEFAULT_REVISION_ATTRIBUTE_NAME = "data-src-rev";
14
+ function buildSourceInspectorLoaderOptions(options = {}, cwd = process.cwd()) {
15
+ return {
16
+ attributeName: options.attributeName ?? exports.DEFAULT_ATTRIBUTE_NAME,
17
+ wrapLooseTextNodes: options.wrapLooseTextNodes === true,
18
+ annotateLeafNodesOnly: options.annotateLeafNodesOnly === true,
19
+ includePaths: resolveIncludePaths(options.include, cwd),
20
+ };
21
+ }
22
+ function isSourceInspectorEnabled(options) {
23
+ if (typeof options.enabled === "boolean") {
24
+ return options.enabled;
25
+ }
26
+ return (process.env.NEXT_PUBLIC_SOURCE_INSPECTOR === "1" ||
27
+ process.env.VITE_SOURCE_INSPECTOR === "1" ||
28
+ process.env.SOURCE_INSPECTOR === "1");
29
+ }
30
+ function resolveIncludePaths(include, cwd = process.cwd()) {
31
+ const entries = include && include.length > 0 ? include : [node_path_1.default.resolve(cwd, "src")];
32
+ return entries.map((entry) => node_path_1.default.resolve(cwd, entry));
33
+ }
34
+ function injectSourceInspectorLoader(webpackConfig, options = {}, cwd = process.cwd()) {
35
+ var _a;
36
+ const loaderOptions = buildSourceInspectorLoaderOptions(options, cwd);
37
+ webpackConfig.module ?? (webpackConfig.module = {});
38
+ (_a = webpackConfig.module).rules ?? (_a.rules = []);
39
+ webpackConfig.module.rules.unshift({
40
+ test: /\.[jt]sx?$/,
41
+ include: loaderOptions.includePaths,
42
+ exclude: /node_modules/,
43
+ enforce: "pre",
44
+ use: [
45
+ {
46
+ loader: "@deshlo/loader",
47
+ options: loaderOptions,
48
+ },
49
+ ],
50
+ });
51
+ return webpackConfig;
52
+ }
@@ -0,0 +1,13 @@
1
+ export interface InjectSourceAttributesOptions {
2
+ attributeName?: string;
3
+ cwd?: string;
4
+ wrapLooseTextNodes?: boolean;
5
+ annotateLeafNodesOnly?: boolean;
6
+ }
7
+ export interface InjectSourceAttributesResult {
8
+ code: string;
9
+ map: unknown;
10
+ changed: boolean;
11
+ }
12
+ export declare function injectSourceAttributes(source: string, resourcePath: string, options?: InjectSourceAttributesOptions): InjectSourceAttributesResult;
13
+ //# sourceMappingURL=transform.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transform.d.ts","sourceRoot":"","sources":["../../src/transform.ts"],"names":[],"mappings":"AASA,MAAM,WAAW,6BAA6B;IAC5C,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,qBAAqB,CAAC,EAAE,OAAO,CAAC;CACjC;AAED,MAAM,WAAW,4BAA4B;IAC3C,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,OAAO,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;CAClB;AAwED,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,MAAM,EACpB,OAAO,GAAE,6BAAkC,GAC1C,4BAA4B,CA6L9B"}
@@ -0,0 +1,227 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.injectSourceAttributes = injectSourceAttributes;
40
+ const node_path_1 = __importDefault(require("node:path"));
41
+ const parser = __importStar(require("@babel/parser"));
42
+ const generator_1 = __importDefault(require("@babel/generator"));
43
+ const traverse_1 = __importDefault(require("@babel/traverse"));
44
+ const t = __importStar(require("@babel/types"));
45
+ const revision_1 = require("./revision");
46
+ const shared_1 = require("./shared");
47
+ function toRelativePath(absolutePath, cwd) {
48
+ return node_path_1.default.relative(cwd, absolutePath).replace(/\\/g, "/");
49
+ }
50
+ function splitMeaningfulText(value) {
51
+ let firstNonWhitespace = -1;
52
+ for (let index = 0; index < value.length; index += 1) {
53
+ if (value[index].trim() !== "") {
54
+ firstNonWhitespace = index;
55
+ break;
56
+ }
57
+ }
58
+ if (firstNonWhitespace === -1) {
59
+ return null;
60
+ }
61
+ let lastNonWhitespace = -1;
62
+ for (let index = value.length - 1; index >= 0; index -= 1) {
63
+ if (value[index].trim() !== "") {
64
+ lastNonWhitespace = index;
65
+ break;
66
+ }
67
+ }
68
+ if (lastNonWhitespace === -1) {
69
+ return null;
70
+ }
71
+ return {
72
+ leading: value.slice(0, firstNonWhitespace),
73
+ text: value.slice(firstNonWhitespace, lastNonWhitespace + 1),
74
+ trailing: value.slice(lastNonWhitespace + 1),
75
+ };
76
+ }
77
+ function advanceLocation(start, value) {
78
+ let line = start.line;
79
+ let column = start.column;
80
+ for (const character of value) {
81
+ if (character === "\n") {
82
+ line += 1;
83
+ column = 0;
84
+ continue;
85
+ }
86
+ if (character === "\r") {
87
+ continue;
88
+ }
89
+ column += 1;
90
+ }
91
+ return { line, column };
92
+ }
93
+ function isHostElement(nameNode) {
94
+ return t.isJSXIdentifier(nameNode) && /^[a-z]/.test(nameNode.name);
95
+ }
96
+ function hasJsxElementChildren(node) {
97
+ return node.children.some((child) => t.isJSXElement(child) || t.isJSXFragment(child));
98
+ }
99
+ function injectSourceAttributes(source, resourcePath, options = {}) {
100
+ const attributeName = typeof options.attributeName === "string" && options.attributeName.trim().length > 0
101
+ ? options.attributeName.trim()
102
+ : shared_1.DEFAULT_ATTRIBUTE_NAME;
103
+ const revisionValue = (0, revision_1.resolveBuildCommitSha)();
104
+ if (typeof source !== "string" || !source.includes("<")) {
105
+ return { code: source, map: null, changed: false };
106
+ }
107
+ const cwd = options.cwd ?? process.cwd();
108
+ const relativePath = toRelativePath(resourcePath, cwd);
109
+ const wrapLooseTextNodes = options.wrapLooseTextNodes === true;
110
+ const annotateLeafNodesOnly = options.annotateLeafNodesOnly === true;
111
+ let ast;
112
+ try {
113
+ ast = parser.parse(source, {
114
+ sourceType: "unambiguous",
115
+ errorRecovery: true,
116
+ plugins: [
117
+ "jsx",
118
+ "typescript",
119
+ "classProperties",
120
+ "classPrivateProperties",
121
+ "classPrivateMethods",
122
+ "dynamicImport",
123
+ "importMeta",
124
+ "topLevelAwait",
125
+ ],
126
+ });
127
+ }
128
+ catch {
129
+ return { code: source, map: null, changed: false };
130
+ }
131
+ let changed = false;
132
+ (0, traverse_1.default)(ast, {
133
+ JSXOpeningElement(openingPath) {
134
+ const nameNode = openingPath.node.name;
135
+ if (!isHostElement(nameNode)) {
136
+ return;
137
+ }
138
+ if (!openingPath.node.loc) {
139
+ return;
140
+ }
141
+ if (annotateLeafNodesOnly) {
142
+ const parentNode = openingPath.parentPath.node;
143
+ if (t.isJSXElement(parentNode) && hasJsxElementChildren(parentNode)) {
144
+ return;
145
+ }
146
+ }
147
+ const hasSourceAttribute = openingPath.node.attributes.some((attribute) => t.isJSXAttribute(attribute) &&
148
+ t.isJSXIdentifier(attribute.name, { name: attributeName }));
149
+ const hasRevisionAttribute = openingPath.node.attributes.some((attribute) => t.isJSXAttribute(attribute) &&
150
+ t.isJSXIdentifier(attribute.name, { name: shared_1.DEFAULT_REVISION_ATTRIBUTE_NAME }));
151
+ if (hasSourceAttribute && hasRevisionAttribute) {
152
+ return;
153
+ }
154
+ const { line, column } = openingPath.node.loc.start;
155
+ const locationValue = `${relativePath}:${line}:${column + 1}`;
156
+ if (!hasSourceAttribute) {
157
+ openingPath.node.attributes.push(t.jsxAttribute(t.jsxIdentifier(attributeName), t.stringLiteral(locationValue)));
158
+ changed = true;
159
+ }
160
+ if (!hasRevisionAttribute) {
161
+ openingPath.node.attributes.push(t.jsxAttribute(t.jsxIdentifier(shared_1.DEFAULT_REVISION_ATTRIBUTE_NAME), t.stringLiteral(revisionValue)));
162
+ changed = true;
163
+ }
164
+ },
165
+ JSXElement(elementPath) {
166
+ if (!wrapLooseTextNodes) {
167
+ return;
168
+ }
169
+ const nameNode = elementPath.node.openingElement.name;
170
+ if (!isHostElement(nameNode)) {
171
+ return;
172
+ }
173
+ const children = elementPath.node.children;
174
+ if (children.length === 0) {
175
+ return;
176
+ }
177
+ // Only wrap loose text when mixed with other child nodes.
178
+ const hasNonTextSiblings = children.some((child) => t.isJSXElement(child) || t.isJSXFragment(child) || t.isJSXExpressionContainer(child));
179
+ if (!hasNonTextSiblings) {
180
+ return;
181
+ }
182
+ const nextChildren = [];
183
+ let wrappedAnyTextNode = false;
184
+ for (const child of children) {
185
+ if (!t.isJSXText(child) || !child.loc) {
186
+ nextChildren.push(child);
187
+ continue;
188
+ }
189
+ const parts = splitMeaningfulText(child.value);
190
+ if (!parts) {
191
+ nextChildren.push(child);
192
+ continue;
193
+ }
194
+ const textStart = advanceLocation({ line: child.loc.start.line, column: child.loc.start.column }, parts.leading);
195
+ const locationValue = `${relativePath}:${textStart.line}:${textStart.column + 1}`;
196
+ if (parts.leading.length > 0) {
197
+ nextChildren.push(t.jsxText(parts.leading));
198
+ }
199
+ nextChildren.push(t.jsxElement(t.jsxOpeningElement(t.jsxIdentifier("span"), [
200
+ t.jsxAttribute(t.jsxIdentifier(attributeName), t.stringLiteral(locationValue)),
201
+ t.jsxAttribute(t.jsxIdentifier(shared_1.DEFAULT_REVISION_ATTRIBUTE_NAME), t.stringLiteral(revisionValue)),
202
+ ]), t.jsxClosingElement(t.jsxIdentifier("span")), [t.jsxText(parts.text)], false));
203
+ if (parts.trailing.length > 0) {
204
+ nextChildren.push(t.jsxText(parts.trailing));
205
+ }
206
+ wrappedAnyTextNode = true;
207
+ changed = true;
208
+ }
209
+ if (wrappedAnyTextNode) {
210
+ elementPath.node.children = nextChildren;
211
+ }
212
+ },
213
+ });
214
+ if (!changed) {
215
+ return { code: source, map: null, changed: false };
216
+ }
217
+ const output = (0, generator_1.default)(ast, {
218
+ sourceMaps: true,
219
+ sourceFileName: relativePath,
220
+ jsescOption: { minimal: true },
221
+ }, source);
222
+ return {
223
+ code: output.code,
224
+ map: output.map,
225
+ changed: true,
226
+ };
227
+ }
package/package.json ADDED
@@ -0,0 +1,46 @@
1
+ {
2
+ "name": "@deshlo/core",
3
+ "version": "0.1.0",
4
+ "description": "Shared source inspector helper/wrapper utilities and contracts",
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-plugin": {
16
+ "types": "./build/src/overlay-plugin.d.ts",
17
+ "require": "./build/src/overlay-plugin.js",
18
+ "import": "./build/src/overlay-plugin.js"
19
+ }
20
+ },
21
+ "files": [
22
+ "build"
23
+ ],
24
+ "scripts": {
25
+ "clean": "rm -rf build",
26
+ "build": "tsc -p tsconfig.json",
27
+ "test": "echo \"No tests yet\""
28
+ },
29
+ "keywords": [
30
+ "source-map",
31
+ "debug",
32
+ "inspector"
33
+ ],
34
+ "author": "Nikos Gerontakis",
35
+ "license": "MIT",
36
+ "dependencies": {
37
+ "@babel/generator": "^7.28.3",
38
+ "@babel/parser": "^7.28.4",
39
+ "@babel/traverse": "^7.29.0",
40
+ "@babel/types": "^7.28.4",
41
+ "@deshlo/loader": "0.1.0"
42
+ },
43
+ "devDependencies": {
44
+ "@types/node": "^24.10.1"
45
+ }
46
+ }