angular-grab 0.1.0 → 0.1.2

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.
Files changed (132) hide show
  1. package/README.md +215 -0
  2. package/examples/angular-19-app/.editorconfig +17 -0
  3. package/examples/angular-19-app/.vscode/extensions.json +4 -0
  4. package/examples/angular-19-app/.vscode/launch.json +20 -0
  5. package/examples/angular-19-app/.vscode/mcp.json +9 -0
  6. package/examples/angular-19-app/.vscode/tasks.json +42 -0
  7. package/examples/angular-19-app/README.md +59 -0
  8. package/examples/angular-19-app/angular.json +74 -0
  9. package/examples/angular-19-app/package.json +44 -0
  10. package/examples/angular-19-app/public/favicon.ico +0 -0
  11. package/examples/angular-19-app/src/app/app.config.ts +13 -0
  12. package/examples/angular-19-app/src/app/app.css +37 -0
  13. package/examples/angular-19-app/src/app/app.html +25 -0
  14. package/examples/angular-19-app/src/app/app.routes.ts +3 -0
  15. package/examples/angular-19-app/src/app/app.spec.ts +23 -0
  16. package/examples/angular-19-app/src/app/app.ts +12 -0
  17. package/examples/angular-19-app/src/app/button/button.component.ts +25 -0
  18. package/examples/angular-19-app/src/app/card/card.component.ts +33 -0
  19. package/examples/angular-19-app/src/app/header/header.component.ts +31 -0
  20. package/examples/angular-19-app/src/app/popover/popover.component.ts +133 -0
  21. package/examples/angular-19-app/src/index.html +13 -0
  22. package/examples/angular-19-app/src/main.ts +6 -0
  23. package/examples/angular-19-app/src/styles.css +1 -0
  24. package/examples/angular-19-app/tsconfig.app.json +15 -0
  25. package/examples/angular-19-app/tsconfig.json +33 -0
  26. package/examples/angular-19-app/tsconfig.spec.json +15 -0
  27. package/package.json +14 -111
  28. package/packages/angular-grab/package.json +96 -0
  29. package/packages/angular-grab/src/angular/__tests__/context-builder.test.ts +216 -0
  30. package/packages/angular-grab/src/angular/angular-grab.service.ts +62 -0
  31. package/packages/angular-grab/src/angular/index.ts +13 -0
  32. package/packages/angular-grab/src/angular/provide-angular-grab.ts +22 -0
  33. package/packages/angular-grab/src/angular/resolvers/component-resolver.ts +71 -0
  34. package/packages/angular-grab/src/angular/resolvers/context-builder.ts +86 -0
  35. package/packages/angular-grab/src/angular/resolvers/ng-utils.ts +14 -0
  36. package/packages/angular-grab/src/angular/resolvers/source-resolver.ts +61 -0
  37. package/packages/angular-grab/src/builder/__tests__/builder.test.ts +72 -0
  38. package/packages/angular-grab/src/builder/builders/application/index.ts +13 -0
  39. package/packages/angular-grab/src/builder/builders/dev-server/index.ts +9 -0
  40. package/packages/angular-grab/src/builder/index.ts +3 -0
  41. package/packages/angular-grab/src/cli/__tests__/cli.test.ts +239 -0
  42. package/packages/angular-grab/src/cli/commands/init.ts +106 -0
  43. package/packages/angular-grab/src/cli/index.ts +15 -0
  44. package/packages/angular-grab/src/cli/utils/detect-project.ts +78 -0
  45. package/packages/angular-grab/src/cli/utils/modify-angular-json.ts +42 -0
  46. package/packages/angular-grab/src/cli/utils/modify-app-config.ts +42 -0
  47. package/packages/angular-grab/src/core/__tests__/generate-snippet.test.ts +149 -0
  48. package/packages/angular-grab/src/core/__tests__/plugin-registry.test.ts +286 -0
  49. package/packages/angular-grab/src/core/__tests__/store.test.ts +118 -0
  50. package/packages/angular-grab/src/core/__tests__/utils.test.ts +85 -0
  51. package/packages/angular-grab/src/core/clipboard/copy.ts +104 -0
  52. package/packages/angular-grab/src/core/clipboard/generate-snippet.ts +38 -0
  53. package/packages/angular-grab/src/core/constants.ts +10 -0
  54. package/packages/angular-grab/src/core/grab.ts +596 -0
  55. package/packages/angular-grab/src/core/index.global.ts +13 -0
  56. package/packages/angular-grab/src/core/index.ts +19 -0
  57. package/packages/angular-grab/src/core/keyboard/keyboard-handler.ts +163 -0
  58. package/packages/angular-grab/src/core/overlay/crosshair.ts +107 -0
  59. package/packages/angular-grab/src/core/overlay/freeze-overlay.ts +239 -0
  60. package/packages/angular-grab/src/core/overlay/overlay-renderer.ts +180 -0
  61. package/packages/angular-grab/src/core/overlay/select-feedback.ts +108 -0
  62. package/packages/angular-grab/src/core/overlay/toast.ts +175 -0
  63. package/packages/angular-grab/src/core/picker/element-picker.ts +114 -0
  64. package/packages/angular-grab/src/core/plugins/plugin-registry.ts +83 -0
  65. package/packages/angular-grab/src/core/store.ts +52 -0
  66. package/packages/angular-grab/src/core/toolbar/actions-menu.ts +178 -0
  67. package/packages/angular-grab/src/core/toolbar/comment-popover.ts +235 -0
  68. package/packages/angular-grab/src/core/toolbar/copy-actions.ts +98 -0
  69. package/packages/angular-grab/src/core/toolbar/history-popover.ts +245 -0
  70. package/packages/angular-grab/src/core/toolbar/theme-manager.ts +188 -0
  71. package/packages/angular-grab/src/core/toolbar/toolbar-icons.ts +29 -0
  72. package/packages/angular-grab/src/core/toolbar/toolbar-renderer.ts +239 -0
  73. package/packages/angular-grab/src/core/types.ts +139 -0
  74. package/packages/angular-grab/src/core/utils.ts +16 -0
  75. package/packages/angular-grab/src/esbuild-plugin/__tests__/transform.test.ts +174 -0
  76. package/packages/angular-grab/src/esbuild-plugin/index.ts +3 -0
  77. package/packages/angular-grab/src/esbuild-plugin/plugin.ts +29 -0
  78. package/packages/angular-grab/src/esbuild-plugin/scan.ts +105 -0
  79. package/packages/angular-grab/src/esbuild-plugin/transform.ts +152 -0
  80. package/packages/angular-grab/src/vite-plugin/__tests__/plugin.test.ts +84 -0
  81. package/packages/angular-grab/src/vite-plugin/index.ts +19 -0
  82. package/packages/angular-grab/src/webpack-plugin/__tests__/plugin.test.ts +72 -0
  83. package/packages/angular-grab/src/webpack-plugin/index.ts +2 -0
  84. package/packages/angular-grab/src/webpack-plugin/loader.ts +15 -0
  85. package/packages/angular-grab/src/webpack-plugin/plugin.ts +20 -0
  86. package/packages/angular-grab/tsconfig.json +15 -0
  87. package/packages/angular-grab/tsup.config.ts +119 -0
  88. package/pnpm-workspace.yaml +3 -0
  89. package/turbo.json +21 -0
  90. package/dist/angular/index.d.ts +0 -151
  91. package/dist/angular/index.js +0 -2811
  92. package/dist/angular/index.js.map +0 -1
  93. package/dist/builder/builders/application/index.js +0 -143
  94. package/dist/builder/builders/application/index.js.map +0 -1
  95. package/dist/builder/builders/dev-server/index.js +0 -139
  96. package/dist/builder/builders/dev-server/index.js.map +0 -1
  97. package/dist/builder/index.js +0 -2
  98. package/dist/builder/index.js.map +0 -1
  99. package/dist/builder/package.json +0 -1
  100. package/dist/cli/index.js +0 -223
  101. package/dist/cli/index.js.map +0 -1
  102. package/dist/core/index.cjs +0 -2589
  103. package/dist/core/index.cjs.map +0 -1
  104. package/dist/core/index.d.cts +0 -139
  105. package/dist/core/index.d.ts +0 -139
  106. package/dist/core/index.global.js +0 -542
  107. package/dist/core/index.js +0 -2560
  108. package/dist/core/index.js.map +0 -1
  109. package/dist/esbuild-plugin/index.cjs +0 -239
  110. package/dist/esbuild-plugin/index.cjs.map +0 -1
  111. package/dist/esbuild-plugin/index.d.cts +0 -26
  112. package/dist/esbuild-plugin/index.d.ts +0 -26
  113. package/dist/esbuild-plugin/index.js +0 -200
  114. package/dist/esbuild-plugin/index.js.map +0 -1
  115. package/dist/vite-plugin/index.d.ts +0 -7
  116. package/dist/vite-plugin/index.js +0 -128
  117. package/dist/vite-plugin/index.js.map +0 -1
  118. package/dist/webpack-plugin/index.cjs +0 -54
  119. package/dist/webpack-plugin/index.cjs.map +0 -1
  120. package/dist/webpack-plugin/index.d.cts +0 -5
  121. package/dist/webpack-plugin/index.d.ts +0 -5
  122. package/dist/webpack-plugin/index.js +0 -23
  123. package/dist/webpack-plugin/index.js.map +0 -1
  124. package/dist/webpack-plugin/loader.cjs +0 -155
  125. package/dist/webpack-plugin/loader.cjs.map +0 -1
  126. package/dist/webpack-plugin/loader.d.cts +0 -3
  127. package/dist/webpack-plugin/loader.d.ts +0 -3
  128. package/dist/webpack-plugin/loader.js +0 -122
  129. package/dist/webpack-plugin/loader.js.map +0 -1
  130. /package/{builders.json → packages/angular-grab/builders.json} +0 -0
  131. /package/{dist → packages/angular-grab/src}/builder/builders/application/schema.json +0 -0
  132. /package/{dist → packages/angular-grab/src}/builder/builders/dev-server/schema.json +0 -0
