@embroider/compat 3.6.2 → 3.6.4

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.
@@ -10,11 +10,19 @@ const fs_1 = require("fs");
10
10
  const broccoli_plugin_1 = __importDefault(require("broccoli-plugin"));
11
11
  const core_1 = require("@babel/core");
12
12
  const core_2 = require("@embroider/core");
13
- const babel_import_util_1 = require("babel-import-util");
14
13
  const resolver_transform_1 = __importDefault(require("./resolver-transform"));
15
14
  const child_process_1 = require("child_process");
16
15
  const core_3 = require("@embroider/core");
17
- function templateTagCodemod(emberApp, { shouldTransformPath = (() => true), dryRun = false } = {}) {
16
+ function templateTagCodemod(emberApp, { shouldTransformPath = (() => true), nameHint = (path => {
17
+ return path
18
+ .split('/')
19
+ .map(part => part
20
+ .split('-')
21
+ // capitalize first letter
22
+ .map(inner_part => inner_part.charAt(0).toUpperCase() + inner_part.slice(1))
23
+ .join(''))
24
+ .join('_');
25
+ }), dryRun = false, } = {}) {
18
26
  return new TemplateTagCodemodPlugin([
19
27
  (0, default_pipeline_1.default)(emberApp, undefined, {
20
28
  staticAddonTrees: true,
@@ -27,8 +35,10 @@ function templateTagCodemod(emberApp, { shouldTransformPath = (() => true), dryR
27
35
  es: [],
28
36
  },
29
37
  }),
30
- ], { shouldTransformPath, dryRun });
38
+ ], { shouldTransformPath, nameHint, dryRun });
31
39
  }
