afterpresets 0.1.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -4
- package/native-runtime/CMakeLists.txt +82 -0
- package/native-runtime/README.md +40 -0
- package/native-runtime/THIRD_PARTY_NOTICES.md +14 -0
- package/native-runtime/include/ap_native.h +223 -0
- package/native-runtime/src/apply.cpp +199 -0
- package/native-runtime/src/crypto.cpp +225 -0
- package/native-runtime/src/crypto.hpp +51 -0
- package/native-runtime/src/dialog.cpp +62 -0
- package/native-runtime/src/dialog.hpp +35 -0
- package/native-runtime/src/engine.cpp +909 -0
- package/native-runtime/src/engine.hpp +232 -0
- package/native-runtime/src/fsutil.cpp +291 -0
- package/native-runtime/src/fsutil.hpp +57 -0
- package/native-runtime/src/json.cpp +326 -0
- package/native-runtime/src/json.hpp +70 -0
- package/native-runtime/src/platform.hpp +83 -0
- package/native-runtime/src/platform_common.cpp +60 -0
- package/native-runtime/src/platform_mac.mm +314 -0
- package/native-runtime/src/platform_win.cpp +277 -0
- package/native-runtime/src/runtime.cpp +473 -0
- package/native-runtime/src/util.cpp +169 -0
- package/native-runtime/src/util.hpp +32 -0
- package/native-runtime/src/zip.cpp +243 -0
- package/native-runtime/src/zip.hpp +58 -0
- package/native-runtime/third_party/monocypher/LICENCE.md +167 -0
- package/native-runtime/third_party/monocypher/monocypher-ed25519.c +500 -0
- package/native-runtime/third_party/monocypher/monocypher-ed25519.h +140 -0
- package/native-runtime/third_party/monocypher/monocypher.c +2956 -0
- package/native-runtime/third_party/monocypher/monocypher.h +321 -0
- package/native-runtime/third_party/tinf/LICENSE +22 -0
- package/native-runtime/third_party/tinf/crc32.c +57 -0
- package/native-runtime/third_party/tinf/tinf.h +140 -0
- package/native-runtime/third_party/tinf/tinflate.c +636 -0
- package/native-runtime/vendor-files.json +39 -0
- package/package.json +6 -3
- package/runtime/docs/cep/host-after-effects.md +57 -0
- package/runtime/docs/cep/host-premiere.md +84 -0
- package/runtime/docs/{host.md → cep/host.md} +42 -16
- package/runtime/docs/{README.md → common/README.md} +10 -8
- package/runtime/docs/{assets.md → common/assets.md} +16 -2
- package/runtime/docs/{licensing.md → common/licensing.md} +1 -1
- package/runtime/docs/{panels.md → common/panels.md} +5 -5
- package/runtime/docs/{storage.md → common/storage.md} +5 -5
- package/runtime/docs/{updates.md → common/updates.md} +1 -1
- package/runtime/docs/native/README.md +44 -0
- package/runtime/docs/native/debugging.md +140 -0
- package/runtime/docs/native/rules.md +402 -0
- package/runtime/docs/native/testing.md +154 -0
- package/runtime/package.json +1 -1
- package/runtime/scripts/ae-sdk-docs/config.js +102 -0
- package/runtime/scripts/ae-sdk-docs/convert.js +430 -0
- package/runtime/scripts/ae-sdk-docs/index.js +314 -0
- package/runtime/scripts/ae-sdk-docs/source.js +205 -0
- package/runtime/scripts/ae-sdk-docs/split.js +170 -0
- package/runtime/scripts/ae-sdk-docs.js +72 -0
- package/runtime/src/host.js +1 -1
- package/runtime/src/updates.js +1 -1
- package/src/api/error-messages.js +1 -1
- package/src/build/build.js +7 -7
- package/src/build/html.js +1 -1
- package/src/build/jsx.js +2 -2
- package/src/build/runtime.js +3 -3
- package/src/check/check.js +3 -3
- package/src/check/native.js +14 -0
- package/src/check/pricing.js +1 -1
- package/src/check/types.js +2 -2
- package/src/cli.js +5 -5
- package/src/commands/add.js +8 -3
- package/src/commands/build.js +8 -2
- package/src/commands/check.js +11 -3
- package/src/commands/dev.js +9 -2
- package/src/commands/docs.js +5 -1
- package/src/commands/init.js +15 -3
- package/src/commands/push.js +5 -2
- package/src/commands/sdk.js +14 -0
- package/src/commands/testers.js +1 -1
- package/src/commands/upgrade.js +2 -2
- package/src/commands/whoami.js +1 -1
- package/src/config.js +1 -1
- package/src/dev/bridge.js +8 -0
- package/src/dev/cep-link.js +1 -1
- package/src/dev/debug-file.js +5 -5
- package/src/dev/native.js +3 -0
- package/src/dev/session.js +4 -3
- package/src/mcp/extendscript.js +10 -7
- package/src/mcp/host-target.js +1 -0
- package/src/mcp/panels.js +1 -1
- package/src/mcp/png.js +1 -0
- package/src/mcp/server.js +2 -2
- package/src/mcp/tools/capture.js +3 -0
- package/src/mcp/tools/host.js +1 -1
- package/src/mcp/tools/native.js +6 -0
- package/src/mcp/tools/panel.js +4 -4
- package/src/mcp/tools/project.js +47 -31
- package/src/mcp/tools/releases.js +23 -20
- package/src/native/build.js +27 -0
- package/src/native/cmake/CMakeLists.txt +88 -0
- package/src/native/cmake/zig-windows.cmake +19 -0
- package/src/native/effect.js +3 -0
- package/src/native/install.js +8 -0
- package/src/native/installers.js +4 -0
- package/src/native/pipl.js +20 -0
- package/src/native/restart.js +2 -0
- package/src/native/sdk.js +8 -0
- package/src/project/add-panel.js +1 -1
- package/src/project/docs.js +3 -1
- package/src/project/manifest.js +3 -2
- package/src/project/project.js +2 -2
- package/src/project/template.js +5 -1
- package/src/prompt.js +1 -1
- package/src/release/installers.js +4 -4
- package/src/release/native.js +3 -0
- package/src/release/package.js +1 -1
- package/src/release/publish.js +1 -1
- package/src/system/run-command.js +1 -1
- package/src/targets.js +1 -0
- package/src/user-config.js +2 -2
- package/template/cep/AGENTS.md +104 -0
- package/template/{README.md → cep/README.md} +16 -11
- package/template/cep/docs/code_guide.md +67 -0
- package/template/cep/docs/initial_setup.md +115 -0
- package/template/cep/docs/release_checklist.md +24 -0
- package/template/{src → cep/src}/features/home/home.html +4 -4
- package/template/{src → cep/src}/features/home/home.js +10 -11
- package/template/{src → cep/src}/shared/lib/host-theme.js +3 -3
- package/template/{src → cep/src}/shared/lib/view.js +1 -1
- package/template/{src → cep/src}/shared/ui/tokens.css +1 -1
- package/template/hosts/AGENTS.two-apps.md +12 -0
- package/template/hosts/aeft/AGENTS.host.md +10 -0
- package/template/hosts/aeft/jsx/aeft/home.jsx +16 -0
- package/template/hosts/ppro/AGENTS.host.md +15 -0
- package/template/hosts/ppro/jsx/ppro/home.jsx +20 -0
- package/template/native/.mcp.json +8 -0
- package/template/native/AGENTS.md +105 -0
- package/template/native/README.md +71 -0
- package/template/native/docs/code_guide.md +72 -0
- package/template/native/docs/initial_setup.md +179 -0
- package/template/native/docs/release_checklist.md +24 -0
- package/template/native/effect.json +16 -0
- package/template/native/gitignore +8 -0
- package/template/native/package.json +14 -0
- package/template/native/src/Effect.cpp +224 -0
- package/template/native/src/License.cpp +95 -0
- package/template/native/src/License.h +29 -0
- package/template/native/src/Render.h +68 -0
- package/vendor/afterpresets-additions/AfterEffects.d.ts +291 -0
- package/vendor/afterpresets-additions/Premiere.d.ts +179 -0
- package/vendor/types-for-adobe/Premiere/24.0/index.d.ts +2567 -0
- package/vendor/types-for-adobe/README.md +8 -4
- package/template/AGENTS.md +0 -168
- package/template/docs/initial_setup.md +0 -69
- package/template/jsx/home.jsx +0 -17
- /package/runtime/docs/{boot.md → common/boot.md} +0 -0
- /package/template/{.mcp.json → cep/.mcp.json} +0 -0
- /package/template/{gitignore → cep/gitignore} +0 -0
- /package/template/{package.json → cep/package.json} +0 -0
- /package/template/{src → cep/src}/features/home/home.css +0 -0
- /package/template/{src → cep/src}/features/license-screen/license-screen.css +0 -0
- /package/template/{src → cep/src}/features/license-screen/license-screen.html +0 -0
- /package/template/{src → cep/src}/features/license-screen/license-screen.js +0 -0
- /package/template/{src → cep/src}/features/update-screen/update-screen.css +0 -0
- /package/template/{src → cep/src}/features/update-screen/update-screen.html +0 -0
- /package/template/{src → cep/src}/features/update-screen/update-screen.js +0 -0
- /package/template/{src → cep/src}/panels/main/index.html +0 -0
- /package/template/{src → cep/src}/panels/main/main.js +0 -0
- /package/template/{src → cep/src}/shared/lib/dom.js +0 -0
- /package/template/{src → cep/src}/shared/lib/markdown.js +0 -0
- /package/template/{src → cep/src}/shared/ui/base.css +0 -0
- /package/template/{src → cep/src}/shared/ui/button.css +0 -0
- /package/template/{src → cep/src}/shared/ui/card.css +0 -0
- /package/template/{src → cep/src}/shared/ui/field.css +0 -0
- /package/template/{src → cep/src}/shared/ui/index.css +0 -0
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
|
|
4
|
+
// Generates the After Effects SDK topic files for native (C++) projects.
|
|
5
|
+
//
|
|
6
|
+
// node scripts/ae-sdk-docs.js --out <dir> download the pinned guide (cached) and generate
|
|
7
|
+
// node scripts/ae-sdk-docs.js --out <dir> --source <checkout> [--allow-unpinned]
|
|
8
|
+
// options: --cache <dir> (default ~/.afterpresets/cache), --quiet, --json
|
|
9
|
+
//
|
|
10
|
+
// Adobe's guide is not redistributed: it is downloaded by the user's machine
|
|
11
|
+
// from GitHub at the commit pinned in ae-sdk-docs/config.js and checked
|
|
12
|
+
// against the pinned digest. See ../docs/native/README.md.
|
|
13
|
+
|
|
14
|
+
const { generate } = require("./ae-sdk-docs/index");
|
|
15
|
+
|
|
16
|
+
function parseArgs(argv) {
|
|
17
|
+
const opts = {};
|
|
18
|
+
for (let i = 0; i < argv.length; i++) {
|
|
19
|
+
const arg = argv[i];
|
|
20
|
+
const value = () => {
|
|
21
|
+
if (i + 1 >= argv.length) throw new Error(arg + " needs a value.");
|
|
22
|
+
return argv[++i];
|
|
23
|
+
};
|
|
24
|
+
if (arg === "--out") opts.out = value();
|
|
25
|
+
else if (arg === "--source") opts.source = value();
|
|
26
|
+
else if (arg === "--cache") opts.cacheDir = value();
|
|
27
|
+
else if (arg === "--allow-unpinned") opts.allowUnpinned = true;
|
|
28
|
+
else if (arg === "--quiet") opts.quiet = true;
|
|
29
|
+
else if (arg === "--json") opts.json = true;
|
|
30
|
+
else if (arg === "--help" || arg === "-h") opts.help = true;
|
|
31
|
+
else throw new Error("Unknown option " + arg);
|
|
32
|
+
}
|
|
33
|
+
return opts;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
async function main() {
|
|
37
|
+
let opts;
|
|
38
|
+
try {
|
|
39
|
+
opts = parseArgs(process.argv.slice(2));
|
|
40
|
+
} catch (error) {
|
|
41
|
+
console.error(error.message);
|
|
42
|
+
process.exitCode = 2;
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
if (opts.help || !opts.out) {
|
|
46
|
+
console.log("Usage: node scripts/ae-sdk-docs.js --out <dir> [--source <checkout>] [--allow-unpinned] [--cache <dir>] [--quiet] [--json]");
|
|
47
|
+
if (!opts.help) process.exitCode = 2;
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
const result = await generate(opts);
|
|
51
|
+
if (opts.json) {
|
|
52
|
+
console.log(JSON.stringify(result, null, 2));
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
if (!opts.quiet) {
|
|
56
|
+
const width = Math.max.apply(null, result.files.map((f) => f.name.length));
|
|
57
|
+
result.files.forEach((f) => console.log(f.name.padEnd(width) + " " + String(f.tokens).padStart(6)));
|
|
58
|
+
console.log("");
|
|
59
|
+
}
|
|
60
|
+
const sizes = result.files.map((f) => f.tokens).sort((a, b) => a - b);
|
|
61
|
+
console.log(
|
|
62
|
+
result.files.length + " files from " + result.pages + " pages, about " + result.totalTokens + " tokens (source pages: about " + result.sourceTokens + "). " +
|
|
63
|
+
"Median file " + sizes[Math.floor(sizes.length / 2)] + ", largest " + sizes[sizes.length - 1] + "."
|
|
64
|
+
);
|
|
65
|
+
console.log("Source: commit " + result.commit + ", " + result.digest + " (" + result.from + ")");
|
|
66
|
+
result.warnings.forEach((w) => console.warn("warning: " + w));
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
main().catch((error) => {
|
|
70
|
+
console.error("ae-sdk-docs: " + error.message);
|
|
71
|
+
process.exitCode = 1;
|
|
72
|
+
});
|
package/runtime/src/host.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
(function(d){"use strict";var
|
|
1
|
+
(function(d){"use strict";var s=d.AP,i=s._,S=/^[A-Za-z_$][A-Za-z0-9_$]*(\.[A-Za-z_$][A-Za-z0-9_$]*)*$/,y="EvalScript error.",o="idle",f=null,p=[];function a(e){var t=JSON.stringify(e===void 0?null:e);return t===void 0&&(t="null"),t.replace(/\u2028/g,"\\u2028").replace(/\u2029/g,"\\u2029")}i.jsxLiteral=a;function h(e,t){for(var n=[],r=0;r<t.length;r++)n.push(a(t[r]));return["(function () {"," function apQ(s) { s = String(s); return '\"' + s.replace(/\\\\/g, '\\\\\\\\').replace(/\"/g, '\\\\\"')"," .replace(/\\r/g, '\\\\r').replace(/\\n/g, '\\\\n').replace(/\\t/g, '\\\\t') + '\"'; }"," try {"," var r = "+e+"("+n.join(", ")+");"," if (r === undefined || r === null) return 'null';"," return String(r);"," } catch (e) {"," return '{\"error\":' + apQ(e && e.message ? e.message : e) + '}';"," }","}())"].join("\n")}i.wrapHostCall=h;function v(e,t){var n=i.cs();if(!n){t(JSON.stringify({error:"CEP host API is unavailable."}));return}n.evalScript(e,t)}function c(){try{var e=i.cs(),t=e&&e.getHostEnvironment();return t&&t.appName?String(t.appName):null}catch(n){return null}}i.hostAppName=c;function R(e){return!!e&&typeof e.code=="string"&&!!e.code}function _(){var e=d.AP_JSX;if(!e||typeof e!="object")return{missing:"This bundle has no host script (AP_JSX). Rebuild it with the AfterPresets CLI."};var t=c();return t&&Object.prototype.hasOwnProperty.call(e,t)&&R(e[t])?e[t]:{missing:"This extension has no host script for "+(t||"this app")+"."}}function O(){var e=_();return e.missing?"'AP_LOAD_ERROR:' + "+a(e.missing):"try { eval("+a(e.code)+"); 'ok'; } catch (e) { 'AP_LOAD_ERROR:' + (e && e.message ? e.message : e); }"}function g(e){if(e=e||function(){},o==="loaded"){e(null);return}if(o==="failed"){e(f);return}if(p.push(e),o==="loading")return;o="loading";function t(r){o=r?"failed":"loaded",f=r,r&&i.log("error",r);var u=p;p=[];for(var l=0;l<u.length;l++)u[l](r)}var n=O();v(n,function(r){t(r==="ok"?null:String(r||"Could not load host script.").replace(/^AP_LOAD_ERROR:/,"Could not load host script: "))})}i.preloadHost=function(){g(null)};function A(e){if(e===y)return{error:"The host script failed to run."};if(e==null||e===""||e==="undefined")return null;try{return JSON.parse(e)}catch(t){return{error:"The host returned a non-JSON result.",raw:String(e)}}}i.parseHostResult=A,s.host={eval:function(e,t,n){if(typeof t=="function"&&n===void 0&&(n=t,t=[]),n=typeof n=="function"?n:function(){},typeof e!="string"||!S.test(e)){n({error:"Invalid host function name: "+String(e)});return}t==null&&(t=[]),Object.prototype.toString.call(t)!=="[object Array]"&&(t=[t]);var r=h(e,t);g(function(u){if(u){n({error:String(u)});return}v(r,function(l){n(A(l))})})},reload:function(){o="idle",f=null}},Object.defineProperty(s.host,"app",{enumerable:!0,get:c})})(typeof window!="undefined"?window:this);
|
package/runtime/src/updates.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
(function(g){"use strict";var x=g.AP,n=x._,N="afterpresets-release-v1",U=600*1e3,P=[],m=[],w=[],k=!1,v=null,R={background:!0,prompt:!0,silent:!0},y="background",f=null,
|
|
1
|
+
(function(g){"use strict";var x=g.AP,n=x._,N="afterpresets-release-v1",U=600*1e3,P=[],m=[],w=[],k=!1,v=null,R={background:!0,prompt:!0,silent:!0},y="background",f=null,C=null,b=!1;function S(e,t){return typeof t!="function"?function(){}:(e.push(t),function(){var r=e.indexOf(t);r!==-1&&e.splice(r,1)})}function p(e,t){for(var r=e.slice(),i=0;i<r.length;i++)n.safeCall(r[i],null,[t])}function s(e,t,r){var i=new Error(t);return i.code=e,r&&n.extend(i,r),i}function D(){return n.node("path").join(n.dataDir(),"updates.json")}function E(){if(v)return v;var e=null;try{e=n.readJson(D())}catch(t){e=null}return v=e&&(e.channel==="test"||e.channel==="production")?e.channel:n.config().channel==="test"?"test":"production",v}function K(e){if(e!=="test"&&e!=="production")throw s("bad_channel","Channel must be 'production' or 'test'.");v=e;try{n.writeJson(D(),{channel:e})}catch(t){n.log("warn","Could not save update channel",t&&t.message)}}n.publicKeyPem=function(e){var t=String(e||"").replace(/^\s+|\s+$/g,"");if(!t)throw s("no_public_key","This build has no update signing key.");if(t.indexOf("-----BEGIN")!==-1)return t;var r=n.Buffer(),i=r.from(t,"base64"),o=i.toString("utf8");if(o.indexOf("-----BEGIN")!==-1)return o;for(var l=i.toString("base64"),a=[],u=0;u<l.length;u+=64)a.push(l.slice(u,u+64));return"-----BEGIN PUBLIC KEY-----\n"+a.join("\n")+"\n-----END PUBLIC KEY-----\n"},n.signaturePayload=function(e,t,r){return N+"\n"+e+"\n"+t+"\n"+r},n.verifyReleaseSignature=function(e,t,r){var i=n.node("crypto");if(typeof i.verify!="function")throw s("verify_unsupported","This app version cannot verify signed updates (Node 12+ is required). Download the update from AfterPresets instead.");var o=n.config(),l=n.Buffer(),a=!1;try{a=i.verify(null,l.from(n.signaturePayload(o.bundleId,e,t),"utf8"),n.publicKeyPem(o.publicKey),l.from(String(r),"base64"))}catch(u){throw u&&u.code==="no_public_key"?u:s("bad_signature","The update signature could not be verified: "+(u&&u.message))}if(!a)throw s("bad_signature","The update signature is not valid for this extension. The update was not installed.")};function G(e){if(!e||typeof e!="object")throw s("bad_update_info","No update information.");if(!/^https?:\/\//i.test(String(e.downloadUrl||"")))throw s("bad_update_info","The update has no download URL.");if(!/^[0-9a-fA-F]{64}$/.test(String(e.sha256||"")))throw s("bad_update_info","The update has no valid checksum.");if(!e.signature||typeof e.signature!="string")throw s("bad_update_info","The update is not signed.");if(!/^[0-9A-Za-z.+-]{1,64}$/.test(String(e.targetVersion||"")))throw s("bad_update_info","The update has an invalid version.")}function O(e){var t=n.extend({},e),r=String(e.targetVersion||e.version||""),i=[],o=e.releaseNotes;if(o&&o.length)for(var l=0;l<o.length;l++){var a=o[l]||{};i.push({version:String(a.version||""),changeLog:String(a.changeLog||""),releaseDate:a.releaseDate||null})}else e.changeLog&&i.push({version:r,changeLog:String(e.changeLog),releaseDate:null});return t.updateAvailable=!0,t.version=r,t.targetVersion=r,t.direction=e.direction==="downgrade"?"downgrade":"upgrade",t.changeLog=String(e.changeLog||""),t.releaseNotes=i,t}function _(e){return{updateAvailable:!0,version:String(e.version||e.targetVersion||""),direction:e.direction==="downgrade"?"downgrade":"upgrade",changeLog:String(e.changeLog||""),releaseNotes:e.releaseNotes||[],mode:y}}function I(e,t){e=typeof e=="function"?e:function(){};function r(a){a.stage="check",t&&p(w,a),e(a)}var i=n.license.enabled(),o={currentVersion:n.config().version,channel:E()};try{if(i){var l=n.license.storedToken();if(!l){r(s("no_license","Sign in to check for updates."));return}o.license_token=l,o.computer_id=n.computerId()}}catch(a){r(s("error",a.message));return}n.api("/updates/check",o,function(a,u){if(a){i&&a.kind==="rejected"&&n.license.isRejectionCode(a.code)&&n.license.applyRejection(a),r(s(a.kind==="network"?"network":a.code,a.message));return}if(!u||!u.updateAvailable){e(null,{updateAvailable:!1});return}var d=O(u);if(f&&f===d.version){d.alreadyInstalled=!0,e(null,d);return}if(e(null,d),y==="prompt"){p(P,d);return}t&&C===d.version||V(d,function(c){if(c){if(c.code==="busy"){n.log("info","Another panel is installing update "+d.version+".");return}C=d.version,c.stage="install",c.info=_(d),p(w,c)}})})}function q(){return n.node("path").join(n.dataDir(),"update.lock")}function z(){var e=n.node("fs"),t;try{t=q(),n.mkdirp(n.dataDir())}catch(o){return n.log("warn","Update lock unavailable",o&&o.message),function(){}}for(var r=0;r<2;r++)try{return e.closeSync(e.openSync(t,"wx")),function(){try{e.unlinkSync(t)}catch(o){}}}catch(o){if(!o||o.code!=="EEXIST")return n.log("warn","Update lock unavailable",o&&o.message),function(){};var i=!1;try{i=n.now()-e.statSync(t).mtime.getTime()>U}catch(l){i=!0}if(!i)return null;try{e.unlinkSync(t)}catch(l){}}return null}function F(){try{var e=n.node("fs"),t=e.readFileSync(n.node("path").join(n.extensionPath(),"CSXS","manifest.xml"),"utf8"),r=/ExtensionBundleVersion\s*=\s*"([^"]+)"/.exec(t);return r?r[1]:null}catch(i){return null}}function A(e,t){var r=_(e);f=r.version,p(m,r),t&&n.events.emit("update.installed",r)}function V(e,t){if(t=typeof t=="function"?t:function(){},k){t(s("busy","An update is already being installed."));return}if(n.isDev()){t(s("dev_build","Updates are not installed in dev builds."));return}e&&!e.targetVersion&&e.version&&(e=n.extend({},e,{targetVersion:e.version}));try{G(e),n.verifyReleaseSignature(String(e.targetVersion),String(e.sha256).toLowerCase(),e.signature)}catch(a){t(a);return}var r=String(e.targetVersion);if(r!==String(n.config().version)&&F()===r){var i={version:r,backupPath:null,alreadyInstalled:!0};f!==r&&A(e,!1),t(null,i);return}var o=z();if(!o){t(s("busy","Another panel is installing an update."));return}k=!0;function l(a,u){k=!1,o(),a||A(e,!0),t(a||null,u)}n.request("GET",e.downloadUrl,null,function(a,u){if(a){l(s("download_failed","Download failed: "+a.message));return}if(u.status!==200){l(s("download_failed","Download failed (HTTP "+u.status+")."));return}var d;try{d=X(u.body,e)}catch(c){l(c);return}l(null,d)})}function X(e,t){var r=n.node("path"),i=n.node("fs"),o=n.config(),l=String(t.sha256).toLowerCase();if(n.sha256Hex(e)!==l)throw s("bad_checksum","The downloaded update is corrupted (checksum mismatch). Nothing was installed.");var a=n.makeTempDir("afterpresets-update-"+String(o.bundleId).replace(/[^A-Za-z0-9.-]/g,"_")),u=r.join(a,"stage");try{n.mkdirp(u),n.extractBundle(e,o.bundleId,u)}catch(h){try{n.rmrf(a)}catch(L){}throw h}var d=n.extensionPath();if(!d||!i.existsSync(d)){try{n.rmrf(a)}catch(h){}throw s("install_failed","The extension folder could not be found.")}var c=r.join(a,"backup");try{n.copyDir(d,c)}catch(h){try{n.rmrf(a)}catch(L){}throw s("install_failed","Could not back up the current version: "+h.message)}try{n.emptyDir(d),n.copyDir(u,d)}catch(h){var T=!1;try{n.emptyDir(d),n.copyDir(c,d),T=!0}catch(L){n.log("error","Restoring the backup failed. Backup kept at "+c,L)}throw s("install_failed","The update could not be installed: "+h.message+(T?" The previous version was restored.":" The previous version is backed up at "+c+"."),{restored:T,backupPath:c})}try{n.rmrf(u)}catch(h){}return{version:String(t.targetVersion),backupPath:c}}function B(){try{g.location&&typeof g.location.reload=="function"&&g.location.reload()}catch(e){n.log("error","Could not reload the panel",e&&e.message)}}function $(){b||(b=!0,n.events.emit("reload",{version:f}),g.setTimeout(B,50))}x.updates={check:function(e){I(e,!1)},install:V,reload:$,onAvailable:function(e){return S(P,e)},onInstalled:function(e){return S(m,e)},onError:function(e){return S(w,e)},getChannel:E,setChannel:K},n.updates={configure:function(e){y=e&&R[e.mode]===!0?e.mode:"background",n.events.on("update.installed",function(t){!t||typeof t.version!="string"||t.version===f||(f=t.version,p(m,_(t)))}),n.events.on("reload",function(){b=!0,B()})},autoCheck:function(){I(null,!0)},mode:function(){return y}}})(typeof window!="undefined"?window:this);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";function n(e,s){const a=s&&s.webBase?s.webBase:"https://afterpresets.com",t=e.details||{};switch(e.code){case"push_quota_exceeded":return{message:"You have used all production pushes for this month.",hint:"Test-channel pushes and rollbacks do not count. Push to test with `--channel test`, wait for the next UTC month, or upgrade to Creator or Studio: "+a+"/membership"};case"version_not_greater":return{message:"This version is not greater than every existing release.",hint:"Check `ap releases list`, then push again with a larger --bump."};case"runtime_retired":return{message:"The @afterpresets/runtime version in this build has been retired.",hint:"Update it with `ap upgrade`, test with `ap dev`, and push again. Published releases keep working."};case"unauthorized":case"invalid_token":case"token_revoked":return{message:"Your CLI login is no longer valid.",hint:"Run `ap login` again."};case"forbidden":case"not_owner":return{message:"Your account does not own this extension.",hint:"Check that you are logged in as the right account with `ap whoami`."};case"not_found":case"product_not_found":return{message:e.serverMessage||"Not found.",hint:"Check the bundle ID in afterpresets.json and `ap whoami`."};case"expired_token":return{message:"The login request expired before it was approved.",hint:"Run `ap login` again."};case"slug_taken":case"slug_conflict":return{message:e.serverMessage||"That slug is already used by one of your extensions.",hint:"Choose a different slug."};case"tester_limit":case"tester_limit_reached":return{message:"
|
|
1
|
+
"use strict";function n(e,s){const a=s&&s.webBase?s.webBase:"https://afterpresets.com",t=e.details||{};switch(e.code){case"push_quota_exceeded":return{message:"You have used all production pushes for this month.",hint:"Test-channel pushes and rollbacks do not count. Push to test with `--channel test`, wait for the next UTC month, or upgrade to Creator or Studio: "+a+"/membership"};case"version_not_greater":return{message:"This version is not greater than every existing release.",hint:"Check `ap releases list`, then push again with a larger --bump."};case"runtime_retired":return{message:"The @afterpresets/runtime version in this build has been retired.",hint:"Update it with `ap upgrade`, test with `ap dev`, and push again. Published releases keep working."};case"unauthorized":case"invalid_token":case"token_revoked":return{message:"Your CLI login is no longer valid.",hint:"Run `ap login` again."};case"forbidden":case"not_owner":return{message:"Your account does not own this extension.",hint:"Check that you are logged in as the right account with `ap whoami`."};case"not_found":case"product_not_found":return{message:e.serverMessage||"Not found.",hint:"Check the bundle ID in afterpresets.json and `ap whoami`."};case"expired_token":return{message:"The login request expired before it was approved.",hint:"Run `ap login` again."};case"slug_taken":case"slug_conflict":return{message:e.serverMessage||"That slug is already used by one of your extensions.",hint:"Choose a different slug."};case"tester_limit":case"tester_limit_reached":return{message:e.serverMessage||"You've reached your plan's tester limit.",hint:"Remove a tester with `ap testers remove <email>`, or upgrade your plan on afterpresets.com/membership."};case"payload_too_large":return{message:"The bundle is larger than 200 MB.",hint:"Remove unused assets from the asset folders."};case"network_error":return{message:e.serverMessage,hint:"Check your internet connection. AI agents: your sandbox may be blocking the internet; ask the user to allow this command to run outside the sandbox. (When testing locally, check AP_API_BASE.)"};default:return{message:e.serverMessage||"The AfterPresets API returned HTTP "+e.status+".",hint:t.manageDevicesUrl?"Manage devices: "+t.manageDevicesUrl:null}}}module.exports={describeApiError:n};
|
package/src/build/build.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
"use strict";const
|
|
2
|
-
`):""}function
|
|
1
|
+
"use strict";const l=require("fs"),u=require("path"),w=require("../config"),{generateManifest:F}=require("../project/manifest"),{bundlePanel:D,assetUrl:E}=require("./bundle"),{concatJsx:k}=require("./jsx"),{loadRuntime:A,concatFiles:x}=require("./runtime"),{copyAssets:B}=require("./assets"),{processIndexHtml:K}=require("./html"),{debugFileXml:O,debugPorts:R}=require("../dev/debug-file"),{CliError:S}=require("../errors"),{projectTargets:J}=require("../targets"),I="src";function q(e){const n=I+"/panels/"+e;return{dir:n,html:n+"/index.html",js:n+"/main.js"}}function P(e,n){return u.join(e,n.split("/").join(u.sep))}function L(e){l.mkdirSync(e,{recursive:!0}),l.readdirSync(e).forEach(n=>l.rmSync(u.join(e,n),{recursive:!0,force:!0}))}function N(e,n,r,s,a){const t=w.webBase(e),o=w.signingPublicKey(e);if(!o&&!s.dev)throw new S("No release signing public key is configured.",{hint:"Set AP_SIGNING_PUBLIC_KEY or run `ap config set signing-public-key <file-or-pem>`. The production key is not yet embedded in this CLI."});return{bundleId:n.settings.bundleId,panelId:r.id,version:s.version,apiBase:s.apiBase||w.apiBase(e,null),publicKey:o,name:n.settings.name||void 0,productUrl:n.settings.listingUrl||t,manageDevicesUrl:t+"/settings/extensions",dev:!!s.dev,runtimeVersion:a}}function y(e){return JSON.stringify(String(e)).replace(/\u2028/g,"\\u2028").replace(/\u2029/g,"\\u2029").replace(/<\/(script)/gi,"<\\/$1")}function _(e){return e.trim()?["(function () {",' var style = document.createElement("style");',' style.setAttribute("data-ap", "bundle");'," style.textContent = "+y(e)+";"," (document.head || document.documentElement).appendChild(style);","}());"].join(`
|
|
2
|
+
`):""}function M(e){return e.trim()?`(function () {
|
|
3
3
|
document.body.innerHTML = `+y(e)+`;
|
|
4
4
|
}());`:""}function C(e){return["/* ---- ap dev live reload (dev builds only) ---- */","(function () {"," var BUILD = "+y(e)+";",' var KEY = "ap-dev-reloaded-for";',' if (typeof require !== "function" || !window.AP || !AP.paths) return;',' var fs = require("fs");',' var stamp = require("path").join(AP.paths.extension(), ".ap-dev-build");'," var warned = null;"," var timer = setInterval(function () {"," var id, last = null;",' try { id = String(fs.readFileSync(stamp, "utf8")).trim(); } catch (e) { return; }'," if (!id || id === BUILD) return;"," try { last = window.sessionStorage.getItem(KEY); } catch (e) { last = null; }"," if (last === id) {",' if (warned !== id) { warned = id; console.warn("ap dev: this page is not build " + id + " (two builds overlapped?). Save a file to rebuild; not reloading again for this build."); }'," return;"," }"," try { window.sessionStorage.setItem(KEY, id); } catch (e) { /* reload anyway */ }"," clearInterval(timer);"," window.location.reload();"," }, 400);","}());"].join(`
|
|
5
|
-
`)}async function U(e,n,r,
|
|
6
|
-
`));if(
|
|
7
|
-
`:"",
|
|
8
|
-
`),"/* ---- markup ("+i.html+") ---- */",
|
|
9
|
-
`)),{inputs:
|
|
5
|
+
`)}async function U(e,n,r,s,a,t,o,c){const d=n.root,i=q(r.id),g=P(d,i.html);if(!l.existsSync(g))throw new S("Missing "+i.html+".",{hint:"Create it, or run `ap add panel "+r.id+"`."});const f=K(l.readFileSync(g,"utf8"),i.html,i.js,v=>E(d,n.settings,g,v));if(f.errors.length)throw new S(f.errors.join(`
|
|
6
|
+
`));if(c.push.apply(c,f.warnings),!l.existsSync(P(d,i.js)))throw new S("Missing "+i.js+".",{hint:"It starts the panel with AP.boot({ start })."});const m=await D(d,i.js,n.settings),b=N(e,n,r,t,s.version),j=s.files.css.length?x(s.files.css)+`
|
|
7
|
+
`:"",h=t.dev?2:0,p=u.join(o,"panels",r.id);return l.mkdirSync(p,{recursive:!0}),l.writeFileSync(u.join(p,"index.html"),f.shell),l.writeFileSync(u.join(p,"main.js"),["/* Built by the AfterPresets CLI. Edit the source files, not this bundle. */","var AP_CONFIG = "+JSON.stringify(b,null,h)+";","var AP_JSX = "+Y(a)+";","/* ---- styles (imported by "+i.js+") ---- */",_(j+m.css+`
|
|
8
|
+
`),"/* ---- markup ("+i.html+") ---- */",M(f.body),"/* ---- @afterpresets/runtime ---- */",x(s.files.js),";","/* ---- developer code ("+i.js+" and its imports) ---- */",m.js,t.liveReload?C(t.buildId):"",""].join(`
|
|
9
|
+
`)),{inputs:m.inputs,publicKey:b.publicKey}}function X(e){return"{ type: "+y(e.type)+", code: "+y(e.code)+" }"}function Y(e){return"{ "+Object.keys(e.hosts).map(n=>y(n)+": "+X(e.hosts[n])).join(", ")+" }"}function G(e,n,r,s,a){const t=k(e.root,n.files.jsx,a);if(r.dev)return{type:"jsx",code:t.source,files:t.files};const c=(r.compileJsx||require("./jsxbin").compileJsxbin)(t.source,{fileName:u.join(s,"jsx","main.jsx"),lineMap:t.lineMap});return{type:"jsxbin",code:String(c).trim(),files:t.files}}function H(e,n,r,s){const a={},t=[];return J(e.settings).filter(o=>o.platform==="cep").forEach(o=>{const c=G(e,n,r,s,o.jsxDir);a[o.host]={type:c.type,code:c.code},c.files.forEach(d=>t.indexOf(d)===-1&&t.push(d))}),{hosts:a,files:t.sort()}}async function T(e,n,r){const s=!!r.dev,a=r.version||n.version,t=s?Date.now().toString(36)+"-"+Math.random().toString(36).slice(2,8):null,o=Object.assign({},r,{dev:s,version:a,buildId:t,liveReload:s&&r.liveReload!==!1}),c=[],d=A(e,n.root),i=r.outDir;L(i);const g=H(n,d,o,i),f={};let m=!1;for(const p of n.panels){const v=await U(e,n,p,d,g,o,i,c);f[p.id]={inputs:v.inputs},v.publicKey||(m=!0)}m&&c.push("No signing public key is set; update signature checks cannot run in this dev build.");const b=g.files;l.mkdirSync(u.join(i,"CSXS"),{recursive:!0}),l.writeFileSync(u.join(i,"CSXS","manifest.xml"),F(n.settings,n.panels,a));const j=B(n.root,i,n.settings),h=R(n.panels,w.projectDebugPort(n.settings));return s&&l.writeFileSync(u.join(i,".debug"),O(h,n.settings.hosts.map(p=>p.app))),o.liveReload&&l.writeFileSync(u.join(i,".ap-dev-build"),t),{outDir:i,version:a,runtimeVersion:d.version,warnings:c,debugPorts:h,files:{panels:f,jsx:b,assets:j}}}function V(e){return u.join(e.root,"dist",e.settings.bundleId)}function $(e){return u.join(e.root,"dist-dev",e.settings.bundleId)}module.exports={buildProject:T,productionOutDir:V,devOutDir:$,panelSources:q,SRC_DIR:I,__liveReloadClient:C};
|
package/src/build/html.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"use strict";const m={js:"main.js",css:"main.css"},b={js:["main.js"
|
|
1
|
+
"use strict";const m={js:"main.js",css:"main.css"},b={js:["main.js"],css:["main.css"]},g=/(\b(?:src|href)\s*=\s*)(["'])([^"']+)\2/gi;function j(t){return!/^(?:[a-z][a-z0-9+.-]*:|\/\/|#)/i.test(t)}function x(t){const s=t.replace(/[?#].*$/,"").replace(/^\.\//,"");return b.js.indexOf(s)!==-1?"js":b.css.indexOf(s)!==-1?"css":/\.(?:js|css)$/i.test(s)?"other":null}const C=/<script\b[^>]*>[\s\S]*?<\/script\s*>/gi,y=/<link\b[^>]*\bhref\s*=\s*(["'])(?:\.\/)?(?:css\/)?main\.css(?:[?#][^"']*)?\1[^>]*>\s*/gi;function I(t){return t.replace(/<!--[\s\S]*?-->/g,"")}function S(t){const s=I(t),r=/<html\b([^>]*)>/i.exec(s),i=/<head\b[^>]*>([\s\S]*?)<\/head\s*>/i.exec(s),e=/<body\b([^>]*)>([\s\S]*?)<\/body\s*>/i.exec(s),h=(i?i[1]:"").replace(y,"").trim();let o=0;const a=[],d=(e?e[2]:s.replace(/<head\b[\s\S]*?<\/head\s*>/i,"").replace(/<\/?(?:html|body|!doctype)[^>]*>/gi,"")).replace(y,"").replace(C,n=>{const c=/\bsrc\s*=\s*(["'])([^"']+)\1/i.exec(n);return c?j(c[2])||a.push(n.trim()):o++,""}).replace(/\n\s*\n/g,`
|
|
2
2
|
`).trim();return{shell:["<!doctype html>","<html"+(r?r[1]:' lang="en"')+">","<head>",h?" "+h.replace(/\n\s*/g,`
|
|
3
3
|
`):' <meta charset="utf-8" />',"</head>","<body"+(e?e[1]:"")+">"].concat(a.map(n=>" "+n)).concat([' <script src="'+m.js+'"></script>',"</body>","</html>",""]).join(`
|
|
4
4
|
`),body:d,inlineScripts:o}}function L(t,s,r,i){const e=[],h=[],o={js:!1,css:!1},a=t.replace(g,(d,u,n,c)=>{if(!j(c))return d;const l=x(c);if(l==="js"||l==="css")return o[l]=!0,u+n+m[l]+n;if(l==="other")e.push(s+" references "+c+", which is not in the bundle. Import it from "+r+" instead.");else if(i){const f=i(c);if(f.error)e.push(f.error);else return u+n+f.url+n}return d});o.js||e.push(s+' must load the bundle with <script src="main.js"></script>.');const p=S(a);return p.inlineScripts&&e.push(s+" has an inline <script> in <body>. Move that code into "+r+"."),{html:a,shell:p.shell,body:p.body,errors:e,warnings:h}}module.exports={processIndexHtml:L,splitIndexHtml:S,BUILT:m};
|
package/src/build/jsx.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
"use strict";const
|
|
1
|
+
"use strict";const u=require("fs"),i=require("path"),{TARGETS:D}=require("../targets"),f="jsx",a=D.filter(n=>n.jsxDir).map(n=>n.jsxDir);function p(n){if(!u.existsSync(n))return[];const e=[];return u.readdirSync(n,{withFileTypes:!0}).forEach(t=>{const s=i.join(n,t.name);t.isDirectory()?e.push.apply(e,p(s)):t.isFile()&&e.push(s)}),e}function F(n){return n.split(i.sep).join("/")}function h(n){return p(i.join(n,f)).map(e=>F(i.relative(n,e))).sort()}function j(n){const e=n.split("/");return e.length>2&&a.indexOf(e[1])!==-1?e[1]:null}function x(n,e){return h(n).filter(t=>{if(!t.toLowerCase().endsWith(".jsx"))return!1;if(e===void 0)return!0;const s=j(t);return s===null||s===e})}function m(n,e,t){const s=[],o=[],c=(r,S)=>{S.replace(/^/,"").split(/\r?\n/).forEach((d,y)=>{s.push(d),o.push({file:r,line:y+1})})};e.forEach(r=>c("@afterpresets/runtime/"+i.basename(r),u.readFileSync(r,"utf8")));const l=x(n,t);return l.forEach(r=>c(r,u.readFileSync(i.join(n,r),"utf8"))),{source:s.join(`
|
|
2
2
|
`)+`
|
|
3
|
-
`,files:
|
|
3
|
+
`,files:l,lineMap:o}}module.exports={JSX_DIR:f,HOST_JSX_DIRS:a,hostDirOf:j,jsxFiles:x,jsxDirFiles:h,concatJsx:m};
|
package/src/build/runtime.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"use strict";const
|
|
2
|
-
`+
|
|
1
|
+
"use strict";const i=require("fs"),e=require("path"),{CliError:o}=require("../errors");function d(s){try{return e.dirname(require.resolve("@afterpresets/runtime/package.json",{paths:[s]}))}catch{return null}}const j=e.join(__dirname,"..","..","runtime");function h(s,r){return s.runtimeDir?s.runtimeDir:i.existsSync(e.join(j,"runtime-files.json"))?j:d(__dirname)}function w(s,r){const n=h(s,r);if(!n)throw new o("The AfterPresets runtime was not found.",{hint:"Run `npm install` in the project, or `ap upgrade`."});const f=JSON.parse(i.readFileSync(e.join(n,"package.json"),"utf8")),p=e.join(n,"runtime-files.json");if(!i.existsSync(p))throw new o("@afterpresets/runtime "+f.version+" has no runtime-files.json at "+n+".",{hint:"Reinstall the CLI with `ap upgrade`."});const t=JSON.parse(i.readFileSync(p,"utf8")),m=Array.isArray(t)?t:t&&Array.isArray(t.files)?t.files:null;if(!m)throw new o("runtime-files.json must be an array of file paths.");const a={js:[],css:[],jsx:[]};return m.forEach(u=>{const c=e.resolve(n,u);if(!i.existsSync(c))throw new o("Runtime file listed in runtime-files.json is missing: "+u);const l=e.extname(u).toLowerCase();if(l===".js")a.js.push(c);else if(l===".css")a.css.push(c);else if(l===".jsx")a.jsx.push(c);else throw new o("runtime-files.json lists an unsupported file type: "+u)}),{dir:n,version:f.version,files:a,docsDir:e.join(n,"docs")}}function y(s){return s.map(r=>"/* "+e.basename(r)+` */
|
|
2
|
+
`+i.readFileSync(r,"utf8").replace(/^/,"")).join(`
|
|
3
3
|
;
|
|
4
|
-
`)}module.exports={findRuntimeDir:
|
|
4
|
+
`)}module.exports={findRuntimeDir:h,loadRuntime:w,concatFiles:y};
|
package/src/check/check.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
"use strict";const
|
|
2
|
-
`;)
|
|
3
|
-
`),
|
|
1
|
+
"use strict";const l=require("fs"),m=require("path"),{processIndexHtml:L}=require("../build/html"),{panelSources:q,SRC_DIR:b}=require("../build/build"),{bundlePanel:k,assetUrl:v}=require("../build/bundle"),{JSX_DIR:x,jsxDirFiles:T,hostDirOf:F}=require("../build/jsx"),{TARGETS:I,projectTargets:R}=require("../targets"),E=["signed_out","signing_in","checking","active","not_owned","refunded","offline_grace","offline_expired","error"],O=/\blicense\s*:\s*(?:true\b|\{)/,N=/\bAP\s*\.\s*boot\s*\(/;function j(s){if(!l.existsSync(s))return[];const e=[];return l.readdirSync(s,{withFileTypes:!0}).forEach(n=>{const o=m.join(s,n.name);n.isDirectory()?e.push.apply(e,j(o)):n.isFile()&&e.push(o)}),e}function P(s){let e="",n=0,o=null;for(;n<s.length;){const i=s[n],f=s[n+1];if(o){if(e+=i,i==="\\"){e+=f||"",n+=2;continue}i===o&&(o=null),n++;continue}if(i==='"'||i==="'"||i==="`"){o=i,e+=i,n++;continue}if(i==="/"&&f==="/"){for(;n<s.length&&s[n]!==`
|
|
2
|
+
`;)n++;continue}if(i==="/"&&f==="*"){const u=s.indexOf("*/",n+2);n=u===-1?s.length:u+2;continue}e+=i,n++}return e}function B(s,e){return m.relative(s,e).split(m.sep).join("/")}function d(s,e){return m.join(s,e.split("/").join(m.sep))}function D(s){const e=P(s),n=O.test(e);return{boots:N.test(e),licensed:n,rendersLicense:/\brenderLicense\b/.test(e),browserStorage:/\b(localStorage|sessionStorage|indexedDB)\b/.test(e),missingStatuses:E.filter(o=>!new RegExp("[\"'`]"+o+"[\"'`]").test(e))}}async function $(s){if(s.settings&&s.settings.platform==="native")return require("./native").checkNativeProject(s);const e=s.root,n=[],o=[],i=(t,r,h)=>t.push({code:r,message:h}),f={},u=[];for(const t of s.panels){const r=q(t.id);f[r.html]=!0;const h={id:t.id,boots:!1,licensed:!1};if(u.push(h),!l.existsSync(d(e,r.dir))){i(n,"missing_panel",'afterpresets.json lists panel "'+t.id+'" but '+r.dir+"/ does not exist. Run `ap add panel "+t.id+"` or remove it from afterpresets.json.");continue}if([r.html,r.js].forEach(a=>{l.existsSync(d(e,a))||i(n,"missing_entry","Missing "+a+".")}),l.existsSync(d(e,r.html))){const a=d(e,r.html),w=L(l.readFileSync(a,"utf8"),r.html,r.js,g=>v(e,s.settings,a,g));w.errors.forEach(g=>i(n,"index_html",g)),w.warnings.forEach(g=>i(o,"index_html",g))}if(!l.existsSync(d(e,r.js)))continue;let p;try{p=await k(e,r.js,s.settings)}catch(a){i(n,"bundle_failed",a.message);continue}p.inputs.forEach(a=>f[a]=!0);const A=p.inputs.filter(a=>/\.(js|html)$/i.test(a)&&!/(^|\/)node_modules\//.test(a)).map(a=>l.readFileSync(d(e,a),"utf8")).join(`
|
|
3
|
+
`),c=D(A);h.boots=c.boots,h.licensed=c.licensed,c.boots||i(n,"missing_boot",'Panel "'+t.id+'" never calls AP.boot(...). Start the panel from AP.boot({ start: ... }) in '+r.js+"."),c.browserStorage&&i(o,"browser_storage",'Panel "'+t.id+'" uses localStorage, sessionStorage or indexedDB. In CEP each panel gets its own copy and it can be cleared; save data with AP.storage instead. See docs/afterpresets/storage.md.'),c.licensed&&!c.rendersLicense&&i(n,"missing_render_license",'Panel "'+t.id+'" boots with licensing on but has no renderLicense. Pass renderLicense: function (api, root) { ... } to AP.boot. See docs/afterpresets/.'),c.licensed&&c.rendersLicense&&c.missingStatuses.forEach(a=>i(o,"license_status_unhandled",'Panel "'+t.id+'": license status "'+a+'" is not handled by its license screen code. See docs/afterpresets/.'))}j(d(e,b)).map(t=>B(e,t)).filter(t=>/\.(js|css|html)$/i.test(t)&&!f[t]).forEach(t=>i(o,"unused_file",t+" is not imported by any panel, so it is not built. Import it, or delete it."));const C=R(s.settings).map(t=>t.jsxDir).filter(Boolean),S={};T(e).forEach(t=>{const r=F(t);if(r&&C.indexOf(r)===-1){if(!S[r]){S[r]=!0;const h=I.find(p=>p.jsxDir===r).appName;i(o,"jsx_other_host",x+"/"+r+"/ is only loaded in "+h+", which this project does not target, so it is not built. Add the app with `ap add host "+r+"`, or move the files.")}return}/\.jsx$/i.test(t)||i(o,"jsx_not_loaded",t+" is not loaded: only .jsx files in "+x+"/ go into the build.")});const y={};s.panels.forEach(t=>y[t.id]=!0);const _=d(e,b+"/panels");return l.existsSync(_)&&l.readdirSync(_,{withFileTypes:!0}).filter(t=>t.isDirectory()&&!y[t.name]).forEach(t=>i(o,"unlisted_panel",b+"/panels/"+t.name+'/ is not listed in afterpresets.json, so it is not built. Add it to "panels" or delete the folder.')),{errors:n,warnings:o,panels:u,licensed:u.some(t=>t.licensed)}}function H(s,e){e.errors.forEach(o=>s.error(o.message)),e.warnings.forEach(o=>s.warn(o.message));const n=e.errors.length+" error(s), "+e.warnings.length+" warning(s)";e.errors.length?s.log(s.style.red("Check failed: "+n)):e.warnings.length?s.log(s.style.yellow("Check passed with "+n)):s.success("Check passed")}module.exports={checkProject:$,printCheck:H,stripComments:P,analyzePanelCode:D,LICENSE_STATUSES:E};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use strict";const U=require("crypto"),L=require("fs"),R=require("path"),H=/\.(c|cc|cpp|cxx|h|hh|hpp|hxx|m|mm|inl)$/i,B=/\.(c|cc|cpp|cxx|h|hh|hpp|hxx|m|mm|inl|r|rc|txt|md|json|cmake|plist|js|jsx|py|sh|bat|command)$/i,K=["build","dist","dist-dev","node_modules",".git","vendor","out"],X=["docs/afterpresets"],$=2*1024*1024,I={slider:"fs_d",angle:"ad",color:"cd",point:"td",checkbox:"bd",popup:"pd"},W=["sd","fs_d","ad","cd","td","bd","pd","ld","path_d","arb_d","button_d"],j=["A.h","AE_Effect.h","AE_EffectCB.h","AE_EffectCBSuites.h","AE_EffectSuites.h","AE_EffectSuitesHelper.h","AE_EffectUI.h","AE_EffectPixelFormat.h","AE_EffectGPUSuites.h","AE_EffectVers.h","AE_GeneralPlug.h","AE_GeneralPlugOld.h","AE_GeneralPlugPanels.h","AE_Hook.h","AE_IO.h","AE_IO_FileExt.h","AE_Macros.h","AE_PluginData.h","AEConfig.h","AEFX_ArbParseHelper.h","AEFX_ChannelDepthTpl.h","AEFX_SuiteHelper.h","AEGP_SuiteHandler.h","AEGP_SuiteHandler.cpp","AEGP_Utils.h","AE_ChannelSuites.h","AE_AdvEffectSuites.h","AE_ComputeCacheSuite.h","DrawbotSuite.h","FIEL_Public.h","Param_Utils.h","PF_Masks.h","PR_Public.h","PT_Public.h","SPAccess.h","SPAdapts.h","SPBasic.h","SPBckDbg.h","SPCaches.h","SPConfig.h","SPErrorCodes.h","SPErrors.h","SPFiles.h","SPHost.h","SPInterf.h","SPMData.h","SPPiPL.h","SPPlugs.h","SPProps.h","SPSuites.h","SPTypes.h","Smart_Utils.h","Smart_Utils.cpp","String_Utils.h","entry.h","AE_Effect.r","AE_General.r","AE_PluginData.r","AE_SDK.xcconfig","PiPLtool.exe","PiPLTool.exe"],Z=[/ADOBE\s+CONFIDENTIAL/,/Copyright\s*(?:\(c\)|©)?\s*(?:19|20)\d\d(?:\s*[-,]\s*(?:19|20)\d\d)?[^\n]{0,20}Adobe/i,/Adobe\s+Systems\s+Incorporated/i,/Adobe\s+permits\s+you\s+to\s+use,\s+modify,\s+and\s+distribute/i],q=["3521eb14b4afc632c9fa9e77093bfc501832c04adaf864c46e1bd8776f87f77e","0461c1fe4a979d33a1d8bda78c548d2af04b38e7ac772d405fe1efea3010d38f"],z=[{re:/\b(?:usleep|nanosleep|sleep|Sleep|SleepEx)\s*\(/,what:"sleeps"},{re:/\bsleep_for\s*\(|\bsleep_until\s*\(/,what:"sleeps"},{re:/\b(?:socket|getaddrinfo|gethostbyname|WSAStartup|recv|send)\s*\(/,what:"uses the network"},{re:/\bcurl_\w+\s*\(|\bWinHttp\w*\s*\(|\bInternetOpen\w*\s*\(|\bNSURLSession\b|\bNSURLConnection\b|\bCFNetwork\b|\bURLSession\b/,what:"uses the network"},{re:/\b(?:system|popen|_popen|fork|execv|execvp|CreateProcess\w*|ShellExecute\w*)\s*\(/,what:"starts a process"},{re:/\bMessageBox\w*\s*\(|\bNSAlert\b|\bstd::cin\b|\bgetchar\s*\(/,what:"waits for the user"}];function N(t,o,e){let i;try{i=L.readdirSync(o,{withFileTypes:!0})}catch{return e}return i.forEach(n=>{const r=R.join(o,n.name),c=R.relative(t,r).split(R.sep).join("/");if(n.isDirectory()){if(K.indexOf(n.name)!==-1||X.indexOf(c)!==-1||/\.(plugin|bundle)$/i.test(n.name))return;N(t,r,e)}else n.isFile()&&e.push(c)}),e}function v(t,o){const e=R.join(t,o.split("/").join(R.sep));try{return L.statSync(e).size>$?null:L.readFileSync(e,"utf8")}catch{return null}}function M(t){let o="",e=0;const i=t.length;let n=!0;for(;e<i;){const r=t[e],c=t[e+1];if(n&&r==="#"){for(;e<i&&t[e]!==`
|
|
2
|
+
`;){if(t[e]==="\\"&&t[e+1]===`
|
|
3
|
+
`){o+=`
|
|
4
|
+
`,e+=2;continue}o+=" ",e++}continue}if(r==="/"&&c==="/"){for(;e<i&&t[e]!==`
|
|
5
|
+
`;)o+=" ",e++;continue}if(r==="/"&&c==="*"){for(o+=" ",e+=2;e<i&&!(t[e]==="*"&&t[e+1]==="/");)o+=t[e]===`
|
|
6
|
+
`?`
|
|
7
|
+
`:" ",e++;e<i&&(o+=" ",e+=2);continue}if(r==='"'||r==="'"){for(o+=r,e++;e<i&&t[e]!==r&&t[e]!==`
|
|
8
|
+
`;)t[e]==="\\"&&(o+=" ",e++),o+=e<i?t[e]===`
|
|
9
|
+
`?`
|
|
10
|
+
`:" ":"",e++;e<i&&t[e]===r&&(o+=r,e++);continue}r===`
|
|
11
|
+
`?n=!0:r!==" "&&r!==" "&&r!=="\r"&&(n=!1),o+=r,e++}return o}function F(t,o){let e=1;for(let i=0;i<o&&i<t.length;i++)t.charCodeAt(i)===10&&e++;return e}function V(t){const o={};return t.split(`
|
|
12
|
+
`).forEach((e,i)=>{const n=e.match(/ap-check:\s*allow\b([^\n]*)/);n&&(o[i+1]=n[1])}),o}function T(t,o,e){return[o,o-1].some(i=>{const n=t[i];return n!==void 0&&(!n.trim()||n.indexOf(e)!==-1)})}const Y=/^(?:const|constexpr|consteval|constinit|typedef|using|extern|template|return|namespace|class|struct|union|enum|friend|case|default|goto|public|private|protected|static_assert|thread_local|delete|throw|break|continue|operator|virtual|explicit|inline\s+constexpr)\b/,J=/\b(?:std::)?(?:atomic\w*|mutex|shared_mutex|recursive_mutex|once_flag|condition_variable)\b|\bthread_local\b|\bconst\b|\bconstexpr\b/;function G(t){const o=[],e=[];let i=-1,n="",r=0;const c=()=>e.filter(a=>a==="block").length;function A(a,m){const _=n.replace(/\s+/g," ").trim(),P=i;if(n="",i=-1,!_)return;const p=c(),E=/^(?:\[\[[^\]]*\]\]\s*)?static\b/.test(_);if(p>0&&!E)return;const s=_.replace(/^(?:\[\[[^\]]*\]\]\s*)?static\s+/,"").replace(/^inline\s+/,"");if(Y.test(s)||J.test(_)||a==="{")return;const h=s.indexOf("{"),d=s.indexOf("="),f=h!==-1&&(d===-1||h<d)?h:d,l=s.indexOf("(");if(l!==-1&&(f===-1||l<f))return;const u=f===-1?s:s.slice(0,f);/^[A-Za-z_][\w:<>,\s*&]*[\s*&]\**\s*[A-Za-z_]\w*\s*(\[[^\]]*\]\s*)*$/.test(u.trim())&&o.push({line:F(t,P),text:_.length>80?_.slice(0,77)+"...":_})}for(let a=0;a<t.length;a++){const m=t[a];if(m==="("&&r++,m===")"&&(r=Math.max(0,r-1)),r>0){n+=m;continue}if(m===";"){A(";",a);continue}if(m==="{"){const _=n.replace(/\s+/g," ").trim();if(/=\s*$/.test(_)||/^(?:static\s+)?[A-Za-z_][\w:<>,\s*&]*\s[A-Za-z_]\w*\s*$/.test(_)&&!/^(?:namespace|class|struct|union|enum|extern)\b/.test(_)&&c()===0&&!/\)\s*(?:const)?\s*$/.test(_)){let p=1;n+="{";let E=a+1;for(;E<t.length&&p>0;E++)t[E]==="{"?p++:t[E]==="}"&&p--,n+=t[E];a=E-1;continue}const P=/^(?:inline\s+)?namespace\b/.test(_)||/^extern\s*""\s*$/.test(_)||/^extern\s*"C"\s*$/.test(_);A("{",a),e.push(P?"ns":"block");continue}if(m==="}"){A("}",a),e.pop();continue}i===-1&&!/\s/.test(m)&&(i=a),n+=m}return o}function Q(t){return String(t).toUpperCase()}function ee(t,o){const e=o||{},i=t.root,n=[],r=[],c=(s,h,d,f,l)=>s.push({code:h,file:d||null,line:f||null,message:(d?d+(f?":"+f:"")+": ":"")+l}),A=e.effectLib||te("../native/effect");let a=null;if(!A)c(r,"effect_json","effect.json",null,"This CLI cannot validate effect.json (no native toolchain). Run `ap upgrade`.");else try{a=A.loadEffect(i)}catch(s){(s&&Array.isArray(s.problems)?s.problems:[s.message]).forEach(d=>c(n,"effect_json","effect.json",null,d))}const m=t.settings.releasedEffect;a&&m&&A&&typeof A.compatibilityProblems=="function"&&A.compatibilityProblems({matchName:m.matchName,params:m.params||[]},a).forEach(s=>c(n,"effect_changed","effect.json",null,s+" (Version "+(m.version||"?")+" was released with the old value.)"));const _=N(i,i,[]),P=_.filter(s=>/^src\//.test(s)&&H.test(s)),p={};P.forEach(s=>{const h=v(i,s);h!==null&&(p[s]={raw:h,code:M(h),allow:V(h)})});const E=Object.keys(p).map(s=>p[s].code).join(`
|
|
13
|
+
`);if(P.length&&!/\bEffectMain\b/.test(E)&&c(n,"missing_entry_point","src/",null,"No EffectMain function. After Effects calls the entry point named in the PiPL (EffectMain); keep the starter's `PF_Err EffectMain(...)` with its export macro."),a){const s=a.outFlags||[],h=a.outFlags2||[];Object.keys(p).forEach(f=>{const l=p[f],u=/\bout_flags(2?)\s*(\|?=)\s*([^;]+);/g;let b;for(;b=u.exec(l.code);){const g=b[1]?"AP_OUT_FLAGS2":"AP_OUT_FLAGS",D=F(l.code,b.index);if(T(l.allow,D,"out_flags"))continue;const y=b[1]?A.OUT_FLAGS2||{}:A.OUT_FLAGS||{},S=(b[3].match(/PF_OutFlag2?_(\w+)/g)||[]).map(x=>x.replace(/^PF_OutFlag2?_/,"")).filter(x=>Object.prototype.hasOwnProperty.call(y,x));(b[2]==="|="?S.length>0:!/\bAP_OUT_FLAGS2?\b/.test(b[3])||S.length>0)&&c(n,"out_flags",f,D,"Set out_data->out_flags"+b[1]+" = "+g+'; exactly (generated from effect.json). The PiPL carries the same flags and After Effects refuses an effect whose flags disagree. Change flags in effect.json "outFlags'+b[1]+'".')}}),h.indexOf("SUPPORTS_SMART_RENDER")!==-1&&P.length&&!/\bPF_Cmd_SMART_RENDER\b/.test(E)&&c(n,"smart_render","src/",null,"effect.json promises Smart Render (SUPPORTS_SMART_RENDER) but no code handles PF_Cmd_SMART_PRE_RENDER / PF_Cmd_SMART_RENDER. Handle both (see the starter), or remove the flag."),s.indexOf("DEEP_COLOR_AWARE")!==-1&&P.length&&!/\bPF_Pixel16\b|\bPF_PixelFormat_ARGB64\b|\biterate16\b|\bPF_WORLD_IS_DEEP\b/.test(E)&&c(r,"bit_depth","src/",null,"effect.json says 16 bpc (DEEP_COLOR_AWARE) but no code handles PF_Pixel16 / PF_PixelFormat_ARGB64. Render 16-bpc worlds too, or remove the flag."),h.indexOf("FLOAT_COLOR_AWARE")!==-1&&P.length&&!/\bPF_PixelFloat\b|\bPF_PixelFormat_ARGB128\b|\bPF_Pixel32\b/.test(E)&&c(r,"bit_depth","src/",null,"effect.json says 32 bpc (FLOAT_COLOR_AWARE) but no code handles PF_PixelFloat / PF_PixelFormat_ARGB128. Render float worlds too, or remove the flag."),s.indexOf("I_DO_DIALOG")!==-1&&P.length&&!/\bPF_Cmd_DO_DIALOG\b/.test(E)&&c(r,"dialog","src/",null,"effect.json sets I_DO_DIALOG (the Options button) but no code handles PF_Cmd_DO_DIALOG."),h.indexOf("SUPPORTS_THREADED_RENDERING")!==-1&&Object.keys(p).forEach(f=>{const l=p[f];G(l.code).forEach(u=>{T(l.allow,u.line,"mfr_global")||c(n,"mfr_global",f,u.line,"`"+u.text+"` is a mutable global/static, but multi-frame rendering (SUPPORTS_THREADED_RENDERING) renders several frames at once on different threads. Make it const, keep the value in a local variable or the effect's sequence data, or use std::atomic / a mutex. If it is written only in GLOBAL_SETUP/GLOBAL_SETDOWN (before or after every render) or is already thread-safe, put `// ap-check: allow mfr_global` on that line or the line above.")})});const d={};a.params.forEach(f=>d["AP_PARAM_"+Q(f.key)]=f),Object.keys(p).forEach(f=>{const l=p[f],u=(w,S,O)=>{const x=d[w],k=x&&I[x.type];if(!k||S===k||W.indexOf(S)===-1)return;const C=F(l.code,O);T(l.allow,C,"param_union")||c(n,"param_union",f,C,w+" is a "+x.type+' ("'+x.name+'"): read it with u.'+k+" (not u."+S+"); the other members hold garbage for this type.")},b=/\[\s*(AP_PARAM_[A-Z0-9_]+)\s*\]\s*(?:->|\.)\s*u\s*\.\s*(\w+)/g;let g;for(;g=b.exec(l.code);)u(g[1],g[2],g.index);const D=/PF_CHECKOUT_PARAM\s*\(\s*[^,]+,\s*(AP_PARAM_[A-Z0-9_]+)\s*,[^;]*?&\s*([A-Za-z_]\w*)\s*\)/g,y={};for(;g=D.exec(l.code);)y[g[2]]=g[1];Object.keys(y).forEach(w=>{const S=new RegExp("\\b"+w+"\\s*(?:->|\\.)\\s*u\\s*\\.\\s*(\\w+)","g");let O;for(;O=S.exec(l.code);)u(y[w],O[1],O.index)})})}return Object.keys(p).forEach(s=>{const h=p[s],d=/\b65535(?:\.0*)?[fFuU]?\b|\b0[xX][fF]{4}\b/g;let f;for(;f=d.exec(h.code);){const l=F(h.code,f.index);T(h.allow,l,"chan16_max")||c(n,"chan16_max",s,l,"After Effects' 16-bpc white is 32768 (PF_MAX_CHAN16), not 65535. Use PF_MAX_CHAN16, or add `// ap-check: allow chan16_max` if this is not a pixel value.")}h.code.split(`
|
|
14
|
+
`).forEach((l,u)=>{z.forEach(b=>{!b.re.test(l)||T(h.allow,u+1,"blocking_call")||c(n,"blocking_call",s,u+1,"This "+b.what+". After Effects calls Render on many threads at once and waits for it, so it must never wait or do I/O; ap_native already checks licences and updates on its own thread. Move it out of the render path, or add `// ap-check: allow blocking_call` for code that never runs while rendering.")})})}),_.forEach(s=>{const h=R.posix.basename(s);if(j.indexOf(h)!==-1){c(n,"sdk_file",s,null,"This is a file from Adobe's After Effects SDK. Delete it: the build reads the SDK from `ap sdk`'s folder on this computer, and Adobe's files must not be copied into your project or shipped.");return}if(/\.r$/i.test(s)&&/^src\//.test(s)){const u=v(i,s);u&&/\bPiPL\b/.test(u)&&c(r,"pipl_file",s,null,"The build generates the PiPL from effect.json; this hand-written PiPL is not used. Delete it and change effect.json instead.")}if(!B.test(s))return;const d=v(i,s);if(d===null)return;for(const u of Z){const b=u.exec(d);if(b){c(n,"sdk_file",s,F(d,b.index),"This file contains Adobe's SDK copyright text, so it looks copied from the SDK. Write your own code (the SDK guide in docs/afterpresets/sdk/ explains the APIs) and delete the copied text.");break}}const l=(d.match(/\bsave[A-Za-z]{4,20}\b/g)||[]).find(u=>q.indexOf(U.createHash("sha256").update(u).digest("hex"))!==-1);l&&c(n,"private_api",s,F(d,d.indexOf(l)),"`"+l+"` is not part of After Effects' public scripting API. Remove it from the project; use the documented API (to look at frames while developing, use comp_capture).")}),a&&a.license&&a.license.enabled&&P.length&&!/\bap_is_unlocked\s*\(/.test(E)&&c(r,"license_unused","src/",null,"Licensing is on in effect.json but no code calls ap_is_unlocked(). Render must check it (the starter draws a watermark when it returns 0), or buyers without a licence get the full effect."),{errors:n,warnings:r,panels:[],licensed:!!(a&&a.license&&a.license.enabled),native:!0,effect:a}}function te(t){try{return require(t)}catch{return null}}function se(t,o){return{version:o,matchName:t.matchName,params:t.params.map(e=>({id:e.id,type:e.type,name:e.name}))}}module.exports={checkNativeProject:ee,releasedEffectRecord:se,stripCode:M,mutableGlobals:G,SDK_FILE_NAMES:j,UNION_MEMBER:I};
|
package/src/check/pricing.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";const{readCredentials:
|
|
1
|
+
"use strict";const{readCredentials:u}=require("../auth/credentials"),{createApiClient:a}=require("../api/client"),{productPath:l}=require("../api/session");function c(r,t){const e=(r/100).toFixed(2);return t?e+" "+String(t).toUpperCase():e}function d(r,t){const e=[],i=[],s=r?r.priceMinor:void 0;if(s===void 0)return i.push({code:"price_unknown",message:"The API did not report this product's price, so the paid-product licensing rule could not be verified."}),{errors:e,warnings:i};if(!(Number(s)>0))return{errors:e,warnings:i};const o=c(Number(s),r.currency);return!t.licensed&&t.native?(e.push({code:"paid_without_license",message:"This product is paid ("+o+') but effect.json turns licensing off ("license": false). Remove that line (licensing is on by default). See docs/afterpresets/.'}),{errors:e,warnings:i}):t.licensed?(t.panels.filter(n=>n.boots&&!n.licensed).forEach(n=>i.push({code:"paid_panel_unlicensed",message:'Panel "'+n.id+'" boots without licensing although the product is paid. Make sure it does nothing useful without a license.'})),{errors:e,warnings:i}):(e.push({code:"paid_without_license",message:"This product is paid ("+o+") but no panel boots with licensing on. Pass `license: true` and a renderLicense function to AP.boot in src/panels/<id>/main.js. See docs/afterpresets/."}),{errors:e,warnings:i})}async function p(r,t,e){const i=u(r),s=n=>({errors:[],warnings:[{code:"price_unverified",message:"Could not verify the product price ("+n+"). Paid products must boot with licensing on; `ap push` enforces this."}],verified:!1});if(!i)return s("not logged in");let o;try{o=await a(r,i).get(l(t.settings.bundleId))}catch(n){return s(n.code==="network_error"?"offline":n.code||n.message)}return Object.assign(d(o.product||null,e),{verified:!0})}module.exports={pricingProblems:d,verifyPricingOnline:p,formatPrice:c};
|
package/src/check/types.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
"use strict";const
|
|
1
|
+
"use strict";const h=require("fs"),a=require("path"),{jsxFiles:v}=require("../build/jsx"),{projectTargets:O}=require("../targets"),_=a.join(__dirname,"..","..","vendor","types-for-adobe"),F=a.join(__dirname,"..","..","vendor","afterpresets-additions");function k(e){return O(e.settings).filter(o=>o.types)}function m(e){if(!e.typesAdditions)return null;const o=a.join(F,e.typesAdditions);if(!h.existsSync(o))return null;const s=h.readFileSync(o,"utf8").slice(0,600),t=/^\/\/ Source: .*? (\d+(?:\.\d+)+)/m.exec(s);return{file:o,version:t?t[1]:null}}function I(e){const o=k(e).map(s=>{const t=m(s);return s.typesLabel+(t&&t.version?" (+ "+t.version+" additions)":"")});return(o.length?o.join(" and "):"no")+" types"}const P=a.join(__dirname,"extendscript-globals.d.ts"),A=[2551,2552,2554,2555],D=2339,N=/^Property '([^']+)' does not exist on type '(string|number|boolean|String|Number|Boolean|Math|Array<.*>|.*\[\]|"[^"]*"|-?\d[\d.]*)'\.?$/,w=["toJSON"];function L(e){return e.replace(/^[ \t]*#[A-Za-z].*$/gm,"")}function R(e,o,s){if(s||A.indexOf(e)!==-1)return!0;if(e!==D)return!1;const t=N.exec(o);return!!t&&w.indexOf(t[1])===-1}function q(e){const o=k(e),s={files:0,likely:[],other:[]},t={},i={};o.forEach(c=>{const l=v(e.root,c.jsxDir);if(l.forEach(n=>{i[n]||(s.files+=1),i[n]=!0}),!l.length)return;const f=m(c),g=[a.join(_,c.types,"index.d.ts")].concat(f?[f.file]:[]),d=H(e.root,l,g);["likely","other"].forEach(n=>d[n].forEach(r=>{const y=r.file+":"+r.line+":"+r.column+":"+r.code+":"+r.message;t[y]||(t[y]=!0,o.length>1&&(r.app=c.appName),s[n].push(r))}))});const u=(c,l)=>c.file<l.file?-1:c.file>l.file?1:c.line-l.line||c.column-l.column;return s.likely.sort(u),s.other.sort(u),s}function H(e,o,s){const t=require("typescript"),i={likely:[],other:[]},u={allowJs:!0,checkJs:!0,noEmit:!0,noLib:!0,target:t.ScriptTarget.ES5,types:[],typeRoots:[],skipLibCheck:!0,strict:!1},c=o.map(n=>a.join(e,n)),l={};c.forEach(n=>l[a.resolve(n)]=!0);const f=t.createCompilerHost(u),g=f.getSourceFile.bind(f);f.getSourceFile=(n,r,y,p)=>{if(!l[a.resolve(n)])return g(n,r,y,p);const S=L(h.readFileSync(n,"utf8"));return t.createSourceFile(n,S,r,!0,t.ScriptKind.JS)};const d=t.createProgram([].concat(s,[P],c),u,f);return d.getSourceFiles().forEach(n=>{if(!l[a.resolve(n.fileName)])return;const r=d.getSyntacticDiagnostics(n);(r.length?r:d.getSemanticDiagnostics(n)).forEach(p=>{const x=t.flattenDiagnosticMessageText(p.messageText,`
|
|
2
2
|
`).split(`
|
|
3
|
-
`)[0],
|
|
3
|
+
`)[0],E=p.start===void 0?{line:0,character:0}:n.getLineAndCharacterOfPosition(p.start),b={file:a.relative(e,n.fileName).split(a.sep).join("/"),line:E.line+1,column:E.character+1,code:p.code,message:x};(R(p.code,x,r.length>0)?i.likely:i.other).push(b)})}),i}const T="Type hints are optional and can be wrong: the Adobe types have gaps and TypeScript does not follow every ExtendScript pattern. Test in the app before changing working code. Hints never fail the check.";function j(e){return e.file+":"+e.line+":"+e.column+" "+(e.app?"["+e.app+"] ":"")+e.message}function J(e,o,s){const t=o?e.likely.concat(e.other):e.likely,i=["Type hints for jsx/ ("+e.files+" file"+(e.files===1?"":"s")+", "+(s||"After Effects 26.0 types")+")",T];return e.files?(o?i.push(e.likely.length+" likely problem(s), "+e.other.length+" other hint(s) (often false alarms):"):i.push(e.likely.length+" likely problem(s)"+(e.other.length?"; "+e.other.length+" other hint(s) hidden, often false alarms (--types-all shows them)":"")+(e.likely.length?":":".")),t.forEach(u=>i.push(" "+j(u))),i):i.concat(["No .jsx files in jsx/."])}module.exports={typeHints:q,hintLines:J,formatHint:j,stripDirectives:L,typesLabel:I,additionsFor:m,NOISE_NOTE:T};
|
package/src/cli.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
"use strict";const{parseArgs:
|
|
2
|
-
`+
|
|
3
|
-
`),
|
|
4
|
-
`+
|
|
5
|
-
`),
|
|
1
|
+
"use strict";const{parseArgs:c}=require("./args"),{CliError:g}=require("./errors"),{findProjectRoot:m}=require("./project/project"),i=["login","logout","whoami","init","dev","check","add","build","push","releases","testers","docs","sdk","upgrade","config","mcp"].map(e=>require("./commands/"+e)),s=require("../package.json").version,l=require("./system/update-check");async function h(e,r){if(!(r==="mcp"||r==="upgrade"||!(e.stdout&&e.stdout.isTTY)))try{const o=await l.newerVersion(e);o&&e.out.log(`
|
|
2
|
+
`+e.out.style.dim(l.noticeText(o)))}catch{}}function a(e){return i.find(r=>r.name===e)||null}function f(e){e.banner("CLI "+s+" \xB7 build and publish After Effects and Premiere Pro extensions and effect plugins"),e.log("Usage: "+e.style.cyan("ap <command>")+` [options]
|
|
3
|
+
`),i.forEach(r=>e.log(" "+e.style.cyan(r.name.padEnd(10))+r.summary)),e.log(`
|
|
4
|
+
`+e.style.dim("Run `ap <command> --help` for details. Agent reference: docs/afterpresets/ in your project."))}function d(e,r){e.log("Usage: "+r.usage+`
|
|
5
|
+
`),e.log(r.description)}async function y(e,r){const o=e[0];if(!o&&r.prompt&&!m(r.cwd))return p(r,a("init"),[],n=>require("./commands/init").wizard(n));if(!o||o==="help"||o==="--help"||o==="-h"){const n=o==="help"&&e[1]?a(e[1]):null;return n?d(r.out,n):f(r.out),0}if(o==="--version"||o==="-v")return r.out.log(s),0;const t=a(o);return t?p(r,t,e.slice(1)):(r.out.error("Unknown command: "+o),f(r.out),2)}async function p(e,r,o,t){try{let n;if(t)n=await t(e);else{const u=c(o,r.flags);if(u.flags.help)return d(e.out,r),0;n=await r.run(e,u)}return await h(e,r.name),typeof n=="number"?n:0}catch(n){return n instanceof g?(e.out.error(n.message),n.hint&&e.out.log(" "+n.hint),n.exitCode===2&&e.out.log(" Usage: "+r.usage),n.exitCode||1):(e.out.error("Unexpected error: "+(n&&n.message?n.message:String(n))),e.env.AP_DEBUG?e.out.log(n&&n.stack):e.out.log(" Set AP_DEBUG=1 for the stack trace."),1)}}module.exports={main:y,COMMANDS:i,VERSION:s};
|
package/src/commands/add.js
CHANGED
|
@@ -1,6 +1,11 @@
|
|
|
1
|
-
"use strict";const
|
|
1
|
+
"use strict";const g=require("fs"),u=require("path"),{loadProject:w,updateProjectFile:A,readProjectFile:y}=require("../project/project"),{validatePanelId:x,normalizePanel:N,PANEL_TYPES:P}=require("../project/panels"),{scaffoldPanel:b}=require("../project/add-panel"),{UsageError:h,CliError:f}=require("../errors"),{apiSession:q,productPath:v}=require("../api/session"),{parseApp:S,cepHostCode:I,targetFor:U,hostAppNames:j}=require("../targets"),{copyHostStarter:C}=require("../project/template"),{writeProjectFile:D}=require("../project/project"),{findRuntimeDir:R}=require("../build/runtime"),{syncRuntimeDocs:O}=require("../project/docs");module.exports={name:"add",summary:"Add a panel, or the other Adobe app to a CEP extension",usage:`ap add panel <id> [--type panel|modal|invisible] [--title <title>] [--width <px>] [--height <px>]
|
|
2
|
+
ap add host aeft|ppro`,description:`ap add host aeft|ppro: makes a CEP extension run in After Effects (aeft) or Premiere Pro (ppro)
|
|
3
|
+
too. Updates the extension on AfterPresets and afterpresets.json; ExtendScript for that app
|
|
4
|
+
goes in jsx/aeft/ or jsx/ppro/ (jsx/*.jsx is shared). Requires \`ap login\`.
|
|
5
|
+
|
|
6
|
+
ap add panel: creates src/panels/<id>/ (index.html, and main.js with a placeholder AP.boot)
|
|
2
7
|
and adds the panel to afterpresets.json. Ids use lowercase letters, digits, and dashes.
|
|
3
8
|
panel a dockable window listed under Window > Extensions
|
|
4
9
|
modal a dialog you open from code with AP.panels.open(id)
|
|
5
|
-
invisible starts with
|
|
6
|
-
Restart
|
|
10
|
+
invisible starts with the app and has no window
|
|
11
|
+
Restart the app after adding a panel so it reads the new manifest.`,flags:{type:{type:"string",alias:"t"},title:{type:"string"},width:{type:"string"},height:{type:"string"}},async run(e,o){const p=o.positionals[0];if(p==="host")return k(e,o.positionals[1]);if(p!=="panel")throw new h(p?"Unknown item "+JSON.stringify(p)+".":"What should I add?","Example: ap add panel settings --type modal");const n=o.positionals[1];if(!n)throw new h("Give the panel an id.","Example: ap add panel settings");const r=x(n);if(r)throw new h(r);const s=o.flags.type||"panel";if(P.indexOf(s)===-1)throw new h("--type must be one of "+P.join(", ")+".");const t=w(e);if(t.panels.some(l=>l.id===n))throw new f('Panel "'+n+'" is already in afterpresets.json.');if(g.existsSync(u.join(t.root,"src","panels",n)))throw new f("src/panels/"+n+"/ already exists.",{hint:"Add it to afterpresets.json by hand, or choose another id."});const a={id:n,title:o.flags.title||T(t.settings.name,n),type:s};o.flags.width!==void 0&&(a.width=Number(o.flags.width)),o.flags.height!==void 0&&(a.height=Number(o.flags.height));const d=N(a,t.settings);a.width=d.width,a.height=d.height,a.menu=d.menu;const c=b(t,d),m=y(t.root);return A(t.root,{panels:(m.panels||[]).concat([a])}),e.out.success("Added "+s+' panel "'+n+'" ('+d.extensionId+")"),c.forEach(l=>e.out.log(" "+l)),s==="modal"&&e.out.log('Open it from another panel with AP.panels.open("'+n+'").'),e.out.log("Restart "+j(t.settings)+" (with `ap dev` running) to load the new panel."),0}};function T(e,o){const p=o.replace(/-+/g," ").replace(/\b\w/g,n=>n.toUpperCase());return(e?e+" ":"")+p}async function k(e,o){if(!o)throw new h("Which app should the extension also run in?","Example: ap add host ppro (Premiere Pro) or ap add host aeft (After Effects)");const p=S(o),n=p&&I(p);if(!n)throw new h("Unknown app "+JSON.stringify(o)+".","Use aeft (After Effects) or ppro (Premiere Pro).");const r=w(e),s=r.settings;if(s.platform!=="cep")throw new f("A UXP plugin runs in exactly one app.",{hint:"Create a separate extension for the other app (ap init)."});const t=U("cep",n);if(s.hosts.some(i=>i.app===n))return e.out.info("This extension already runs in "+t.appName+"."),0;const a=s.hosts.concat([{app:n,minVersion:t.minVersion}]),d=q(e),c=await e.out.task("Adding "+t.appName+" on AfterPresets",()=>d.patch(v(s.bundleId),{hosts:a.map(i=>i.app)}));if((c&&c.product&&c.product.hosts||[]).indexOf(n)===-1)throw new f("AfterPresets did not save "+t.appName+" for this extension.",{hint:"The server may not support it yet. Nothing was changed locally."});const l=y(r.root);l.platform="cep",l.hosts=a,D(r.root,l);const E=g.existsSync(u.join(r.root,"src","features","home"))?C(r.root,{EXTENSION_NAME:s.name,BUNDLE_ID:s.bundleId},t,e.templateDir):[];e.out.success("The extension now runs in "+j({platform:"cep",hosts:a}," and ")+"."),E.forEach(i=>e.out.log(" "+i.split(u.sep).join("/"))),e.out.log("Put "+t.appName+"-only ExtendScript in jsx/"+t.jsxDir+"/ (jsx/*.jsx is shared by every app).");try{const i=R(e,r.root);i&&(O(i,r.root,w(e).settings),e.out.log("Added the "+t.appName+" reference: docs/afterpresets/"+t.docsPage))}catch(i){e.out.warn("Could not refresh docs/afterpresets/ ("+i.message+"). Run `ap docs`.")}return e.out.log("Restart "+t.appName+" with `ap dev` running and open Window > Extensions."),0}
|
package/src/commands/build.js
CHANGED
|
@@ -1,6 +1,12 @@
|
|
|
1
|
-
"use strict";const
|
|
1
|
+
"use strict";const u=require("path"),c=require("../config"),{readCredentials:b}=require("../auth/credentials"),{loadProject:w}=require("../project/project"),{checkProject:v,printCheck:y}=require("../check/check"),{pricingProblems:k}=require("../check/pricing"),{buildProject:B,productionOutDir:I}=require("../build/build"),{CliError:h}=require("../errors");async function f(e,i,t){const n=await v(i);if(t!==void 0){const s=k(t,n);n.errors.push.apply(n.errors,s.errors),n.warnings.push.apply(n.warnings,s.warnings)}if((n.errors.length||n.warnings.length)&&y(e.out,n),n.errors.length)throw new h("Fix the check errors above before building.");return n}async function g(e,i,t,n){n&&n.checked||await f(e,i);const s=c.apiBase(e,b(e));s!==c.DEFAULT_API_BASE&&e.out.warn("This build talks to "+s+" (AP_API_BASE, `ap config`, or your login), not production.");const a=await B(e,i,{outDir:I(i),dev:!1,version:t,apiBase:s,compileJsx:e.compileJsx});return a.warnings.forEach(r=>e.out.warn(r)),a}async function m(e,i,t){const n=require("fs"),s=require("../release/native"),a=s.resolveReleaseOses(e,t&&t.os),r=await e.out.task("Building "+i.settings.name+" for "+s.osesLabel(a),()=>s.buildNativeRelease(e,i,i.version,Object.assign({},t,{os:a})),o=>"Built "+i.settings.bundleId+" "+o.version+e.out.style.dim(" (ap_native "+o.runtimeVersion+")"));r.warnings.forEach(o=>e.out.warn(o));const l=s.assembleNativeZip(e,r.artefacts,{bundleId:i.settings.bundleId,name:i.settings.name,version:r.version,listingUrl:i.settings.listingUrl||null}),d=s.nativeZipPath(i,r.version);n.mkdirSync(u.dirname(d),{recursive:!0}),n.writeFileSync(d,l.buffer);const p=l.entries.filter(o=>!/\.plugin\//.test(o)).concat(r.artefacts.mac?[u.basename(r.artefacts.mac)+"/"]:[]);return e.out.success("Wrote "+u.relative(e.cwd,d)+s.publishedOsSuffix(null,r.oses)+e.out.style.dim(" ("+Math.max(1,Math.round(l.sizeBytes/1024))+" KB: "+p.join(", ")+")")),0}module.exports={name:"build",summary:"Build the production bundle into dist/<bundleId>/",usage:"ap build [--os mac,win]",description:`Runs the check, then for every panel in afterpresets.json writes one main.js with
|
|
2
2
|
the JSXBIN-compiled jsx/ folder, the panel's imported CSS, its index.html <body>,
|
|
3
3
|
the runtime and src/panels/<id>/main.js with its imports, plus a thin index.html;
|
|
4
4
|
generates CSXS/manifest.xml, and
|
|
5
5
|
copies the asset folders. Needs a signing public key (AP_SIGNING_PUBLIC_KEY or
|
|
6
|
-
\`ap config set signing-public-key\`) until the production key is embedded
|
|
6
|
+
\`ap config set signing-public-key\`) until the production key is embedded.
|
|
7
|
+
|
|
8
|
+
Native effect plugins: runs the check, builds the release plugin for macOS
|
|
9
|
+
(universal, ad-hoc signed) and Windows (.aex), and writes the buyer ZIP with its
|
|
10
|
+
install scripts to dist/<bundleId>-<version>.zip, exactly what \`ap push\` uploads.
|
|
11
|
+
A Mac builds both; Windows builds the Windows version only (build the macOS
|
|
12
|
+
version on a Mac). --os mac, --os win or --os mac,win picks the versions.`,flags:{os:{type:"string"}},checkedProductionBuild:g,buildNativeZip:m,runGate:f,async run(e,i){const t=w(e),n=i&&i.flags?i.flags.os:void 0;if(t.settings.platform==="native")return m(e,t,{os:n});if(n!==void 0)throw new h("--os is for native effect plugins; CEP extensions run on both macOS and Windows.");return await e.out.task("Building "+t.settings.bundleId,()=>g(e,t),s=>"Built "+t.settings.bundleId+" "+s.version+e.out.style.dim(" (runtime "+s.runtimeVersion+") into "+u.relative(e.cwd,s.outDir))),0}};
|
package/src/commands/check.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"use strict";const{loadProject:l}=require("../project/project"),{checkProject:
|
|
1
|
+
"use strict";const{loadProject:l}=require("../project/project"),{checkProject:c,printCheck:p}=require("../check/check"),{verifyPricingOnline:h}=require("../check/pricing"),{typeHints:d,hintLines:u,typesLabel:g}=require("../check/types");module.exports={name:"check",summary:"Run the static checks that gate a push",usage:"ap check [--types] [--types-all]",description:`Errors: a panel folder lacks index.html or main.js; a panel's code does not bundle
|
|
2
2
|
(a missing import, or syntax newer than ES5); a panel never calls AP.boot(; a panel
|
|
3
3
|
turns licensing on without a renderLicense; a panel's index.html does not load
|
|
4
4
|
main.js; or the product is paid and no panel boots with licensing on.
|
|
@@ -7,7 +7,15 @@ code (use AP.storage), src/ files no panel imports, non-.jsx files in jsx/.
|
|
|
7
7
|
The paid-product rule needs \`ap login\`; offline it is a warning (ap push enforces it).
|
|
8
8
|
|
|
9
9
|
--types Optional type hints for jsx/: TypeScript checks your ExtendScript against the
|
|
10
|
-
After Effects
|
|
10
|
+
app's API types (After Effects, Premiere Pro) and lists likely mistakes (misspelled names and
|
|
11
11
|
properties, wrong argument counts, methods ES3 lacks such as "".trim()).
|
|
12
12
|
Hints can be wrong (the types have gaps) and never fail the check.
|
|
13
|
-
--types-all Also lists every other hint. Expect false alarms on working code
|
|
13
|
+
--types-all Also lists every other hint. Expect false alarms on working code.
|
|
14
|
+
|
|
15
|
+
Native effect plugins: effect.json is valid; matchName and param ids/types unchanged
|
|
16
|
+
since the last release; an EffectMain entry point; out_flags set from AP_OUT_FLAGS
|
|
17
|
+
(the PiPL uses the same flags); Smart Render handled when promised; no mutable
|
|
18
|
+
globals/statics with multi-frame rendering; params read with the right union member;
|
|
19
|
+
16-bpc white is 32768, not 65535; no sleeping, network or process calls in src/; no
|
|
20
|
+
Adobe SDK files or text copied into the project. Each finding names file:line.
|
|
21
|
+
Silence a false alarm on one line with \`// ap-check: allow <code>\`.`,flags:{types:{type:"boolean"},"types-all":{type:"boolean"}},async run(n,t){const s=l(n),e=await c(s),a=await h(n,s,e);e.errors.push.apply(e.errors,a.errors),e.warnings.push.apply(e.warnings,a.warnings),p(n.out,e);const i=!!t.flags["types-all"];return(i||t.flags.types)&&(n.out.log(""),u(d(s),i,g(s)).forEach((r,o)=>n.out.log(o===1?n.out.style.dim(r):r))),e.errors.length?1:0}};
|
package/src/commands/dev.js
CHANGED
|
@@ -1,6 +1,13 @@
|
|
|
1
|
-
"use strict";const{loadProject:
|
|
1
|
+
"use strict";const{loadProject:d}=require("../project/project"),{createDevSession:a,otherDevProcess:u}=require("../dev/session"),{CliError:f}=require("../errors"),{debugPorts:c}=require("../dev/debug-file"),{projectDebugPort:p}=require("../config"),{hostAppNames:i}=require("../targets");module.exports={name:"dev",summary:"Develop inside After Effects or Premiere Pro with rebuild on change",usage:"ap dev [--once] [--no-reload] [--restart]",description:`Builds a readable dev bundle into dist-dev/<bundleId>/, links it into your CEP
|
|
2
2
|
extensions folder, enables PlayerDebugMode, runs \`ap check\`, and rebuilds whenever
|
|
3
3
|
a project file changes. Open panels reload themselves after each rebuild (dev
|
|
4
4
|
builds only; releases never include it). The .debug file gives panel i of
|
|
5
5
|
afterpresets.json the remote-debugging port debugPort + i.
|
|
6
|
-
--once builds and links without watching. --no-reload turns live reload off
|
|
6
|
+
--once builds and links without watching. --no-reload turns live reload off.
|
|
7
|
+
|
|
8
|
+
Native effect plugins (platform "native"): builds the plugin for this computer,
|
|
9
|
+
installs it into MediaCore/AfterPresets Dev/, installs the dev bridge (for host_eval
|
|
10
|
+
and comp_capture), converts Adobe's SDK guide into docs/afterpresets/sdk/, and says
|
|
11
|
+
when After Effects must restart (it loads plugins only at launch). Rebuilds on save.
|
|
12
|
+
--restart restarts After Effects when needed, but only when that is safe (the open
|
|
13
|
+
project is saved or a scratch project); it never force-quits.`,flags:{once:{type:"boolean"},"no-reload":{type:"boolean"},restart:{type:"boolean"}},async run(e,s){const t=d(e),o=u(t);if(o)throw new f("`ap dev` is already running for this project (process "+o+").",{hint:"Two can't build into the same folder. Use that one, or stop it (Ctrl+C in its terminal, or `kill "+o+"`) first."});if(t.settings.platform==="native")return h(e,t,s);const n=a(e,t,{liveReload:!s.flags["no-reload"]});return s.flags.once||n.claim(),await n.rebuild(),await n.link(),e.out.log(""),e.out.log("Open "+i(t.settings)+" > Window > Extensions > "+e.out.style.bold(t.panels[0].title)),e.out.log("Debug ports (Chrome DevTools; the afterpresets MCP finds them itself):"),c(t.panels,p(t.settings)).forEach(r=>{e.out.log(" "+r.panelId.padEnd(16)+"http://127.0.0.1:"+r.port)}),e.out.log((s.flags["no-reload"]?"Reload a panel to pick up changes.":"Panels reload by themselves when you save.")+" Restart "+i(t.settings)+" after adding a panel."),s.flags.once?0:l(e,n)}};function l(e,s){e.out.info("Watching for changes. Press Ctrl+C to stop.");const t=s.watch();return new Promise(o=>{const n=()=>{Promise.resolve(t.close()).then(()=>o(0))};e.onDevStarted?e.onDevStarted({stop:n,session:s}):process.once("SIGINT",n)})}async function h(e,s,t){const o=a(e,s,{restart:!!t.flags.restart});t.flags.once||o.claim();const n=await o.rebuild(),r=o.lastReport();return e.out.log(""),n&&e.out.log("Test it in After Effects: apply "+e.out.style.bold(s.settings.name)+" from the Effects menu (or with host_eval by its match name), then look at frames with comp_capture."),t.flags.once?(o.release&&o.release(),n?0:1):r&&r.stage==="sdk"?(o.release(),1):l(e,o)}
|
package/src/commands/docs.js
CHANGED
|
@@ -1 +1,5 @@
|
|
|
1
|
-
"use strict";const
|
|
1
|
+
"use strict";const d=require("fs"),i=require("path"),{loadProject:f}=require("../project/project"),{findRuntimeDir:c}=require("../build/runtime"),{syncRuntimeDocs:p}=require("../project/docs"),{CliError:l}=require("../errors");module.exports={name:"docs",summary:"Refresh docs/afterpresets/ from the installed runtime",usage:"ap docs",description:`Replaces the project's docs/afterpresets/ folder with the docs/*.md files of the
|
|
2
|
+
runtime that ships with the installed CLI. \`ap upgrade\` runs it for you. Your agent
|
|
3
|
+
reads these files before using AP.*. Native effect plugins also get
|
|
4
|
+
docs/afterpresets/sdk/: Adobe's SDK guide, converted on this computer (downloaded
|
|
5
|
+
once, then works offline), and vendor/ap_native/ is refreshed from this CLI.`,flags:{},async run(e){const t=f(e),n=c(e,t.root);if(!n)throw new l("The AfterPresets runtime was not found.",{hint:"Run `npm install` in the project, or `ap upgrade`."});const a=JSON.parse(d.readFileSync(i.join(n,"package.json"),"utf8")).version,o=p(n,t.root,t.settings);if(e.out.success("Copied "+o.files.length+" file(s) from @afterpresets/runtime "+a+" into "+i.relative(e.cwd,o.target)+"/"),o.files.forEach(r=>e.out.log(" "+r)),t.settings.platform==="native"){const r=require("../dev/native").vendorNativeRuntime(e,t.root);r.status!=="current"&&e.out.success((r.status==="created"?"Added":"Updated")+" ap_native "+(r.version||"")+" in vendor/ap_native/");const{ensureSdkDocs:u}=require("../project/docs"),s=await u(e,n,t.root,t.settings);if(s.status==="failed")return e.out.warn(s.message),s.hint&&e.out.log(" "+s.hint),1;s.status==="skipped"?e.out.warn(s.message+(s.hint?" "+s.hint:"")):e.out.success(s.message)}return 0}};
|