@@ -1,155 +0,0 @@
1
- "use strict";
2
- var __create = Object.create;
3
- var __defProp = Object.defineProperty;
4
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
- var __getOwnPropNames = Object.getOwnPropertyNames;
6
- var __getProtoOf = Object.getPrototypeOf;
7
- var __hasOwnProp = Object.prototype.hasOwnProperty;
8
- var __export = (target, all) => {
9
- for (var name in all)
10
- __defProp(target, name, { get: all[name], enumerable: true });
11
- };
12
- var __copyProps = (to, from, except, desc) => {
13
- if (from && typeof from === "object" || typeof from === "function") {
14
- for (let key of __getOwnPropNames(from))
15
- if (!__hasOwnProp.call(to, key) && key !== except)
16
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
- }
18
- return to;
19
- };
20
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
- // If the importer is in node compatibility mode or this is not an ESM
22
- // file that has been converted to a CommonJS file using a Babel-
23
- // compatible transform (i.e. "__esModule" has not been set), then set
24
- // "default" to the CommonJS "module.exports" for node compatibility.
25
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
- mod
27
- ));
28
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
-
30
- // src/webpack-plugin/loader.ts
31
- var loader_exports = {};
32
- __export(loader_exports, {
33
- default: () => angularGrabLoader
34
- });
35
- module.exports = __toCommonJS(loader_exports);
36
-
37
- // src/esbuild-plugin/scan.ts
38
- var import_typescript = __toESM(require("typescript"), 1);
39
-
40
- // src/esbuild-plugin/transform.ts
41
- var import_typescript2 = __toESM(require("typescript"), 1);
42
- var import_path = __toESM(require("path"), 1);
43
- function transformAngularComponent(code, filePath, rootDir) {
44
- const sourceFile = import_typescript2.default.createSourceFile(
45
- filePath,
46
- code,
47
- import_typescript2.default.ScriptTarget.Latest,
48
- true,
49
- import_typescript2.default.ScriptKind.TS
50
- );
51
- const relativePath = import_path.default.relative(rootDir, filePath).replace(/\\/g, "/").replace(/'/g, "\\'");
52
- const edits = [];
53
- visitNode(sourceFile);
54
- if (edits.length === 0) return null;
55
- edits.sort((a, b) => b.pos - a.pos);
56
- let result = code;
57
- for (const edit of edits) {
58
- result = result.slice(0, edit.pos) + edit.text + result.slice(edit.end);
59
- }
60
- return { code: result };
61
- function visitNode(node) {
62
- if (import_typescript2.default.isClassDeclaration(node)) {
63
- processClassDeclaration(node);
64
- }
65
- import_typescript2.default.forEachChild(node, visitNode);
66
- }
67
- function processClassDeclaration(classNode) {
68
- const decorators = import_typescript2.default.getDecorators(classNode);
69
- if (!decorators) return;
70
- for (const decorator of decorators) {
71
- if (!import_typescript2.default.isCallExpression(decorator.expression)) continue;
72
- const expr = decorator.expression;
73
- if (!import_typescript2.default.isIdentifier(expr.expression)) continue;
74
- if (expr.expression.text !== "Component") continue;
75
- processComponentDecorator(expr);
76
- }
77
- }
78
- function processComponentDecorator(callExpr) {
79
- if (callExpr.arguments.length === 0) {
80
- const line2 = sourceFile.getLineAndCharacterOfPosition(callExpr.getStart()).line;
81
- const sourceAttr2 = `'data-ng-source': '${relativePath}:${line2}:0'`;
82
- const insertText = `{ host: { ${sourceAttr2} } }`;
83
- const openParen = callExpr.getStart() + callExpr.expression.getText().length;
84
- const parenPos = code.indexOf("(", openParen);
85
- const closeParenPos = code.indexOf(")", parenPos);
86
- edits.push({
87
- pos: parenPos + 1,
88
- end: closeParenPos,
89
- text: insertText
90
- });
91
- return;
92
- }
93
- const arg = callExpr.arguments[0];
94
- if (!import_typescript2.default.isObjectLiteralExpression(arg)) return;
95
- const line = sourceFile.getLineAndCharacterOfPosition(callExpr.getStart()).line;
96
- const sourceAttr = `'data-ng-source': '${relativePath}:${line}:0'`;
97
- const hostProp = arg.properties.find(
98
- (p) => import_typescript2.default.isPropertyAssignment(p) && import_typescript2.default.isIdentifier(p.name) && p.name.text === "host"
99
- );
100
- if (hostProp) {
101
- if (!import_typescript2.default.isObjectLiteralExpression(hostProp.initializer)) return;
102
- const hostObj = hostProp.initializer;
103
- const hasExisting = hostObj.properties.some(
104
- (p) => import_typescript2.default.isPropertyAssignment(p) && (import_typescript2.default.isStringLiteral(p.name) && p.name.text === "data-ng-source" || import_typescript2.default.isIdentifier(p.name) && p.name.text === "data-ng-source")
105
- );
106
- if (hasExisting) return;
107
- if (hostObj.properties.length > 0) {
108
- const lastProp = hostObj.properties[hostObj.properties.length - 1];
109
- edits.push({
110
- pos: lastProp.getEnd(),
111
- end: lastProp.getEnd(),
112
- text: `, ${sourceAttr}`
113
- });
114
- } else {
115
- const openBrace = hostObj.getStart();
116
- const closeBrace = hostObj.getEnd();
117
- edits.push({
118
- pos: openBrace + 1,
119
- end: closeBrace - 1,
120
- text: ` ${sourceAttr} `
121
- });
122
- }
123
- } else {
124
- if (arg.properties.length > 0) {
125
- const lastProp = arg.properties[arg.properties.length - 1];
126
- edits.push({
127
- pos: lastProp.getEnd(),
128
- end: lastProp.getEnd(),
129
- text: `, host: { ${sourceAttr} }`
130
- });
131
- } else {
132
- const openBrace = arg.getStart();
133
- const closeBrace = arg.getEnd();
134
- edits.push({
135
- pos: openBrace + 1,
136
- end: closeBrace - 1,
137
- text: ` host: { ${sourceAttr} } `
138
- });
139
- }
140
- }
141
- }
142
- }
143
-
144
- // src/webpack-plugin/loader.ts
145
- function angularGrabLoader(source) {
146
- const callback = this.async();
147
- const filePath = this.resourcePath;
148
- if (!filePath.endsWith(".component.ts") || !source.includes("@Component")) {
149
- return callback(null, source);
150
- }
151
- const rootDir = this.rootContext || process.cwd();
152
- const result = transformAngularComponent(source, filePath, rootDir);
153
- callback(null, result?.code || source);
154
- }
155
- //# sourceMappingURL=loader.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/webpack-plugin/loader.ts","../../src/esbuild-plugin/scan.ts","../../src/esbuild-plugin/transform.ts"],"sourcesContent":["import { transformAngularComponent } from '../esbuild-plugin';\n\nexport default function angularGrabLoader(this: any, source: string) {\n const callback = this.async();\n const filePath = this.resourcePath;\n\n if (!filePath.endsWith('.component.ts') || !source.includes('@Component')) {\n return callback(null, source);\n }\n\n const rootDir = this.rootContext || process.cwd();\n const result = transformAngularComponent(source, filePath, rootDir);\n\n callback(null, result?.code || source);\n}\n","import ts from 'typescript';\nimport path from 'path';\nimport fs from 'fs';\n\nexport interface ComponentSourceInfo {\n file: string;\n line: number;\n}\n\nexport type SourceMap = Record<string, ComponentSourceInfo>;\n\n/**\n * Scans the project for `.component.ts` files and extracts component\n * class names with their source locations. Returns a map of\n * `{ ComponentName: { file, line } }`.\n */\nexport function scanComponentSources(rootDir: string): SourceMap {\n const sourceMap: SourceMap = {};\n const files = findComponentFiles(rootDir);\n\n for (const filePath of files) {\n const content = fs.readFileSync(filePath, 'utf8');\n if (!content.includes('@Component')) continue;\n\n const relativePath = path.relative(rootDir, filePath).replace(/\\\\/g, '/');\n const components = extractComponents(content, filePath);\n\n for (const comp of components) {\n sourceMap[comp.name] = { file: relativePath, line: comp.line };\n }\n }\n\n return sourceMap;\n}\n\ninterface ComponentInfo {\n name: string;\n line: number;\n}\n\nfunction extractComponents(code: string, filePath: string): ComponentInfo[] {\n const sourceFile = ts.createSourceFile(\n filePath,\n code,\n ts.ScriptTarget.Latest,\n true,\n ts.ScriptKind.TS,\n );\n\n const results: ComponentInfo[] = [];\n\n function visit(node: ts.Node): void {\n if (ts.isClassDeclaration(node) && node.name) {\n const decorators = ts.getDecorators(node);\n if (!decorators) return;\n\n const hasComponent = decorators.some((d) => {\n if (!ts.isCallExpression(d.expression)) return false;\n if (!ts.isIdentifier(d.expression.expression)) return false;\n return d.expression.expression.text === 'Component';\n });\n\n if (hasComponent) {\n const { line } = sourceFile.getLineAndCharacterOfPosition(node.getStart());\n results.push({ name: node.name.text, line: line + 1 });\n }\n }\n\n ts.forEachChild(node, visit);\n }\n\n visit(sourceFile);\n return results;\n}\n\nfunction findComponentFiles(rootDir: string): string[] {\n const results: string[] = [];\n const srcDir = path.join(rootDir, 'src');\n\n if (!fs.existsSync(srcDir)) return results;\n\n walk(srcDir, results);\n return results;\n}\n\nfunction walk(dir: string, results: string[]): void {\n let entries: fs.Dirent[];\n try {\n entries = fs.readdirSync(dir, { withFileTypes: true });\n } catch {\n return;\n }\n\n for (const entry of entries) {\n if (entry.name === 'node_modules' || entry.name.startsWith('.')) continue;\n\n const fullPath = path.join(dir, entry.name);\n\n if (entry.isDirectory()) {\n walk(fullPath, results);\n } else if (entry.name.endsWith('.component.ts')) {\n results.push(fullPath);\n }\n }\n}\n","import ts from 'typescript';\nimport path from 'path';\n\nexport interface TransformResult {\n code: string;\n}\n\ninterface Edit {\n pos: number;\n end: number;\n text: string;\n}\n\nexport function transformAngularComponent(\n code: string,\n filePath: string,\n rootDir: string,\n): TransformResult | null {\n const sourceFile = ts.createSourceFile(\n filePath,\n code,\n ts.ScriptTarget.Latest,\n true,\n ts.ScriptKind.TS,\n );\n\n const relativePath = path.relative(rootDir, filePath).replace(/\\\\/g, '/').replace(/'/g, \"\\\\'\");\n const edits: Edit[] = [];\n\n visitNode(sourceFile);\n\n if (edits.length === 0) return null;\n\n // Apply edits in reverse order to preserve positions\n edits.sort((a, b) => b.pos - a.pos);\n\n let result = code;\n for (const edit of edits) {\n result = result.slice(0, edit.pos) + edit.text + result.slice(edit.end);\n }\n\n return { code: result };\n\n function visitNode(node: ts.Node): void {\n if (ts.isClassDeclaration(node)) {\n processClassDeclaration(node);\n }\n ts.forEachChild(node, visitNode);\n }\n\n function processClassDeclaration(classNode: ts.ClassDeclaration): void {\n const decorators = ts.getDecorators(classNode);\n if (!decorators) return;\n\n for (const decorator of decorators) {\n if (!ts.isCallExpression(decorator.expression)) continue;\n\n const expr = decorator.expression;\n if (!ts.isIdentifier(expr.expression)) continue;\n if (expr.expression.text !== 'Component') continue;\n\n processComponentDecorator(expr);\n }\n }\n\n function processComponentDecorator(callExpr: ts.CallExpression): void {\n if (callExpr.arguments.length === 0) {\n // Empty decorator call: @Component() — add host arg\n const line = sourceFile.getLineAndCharacterOfPosition(callExpr.getStart()).line;\n const sourceAttr = `'data-ng-source': '${relativePath}:${line}:0'`;\n const insertText = `{ host: { ${sourceAttr} } }`;\n\n const openParen = callExpr.getStart() + callExpr.expression.getText().length;\n // Find the actual position of the opening paren\n const parenPos = code.indexOf('(', openParen);\n const closeParenPos = code.indexOf(')', parenPos);\n\n edits.push({\n pos: parenPos + 1,\n end: closeParenPos,\n text: insertText,\n });\n return;\n }\n\n const arg = callExpr.arguments[0];\n if (!ts.isObjectLiteralExpression(arg)) return;\n\n const line = sourceFile.getLineAndCharacterOfPosition(callExpr.getStart()).line;\n const sourceAttr = `'data-ng-source': '${relativePath}:${line}:0'`;\n\n // Check if host property already exists\n const hostProp = arg.properties.find(\n (p) => ts.isPropertyAssignment(p) && ts.isIdentifier(p.name) && p.name.text === 'host',\n ) as ts.PropertyAssignment | undefined;\n\n if (hostProp) {\n // Host property exists — inject into it\n if (!ts.isObjectLiteralExpression(hostProp.initializer)) return;\n\n const hostObj = hostProp.initializer;\n\n // Check for existing data-ng-source (idempotent)\n const hasExisting = hostObj.properties.some(\n (p) =>\n ts.isPropertyAssignment(p) &&\n ((ts.isStringLiteral(p.name) && p.name.text === 'data-ng-source') ||\n (ts.isIdentifier(p.name) && p.name.text === 'data-ng-source')),\n );\n\n if (hasExisting) return;\n\n // Insert into existing host object\n if (hostObj.properties.length > 0) {\n const lastProp = hostObj.properties[hostObj.properties.length - 1];\n edits.push({\n pos: lastProp.getEnd(),\n end: lastProp.getEnd(),\n text: `, ${sourceAttr}`,\n });\n } else {\n // Empty host object: host: {}\n const openBrace = hostObj.getStart();\n const closeBrace = hostObj.getEnd();\n edits.push({\n pos: openBrace + 1,\n end: closeBrace - 1,\n text: ` ${sourceAttr} `,\n });\n }\n } else {\n // No host property — add one\n if (arg.properties.length > 0) {\n const lastProp = arg.properties[arg.properties.length - 1];\n edits.push({\n pos: lastProp.getEnd(),\n end: lastProp.getEnd(),\n text: `, host: { ${sourceAttr} }`,\n });\n } else {\n // Empty object literal: @Component({})\n const openBrace = arg.getStart();\n const closeBrace = arg.getEnd();\n edits.push({\n pos: openBrace + 1,\n end: closeBrace - 1,\n text: ` host: { ${sourceAttr} } `,\n });\n }\n }\n }\n}\n"],"mappings":"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","names":["import_typescript","ts","path","line","sourceAttr"]}
@@ -1,3 +0,0 @@
1
- declare function angularGrabLoader(this: any, source: string): any;
2
-
3
- export { angularGrabLoader as default };
@@ -1,3 +0,0 @@
1
- declare function angularGrabLoader(this: any, source: string): any;
2
-
3
- export { angularGrabLoader as default };
@@ -1,122 +0,0 @@
1
- // src/esbuild-plugin/scan.ts
2
- import ts from "typescript";
3
-
4
- // src/esbuild-plugin/transform.ts
5
- import ts2 from "typescript";
6
- import path from "path";
7
- function transformAngularComponent(code, filePath, rootDir) {
8
- const sourceFile = ts2.createSourceFile(
9
- filePath,
10
- code,
11
- ts2.ScriptTarget.Latest,
12
- true,
13
- ts2.ScriptKind.TS
14
- );
15
- const relativePath = path.relative(rootDir, filePath).replace(/\\/g, "/").replace(/'/g, "\\'");
16
- const edits = [];
17
- visitNode(sourceFile);
18
- if (edits.length === 0) return null;
19
- edits.sort((a, b) => b.pos - a.pos);
20
- let result = code;
21
- for (const edit of edits) {
22
- result = result.slice(0, edit.pos) + edit.text + result.slice(edit.end);
23
- }
24
- return { code: result };
25
- function visitNode(node) {
26
- if (ts2.isClassDeclaration(node)) {
27
- processClassDeclaration(node);
28
- }
29
- ts2.forEachChild(node, visitNode);
30
- }
31
- function processClassDeclaration(classNode) {
32
- const decorators = ts2.getDecorators(classNode);
33
- if (!decorators) return;
34
- for (const decorator of decorators) {
35
- if (!ts2.isCallExpression(decorator.expression)) continue;
36
- const expr = decorator.expression;
37
- if (!ts2.isIdentifier(expr.expression)) continue;
38
- if (expr.expression.text !== "Component") continue;
39
- processComponentDecorator(expr);
40
- }
41
- }
42
- function processComponentDecorator(callExpr) {
43
- if (callExpr.arguments.length === 0) {
44
- const line2 = sourceFile.getLineAndCharacterOfPosition(callExpr.getStart()).line;
45
- const sourceAttr2 = `'data-ng-source': '${relativePath}:${line2}:0'`;
46
- const insertText = `{ host: { ${sourceAttr2} } }`;
47
- const openParen = callExpr.getStart() + callExpr.expression.getText().length;
48
- const parenPos = code.indexOf("(", openParen);
49
- const closeParenPos = code.indexOf(")", parenPos);
50
- edits.push({
51
- pos: parenPos + 1,
52
- end: closeParenPos,
53
- text: insertText
54
- });
55
- return;
56
- }
57
- const arg = callExpr.arguments[0];
58
- if (!ts2.isObjectLiteralExpression(arg)) return;
59
- const line = sourceFile.getLineAndCharacterOfPosition(callExpr.getStart()).line;
60
- const sourceAttr = `'data-ng-source': '${relativePath}:${line}:0'`;
61
- const hostProp = arg.properties.find(
62
- (p) => ts2.isPropertyAssignment(p) && ts2.isIdentifier(p.name) && p.name.text === "host"
63
- );
64
- if (hostProp) {
65
- if (!ts2.isObjectLiteralExpression(hostProp.initializer)) return;
66
- const hostObj = hostProp.initializer;
67
- const hasExisting = hostObj.properties.some(
68
- (p) => ts2.isPropertyAssignment(p) && (ts2.isStringLiteral(p.name) && p.name.text === "data-ng-source" || ts2.isIdentifier(p.name) && p.name.text === "data-ng-source")
69
- );
70
- if (hasExisting) return;
71
- if (hostObj.properties.length > 0) {
72
- const lastProp = hostObj.properties[hostObj.properties.length - 1];
73
- edits.push({
74
- pos: lastProp.getEnd(),
75
- end: lastProp.getEnd(),
76
- text: `, ${sourceAttr}`
77
- });
78
- } else {
79
- const openBrace = hostObj.getStart();
80
- const closeBrace = hostObj.getEnd();
81
- edits.push({
82
- pos: openBrace + 1,
83
- end: closeBrace - 1,
84
- text: ` ${sourceAttr} `
85
- });
86
- }
87
- } else {
88
- if (arg.properties.length > 0) {
89
- const lastProp = arg.properties[arg.properties.length - 1];
90
- edits.push({
91
- pos: lastProp.getEnd(),
92
- end: lastProp.getEnd(),
93
- text: `, host: { ${sourceAttr} }`
94
- });
95
- } else {
96
- const openBrace = arg.getStart();
97
- const closeBrace = arg.getEnd();
98
- edits.push({
99
- pos: openBrace + 1,
100
- end: closeBrace - 1,
101
- text: ` host: { ${sourceAttr} } `
102
- });
103
- }
104
- }
105
- }
106
- }
107
-
108
- // src/webpack-plugin/loader.ts
109
- function angularGrabLoader(source) {
110
- const callback = this.async();
111
- const filePath = this.resourcePath;
112
- if (!filePath.endsWith(".component.ts") || !source.includes("@Component")) {
113
- return callback(null, source);
114
- }
115
- const rootDir = this.rootContext || process.cwd();
116
- const result = transformAngularComponent(source, filePath, rootDir);
117
- callback(null, result?.code || source);
118
- }
119
- export {
120
- angularGrabLoader as default
121
- };
122
- //# sourceMappingURL=loader.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/esbuild-plugin/scan.ts","../../src/esbuild-plugin/transform.ts","../../src/webpack-plugin/loader.ts"],"sourcesContent":["import ts from 'typescript';\nimport path from 'path';\nimport fs from 'fs';\n\nexport interface ComponentSourceInfo {\n file: string;\n line: number;\n}\n\nexport type SourceMap = Record<string, ComponentSourceInfo>;\n\n/**\n * Scans the project for `.component.ts` files and extracts component\n * class names with their source locations. Returns a map of\n * `{ ComponentName: { file, line } }`.\n */\nexport function scanComponentSources(rootDir: string): SourceMap {\n const sourceMap: SourceMap = {};\n const files = findComponentFiles(rootDir);\n\n for (const filePath of files) {\n const content = fs.readFileSync(filePath, 'utf8');\n if (!content.includes('@Component')) continue;\n\n const relativePath = path.relative(rootDir, filePath).replace(/\\\\/g, '/');\n const components = extractComponents(content, filePath);\n\n for (const comp of components) {\n sourceMap[comp.name] = { file: relativePath, line: comp.line };\n }\n }\n\n return sourceMap;\n}\n\ninterface ComponentInfo {\n name: string;\n line: number;\n}\n\nfunction extractComponents(code: string, filePath: string): ComponentInfo[] {\n const sourceFile = ts.createSourceFile(\n filePath,\n code,\n ts.ScriptTarget.Latest,\n true,\n ts.ScriptKind.TS,\n );\n\n const results: ComponentInfo[] = [];\n\n function visit(node: ts.Node): void {\n if (ts.isClassDeclaration(node) && node.name) {\n const decorators = ts.getDecorators(node);\n if (!decorators) return;\n\n const hasComponent = decorators.some((d) => {\n if (!ts.isCallExpression(d.expression)) return false;\n if (!ts.isIdentifier(d.expression.expression)) return false;\n return d.expression.expression.text === 'Component';\n });\n\n if (hasComponent) {\n const { line } = sourceFile.getLineAndCharacterOfPosition(node.getStart());\n results.push({ name: node.name.text, line: line + 1 });\n }\n }\n\n ts.forEachChild(node, visit);\n }\n\n visit(sourceFile);\n return results;\n}\n\nfunction findComponentFiles(rootDir: string): string[] {\n const results: string[] = [];\n const srcDir = path.join(rootDir, 'src');\n\n if (!fs.existsSync(srcDir)) return results;\n\n walk(srcDir, results);\n return results;\n}\n\nfunction walk(dir: string, results: string[]): void {\n let entries: fs.Dirent[];\n try {\n entries = fs.readdirSync(dir, { withFileTypes: true });\n } catch {\n return;\n }\n\n for (const entry of entries) {\n if (entry.name === 'node_modules' || entry.name.startsWith('.')) continue;\n\n const fullPath = path.join(dir, entry.name);\n\n if (entry.isDirectory()) {\n walk(fullPath, results);\n } else if (entry.name.endsWith('.component.ts')) {\n results.push(fullPath);\n }\n }\n}\n","import ts from 'typescript';\nimport path from 'path';\n\nexport interface TransformResult {\n code: string;\n}\n\ninterface Edit {\n pos: number;\n end: number;\n text: string;\n}\n\nexport function transformAngularComponent(\n code: string,\n filePath: string,\n rootDir: string,\n): TransformResult | null {\n const sourceFile = ts.createSourceFile(\n filePath,\n code,\n ts.ScriptTarget.Latest,\n true,\n ts.ScriptKind.TS,\n );\n\n const relativePath = path.relative(rootDir, filePath).replace(/\\\\/g, '/').replace(/'/g, \"\\\\'\");\n const edits: Edit[] = [];\n\n visitNode(sourceFile);\n\n if (edits.length === 0) return null;\n\n // Apply edits in reverse order to preserve positions\n edits.sort((a, b) => b.pos - a.pos);\n\n let result = code;\n for (const edit of edits) {\n result = result.slice(0, edit.pos) + edit.text + result.slice(edit.end);\n }\n\n return { code: result };\n\n function visitNode(node: ts.Node): void {\n if (ts.isClassDeclaration(node)) {\n processClassDeclaration(node);\n }\n ts.forEachChild(node, visitNode);\n }\n\n function processClassDeclaration(classNode: ts.ClassDeclaration): void {\n const decorators = ts.getDecorators(classNode);\n if (!decorators) return;\n\n for (const decorator of decorators) {\n if (!ts.isCallExpression(decorator.expression)) continue;\n\n const expr = decorator.expression;\n if (!ts.isIdentifier(expr.expression)) continue;\n if (expr.expression.text !== 'Component') continue;\n\n processComponentDecorator(expr);\n }\n }\n\n function processComponentDecorator(callExpr: ts.CallExpression): void {\n if (callExpr.arguments.length === 0) {\n // Empty decorator call: @Component() — add host arg\n const line = sourceFile.getLineAndCharacterOfPosition(callExpr.getStart()).line;\n const sourceAttr = `'data-ng-source': '${relativePath}:${line}:0'`;\n const insertText = `{ host: { ${sourceAttr} } }`;\n\n const openParen = callExpr.getStart() + callExpr.expression.getText().length;\n // Find the actual position of the opening paren\n const parenPos = code.indexOf('(', openParen);\n const closeParenPos = code.indexOf(')', parenPos);\n\n edits.push({\n pos: parenPos + 1,\n end: closeParenPos,\n text: insertText,\n });\n return;\n }\n\n const arg = callExpr.arguments[0];\n if (!ts.isObjectLiteralExpression(arg)) return;\n\n const line = sourceFile.getLineAndCharacterOfPosition(callExpr.getStart()).line;\n const sourceAttr = `'data-ng-source': '${relativePath}:${line}:0'`;\n\n // Check if host property already exists\n const hostProp = arg.properties.find(\n (p) => ts.isPropertyAssignment(p) && ts.isIdentifier(p.name) && p.name.text === 'host',\n ) as ts.PropertyAssignment | undefined;\n\n if (hostProp) {\n // Host property exists — inject into it\n if (!ts.isObjectLiteralExpression(hostProp.initializer)) return;\n\n const hostObj = hostProp.initializer;\n\n // Check for existing data-ng-source (idempotent)\n const hasExisting = hostObj.properties.some(\n (p) =>\n ts.isPropertyAssignment(p) &&\n ((ts.isStringLiteral(p.name) && p.name.text === 'data-ng-source') ||\n (ts.isIdentifier(p.name) && p.name.text === 'data-ng-source')),\n );\n\n if (hasExisting) return;\n\n // Insert into existing host object\n if (hostObj.properties.length > 0) {\n const lastProp = hostObj.properties[hostObj.properties.length - 1];\n edits.push({\n pos: lastProp.getEnd(),\n end: lastProp.getEnd(),\n text: `, ${sourceAttr}`,\n });\n } else {\n // Empty host object: host: {}\n const openBrace = hostObj.getStart();\n const closeBrace = hostObj.getEnd();\n edits.push({\n pos: openBrace + 1,\n end: closeBrace - 1,\n text: ` ${sourceAttr} `,\n });\n }\n } else {\n // No host property — add one\n if (arg.properties.length > 0) {\n const lastProp = arg.properties[arg.properties.length - 1];\n edits.push({\n pos: lastProp.getEnd(),\n end: lastProp.getEnd(),\n text: `, host: { ${sourceAttr} }`,\n });\n } else {\n // Empty object literal: @Component({})\n const openBrace = arg.getStart();\n const closeBrace = arg.getEnd();\n edits.push({\n pos: openBrace + 1,\n end: closeBrace - 1,\n text: ` host: { ${sourceAttr} } `,\n });\n }\n }\n }\n}\n","import { transformAngularComponent } from '../esbuild-plugin';\n\nexport default function angularGrabLoader(this: any, source: string) {\n const callback = this.async();\n const filePath = this.resourcePath;\n\n if (!filePath.endsWith('.component.ts') || !source.includes('@Component')) {\n return callback(null, source);\n }\n\n const rootDir = this.rootContext || process.cwd();\n const result = transformAngularComponent(source, filePath, rootDir);\n\n callback(null, result?.code || source);\n}\n"],"mappings":"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","names":["ts","line","sourceAttr"]}