40
+ const TEMPLATE_ONLY_MARKER = `import templateOnlyComponent from '@ember/component/template-only';`;
41
+ const TEMPLATE_COLOCATION_MARKER = /\/\* import __COLOCATED_TEMPLATE__ from (.*) \*\//;
32
42
  class TemplateTagCodemodPlugin extends broccoli_plugin_1.default {
33
43
  constructor(inputNodes, options) {
34
44
  super(inputNodes, {
@@ -70,25 +80,38 @@ class TemplateTagCodemodPlugin extends broccoli_plugin_1.default {
70
80
  const babel_plugin_syntax_decorators = require.resolve('@babel/plugin-syntax-decorators', {
71
81
  paths: [embroider_compat_path],
72
82
  });
83
+ const babel_plugin_syntax_typescript = require.resolve('@babel/plugin-syntax-typescript', {
84
+ paths: [embroider_compat_path],
85
+ });
86
+ const resolver_transform = (0, resolver_transform_1.default)({
87
+ appRoot: process.cwd(),
88
+ emberVersion: emberVersion,
89
+ externalNameHint: this.options.nameHint,
90
+ });
73
91
  for await (const current_file of walkSync(tmp_path)) {
74
92
  if (hbs_file_test.test(current_file) && this.options.shouldTransformPath(current_file)) {
75
93
  const template_file_src = (0, fs_1.readFileSync)(current_file).toLocaleString();
76
- let src = (_b = (_a = (0, core_1.transformSync)((0, core_2.hbsToJS)(template_file_src), {
94
+ // run the template transformations using embroider resolver information
95
+ // to replace template values with js import syntax used in g(j/t)s
96
+ let transformed_source = (_b = (_a = (0, core_1.transformSync)((0, core_2.hbsToJS)(template_file_src), {
77
97
  plugins: [
78
98
  [
79
99
  babel_plugin_ember_template_compilation,
80
100
  {
81
101
  compilerPath: ember_template_compiler.filename,
82
- transforms: [(0, resolver_transform_1.default)({ appRoot: process.cwd(), emberVersion: emberVersion })],
102
+ transforms: [resolver_transform],
83
103
  targetFormat: 'hbs',
84
104
  },
85
105
  ],
86
106
  ],
87
107
  filename: current_file,
88
108
  })) === null || _a === void 0 ? void 0 : _a.code) !== null && _b !== void 0 ? _b : '';
109
+ // using transformSync to parse and traverse in one go
110
+ // we're only extracting the transformed template information from previous step
111
+ // and preserving it for later assembly in the backing class
89
112
  const import_bucket = [];
90
- let transformed_template_value = '';
91
- (0, core_1.transformSync)(src, {
113
+ let template_tag_value = '';
114
+ (0, core_1.transformSync)(transformed_source, {
92
115
  plugins: [
93
116
  function template_tag_extractor() {
94
117
  return {
@@ -98,11 +121,18 @@ class TemplateTagCodemodPlugin extends broccoli_plugin_1.default {
98
121
  if (extractor) {
99
122
  const result = resolver.nodeResolve(extractor[0], current_file);
100
123
  if (result.type === 'real') {
101
- // find package
124
+ // find package there the resolver is pointing
102
125
  const owner_package = resolver.packageCache.ownerOfFile(result.filename);
103
- // change import to real one
104
- import_declaration.node.source.value =
105
- owner_package.name + '/' + extractor[1] + '/' + extractor[2];
126
+ let relative_import_path = (0, path_1.relative)(owner_package.root, result.filename);
127
+ // for addons strip off appPublicationDir from relative path
128
+ // we do this on app files as well as they don't contain the
129
+ // path that we strip off
130
+ // this makes sure that ambiguous imports get properly attributed
131
+ relative_import_path = relative_import_path.replace('_app_/', '');
132
+ // remove the extension to match what a developer would normally write
133
+ relative_import_path = relative_import_path.slice(0, -(0, path_1.extname)(relative_import_path).length);
134
+ // change import path to real one
135
+ import_declaration.node.source.value = owner_package.name + '/' + relative_import_path;
106
136
  import_bucket.push(import_declaration);
107
137
  }
108
138
  }
@@ -117,7 +147,7 @@ class TemplateTagCodemodPlugin extends broccoli_plugin_1.default {
117
147
  path.node.callee.name === 'precompileTemplate' &&
118
148
  path.node.arguments &&
119
149
  'value' in path.node.arguments[0]) {
120
- transformed_template_value = `<template>\n\t${path.node.arguments[0].value}\n</template>`;
150
+ template_tag_value = `<template>\n\t${path.node.arguments[0].value}\n</template>`;
121
151
  }
122
152
  },
123
153
  },
@@ -128,53 +158,36 @@ class TemplateTagCodemodPlugin extends broccoli_plugin_1.default {
128
158
  //find backing class
129
159
  const backing_class_resolution = resolver.nodeResolve('#embroider_compat/' + (0, path_1.relative)(tmp_path, current_file).replace(/[\\]/g, '/').slice(0, -4), tmp_path);
130
160
  const backing_class_filename = 'filename' in backing_class_resolution ? backing_class_resolution.filename : '';
161
+ // this can be either a generated js file in case of template only components
162
+ // the js or ts file depending on what the app is configured
131
163
  const backing_class_src = (0, fs_1.readFileSync)(backing_class_filename).toString();
132
- const magic_string = '__MAGIC_STRING_FOR_TEMPLATE_TAG_REPLACE__';
133
- const is_template_only = backing_class_src.indexOf("import templateOnlyComponent from '@ember/component/template-only';") !== -1;
134
- src = (0, core_1.transformSync)(backing_class_src, {
164
+ const is_typescript = (0, path_1.extname)(backing_class_filename) === '.ts';
165
+ let insert_imports_byte_count = null;
166
+ let insert_template_byte_count = null;
167
+ const is_template_only = backing_class_src.indexOf(TEMPLATE_ONLY_MARKER) !== -1;
168
+ // we parse the backing class to find the insert points for imports and template
169
+ (0, core_1.transformSync)(backing_class_src, {
135
170
  plugins: [
136
- [babel_plugin_syntax_decorators, { decoratorsBeforeExport: true }],
137
- function glimmer_syntax_creator(babel) {
171
+ [
172
+ is_typescript ? babel_plugin_syntax_typescript : babel_plugin_syntax_decorators,
173
+ { decoratorsBeforeExport: true },
174
+ ],
175
+ function glimmer_syntax_creator( /* babel */) {
138
176
  return {
139
177
  name: 'test',
140
178
  visitor: {
141
- Program: {
142
- enter(path) {
143
- var _a;
144
- // Always instantiate the ImportUtil instance at the Program scope
145
- const importUtil = new babel_import_util_1.ImportUtil(babel.types, path);
146
- const first_node = path.get('body')[0];
147
- if (first_node &&
148
- first_node.node &&
149
- first_node.node.leadingComments &&
150
- ((_a = first_node.node.leadingComments[0]) === null || _a === void 0 ? void 0 : _a.value.includes('__COLOCATED_TEMPLATE__'))) {
151
- //remove magic comment
152
- first_node.node.leadingComments.splice(0, 1);
153
- }
154
- for (const template_import of import_bucket) {
155
- for (let i = 0, len = template_import.node.specifiers.length; i < len; ++i) {
156
- const specifier = template_import.node.specifiers[i];
157
- if (specifier.type === 'ImportDefaultSpecifier') {
158
- importUtil.import(path, template_import.node.source.value, 'default', specifier.local.name);
159
- }
160
- else if (specifier.type === 'ImportSpecifier') {
161
- importUtil.import(path, template_import.node.source.value, specifier.local.name);
162
- }
163
- }
164
- }
165
- },
166
- },
167
179
  ImportDeclaration(import_declaration) {
168
- if (import_declaration.node.source.value.indexOf('@ember/component/template-only') !== -1) {
169
- import_declaration.remove();
170
- }
180
+ insert_imports_byte_count = import_declaration.node.end;
171
181
  },
172
182
  ExportDefaultDeclaration(path) {
183
+ // convention is that we have a default export for each component
184
+ // we look for the closing bracket of the class body
173
185
  path.traverse({
174
186
  ClassBody(path) {
175
- const classbody_nodes = path.get('body');
176
- //add magic string to be replaces with the contents of the template tag
177
- classbody_nodes[classbody_nodes.length - 1].addComment('trailing', magic_string, false);
187
+ // we substract 1 to find the byte right before the final closing bracket `}`
188
+ // this is the default insert point for template tag though it could live anywhere inside the class body
189
+ // possible future point to add option for putting template first thing in class
190
+ insert_template_byte_count = path.node.end ? path.node.end - 1 : 0;
178
191
  },
179
192
  });
180
193
  },
@@ -182,22 +195,54 @@ class TemplateTagCodemodPlugin extends broccoli_plugin_1.default {
182
195
  };
183
196
  },
184
197
  ],
185
- }).code.replace(`/*${magic_string}*/`, transformed_template_value);
198
+ });
199
+ // list of imports needed by the previous hbs template extracted in second step
200
+ const hbs_template_required_imports = import_bucket.join('\n');
201
+ // we extracted all we needed from transformed_source so we switch to the second phase
202
+ // transforming the backing class into what will be our final output
203
+ transformed_source = backing_class_src;
186
204
  if (is_template_only) {
187
205
  // because we can't inject a comment as the default export
188
206
  // we replace the known exported string
189
- src = src.replace('templateOnlyComponent()', transformed_template_value);
207
+ transformed_source = transformed_source.replace('templateOnlyComponent()', template_tag_value);
208
+ // we clean known markers from generated files
209
+ transformed_source = transformed_source.replace(TEMPLATE_ONLY_MARKER, hbs_template_required_imports);
210
+ transformed_source = transformed_source.replace(TEMPLATE_COLOCATION_MARKER, '');
211
+ }
212
+ else {
213
+ // we modify the source from end to start in order to keep our byte counts valid through the transforms
214
+ if (insert_template_byte_count) {
215
+ // first we split the backing class at the byte count we found during backing class parsing
216
+ // then concat the string back together adding the transformed template in the middle
217
+ transformed_source =
218
+ transformed_source.substring(0, insert_template_byte_count) +
219
+ '\n' +
220
+ template_tag_value +
221
+ '\n' +
222
+ transformed_source.substring(insert_template_byte_count, transformed_source.length);
223
+ }
224
+ if (insert_imports_byte_count) {
225
+ // first we split the backing class at the byte count we found during backing class parsing
226
+ // then concat the string back together adding the transformed template in the middle
227
+ transformed_source =
228
+ transformed_source.substring(0, insert_imports_byte_count) +
229
+ '\n' +
230
+ hbs_template_required_imports +
231
+ '\n' +
232
+ transformed_source.substring(insert_imports_byte_count, transformed_source.length);
233
+ }
234
+ transformed_source = transformed_source.replace(TEMPLATE_COLOCATION_MARKER, '');
190
235
  }
191
236
  const dryRun = this.options.dryRun ? '--dry-run' : '';
192
237
  // work out original file path in app tree
193
238
  const app_relative_path = (0, path_1.join)('app', (0, path_1.relative)(tmp_path, current_file));
194
- const new_file_path = app_relative_path.slice(0, -4) + '.gjs';
239
+ const new_file_path = app_relative_path.slice(0, -4) + (is_typescript ? '.gts' : '.gjs');
195
240
  // write glimmer file out
196
241
  if (this.options.dryRun) {
197
- console.log('Write new file', new_file_path, src);
242
+ console.log('Write new file', new_file_path, transformed_source);
198
243
  }
199
244
  else {
200
- (0, fs_1.writeFileSync)((0, path_1.join)(process.cwd(), new_file_path), src, { flag: 'wx+' });
245
+ (0, fs_1.writeFileSync)((0, path_1.join)(process.cwd(), new_file_path), transformed_source, { flag: 'wx+' });
201
246
  }
202
247
  // git rm old files (js/ts if exists + hbs)
203
248
  let rm_hbs = await execute(`git rm ${app_relative_path} ${dryRun}`, {
@@ -206,7 +251,7 @@ class TemplateTagCodemodPlugin extends broccoli_plugin_1.default {
206
251
  console.log(rm_hbs.output);
207
252
  if (!is_template_only) {
208
253
  // remove backing class only if it's not a template only component
209
- // resolve repative path to rewritten-app
254
+ // resolve relative path to rewritten-app
210
255
  const app_relative_path = (0, path_1.join)('app', (0, path_1.relative)(tmp_path, backing_class_filename));
211
256
  let rm_js = await execute(`git rm ${app_relative_path} ${dryRun}`, {
212
257
  pwd: process.cwd(),
@@ -1 +1 @@
1
- {"version":3,"file":"template-tag-codemod.js","sourceRoot":"","sources":["template-tag-codemod.ts"],"names":[],"mappings":"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","sourcesContent":["import { default as compatBuild } from './default-pipeline';\nimport type { EmberAppInstance } from '@embroider/core';\nimport type { Node, InputNode } from 'broccoli-node-api';\nimport { join, relative, resolve } from 'path';\nimport type { types as t } from '@babel/core';\nimport type { NodePath } from '@babel/traverse';\nimport { statSync, readdirSync, readFileSync, writeFileSync } from 'fs';\nimport Plugin from 'broccoli-plugin';\nimport { transformSync } from '@babel/core';\nimport { hbsToJS, ResolverLoader } from '@embroider/core';\nimport { ImportUtil } from 'babel-import-util';\nimport ResolverTransform from './resolver-transform';\nimport { spawn } from 'child_process';\nimport { locateEmbroiderWorkingDir } from '@embroider/core';\n\nexport interface TemplateTagCodemodOptions {\n shouldTransformPath: (outputPath: string) => boolean;\n dryRun: boolean;\n}\n\nexport default function templateTagCodemod(\n emberApp: EmberAppInstance,\n { shouldTransformPath = (() => true) as TemplateTagCodemodOptions['shouldTransformPath'], dryRun = false } = {}\n): Node {\n return new TemplateTagCodemodPlugin(\n [\n compatBuild(emberApp, undefined, {\n staticAddonTrees: true,\n staticAddonTestSupportTrees: true,\n staticComponents: true,\n staticHelpers: true,\n staticModifiers: true,\n staticEmberSource: true,\n amdCompatibility: {\n es: [],\n },\n }),\n ],\n { shouldTransformPath, dryRun }\n );\n}\nclass TemplateTagCodemodPlugin extends Plugin {\n constructor(inputNodes: InputNode[], readonly options: TemplateTagCodemodOptions) {\n super(inputNodes, {\n name: 'TemplateTagCodemodPlugin',\n });\n }\n async build() {\n function* walkSync(dir: string): Generator<string> {\n const files = readdirSync(dir);\n\n for (const file of files) {\n const pathToFile = join(dir, file);\n const isDirectory = statSync(pathToFile).isDirectory();\n if (isDirectory) {\n yield* walkSync(pathToFile);\n } else {\n yield pathToFile;\n }\n }\n }\n this.inputPaths[0];\n const tmp_path = readFileSync(this.inputPaths[0] + '/.stage2-output').toLocaleString();\n const compatPattern = /#embroider_compat\\/(?<type>[^\\/]+)\\/(?<rest>.*)/;\n const resolver = new ResolverLoader(process.cwd()).resolver;\n const hbs_file_test = /[\\\\/]rewritten-app[\\\\/]components[\\\\/].*\\.hbs$/;\n // locate ember-source for the host app so we know which version to insert builtIns for\n const emberSourceEntrypoint = require.resolve('ember-source', { paths: [process.cwd()] });\n const emberVersion = JSON.parse(readFileSync(join(emberSourceEntrypoint, '../../package.json')).toString()).version;\n\n const ember_template_compiler = resolver.nodeResolve(\n 'ember-source/vendor/ember/ember-template-compiler',\n resolve(locateEmbroiderWorkingDir(process.cwd()), 'rewritten-app', 'package.json')\n );\n if (ember_template_compiler.type === 'not_found') {\n throw 'This will not ever be true';\n }\n\n const embroider_compat_path = require.resolve('@embroider/compat', { paths: [process.cwd()] });\n const babel_plugin_ember_template_compilation = require.resolve('babel-plugin-ember-template-compilation', {\n paths: [embroider_compat_path],\n });\n const babel_plugin_syntax_decorators = require.resolve('@babel/plugin-syntax-decorators', {\n paths: [embroider_compat_path],\n });\n\n for await (const current_file of walkSync(tmp_path)) {\n if (hbs_file_test.test(current_file) && this.options.shouldTransformPath(current_file)) {\n const template_file_src = readFileSync(current_file).toLocaleString();\n\n let src =\n transformSync(hbsToJS(template_file_src), {\n plugins: [\n [\n babel_plugin_ember_template_compilation,\n {\n compilerPath: ember_template_compiler.filename,\n transforms: [ResolverTransform({ appRoot: process.cwd(), emberVersion: emberVersion })],\n targetFormat: 'hbs',\n },\n ],\n ],\n filename: current_file,\n })?.code ?? '';\n const import_bucket: NodePath<t.ImportDeclaration>[] = [];\n let transformed_template_value = '';\n transformSync(src, {\n plugins: [\n function template_tag_extractor(): unknown {\n return {\n visitor: {\n ImportDeclaration(import_declaration: NodePath<t.ImportDeclaration>) {\n const extractor = import_declaration.node.source.value.match(compatPattern);\n if (extractor) {\n const result = resolver.nodeResolve(extractor[0], current_file);\n if (result.type === 'real') {\n // find package\n const owner_package = resolver.packageCache.ownerOfFile(result.filename);\n // change import to real one\n import_declaration.node.source.value =\n owner_package!.name + '/' + extractor[1] + '/' + extractor[2];\n import_bucket.push(import_declaration);\n }\n } else if (import_declaration.node.source.value.indexOf('@ember/template-compilation') === -1) {\n import_bucket.push(import_declaration);\n }\n },\n CallExpression(path: NodePath<t.CallExpression>) {\n // reverse of hbs to js\n // extract the template string to put into template tag in backing class\n if (\n 'name' in path.node.callee &&\n path.node.callee.name === 'precompileTemplate' &&\n path.node.arguments &&\n 'value' in path.node.arguments[0]\n ) {\n transformed_template_value = `<template>\\n\\t${path.node.arguments[0].value}\\n</template>`;\n }\n },\n },\n };\n },\n ],\n });\n\n //find backing class\n const backing_class_resolution = resolver.nodeResolve(\n '#embroider_compat/' + relative(tmp_path, current_file).replace(/[\\\\]/g, '/').slice(0, -4),\n tmp_path\n );\n\n const backing_class_filename = 'filename' in backing_class_resolution ? backing_class_resolution.filename : '';\n const backing_class_src = readFileSync(backing_class_filename).toString();\n const magic_string = '__MAGIC_STRING_FOR_TEMPLATE_TAG_REPLACE__';\n const is_template_only =\n backing_class_src.indexOf(\"import templateOnlyComponent from '@ember/component/template-only';\") !== -1;\n\n src = transformSync(backing_class_src, {\n plugins: [\n [babel_plugin_syntax_decorators, { decoratorsBeforeExport: true }],\n function glimmer_syntax_creator(babel): unknown {\n return {\n name: 'test',\n visitor: {\n Program: {\n enter(path: NodePath<t.Program>) {\n // Always instantiate the ImportUtil instance at the Program scope\n const importUtil = new ImportUtil(babel.types, path);\n const first_node = path.get('body')[0];\n if (\n first_node &&\n first_node.node &&\n first_node.node.leadingComments &&\n first_node.node.leadingComments[0]?.value.includes('__COLOCATED_TEMPLATE__')\n ) {\n //remove magic comment\n first_node.node.leadingComments.splice(0, 1);\n }\n for (const template_import of import_bucket) {\n for (let i = 0, len = template_import.node.specifiers.length; i < len; ++i) {\n const specifier = template_import.node.specifiers[i];\n if (specifier.type === 'ImportDefaultSpecifier') {\n importUtil.import(path, template_import.node.source.value, 'default', specifier.local.name);\n } else if (specifier.type === 'ImportSpecifier') {\n importUtil.import(path, template_import.node.source.value, specifier.local.name);\n }\n }\n }\n },\n },\n ImportDeclaration(import_declaration: NodePath<t.ImportDeclaration>) {\n if (import_declaration.node.source.value.indexOf('@ember/component/template-only') !== -1) {\n import_declaration.remove();\n }\n },\n ExportDefaultDeclaration(path: NodePath<t.ExportDefaultDeclaration>) {\n path.traverse({\n ClassBody(path) {\n const classbody_nodes = path.get('body');\n //add magic string to be replaces with the contents of the template tag\n classbody_nodes[classbody_nodes.length - 1].addComment('trailing', magic_string, false);\n },\n });\n },\n },\n };\n },\n ],\n })!.code!.replace(`/*${magic_string}*/`, transformed_template_value);\n if (is_template_only) {\n // because we can't inject a comment as the default export\n // we replace the known exported string\n src = src.replace('templateOnlyComponent()', transformed_template_value);\n }\n\n const dryRun = this.options.dryRun ? '--dry-run' : '';\n // work out original file path in app tree\n const app_relative_path = join('app', relative(tmp_path, current_file));\n const new_file_path = app_relative_path.slice(0, -4) + '.gjs';\n\n // write glimmer file out\n if (this.options.dryRun) {\n console.log('Write new file', new_file_path, src);\n } else {\n writeFileSync(join(process.cwd(), new_file_path), src, { flag: 'wx+' });\n }\n\n // git rm old files (js/ts if exists + hbs)\n let rm_hbs = await execute(`git rm ${app_relative_path} ${dryRun}`, {\n pwd: process.cwd(),\n });\n console.log(rm_hbs.output);\n\n if (!is_template_only) {\n // remove backing class only if it's not a template only component\n // resolve repative path to rewritten-app\n const app_relative_path = join('app', relative(tmp_path, backing_class_filename));\n let rm_js = await execute(`git rm ${app_relative_path} ${dryRun}`, {\n pwd: process.cwd(),\n });\n\n console.log(rm_js.output);\n }\n }\n }\n }\n}\n\nasync function execute(\n shellCommand: string,\n opts?: { env?: Record<string, string>; pwd?: string }\n): Promise<{\n exitCode: number;\n stderr: string;\n stdout: string;\n output: string;\n}> {\n let env: Record<string, string | undefined> | undefined;\n if (opts?.env) {\n env = { ...process.env, ...opts.env };\n }\n let child = spawn(shellCommand, {\n stdio: ['inherit', 'pipe', 'pipe'],\n cwd: opts?.pwd,\n shell: true,\n env,\n });\n let stderrBuffer: string[] = [];\n let stdoutBuffer: string[] = [];\n let combinedBuffer: string[] = [];\n child.stderr.on('data', data => {\n stderrBuffer.push(data);\n combinedBuffer.push(data);\n });\n child.stdout.on('data', data => {\n stdoutBuffer.push(data);\n combinedBuffer.push(data);\n });\n return new Promise(resolve => {\n child.on('close', (exitCode: number) => {\n resolve({\n exitCode,\n get stdout() {\n return stdoutBuffer.join('');\n },\n get stderr() {\n return stderrBuffer.join('');\n },\n get output() {\n return combinedBuffer.join('');\n },\n });\n });\n });\n}\n"]}
1
+ {"version":3,"file":"template-tag-codemod.js","sourceRoot":"","sources":["template-tag-codemod.ts"],"names":[],"mappings":"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","sourcesContent":["import { default as compatBuild } from './default-pipeline';\nimport type { EmberAppInstance } from '@embroider/core';\nimport type { Node, InputNode } from 'broccoli-node-api';\nimport { join, relative, resolve, extname } from 'path';\nimport type { types as t } from '@babel/core';\nimport type { NodePath } from '@babel/traverse';\nimport { statSync, readdirSync, readFileSync, writeFileSync } from 'fs';\nimport Plugin from 'broccoli-plugin';\nimport { transformSync } from '@babel/core';\nimport { hbsToJS, ResolverLoader } from '@embroider/core';\nimport ResolverTransform, { type ExternalNameHint } from './resolver-transform';\nimport { spawn } from 'child_process';\nimport { locateEmbroiderWorkingDir } from '@embroider/core';\n\nexport interface TemplateTagCodemodOptions {\n shouldTransformPath: (outputPath: string) => boolean;\n nameHint: ExternalNameHint;\n dryRun: boolean;\n}\n\nexport default function templateTagCodemod(\n emberApp: EmberAppInstance,\n {\n shouldTransformPath = (() => true) as TemplateTagCodemodOptions['shouldTransformPath'],\n nameHint = (path => {\n return path\n .split('/')\n .map(part =>\n part\n .split('-')\n // capitalize first letter\n .map(inner_part => inner_part.charAt(0).toUpperCase() + inner_part.slice(1))\n .join('')\n )\n .join('_');\n }) as TemplateTagCodemodOptions['nameHint'],\n dryRun = false,\n } = {}\n): Node {\n return new TemplateTagCodemodPlugin(\n [\n compatBuild(emberApp, undefined, {\n staticAddonTrees: true,\n staticAddonTestSupportTrees: true,\n staticComponents: true,\n staticHelpers: true,\n staticModifiers: true,\n staticEmberSource: true,\n amdCompatibility: {\n es: [],\n },\n }),\n ],\n { shouldTransformPath, nameHint, dryRun }\n );\n}\n\nconst TEMPLATE_ONLY_MARKER = `import templateOnlyComponent from '@ember/component/template-only';`;\nconst TEMPLATE_COLOCATION_MARKER = /\\/\\* import __COLOCATED_TEMPLATE__ from (.*) \\*\\//;\n\nclass TemplateTagCodemodPlugin extends Plugin {\n constructor(inputNodes: InputNode[], readonly options: TemplateTagCodemodOptions) {\n super(inputNodes, {\n name: 'TemplateTagCodemodPlugin',\n });\n }\n async build() {\n function* walkSync(dir: string): Generator<string> {\n const files = readdirSync(dir);\n\n for (const file of files) {\n const pathToFile = join(dir, file);\n const isDirectory = statSync(pathToFile).isDirectory();\n if (isDirectory) {\n yield* walkSync(pathToFile);\n } else {\n yield pathToFile;\n }\n }\n }\n this.inputPaths[0];\n const tmp_path = readFileSync(this.inputPaths[0] + '/.stage2-output').toLocaleString();\n const compatPattern = /#embroider_compat\\/(?<type>[^\\/]+)\\/(?<rest>.*)/;\n const resolver = new ResolverLoader(process.cwd()).resolver;\n const hbs_file_test = /[\\\\/]rewritten-app[\\\\/]components[\\\\/].*\\.hbs$/;\n // locate ember-source for the host app so we know which version to insert builtIns for\n const emberSourceEntrypoint = require.resolve('ember-source', { paths: [process.cwd()] });\n const emberVersion = JSON.parse(readFileSync(join(emberSourceEntrypoint, '../../package.json')).toString()).version;\n\n const ember_template_compiler = resolver.nodeResolve(\n 'ember-source/vendor/ember/ember-template-compiler',\n resolve(locateEmbroiderWorkingDir(process.cwd()), 'rewritten-app', 'package.json')\n );\n if (ember_template_compiler.type === 'not_found') {\n throw 'This will not ever be true';\n }\n\n const embroider_compat_path = require.resolve('@embroider/compat', { paths: [process.cwd()] });\n const babel_plugin_ember_template_compilation = require.resolve('babel-plugin-ember-template-compilation', {\n paths: [embroider_compat_path],\n });\n const babel_plugin_syntax_decorators = require.resolve('@babel/plugin-syntax-decorators', {\n paths: [embroider_compat_path],\n });\n const babel_plugin_syntax_typescript = require.resolve('@babel/plugin-syntax-typescript', {\n paths: [embroider_compat_path],\n });\n const resolver_transform = ResolverTransform({\n appRoot: process.cwd(),\n emberVersion: emberVersion,\n externalNameHint: this.options.nameHint,\n });\n\n for await (const current_file of walkSync(tmp_path)) {\n if (hbs_file_test.test(current_file) && this.options.shouldTransformPath(current_file)) {\n const template_file_src = readFileSync(current_file).toLocaleString();\n\n // run the template transformations using embroider resolver information\n // to replace template values with js import syntax used in g(j/t)s\n let transformed_source =\n transformSync(hbsToJS(template_file_src), {\n plugins: [\n [\n babel_plugin_ember_template_compilation,\n {\n compilerPath: ember_template_compiler.filename,\n transforms: [resolver_transform],\n targetFormat: 'hbs',\n },\n ],\n ],\n filename: current_file,\n })?.code ?? '';\n\n // using transformSync to parse and traverse in one go\n // we're only extracting the transformed template information from previous step\n // and preserving it for later assembly in the backing class\n const import_bucket: NodePath<t.ImportDeclaration>[] = [];\n let template_tag_value = '';\n transformSync(transformed_source, {\n plugins: [\n function template_tag_extractor(): unknown {\n return {\n visitor: {\n ImportDeclaration(import_declaration: NodePath<t.ImportDeclaration>) {\n const extractor = import_declaration.node.source.value.match(compatPattern);\n if (extractor) {\n const result = resolver.nodeResolve(extractor[0], current_file);\n if (result.type === 'real') {\n // find package there the resolver is pointing\n const owner_package = resolver.packageCache.ownerOfFile(result.filename);\n let relative_import_path = relative(owner_package!.root, result.filename);\n // for addons strip off appPublicationDir from relative path\n // we do this on app files as well as they don't contain the\n // path that we strip off\n // this makes sure that ambiguous imports get properly attributed\n relative_import_path = relative_import_path.replace('_app_/', '');\n // remove the extension to match what a developer would normally write\n relative_import_path = relative_import_path.slice(0, -extname(relative_import_path).length);\n\n // change import path to real one\n import_declaration.node.source.value = owner_package!.name + '/' + relative_import_path;\n import_bucket.push(import_declaration);\n }\n } else if (import_declaration.node.source.value.indexOf('@ember/template-compilation') === -1) {\n import_bucket.push(import_declaration);\n }\n },\n CallExpression(path: NodePath<t.CallExpression>) {\n // reverse of hbs to js\n // extract the template string to put into template tag in backing class\n if (\n 'name' in path.node.callee &&\n path.node.callee.name === 'precompileTemplate' &&\n path.node.arguments &&\n 'value' in path.node.arguments[0]\n ) {\n template_tag_value = `<template>\\n\\t${path.node.arguments[0].value}\\n</template>`;\n }\n },\n },\n };\n },\n ],\n });\n\n //find backing class\n const backing_class_resolution = resolver.nodeResolve(\n '#embroider_compat/' + relative(tmp_path, current_file).replace(/[\\\\]/g, '/').slice(0, -4),\n tmp_path\n );\n\n const backing_class_filename = 'filename' in backing_class_resolution ? backing_class_resolution.filename : '';\n // this can be either a generated js file in case of template only components\n // the js or ts file depending on what the app is configured\n const backing_class_src = readFileSync(backing_class_filename).toString();\n\n const is_typescript = extname(backing_class_filename) === '.ts';\n\n let insert_imports_byte_count = null;\n let insert_template_byte_count = null;\n\n const is_template_only = backing_class_src.indexOf(TEMPLATE_ONLY_MARKER) !== -1;\n\n // we parse the backing class to find the insert points for imports and template\n transformSync(backing_class_src, {\n plugins: [\n [\n is_typescript ? babel_plugin_syntax_typescript : babel_plugin_syntax_decorators,\n { decoratorsBeforeExport: true },\n ],\n function glimmer_syntax_creator(/* babel */): unknown {\n return {\n name: 'test',\n visitor: {\n ImportDeclaration(import_declaration: NodePath<t.ImportDeclaration>) {\n insert_imports_byte_count = import_declaration.node.end;\n },\n ExportDefaultDeclaration(path: NodePath<t.ExportDefaultDeclaration>) {\n // convention is that we have a default export for each component\n // we look for the closing bracket of the class body\n path.traverse({\n ClassBody(path) {\n // we substract 1 to find the byte right before the final closing bracket `}`\n // this is the default insert point for template tag though it could live anywhere inside the class body\n // possible future point to add option for putting template first thing in class\n insert_template_byte_count = path.node.end ? path.node.end - 1 : 0;\n },\n });\n },\n },\n };\n },\n ],\n });\n\n // list of imports needed by the previous hbs template extracted in second step\n const hbs_template_required_imports = import_bucket.join('\\n');\n\n // we extracted all we needed from transformed_source so we switch to the second phase\n // transforming the backing class into what will be our final output\n transformed_source = backing_class_src;\n if (is_template_only) {\n // because we can't inject a comment as the default export\n // we replace the known exported string\n transformed_source = transformed_source.replace('templateOnlyComponent()', template_tag_value);\n // we clean known markers from generated files\n transformed_source = transformed_source.replace(TEMPLATE_ONLY_MARKER, hbs_template_required_imports);\n transformed_source = transformed_source.replace(TEMPLATE_COLOCATION_MARKER, '');\n } else {\n // we modify the source from end to start in order to keep our byte counts valid through the transforms\n if (insert_template_byte_count) {\n // first we split the backing class at the byte count we found during backing class parsing\n // then concat the string back together adding the transformed template in the middle\n transformed_source =\n transformed_source.substring(0, insert_template_byte_count) +\n '\\n' +\n template_tag_value +\n '\\n' +\n transformed_source.substring(insert_template_byte_count, transformed_source.length);\n }\n if (insert_imports_byte_count) {\n // first we split the backing class at the byte count we found during backing class parsing\n // then concat the string back together adding the transformed template in the middle\n transformed_source =\n transformed_source.substring(0, insert_imports_byte_count) +\n '\\n' +\n hbs_template_required_imports +\n '\\n' +\n transformed_source.substring(insert_imports_byte_count, transformed_source.length);\n }\n transformed_source = transformed_source.replace(TEMPLATE_COLOCATION_MARKER, '');\n }\n\n const dryRun = this.options.dryRun ? '--dry-run' : '';\n // work out original file path in app tree\n const app_relative_path = join('app', relative(tmp_path, current_file));\n const new_file_path = app_relative_path.slice(0, -4) + (is_typescript ? '.gts' : '.gjs');\n\n // write glimmer file out\n if (this.options.dryRun) {\n console.log('Write new file', new_file_path, transformed_source);\n } else {\n writeFileSync(join(process.cwd(), new_file_path), transformed_source, { flag: 'wx+' });\n }\n\n // git rm old files (js/ts if exists + hbs)\n let rm_hbs = await execute(`git rm ${app_relative_path} ${dryRun}`, {\n pwd: process.cwd(),\n });\n console.log(rm_hbs.output);\n\n if (!is_template_only) {\n // remove backing class only if it's not a template only component\n // resolve relative path to rewritten-app\n const app_relative_path = join('app', relative(tmp_path, backing_class_filename));\n let rm_js = await execute(`git rm ${app_relative_path} ${dryRun}`, {\n pwd: process.cwd(),\n });\n\n console.log(rm_js.output);\n }\n }\n }\n }\n}\n\nasync function execute(\n shellCommand: string,\n opts?: { env?: Record<string, string>; pwd?: string }\n): Promise<{\n exitCode: number;\n stderr: string;\n stdout: string;\n output: string;\n}> {\n let env: Record<string, string | undefined> | undefined;\n if (opts?.env) {\n env = { ...process.env, ...opts.env };\n }\n let child = spawn(shellCommand, {\n stdio: ['inherit', 'pipe', 'pipe'],\n cwd: opts?.pwd,\n shell: true,\n env,\n });\n let stderrBuffer: string[] = [];\n let stdoutBuffer: string[] = [];\n let combinedBuffer: string[] = [];\n child.stderr.on('data', data => {\n stderrBuffer.push(data);\n combinedBuffer.push(data);\n });\n child.stdout.on('data', data => {\n stdoutBuffer.push(data);\n combinedBuffer.push(data);\n });\n return new Promise(resolve => {\n child.on('close', (exitCode: number) => {\n resolve({\n exitCode,\n get stdout() {\n return stdoutBuffer.join('');\n },\n get stderr() {\n return stderrBuffer.join('');\n },\n get output() {\n return combinedBuffer.join('');\n },\n });\n });\n });\n}\n"]}
package/src/v1-addon.js CHANGED
@@ -106,9 +106,10 @@ class V1Addon {
106
106
  // this is only defined when there are custom AST transforms that need it
107
107
  get templateCompilerBabelPlugin() {
108
108
  let plugins = (0, prepare_htmlbars_ast_plugins_1.default)(this.addonInstance.registry);
109
+ let hasTemplateTag = this.addonInstance.addons.find((a) => a.name === 'ember-template-imports');
109
110
  // our macros don't run here in stage1
110
111
  plugins = plugins.filter((p) => !(0, node_1.isEmbroiderMacrosPlugin)(p));
111
- if (plugins.length > 0) {
112
+ if (plugins.length > 0 || hasTemplateTag) {
112
113
  let compilerPath = require.resolve('ember-source/dist/ember-template-compiler.js', {
113
114
  paths: [(0, core_1.findTopmostAddon)(this.addonInstance).parent.root],
114
115
  });
@@ -190,6 +191,34 @@ class V1Addon {
190
191
  // the older inline template compiler is present
191
192
  return true;
192
193
  }
194
+ if (this.addonInstance.addons.find((a) => a.name === 'ember-template-imports')) {
195
+ /**
196
+ * Stage1 will always run custom broccoli preprocessors. So that's enough to convert:
197
+ *
198
+ * import Thing from './thing';
199
+ * <template><Thing/></template>
200
+ * to
201
+ *
202
+ * import Thing from './thing';
203
+ * import { template } from '@ember/template-compiler';
204
+ * export default template("Thing", {
205
+ * eval: function() { return eval(arguments[0]) } })
206
+ * });
207
+ * This is really all we need to do at stage1, since this is now valid Javascript that could appear in a v2 addon.
208
+ *
209
+ * But if the addon is also using TS, we also need to run the typescript transform before it will be valid JS. And if the typescript transform was being truly correct it would not try to delete the import because the eval can see the imported binding. That's why we have an eval. It's a standards-compliant want of gaining access to everything in scope.
210
+ *
211
+ * Normally we only use babel-plugin-ember-template-compilation in stage1 to run custom AST transforms. Since there are none in the addon, we don't add it. The fix here is helping because there is a new reason to add it. It will further convert the above example to:
212
+ *
213
+ * import Thing from './thing';
214
+ * import { template } from '@ember/template-compiler';
215
+ * export default template("Thing", {
216
+ * scope: () => ({ Thing })
217
+ * });
218
+ * which typescript then respects.
219
+ */
220
+ return true;
221
+ }
193
222
  if (this.addonInstance.addons.find((a) => a.name === 'ember-cli-htmlbars' && semver_1.default.satisfies(semver_1.default.coerce(a.pkg.version) || a.pkg.version, '>4.0.0'))) {
194
223
  // a version of ember-cli-htmlbars that natively supports inline hbs is present
195
224
  return true;