juisy 2.0.0-beta.8 → 2.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (31) hide show
  1. package/LICENSE +661 -0
  2. package/bin/cli/cmds/index.js +1 -3
  3. package/bin/cli/cmds/public/print-globals.js +1 -1
  4. package/bin/cli/index.js +1 -1
  5. package/dist/cli/CLIFactory.d.ts +2 -0
  6. package/dist/cli/Command.d.ts +46 -6
  7. package/dist/cli/GlobalSettings.schema.json +1 -1
  8. package/dist/cli/InterfaceUtils.d.ts +17 -13
  9. package/dist/cli/OutputUtils.d.ts +1 -12
  10. package/dist/cli/index.d.ts +1 -1
  11. package/dist/cli/index.js +514 -466
  12. package/dist/cli/plugins/register-bump-version-command/cmds/index.d.ts +14 -2
  13. package/dist/cli/plugins/register-lint-commands/augment.d.ts +2 -3
  14. package/dist/cli/plugins/register-lint-commands/settings.d.ts +1 -1
  15. package/dist/cli/plugins/register-release-command/augment.d.ts +2 -2
  16. package/dist/cli/types.d.ts +6 -2
  17. package/dist/cli/utils.d.ts +1 -10
  18. package/dist/eject.d.ts +2 -0
  19. package/dist/index.js +8 -3
  20. package/dist/project-globals.d.ts +7 -26
  21. package/dist/templater/index.js +11 -11
  22. package/dist/vite/plugins/inject-css-variables/index.d.ts +23 -0
  23. package/dist/vite/plugins/inject-css-variables/index.js +60 -0
  24. package/dist/vite/plugins/inject-project-globals/index.d.ts +19 -0
  25. package/dist/vite/plugins/inject-project-globals/index.js +58 -0
  26. package/package.json +198 -183
  27. package/bin/cli/cmds/private/docs/lint.js +0 -42
  28. package/bin/cli/cmds/public/squeeze.js +0 -269
  29. package/dist/cli/plugins/command-handler-injections/augment.d.ts +0 -29
  30. package/dist/cli/plugins/command-handler-injections/command-visitors/command-handler-injections.d.ts +0 -10
  31. package/dist/cli/plugins/command-handler-injections/index.d.ts +0 -3
@@ -1,3 +1,15 @@
1
1
  import { Command } from '../../../Command';
2
- declare const _default: Command;
3
- export default _default;
2
+ import { CLIEngine, CommandHandlerArgs } from '../../../types';
3
+ export default class BumpVersionCommand extends Command {
4
+ command: string;
5
+ describe: string;
6
+ meta: {
7
+ private: boolean;
8
+ };
9
+ builder(cli: CLIEngine): CLIEngine;
10
+ handler(argv: CommandHandlerArgs<{
11
+ preid: string;
12
+ file: string;
13
+ indent: number;
14
+ }>): Promise<void>;
15
+ }
@@ -1,5 +1,6 @@
1
1
  import { default as ESLint } from 'eslint';
2
2
  import { default as LintStaged } from 'lint-staged';
3
+ import { UserConfig as CommitLintConfig } from '@commitlint/types';
3
4
  import { SettingsLintMarkdown } from './types';
