zapier-platform-cli 17.7.0 → 17.7.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.
- package/oclif.manifest.json +91 -84
- package/package.json +1 -1
- package/src/generators/index.js +18 -2
- package/src/oclif/ZapierBaseCommand.js +7 -2
- package/src/oclif/commands/invoke.js +20 -9
- package/src/oclif/commands/migrate.js +12 -11
- package/src/oclif/commands/pull.js +2 -2
- package/src/oclif/commands/scaffold.js +0 -1
- package/src/oclif/commands/validate.js +9 -0
- package/src/utils/analytics.js +1 -1
- package/src/utils/ast.js +20 -7
- package/src/utils/scaffold.js +49 -11
package/oclif.manifest.json
CHANGED
|
@@ -1157,7 +1157,7 @@
|
|
|
1157
1157
|
"pull": {
|
|
1158
1158
|
"aliases": [],
|
|
1159
1159
|
"args": {},
|
|
1160
|
-
"description": "Retrieve and update your local integration files with the latest version.\n\nThis command updates your local integration files with the latest version. You will be prompted with a confirmation dialog before continuing if there any destructive file changes.\n\nZapier may release new versions of your integration with bug fixes or new features. In the event this occurs, you will be unable to do the following until your local files are updated by running `zapier pull`:\n\n* push to the promoted version\n* promote a new version\n* migrate users from one version to another",
|
|
1160
|
+
"description": "Retrieve and update your local integration files with the promoted version (or latest version if not public).\n\nThis command updates your local integration files with the promoted version (or latest version if not public). You will be prompted with a confirmation dialog before continuing if there any destructive file changes.\n\nZapier may release new versions of your integration with bug fixes or new features. In the event this occurs, you will be unable to do the following until your local files are updated by running `zapier pull`:\n\n* push to the promoted version\n* promote a new version\n* migrate users from one version to another",
|
|
1161
1161
|
"flags": {
|
|
1162
1162
|
"debug": {
|
|
1163
1163
|
"char": "d",
|
|
@@ -1549,6 +1549,7 @@
|
|
|
1549
1549
|
"examples": [
|
|
1550
1550
|
"zapier validate",
|
|
1551
1551
|
"zapier validate --without-style",
|
|
1552
|
+
"zapier validate --skip-build",
|
|
1552
1553
|
"zapier validate --format json"
|
|
1553
1554
|
],
|
|
1554
1555
|
"flags": {
|
|
@@ -1558,6 +1559,12 @@
|
|
|
1558
1559
|
"allowNo": false,
|
|
1559
1560
|
"type": "boolean"
|
|
1560
1561
|
},
|
|
1562
|
+
"skip-build": {
|
|
1563
|
+
"description": "Skip running the _zapier-build script before validation.",
|
|
1564
|
+
"name": "skip-build",
|
|
1565
|
+
"allowNo": false,
|
|
1566
|
+
"type": "boolean"
|
|
1567
|
+
},
|
|
1561
1568
|
"debug": {
|
|
1562
1569
|
"char": "d",
|
|
1563
1570
|
"description": "Show extra debugging output.",
|
|
@@ -1900,6 +1907,88 @@
|
|
|
1900
1907
|
"list.js"
|
|
1901
1908
|
]
|
|
1902
1909
|
},
|
|
1910
|
+
"delete:integration": {
|
|
1911
|
+
"aliases": [
|
|
1912
|
+
"delete:app"
|
|
1913
|
+
],
|
|
1914
|
+
"args": {},
|
|
1915
|
+
"description": "Delete your integration (including all versions).\n\nThis only works if there are no active users or Zaps on any version. If you only want to delete certain versions, use the `zapier delete:version` command instead. It's unlikely that you'll be able to run this on an app that you've pushed publicly, since there are usually still users.",
|
|
1916
|
+
"flags": {
|
|
1917
|
+
"debug": {
|
|
1918
|
+
"char": "d",
|
|
1919
|
+
"description": "Show extra debugging output.",
|
|
1920
|
+
"name": "debug",
|
|
1921
|
+
"allowNo": false,
|
|
1922
|
+
"type": "boolean"
|
|
1923
|
+
},
|
|
1924
|
+
"invokedFromAnotherCommand": {
|
|
1925
|
+
"hidden": true,
|
|
1926
|
+
"name": "invokedFromAnotherCommand",
|
|
1927
|
+
"allowNo": false,
|
|
1928
|
+
"type": "boolean"
|
|
1929
|
+
}
|
|
1930
|
+
},
|
|
1931
|
+
"hasDynamicHelp": false,
|
|
1932
|
+
"hiddenAliases": [],
|
|
1933
|
+
"id": "delete:integration",
|
|
1934
|
+
"pluginAlias": "zapier-platform-cli",
|
|
1935
|
+
"pluginName": "zapier-platform-cli",
|
|
1936
|
+
"pluginType": "core",
|
|
1937
|
+
"strict": true,
|
|
1938
|
+
"enableJsonFlag": false,
|
|
1939
|
+
"skipValidInstallCheck": true,
|
|
1940
|
+
"isESM": false,
|
|
1941
|
+
"relativePath": [
|
|
1942
|
+
"src",
|
|
1943
|
+
"oclif",
|
|
1944
|
+
"commands",
|
|
1945
|
+
"delete",
|
|
1946
|
+
"integration.js"
|
|
1947
|
+
]
|
|
1948
|
+
},
|
|
1949
|
+
"delete:version": {
|
|
1950
|
+
"aliases": [],
|
|
1951
|
+
"args": {
|
|
1952
|
+
"version": {
|
|
1953
|
+
"description": "Specify the version to delete. It must have no users or Zaps.",
|
|
1954
|
+
"name": "version",
|
|
1955
|
+
"required": true
|
|
1956
|
+
}
|
|
1957
|
+
},
|
|
1958
|
+
"description": "Delete a specific version of your integration.\n\nThis only works if there are no users or Zaps on that version. You will probably need to have run `zapier migrate` and `zapier deprecate` before this command will work.",
|
|
1959
|
+
"flags": {
|
|
1960
|
+
"debug": {
|
|
1961
|
+
"char": "d",
|
|
1962
|
+
"description": "Show extra debugging output.",
|
|
1963
|
+
"name": "debug",
|
|
1964
|
+
"allowNo": false,
|
|
1965
|
+
"type": "boolean"
|
|
1966
|
+
},
|
|
1967
|
+
"invokedFromAnotherCommand": {
|
|
1968
|
+
"hidden": true,
|
|
1969
|
+
"name": "invokedFromAnotherCommand",
|
|
1970
|
+
"allowNo": false,
|
|
1971
|
+
"type": "boolean"
|
|
1972
|
+
}
|
|
1973
|
+
},
|
|
1974
|
+
"hasDynamicHelp": false,
|
|
1975
|
+
"hiddenAliases": [],
|
|
1976
|
+
"id": "delete:version",
|
|
1977
|
+
"pluginAlias": "zapier-platform-cli",
|
|
1978
|
+
"pluginName": "zapier-platform-cli",
|
|
1979
|
+
"pluginType": "core",
|
|
1980
|
+
"strict": true,
|
|
1981
|
+
"enableJsonFlag": false,
|
|
1982
|
+
"skipValidInstallCheck": true,
|
|
1983
|
+
"isESM": false,
|
|
1984
|
+
"relativePath": [
|
|
1985
|
+
"src",
|
|
1986
|
+
"oclif",
|
|
1987
|
+
"commands",
|
|
1988
|
+
"delete",
|
|
1989
|
+
"version.js"
|
|
1990
|
+
]
|
|
1991
|
+
},
|
|
1903
1992
|
"env:get": {
|
|
1904
1993
|
"aliases": [],
|
|
1905
1994
|
"args": {
|
|
@@ -2076,88 +2165,6 @@
|
|
|
2076
2165
|
"unset.js"
|
|
2077
2166
|
]
|
|
2078
2167
|
},
|
|
2079
|
-
"delete:integration": {
|
|
2080
|
-
"aliases": [
|
|
2081
|
-
"delete:app"
|
|
2082
|
-
],
|
|
2083
|
-
"args": {},
|
|
2084
|
-
"description": "Delete your integration (including all versions).\n\nThis only works if there are no active users or Zaps on any version. If you only want to delete certain versions, use the `zapier delete:version` command instead. It's unlikely that you'll be able to run this on an app that you've pushed publicly, since there are usually still users.",
|
|
2085
|
-
"flags": {
|
|
2086
|
-
"debug": {
|
|
2087
|
-
"char": "d",
|
|
2088
|
-
"description": "Show extra debugging output.",
|
|
2089
|
-
"name": "debug",
|
|
2090
|
-
"allowNo": false,
|
|
2091
|
-
"type": "boolean"
|
|
2092
|
-
},
|
|
2093
|
-
"invokedFromAnotherCommand": {
|
|
2094
|
-
"hidden": true,
|
|
2095
|
-
"name": "invokedFromAnotherCommand",
|
|
2096
|
-
"allowNo": false,
|
|
2097
|
-
"type": "boolean"
|
|
2098
|
-
}
|
|
2099
|
-
},
|
|
2100
|
-
"hasDynamicHelp": false,
|
|
2101
|
-
"hiddenAliases": [],
|
|
2102
|
-
"id": "delete:integration",
|
|
2103
|
-
"pluginAlias": "zapier-platform-cli",
|
|
2104
|
-
"pluginName": "zapier-platform-cli",
|
|
2105
|
-
"pluginType": "core",
|
|
2106
|
-
"strict": true,
|
|
2107
|
-
"enableJsonFlag": false,
|
|
2108
|
-
"skipValidInstallCheck": true,
|
|
2109
|
-
"isESM": false,
|
|
2110
|
-
"relativePath": [
|
|
2111
|
-
"src",
|
|
2112
|
-
"oclif",
|
|
2113
|
-
"commands",
|
|
2114
|
-
"delete",
|
|
2115
|
-
"integration.js"
|
|
2116
|
-
]
|
|
2117
|
-
},
|
|
2118
|
-
"delete:version": {
|
|
2119
|
-
"aliases": [],
|
|
2120
|
-
"args": {
|
|
2121
|
-
"version": {
|
|
2122
|
-
"description": "Specify the version to delete. It must have no users or Zaps.",
|
|
2123
|
-
"name": "version",
|
|
2124
|
-
"required": true
|
|
2125
|
-
}
|
|
2126
|
-
},
|
|
2127
|
-
"description": "Delete a specific version of your integration.\n\nThis only works if there are no users or Zaps on that version. You will probably need to have run `zapier migrate` and `zapier deprecate` before this command will work.",
|
|
2128
|
-
"flags": {
|
|
2129
|
-
"debug": {
|
|
2130
|
-
"char": "d",
|
|
2131
|
-
"description": "Show extra debugging output.",
|
|
2132
|
-
"name": "debug",
|
|
2133
|
-
"allowNo": false,
|
|
2134
|
-
"type": "boolean"
|
|
2135
|
-
},
|
|
2136
|
-
"invokedFromAnotherCommand": {
|
|
2137
|
-
"hidden": true,
|
|
2138
|
-
"name": "invokedFromAnotherCommand",
|
|
2139
|
-
"allowNo": false,
|
|
2140
|
-
"type": "boolean"
|
|
2141
|
-
}
|
|
2142
|
-
},
|
|
2143
|
-
"hasDynamicHelp": false,
|
|
2144
|
-
"hiddenAliases": [],
|
|
2145
|
-
"id": "delete:version",
|
|
2146
|
-
"pluginAlias": "zapier-platform-cli",
|
|
2147
|
-
"pluginName": "zapier-platform-cli",
|
|
2148
|
-
"pluginType": "core",
|
|
2149
|
-
"strict": true,
|
|
2150
|
-
"enableJsonFlag": false,
|
|
2151
|
-
"skipValidInstallCheck": true,
|
|
2152
|
-
"isESM": false,
|
|
2153
|
-
"relativePath": [
|
|
2154
|
-
"src",
|
|
2155
|
-
"oclif",
|
|
2156
|
-
"commands",
|
|
2157
|
-
"delete",
|
|
2158
|
-
"version.js"
|
|
2159
|
-
]
|
|
2160
|
-
},
|
|
2161
2168
|
"team:add": {
|
|
2162
2169
|
"aliases": [
|
|
2163
2170
|
"team:invite"
|
|
@@ -2537,5 +2544,5 @@
|
|
|
2537
2544
|
]
|
|
2538
2545
|
}
|
|
2539
2546
|
},
|
|
2540
|
-
"version": "17.7.
|
|
2547
|
+
"version": "17.7.1"
|
|
2541
2548
|
}
|
package/package.json
CHANGED
package/src/generators/index.js
CHANGED
|
@@ -79,6 +79,7 @@ const writeGenericTypeScriptPackageJson = (gen, packageJsonExtension) => {
|
|
|
79
79
|
test: 'npm run build && vitest --run',
|
|
80
80
|
clean: 'rimraf ./dist ./build',
|
|
81
81
|
build: 'npm run clean && tsc',
|
|
82
|
+
dev: 'npm run build -- --watch',
|
|
82
83
|
'_zapier-build': 'npm run build',
|
|
83
84
|
},
|
|
84
85
|
dependencies: {
|
|
@@ -252,13 +253,26 @@ class ProjectGenerator extends Generator {
|
|
|
252
253
|
|
|
253
254
|
async prompting() {
|
|
254
255
|
if (!this.options.template) {
|
|
256
|
+
// Filter template choices based on language and module type
|
|
257
|
+
let templateChoices = TEMPLATE_CHOICES;
|
|
258
|
+
let defaultTemplate = 'minimal';
|
|
259
|
+
|
|
260
|
+
// TypeScript filtering takes precedence over ESM filtering
|
|
261
|
+
if (this.options.language === 'typescript') {
|
|
262
|
+
templateChoices = TS_SUPPORTED_TEMPLATES;
|
|
263
|
+
defaultTemplate = 'basic-auth';
|
|
264
|
+
} else if (this.options.module === 'esm') {
|
|
265
|
+
templateChoices = ESM_SUPPORTED_TEMPLATES;
|
|
266
|
+
defaultTemplate = 'minimal'; // minimal is the only ESM template
|
|
267
|
+
}
|
|
268
|
+
|
|
255
269
|
this.answers = await this.prompt([
|
|
256
270
|
{
|
|
257
271
|
type: 'list',
|
|
258
272
|
name: 'template',
|
|
259
|
-
choices:
|
|
273
|
+
choices: templateChoices,
|
|
260
274
|
message: 'Choose a project template to start with:',
|
|
261
|
-
default:
|
|
275
|
+
default: defaultTemplate,
|
|
262
276
|
},
|
|
263
277
|
]);
|
|
264
278
|
this.options.template = this.answers.template;
|
|
@@ -320,6 +334,8 @@ class ProjectGenerator extends Generator {
|
|
|
320
334
|
|
|
321
335
|
module.exports = {
|
|
322
336
|
TEMPLATE_CHOICES,
|
|
337
|
+
ESM_SUPPORTED_TEMPLATES,
|
|
338
|
+
TS_SUPPORTED_TEMPLATES,
|
|
323
339
|
PullGenerator,
|
|
324
340
|
ProjectGenerator,
|
|
325
341
|
};
|
|
@@ -90,9 +90,14 @@ class ZapierBaseCommand extends Command {
|
|
|
90
90
|
|
|
91
91
|
// validate that user input looks like a semver version
|
|
92
92
|
throwForInvalidVersion(version) {
|
|
93
|
-
if (
|
|
93
|
+
if (
|
|
94
|
+
!version.match(
|
|
95
|
+
// this is mirrored in schemas/VersionSchema.js and developer_cli/constants.py
|
|
96
|
+
/^(?:0|[1-9]\d{0,2})\.(?:0|[1-9]\d{0,2})\.(?:0|[1-9]\d{0,2})(?:-(?=.{1,12}$)[A-Za-z0-9]+(?:-[A-Za-z0-9]+)*)?$/g,
|
|
97
|
+
)
|
|
98
|
+
) {
|
|
94
99
|
throw new Error(
|
|
95
|
-
`${version} is an invalid version str. Try something like \`1.2.3\``,
|
|
100
|
+
`${version} is an invalid version str. Try something like \`1.2.3\` or \`0.0.0-TICKET\``,
|
|
96
101
|
);
|
|
97
102
|
}
|
|
98
103
|
}
|
|
@@ -240,15 +240,26 @@ const resolveInputDataTypes = (inputData, inputFields, timezone) => {
|
|
|
240
240
|
};
|
|
241
241
|
|
|
242
242
|
const appendEnv = async (vars, prefix = '') => {
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
243
|
+
const envFile = '.env';
|
|
244
|
+
let content = Object.entries(vars)
|
|
245
|
+
.filter(([k, v]) => v !== undefined)
|
|
246
|
+
.map(
|
|
247
|
+
([k, v]) =>
|
|
248
|
+
`${prefix}${k}='${typeof v === 'object' && v !== null ? JSON.stringify(v) : v || ''}'\n`,
|
|
249
|
+
)
|
|
250
|
+
.join('');
|
|
251
|
+
|
|
252
|
+
// Check if .env file exists and doesn't end with newline
|
|
253
|
+
try {
|
|
254
|
+
const existingContent = await fs.readFile(envFile, 'utf8');
|
|
255
|
+
if (existingContent.length > 0 && !existingContent.endsWith('\n')) {
|
|
256
|
+
content = '\n' + content;
|
|
257
|
+
}
|
|
258
|
+
} catch (error) {
|
|
259
|
+
// File doesn't exist or can't be read, proceed as normal
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
await fs.appendFile(envFile, content);
|
|
252
263
|
};
|
|
253
264
|
|
|
254
265
|
const replaceDoubleCurlies = async (request) => {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
const _ = require('lodash');
|
|
2
2
|
const debug = require('debug')('zapier:migrate');
|
|
3
3
|
const { Args, Flags } = require('@oclif/core');
|
|
4
|
+
const colors = require('colors/safe');
|
|
4
5
|
|
|
5
6
|
const BaseCommand = require('../ZapierBaseCommand');
|
|
6
7
|
const PromoteCommand = require('./promote');
|
|
@@ -118,17 +119,15 @@ class MigrateCommand extends BaseCommand {
|
|
|
118
119
|
|
|
119
120
|
await this.run_require_confirmation_pre_checks(app, body);
|
|
120
121
|
|
|
122
|
+
let message;
|
|
121
123
|
if (user || account) {
|
|
122
|
-
|
|
123
|
-
`Starting migration from ${fromVersion} to ${toVersion} for ${
|
|
124
|
-
user || account
|
|
125
|
-
}`,
|
|
126
|
-
);
|
|
124
|
+
message = `Requesting migration from ${fromVersion} to ${toVersion} for ${user || account}`;
|
|
127
125
|
} else {
|
|
128
|
-
|
|
129
|
-
`Starting migration from ${fromVersion} to ${toVersion} for ${percent}%`,
|
|
130
|
-
);
|
|
126
|
+
message = `Requesting migration from ${fromVersion} to ${toVersion} for ${percent}%`;
|
|
131
127
|
}
|
|
128
|
+
|
|
129
|
+
this.startSpinner(message);
|
|
130
|
+
|
|
132
131
|
if (percent) {
|
|
133
132
|
body.job.percent_human = percent;
|
|
134
133
|
}
|
|
@@ -137,12 +136,14 @@ class MigrateCommand extends BaseCommand {
|
|
|
137
136
|
|
|
138
137
|
try {
|
|
139
138
|
await callAPI(url, { method: 'POST', body });
|
|
140
|
-
}
|
|
141
|
-
this.stopSpinner();
|
|
139
|
+
} catch (err) {
|
|
140
|
+
this.stopSpinner({ success: false });
|
|
141
|
+
throw err;
|
|
142
142
|
}
|
|
143
|
+
this.stopSpinner();
|
|
143
144
|
|
|
144
145
|
this.log(
|
|
145
|
-
|
|
146
|
+
`\nMigration successfully queued, check ${colors.bold.underline('zapier jobs')} to track the status. Migrations usually take between 5-10 minutes.`,
|
|
146
147
|
);
|
|
147
148
|
}
|
|
148
149
|
}
|
|
@@ -53,9 +53,9 @@ class PullCommand extends ZapierBaseCommand {
|
|
|
53
53
|
}
|
|
54
54
|
|
|
55
55
|
PullCommand.flags = buildFlags();
|
|
56
|
-
PullCommand.description = `Retrieve and update your local integration files with the latest version.
|
|
56
|
+
PullCommand.description = `Retrieve and update your local integration files with the promoted version (or latest version if not public).
|
|
57
57
|
|
|
58
|
-
This command updates your local integration files with the latest version. You will be prompted with a confirmation dialog before continuing if there any destructive file changes.
|
|
58
|
+
This command updates your local integration files with the promoted version (or latest version if not public). You will be prompted with a confirmation dialog before continuing if there any destructive file changes.
|
|
59
59
|
|
|
60
60
|
Zapier may release new versions of your integration with bug fixes or new features. In the event this occurs, you will be unable to do the following until your local files are updated by running \`zapier pull\`:
|
|
61
61
|
|
|
@@ -6,9 +6,14 @@ const { buildFlags } = require('../buildFlags');
|
|
|
6
6
|
const { flattenCheckResult } = require('../../utils/display');
|
|
7
7
|
const { localAppCommand } = require('../../utils/local');
|
|
8
8
|
const { validateApp } = require('../../utils/api');
|
|
9
|
+
const { maybeRunBuildScript } = require('../../utils/build');
|
|
9
10
|
|
|
10
11
|
class ValidateCommand extends BaseCommand {
|
|
11
12
|
async perform() {
|
|
13
|
+
if (!this.flags['skip-build']) {
|
|
14
|
+
await maybeRunBuildScript({ printProgress: true });
|
|
15
|
+
}
|
|
16
|
+
|
|
12
17
|
this.log('Validating project locally');
|
|
13
18
|
|
|
14
19
|
const errors = await localAppCommand({ command: 'validate' });
|
|
@@ -121,6 +126,9 @@ ValidateCommand.flags = buildFlags({
|
|
|
121
126
|
'without-style': Flags.boolean({
|
|
122
127
|
description: 'Forgo pinging the Zapier server to run further checks.',
|
|
123
128
|
}),
|
|
129
|
+
'skip-build': Flags.boolean({
|
|
130
|
+
description: 'Skip running the _zapier-build script before validation.',
|
|
131
|
+
}),
|
|
124
132
|
},
|
|
125
133
|
opts: {
|
|
126
134
|
format: true,
|
|
@@ -130,6 +138,7 @@ ValidateCommand.flags = buildFlags({
|
|
|
130
138
|
ValidateCommand.examples = [
|
|
131
139
|
'zapier validate',
|
|
132
140
|
'zapier validate --without-style',
|
|
141
|
+
'zapier validate --skip-build',
|
|
133
142
|
'zapier validate --format json',
|
|
134
143
|
];
|
|
135
144
|
ValidateCommand.description = `Validate your integration.
|
package/src/utils/analytics.js
CHANGED
|
@@ -51,7 +51,7 @@ const recordAnalytics = async (command, isValidCommand, args, flags) => {
|
|
|
51
51
|
numArgs: argKeys.length,
|
|
52
52
|
appId: linkedAppId,
|
|
53
53
|
argsKeys: argKeys,
|
|
54
|
-
flagKeys
|
|
54
|
+
flagKeys,
|
|
55
55
|
cliVersion: pkg.version,
|
|
56
56
|
os: shouldRecordAnonymously ? undefined : process.platform,
|
|
57
57
|
};
|
package/src/utils/ast.js
CHANGED
|
@@ -115,17 +115,23 @@ const registerActionInJsApp = (codeStr, property, varName) => {
|
|
|
115
115
|
|
|
116
116
|
// check if this object already has the property at the top level
|
|
117
117
|
const existingProp = objToModify.properties.find(
|
|
118
|
-
(props) => props.key.name === property,
|
|
118
|
+
(props) => props.key && props.key.name === property,
|
|
119
119
|
);
|
|
120
120
|
if (existingProp) {
|
|
121
|
-
// `triggers: myTriggers` means we shouldn't bother
|
|
122
121
|
const value = existingProp.value;
|
|
123
|
-
if (value.type
|
|
122
|
+
if (value.type === 'Identifier') {
|
|
123
|
+
// Handle shorthand syntax like `creates` instead of `creates: { ... }`
|
|
124
|
+
// Transform it into an object with spread operator: `creates: { ...creates, [newAction.key]: newAction }`
|
|
125
|
+
const spreadProperty = j.spreadElement(j.identifier(value.name));
|
|
126
|
+
existingProp.value = j.objectExpression([spreadProperty, newProperty]);
|
|
127
|
+
existingProp.shorthand = false; // Disable shorthand since we're changing the value
|
|
128
|
+
} else if (value.type === 'ObjectExpression') {
|
|
129
|
+
value.properties.push(newProperty);
|
|
130
|
+
} else {
|
|
124
131
|
throw new Error(
|
|
125
132
|
`Tried to edit the ${property} key, but the value wasn't an object`,
|
|
126
133
|
);
|
|
127
134
|
}
|
|
128
|
-
value.properties.push(newProperty);
|
|
129
135
|
} else {
|
|
130
136
|
objToModify.properties.push(
|
|
131
137
|
j.property(
|
|
@@ -209,16 +215,23 @@ const registerActionInTsApp = (codeStr, actionTypePlural, identifierName) => {
|
|
|
209
215
|
|
|
210
216
|
// Check if this object already has the actionType group inside it.
|
|
211
217
|
const existingProp = appObj.properties.find(
|
|
212
|
-
(props) => props.key.name === actionTypePlural,
|
|
218
|
+
(props) => props.key && props.key.name === actionTypePlural,
|
|
213
219
|
);
|
|
214
220
|
if (existingProp) {
|
|
215
221
|
const value = existingProp.value;
|
|
216
|
-
if (value.type
|
|
222
|
+
if (value.type === 'Identifier') {
|
|
223
|
+
// Handle shorthand syntax like `creates` instead of `creates: { ... }`
|
|
224
|
+
// Transform it into an object with spread operator: `creates: { ...creates, [newAction.key]: newAction }`
|
|
225
|
+
const spreadProperty = j.spreadElement(j.identifier(value.name));
|
|
226
|
+
existingProp.value = j.objectExpression([spreadProperty, newProperty]);
|
|
227
|
+
existingProp.shorthand = false; // Disable shorthand since we're changing the value
|
|
228
|
+
} else if (value.type === 'ObjectExpression') {
|
|
229
|
+
value.properties.push(newProperty);
|
|
230
|
+
} else {
|
|
217
231
|
throw new Error(
|
|
218
232
|
`Tried to edit the ${actionTypePlural} key, but the value wasn't an object`,
|
|
219
233
|
);
|
|
220
234
|
}
|
|
221
|
-
value.properties.push(newProperty);
|
|
222
235
|
} else {
|
|
223
236
|
appObj.properties.push(
|
|
224
237
|
j.property(
|
package/src/utils/scaffold.js
CHANGED
|
@@ -126,6 +126,16 @@ const writeTemplateFile = async ({
|
|
|
126
126
|
const getRelativeRequirePath = (entryFilePath, newFilePath) =>
|
|
127
127
|
path.relative(path.dirname(entryFilePath), newFilePath);
|
|
128
128
|
|
|
129
|
+
/**
|
|
130
|
+
* Detect if a JavaScript file uses ES Module syntax (export default) vs CommonJS (module.exports)
|
|
131
|
+
* @param {string} codeStr - The JavaScript code to check
|
|
132
|
+
* @returns {boolean} - True if the file uses ESM syntax
|
|
133
|
+
*/
|
|
134
|
+
const isEsmJavaScript = (codeStr) => {
|
|
135
|
+
// Look for export default statement
|
|
136
|
+
return /^\s*export\s+default\s/m.test(codeStr);
|
|
137
|
+
};
|
|
138
|
+
|
|
129
139
|
const isValidEntryFileUpdate = (
|
|
130
140
|
language,
|
|
131
141
|
indexFileResolved,
|
|
@@ -193,16 +203,32 @@ const updateEntryFileJs = async ({
|
|
|
193
203
|
let codeStr = (await readFile(indexFileResolved)).toString();
|
|
194
204
|
const originalCodeStr = codeStr; // untouched copy in case we need to bail
|
|
195
205
|
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
+
// Check if this JavaScript file uses ESM syntax (export default)
|
|
207
|
+
// If so, use the TypeScript functions which handle ESM correctly
|
|
208
|
+
if (isEsmJavaScript(codeStr)) {
|
|
209
|
+
codeStr = importActionInTsApp(
|
|
210
|
+
codeStr,
|
|
211
|
+
actionImportName,
|
|
212
|
+
actionRelativeImportPath,
|
|
213
|
+
);
|
|
214
|
+
codeStr = registerActionInTsApp(
|
|
215
|
+
codeStr,
|
|
216
|
+
plural(actionType),
|
|
217
|
+
actionImportName,
|
|
218
|
+
);
|
|
219
|
+
} else {
|
|
220
|
+
// Use traditional CommonJS functions for module.exports
|
|
221
|
+
codeStr = importActionInJsApp(
|
|
222
|
+
codeStr,
|
|
223
|
+
actionImportName,
|
|
224
|
+
actionRelativeImportPath,
|
|
225
|
+
);
|
|
226
|
+
codeStr = registerActionInJsApp(
|
|
227
|
+
codeStr,
|
|
228
|
+
plural(actionType),
|
|
229
|
+
actionImportName,
|
|
230
|
+
);
|
|
231
|
+
}
|
|
206
232
|
await writeFile(indexFileResolved, codeStr);
|
|
207
233
|
return originalCodeStr;
|
|
208
234
|
};
|
|
@@ -283,11 +309,22 @@ const createScaffoldingContext = ({
|
|
|
283
309
|
)}.test.${language}`;
|
|
284
310
|
const testFileLocal = `${path.join(testDirLocal, key)}.${language}`;
|
|
285
311
|
const testFileLocalStem = path.join(testDirLocal, key);
|
|
286
|
-
|
|
312
|
+
|
|
313
|
+
// Generate the relative import path
|
|
314
|
+
let actionRelativeImportPath = `./${getRelativeRequirePath(
|
|
287
315
|
indexFileResolved,
|
|
288
316
|
actionFileResolvedStem,
|
|
289
317
|
)}`;
|
|
290
318
|
|
|
319
|
+
// Normalize path separators to forward slashes for import statements
|
|
320
|
+
// (ES modules always use forward slashes, regardless of OS)
|
|
321
|
+
actionRelativeImportPath = actionRelativeImportPath.replace(/\\/g, '/');
|
|
322
|
+
|
|
323
|
+
// For TypeScript with ESM, imports must use .js extension
|
|
324
|
+
if (language === 'ts') {
|
|
325
|
+
actionRelativeImportPath += '.js';
|
|
326
|
+
}
|
|
327
|
+
|
|
291
328
|
return {
|
|
292
329
|
actionType,
|
|
293
330
|
actionTypePlural: plural(actionType),
|
|
@@ -324,6 +361,7 @@ module.exports = {
|
|
|
324
361
|
updateEntryFile,
|
|
325
362
|
isValidEntryFileUpdate,
|
|
326
363
|
writeTemplateFile,
|
|
364
|
+
isEsmJavaScript,
|
|
327
365
|
};
|
|
328
366
|
|
|
329
367
|
/**
|