4
5
  declare module '../../types' {
5
6
  interface GlobalSettings {
@@ -14,10 +15,8 @@ declare module '../../types' {
14
15
  default?: UserProvidedConfigSetting<ESLint.Linter.LegacyConfig | ESLint.Linter.Config | ESLint.Linter.Config[]>;
15
16
  /**
16
17
  * Configuration for commitlint
17
- * See also: https://github.com/conventional-changelog/commitlint
18
- * Default: `{ extends: [ '@commitlint/config-conventional' ] }`
19
18
  */
20
- commit?: UserProvidedConfigSetting<{}>;
19
+ commit?: UserProvidedConfigSetting<CommitLintConfig>;
21
20
  /**
22
21
  * Configuration for markdownlint (markdownlint-cli2)
23
22
  */
@@ -5,7 +5,7 @@ import { SettingsLintMarkdown } from './types';
5
5
  */
6
6
  export default function resolveSettings(settings?: Required<GlobalSettings>['lint']): {
7
7
  default?: import('../..').UserProvidedConfigSetting<import("eslint").Linter.LegacyConfig | import("eslint").Linter.Config | import("eslint").Linter.Config[]>;
8
- commit?: import('../..').UserProvidedConfigSetting<{}>;
8
+ commit?: import('../..').UserProvidedConfigSetting<import('@commitlint/types').UserConfig>;
9
9
  markdown?: SettingsLintMarkdown;
10
10
  staged?: import('../..').UserProvidedConfigSetting<import('lint-staged').Config>;
11
11
  };
@@ -1,9 +1,9 @@
1
- import { default as ReleaseIt } from 'release-it';
1
+ import { Config as ReleaseItConfig } from 'release-it';
2
2
  declare module '../../types' {
3
3
  interface GlobalSettings {
4
4
  /**
5
5
  * Release configuration
6
6
  */
7
- release?: UserProvidedConfigSetting<ReleaseIt.Config>;
7
+ release?: UserProvidedConfigSetting<ReleaseItConfig>;
8
8
  }
9
9
  }
@@ -1,4 +1,4 @@
1
- import { Argv, CommandModule as YargsCommandModule, MiddlewareFunction } from 'yargs';
1
+ import { Argv, ArgumentsCamelCase, CommandModule as YargsCommandModule, MiddlewareFunction } from 'yargs';
2
2
  import { Command } from './Command';
3
3
  /**
4
4
  * An object whose all properties have the same type.
@@ -110,11 +110,15 @@ export interface CommandObject {
110
110
  /** string used as the description for the command in help text, use `false` for a hidden command */
111
111
  describe: YargsCommandModule['describe'];
112
112
  /** a function which will be passed the parsed argv. */
113
- handler: CommandHandler;
113
+ handler: YargsCommandModule['handler'];
114
114
  /** object declaring the options the command accepts, or a function accepting and returning a yargs instance */
115
115
  builder: (cli: CLIEngine) => CLIEngine | PromiseLike<CLIEngine>;
116
116
  middlewares?: MiddlewareFunction[];
117
117
  }
118
+ /**
119
+ * @group Types
120
+ */
121
+ export type CommandHandlerArgs<T = {}> = ArgumentsCamelCase<T>;
118
122
  /**
119
123
  * @group Types
120
124
  */
@@ -1,4 +1,4 @@
1
- import { CommandObject, CLIEngine, CommandHandler } from './types';
1
+ import { CommandObject, CLIEngine } from './types';
2
2
  /**
3
3
  * @ignore
4
4
  * @param target - The target builder
@@ -8,12 +8,3 @@ import { CommandObject, CLIEngine, CommandHandler } from './types';
8
8
  * that will be called before target. Target can be undefined
9
9
  */
10
10
  export declare function wrapCommandBuilder(target: CommandObject['builder'], builder: (cli: CLIEngine) => CLIEngine): (cli: CLIEngine) => CLIEngine | PromiseLike<CLIEngine>;
11
- /**
12
- * @ignore
13
- * @param target - The target handler
14
- * @param handler - The wrap
15
- * @description
16
- * Wrap command handler (target) with handler passed as second parameter
17
- * that will be called before target. Target can be undefined
18
- */
19
- export declare function wrapCommandhandler(target: CommandHandler, handler: CommandHandler): CommandHandler;
package/dist/eject.d.ts CHANGED
@@ -7,6 +7,7 @@ export type EjectOptions = {
7
7
  targetDir?: string;
8
8
  logLevel?: LogLevelDesc;
9
9
  ignoreFiles?: string[];
10
+ templateData?: Record<string, any> | ((identifier: string) => Record<string, any> | Promise<Record<string, any>>);
10
11
  processor?: (content: string, identifier: string) => string | Promise<string>;
11
12
  onError?: (identifier: string, fromPath: string, toPath: string, err: Error) => void | Promise<void>;
12
13
  onSuccess?: (identifier: string, fromPath: string, toPath: string) => void | Promise<void>;
@@ -17,6 +18,7 @@ export type EjectOptions = {
17
18
  * @param options - The options object
18
19
  * @param options.force - If true, the target files will be overwritten
19
20
  * @param options.targetDir - The target directory absolute path
21
+ * @param options.templateData - The template data object
20
22
  * @param options.processor - The template file content processor function.
21
23
  * Takes content as unique argument and must return string or a Promise that resolves a string
22
24
  * @param options.onError - The callback if an error occurs
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * juisy v2.0.0-beta.8
2
+ * juisy v2.0.1
3
3
  * Copyright © 2022-Present Hervé Perchec
4
4
  */
5
5
 
@@ -123,6 +123,7 @@ async function isFile(filePath) {
123
123
  async function ejectFile(from, to, identifier = null, options) {
124
124
  identifier = identifier || path.basename(from);
125
125
  const force = options?.force || false;
126
+ const templateData = options?.templateData;
126
127
  const processor = options?.processor || (async (str, _identifier) => str);
127
128
  const onError = options?.onError || (async (_identifier, fromPath, toPath, err) => {
128
129
  throw err;
@@ -134,7 +135,7 @@ async function ejectFile(from, to, identifier = null, options) {
134
135
  const write = await fs.exists(to) ? force : true;
135
136
  if (write) {
136
137
  const template = await fs.readFile(from, { encoding: "utf8" });
137
- const content = await templater.render(template);
138
+ const content = await templater.render(template, typeof templateData === "function" ? await templateData(identifier) : templateData);
138
139
  const processedContent = await processor(content, identifier);
139
140
  await fs.ensureFile(to);
140
141
  await fs.writeFile(to, processedContent);
@@ -160,6 +161,8 @@ async function eject(templateDir, identifier, options) {
160
161
  if (await isFile(fullPath)) {
161
162
  if (!ignoreFiles.includes(identifier)) {
162
163
  await ejectFile(fullPath, path.resolve(targetDir, identifier), identifier, {
164
+ force: options?.force,
165
+ templateData: options?.templateData,
163
166
  processor: options?.processor,
164
167
  onSuccess: options?.onSuccess,
165
168
  onError: options?.onError
@@ -171,6 +174,8 @@ async function eject(templateDir, identifier, options) {
171
174
  const fullTemplateFilePath = path.resolve(templateDir, fileRelativePath);
172
175
  if (!ignoreFiles.includes(fileRelativePath)) {
173
176
  await ejectFile(fullTemplateFilePath, path.resolve(targetDir, fileRelativePath), fileRelativePath, {
177
+ force: options?.force,
178
+ templateData: options?.templateData,
174
179
  processor: options?.processor,
175
180
  onSuccess: options?.onSuccess,
176
181
  onError: options?.onError
@@ -241,7 +246,7 @@ function defineGlobals(config, builder) {
241
246
  };
242
247
  return deepmerge(GLOBALS, JSON.parse(JSON.stringify(builder(ctx))));
243
248
  }
244
- async function getProjectGlobals(filePath = "./globals.config.js") {
249
+ async function getProjectGlobals(filePath = "./project.globals.js") {
245
250
  return (await import(pathToFileURL(path.resolve(filePath)))).default;
246
251
  }
247
252
 
@@ -3,7 +3,7 @@ import { IPackageJson as PackageJson, IAuthor as PackageJsonAuthor, IRepository
3
3
  /**
4
4
  * @group Types
5
5
  */
6
- export type ProjectGlobals = Record<string, string | Record<string, unknown> | undefined> & {
6
+ export type DefaultProjectGlobals = {
7
7
  ENV: NodeJS.ProcessEnv;
8
8
  PACKAGE: {
9
9
  NAME: PackageJson['name'];
@@ -29,44 +29,25 @@ export type DotenvOptions = Omit<DotenvConfigOptions, 'processEnv'>;
29
29
  /**
30
30
  * @group Types
31
31
  */
32
- export type DefineGlobalsBuilder = (ctx: {
32
+ export type DefineGlobalsBuilder<T extends Record<string, any>> = (ctx: {
33
33
  env: NodeJS.ProcessEnv;
34
34
  pkg: PackageJson;
35
- }) => ProjectGlobals;
35
+ }) => T;
36
36
  /**
37
37
  * Define project globals
38
38
  * @param config - The config object
39
39
  * @param builder - The builder function
40
40
  * @returns The computed globals object
41
41
  */
42
- export declare function defineGlobals(config: {
42
+ export declare function defineGlobals<CustomGlobals extends Record<string, any>>(config: {
43
43
  env?: {
44
44
  map?: string[];
45
45
  dotenvOptions?: DotenvOptions;
46
46
  };
47
- }, builder: DefineGlobalsBuilder): {
48
- [x: string]: /*elided*/ any;
49
- ENV: NodeJS.ProcessEnv;
50
- PACKAGE: {
51
- NAME: PackageJson["name"];
52
- URL: PackageJson["url"];
53
- };
54
- VERSION: string;
55
- AUTHOR: {
56
- EMAIL: PackageJsonAuthor["email"];
57
- NAME: PackageJsonAuthor["name"];
58
- URL: PackageJsonAuthor["url"];
59
- };
60
- REPOSITORY: {
61
- TYPE: PackageJsonRepository["type"];
62
- URL: PackageJsonRepository["url"];
63
- };
64
- ISSUES_URL: string;
65
- HOMEPAGE: string;
66
- };
47
+ }, builder: DefineGlobalsBuilder<CustomGlobals>): DefaultProjectGlobals & CustomGlobals;
67
48
  /**
68
49
  * Get project globals
69
- * @param filePath - The filePath. Default is `'./globals.config.js'`
50
+ * @param filePath - The filePath. Default is `'./project.globals.js'`
70
51
  * @returns The resolved project globals object
71
52
  */
72
- export declare function getProjectGlobals(filePath?: string): Promise<ProjectGlobals>;
53
+ export declare function getProjectGlobals(filePath?: string): Promise<DefaultProjectGlobals & Record<string, string | Record<string, unknown> | undefined>>;
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * juisy v2.0.0-beta.8
2
+ * juisy v2.0.1
3
3
  * Copyright © 2022-Present Hervé Perchec
4
4
  */
5
5
 
@@ -28,7 +28,7 @@ class Templater {
28
28
  this.methodsMap.compile = async (template) => {
29
29
  return handlebars.compile(template, options.engineOptions);
30
30
  };
31
- this.methodsMap.render = async (template, data = undefined, opts = undefined) => {
31
+ this.methodsMap.render = async (template, data = void 0, opts = void 0) => {
32
32
  return this.methodsMap.compile(template).template(data);
33
33
  };
34
34
  break;
@@ -37,7 +37,7 @@ class Templater {
37
37
  this.methodsMap.compile = async (template) => {
38
38
  return ejs.compile(template, options.engineOptions);
39
39
  };
40
- this.methodsMap.render = async (template, data = undefined, opts) => {
40
+ this.methodsMap.render = async (template, data = void 0, opts) => {
41
41
  return ejs.render(template, data, {
42
42
  ...options.engineOptions,
43
43
  ...opts || {}
@@ -66,7 +66,7 @@ class Templater {
66
66
  /**
67
67
  * Renders a template with the given context.
68
68
  */
69
- async render(template, data = undefined, options = undefined) {
69
+ async render(template, data = void 0, options = void 0) {
70
70
  const mergedData = { ...this.defaultData, ...data || {} };
71
71
  return await this.methodsMap.render(template, mergedData, options);
72
72
  }
@@ -99,8 +99,8 @@ class MarkdownTemplater extends Templater {
99
99
  use: [
100
100
  ...options.use || []
101
101
  ],
102
- toc: options.toc === true ? defaultRemarkTocOptions : options.toc !== undefined ? options.toc : defaultRemarkTocOptions,
103
- frontmatter: options.frontmatter === true ? defaultRemarkFrontmatterOptions : options.frontmatter !== undefined ? options.frontmatter : defaultRemarkFrontmatterOptions
102
+ toc: options.toc === true ? defaultRemarkTocOptions : options.toc !== void 0 ? options.toc : defaultRemarkTocOptions,
103
+ frontmatter: options.frontmatter === true ? defaultRemarkFrontmatterOptions : options.frontmatter !== void 0 ? options.frontmatter : defaultRemarkFrontmatterOptions
104
104
  };
105
105
  }
106
106
  initProcessor() {
@@ -116,7 +116,7 @@ class MarkdownTemplater extends Templater {
116
116
  /**
117
117
  * Renders a template with the given context.
118
118
  */
119
- async render(template, data = undefined, options = undefined) {
119
+ async render(template, data = void 0, options = void 0) {
120
120
  const content = await super.render(template, data, options);
121
121
  return (await this.processor.process(content)).toString();
122
122
  }
@@ -184,7 +184,7 @@ class ReadmeTemplater {
184
184
  }, data), options.data);
185
185
  let template = await fs.readFile(processedConfig.templatePath, { encoding: "utf8" });
186
186
  if (processedConfig.appendAutoGenMessage) {
187
- template += "\n----\n\n*<%= $config.fileName %> - this file was auto generated with [juisy](https://www.npmjs.com/package/juisy) README templater. Don't edit it.*\n";
187
+ template += "\n----\n<!-- markdownlint-disable-next-line line-length -->\n*<%= $config.fileName %> - this file was auto generated with [juisy](https://www.npmjs.com/package/juisy) README templater. Don't edit it.*\n";
188
188
  }
189
189
  return await this.templater.render(template, ejsData, processedConfig.ejsOptions);
190
190
  }
@@ -229,9 +229,9 @@ class ReadmeTemplater {
229
229
  } else {
230
230
  result.ejsOptions = ReadmeTemplater.defaultConfig.ejsOptions;
231
231
  }
232
- result.appendAutoGenMessage = customConfig.appendAutoGenMessage !== undefined ? customConfig.appendAutoGenMessage : ReadmeTemplater.defaultConfig.appendAutoGenMessage;
233
- result.autoToc = customConfig.autoToc !== undefined ? customConfig.autoToc : ReadmeTemplater.defaultConfig.autoToc;
234
- result.slugify = customConfig.slugify !== undefined ? customConfig.slugify : ReadmeTemplater.defaultConfig.slugify;
232
+ result.appendAutoGenMessage = customConfig.appendAutoGenMessage !== void 0 ? customConfig.appendAutoGenMessage : ReadmeTemplater.defaultConfig.appendAutoGenMessage;
233
+ result.autoToc = customConfig.autoToc !== void 0 ? customConfig.autoToc : ReadmeTemplater.defaultConfig.autoToc;
234
+ result.slugify = customConfig.slugify !== void 0 ? customConfig.slugify : ReadmeTemplater.defaultConfig.slugify;
235
235
  return result;
236
236
  }
237
237
  /**
@@ -0,0 +1,23 @@
1
+ import { Plugin } from 'vite';
2
+ export type Options = {
3
+ /**
4
+ * The virtual module ID
5
+ */
6
+ moduleId: string;
7
+ /**
8
+ * The CSS selector.
9
+ * @default ':root'
10
+ */
11
+ selector?: string;
12
+ /**
13
+ * The CSS variables object
14
+ */
15
+ variables: Record<string, string>;
16
+ };
17
+ /**
18
+ * Inject CSS variables via a virtual module
19
+ * @param opts - The plugin options or an array of options
20
+ * @returns {Plugin} The vite plugin function
21
+ */
22
+ export declare function injectCssVariables(optsArg?: Options | Array<Options>): Plugin;
23
+ export default injectCssVariables;
@@ -0,0 +1,60 @@
1
+ /*!
2
+ * juisy v2.0.1
3
+ * Copyright © 2022-Present Hervé Perchec
4
+ */
5
+
6
+ function injectCssVariables(optsArg = []) {
7
+ const optionsArray = optsArg instanceof Array ? optsArg : [optsArg];
8
+ const virtualModules = /* @__PURE__ */ new Map();
9
+ for (let i = 0; i < optionsArray.length; i++) {
10
+ const options = optionsArray[i];
11
+ if (!options.moduleId || options.moduleId.trim().length === 0) {
12
+ throw new Error(`Please provide a non-empty module ID in plugin options at index ${i}`);
13
+ }
14
+ if (virtualModules.has(options.moduleId)) {
15
+ throw new Error(`The module ID "${options.moduleId}" is already used. Please provide another ID`);
16
+ }
17
+ virtualModules.set(options.moduleId, options);
18
+ }
19
+ return {
20
+ name: "vite-plugin-inject-css-variables",
21
+ enforce: "pre",
22
+ resolveId(id) {
23
+ const options = virtualModules.get(id);
24
+ if (!options) {
25
+ return;
26
+ } else {
27
+ return "\0" + options.moduleId;
28
+ }
29
+ },
30
+ async load(id) {
31
+ const options = virtualModules.get(id.slice(1));
32
+ if (!id.startsWith("\0") || !options) {
33
+ return;
34
+ }
35
+ const { selector = ":root", variables } = options;
36
+ try {
37
+ if (Object.keys(variables).length === 0) {
38
+ return "";
39
+ }
40
+ for (const key in variables) {
41
+ if (typeof variables[key] === "string") {
42
+ continue;
43
+ }
44
+ }
45
+ } catch (e) {
46
+ this.error(`The variables object for module "${options.moduleId}" is malformed`);
47
+ }
48
+ let css = `${selector} {
49
+ `;
50
+ for (const key in variables) {
51
+ css += ` --${key}: ${variables[key]};
52
+ `;
53
+ }
54
+ css += "}\n";
55
+ return css;
56
+ }
57
+ };
58
+ }
59
+
60
+ export { injectCssVariables as default, injectCssVariables };
@@ -0,0 +1,19 @@
1
+ import { Plugin } from 'vite';
2
+ export type Options = {
3
+ /**
4
+ * The virtual module ID
5
+ * @default 'virtual:project.globals.js'
6
+ */
7
+ moduleId?: string;
8
+ /**
9
+ * The project globals path (relative from root folder)
10
+ */
11
+ filePath?: string;
12
+ };
13
+ /**
14
+ * Inject project globals via a virtual module
15
+ * @param opts - The plugin options or an array of options
16
+ * @returns {Plugin} The vite plugin function
17
+ */
18
+ export declare function injectProjectGlobals(options?: Options): Plugin;
19
+ export default injectProjectGlobals;
@@ -0,0 +1,58 @@
1
+ /*!
2
+ * juisy v2.0.1
3
+ * Copyright © 2022-Present Hervé Perchec
4
+ */
5
+
6
+ import { getProjectGlobals } from 'juisy';
7
+ import { OutputUtils } from 'juisy/cli';
8
+
9
+ function injectProjectGlobals(options = {}) {
10
+ const { $style } = OutputUtils;
11
+ let config;
12
+ let moduleId = "virtual:project.globals.js";
13
+ if (options.moduleId) {
14
+ if (options.moduleId.trim().length === 0) {
15
+ throw new Error("Please provide a non-empty module ID for juisy/vite-plugin-inject-project-globals");
16
+ }
17
+ moduleId = options.moduleId;
18
+ }
19
+ return {
20
+ name: "vite-plugin-inject-project-globals",
21
+ enforce: "pre",
22
+ configResolved(resolvedConfig) {
23
+ config = resolvedConfig;
24
+ },
25
+ resolveId(id) {
26
+ if (id !== moduleId) {
27
+ return;
28
+ } else {
29
+ return "\0" + moduleId;
30
+ }
31
+ },
32
+ /**
33
+ * Vite plugin `load` hook
34
+ * @param id - The requested module ID
35
+ * @returns The module content as a string
36
+ * @description
37
+ * Load the virtual module and return its content.
38
+ * If the module ID is not the one defined by the plugin, simply return null.
39
+ * Otherwise, call `getProjectGlobals` and build a js string.
40
+ */
41
+ async load(id) {
42
+ if (!id.startsWith("\0") || id.slice(1) !== moduleId) {
43
+ return;
44
+ }
45
+ const PROJECT_GLOBALS = {
46
+ ...await getProjectGlobals(options.filePath)
47
+ };
48
+ if (PROJECT_GLOBALS.ENV) {
49
+ config.logger.warn("\n[vite-plugin-inject-project-globals] " + $style.yellow("The following ENV variables are exposed:"));
50
+ config.logger.warn(JSON.stringify(PROJECT_GLOBALS.ENV));
51
+ config.logger.warn("\n");
52
+ }
53
+ return "const PROJECT_GLOBALS = " + JSON.stringify(PROJECT_GLOBALS) + "\nconst isBrowser = import.meta.env.SSR === false\nif (isBrowser) {\n if (PROJECT_GLOBALS.ENV) {\n console.warn('[vite-plugin-inject-project-globals] WARNING: some ENV variables are exposed! Be careful, do not expose sensitive data!')\n }\n}\nexport default PROJECT_GLOBALS\n";
54
+ }
55
+ };
56
+ }
57
+
58
+ export { injectProjectGlobals as default, injectProjectGlobals };