@popcraft/cli 0.51.0 → 0.53.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/dist/popcraft.mjs +66 -30
- package/package.json +2 -2
package/dist/popcraft.mjs
CHANGED
|
@@ -1196,7 +1196,7 @@ function operations(spec = openapi) {
|
|
|
1196
1196
|
}
|
|
1197
1197
|
async function call(target2, method, path, opts = {}) {
|
|
1198
1198
|
const qs = new URLSearchParams(opts.query ?? {}).toString();
|
|
1199
|
-
const headers = { "user-agent": `popcraft-cli/${"0.
|
|
1199
|
+
const headers = { "user-agent": `popcraft-cli/${"0.53.0"}`, ...opts.headers };
|
|
1200
1200
|
if (target2.token) headers.authorization = `Bearer ${target2.token}`;
|
|
1201
1201
|
if (opts.contentType) headers["content-type"] = opts.contentType;
|
|
1202
1202
|
try {
|
|
@@ -33524,12 +33524,6 @@ var init_en2 = __esm({
|
|
|
33524
33524
|
"drawSettingsPanel.wetMix": "Wet mix",
|
|
33525
33525
|
"drawSettingsPanel.wetPaint": "Wet paint",
|
|
33526
33526
|
"drawSettingsPanel.whatTheTipRotatesWith": "What the tip rotates with",
|
|
33527
|
-
"duoHarness.closed": "Closed",
|
|
33528
|
-
"duoHarness.frameTitle": "PopCraft on an iPhone Duo",
|
|
33529
|
-
"duoHarness.halfOpen": "Half open",
|
|
33530
|
-
"duoHarness.open": "Open",
|
|
33531
|
-
"duoHarness.posture": "Fold posture",
|
|
33532
|
-
"duoHarness.rotate": "Rotate",
|
|
33533
33527
|
"editorStore.leftNothingThoseShapesProduce": "{toLowerCase} left nothing \u2014 those shapes produce an empty result.",
|
|
33534
33528
|
"editorStore.readOnlyPickAMode": "This file is read only. Pick Design, or another mode, to edit it.",
|
|
33535
33529
|
"editorStore.savingToBrowserStorageFailed": "Saving to browser storage failed \u2014 recent changes may not be saved.",
|
|
@@ -33955,9 +33949,9 @@ var init_en2 = __esm({
|
|
|
33955
33949
|
"homeTemplates.browseAll": "Browse all templates",
|
|
33956
33950
|
"homeTemplates.communityBody": "Templates people made and shared. Tap one to start from a copy.",
|
|
33957
33951
|
"homeTemplates.fromTheCommunity": "From the community",
|
|
33958
|
-
"homeTemplates.loadMore": "Load more templates",
|
|
33959
33952
|
"homeTemplates.loading": "Loading templates\u2026",
|
|
33960
33953
|
"homeTemplates.loadingMore": "Loading more templates\u2026",
|
|
33954
|
+
"homeTemplates.loadMore": "Load more templates",
|
|
33961
33955
|
"homeTemplates.noneInThisGroup": "No templates in this group yet.",
|
|
33962
33956
|
"homeTemplates.pickOneToOpen": "Pick one and it opens as a new file, ready to edit.",
|
|
33963
33957
|
"homeTemplates.startFromATemplate": "Start from a template",
|
|
@@ -96492,7 +96486,6 @@ async function sha256Prefix(bytes2) {
|
|
|
96492
96486
|
}
|
|
96493
96487
|
var init_media_hash = __esm({
|
|
96494
96488
|
"lib/storage/media-hash.ts"() {
|
|
96495
|
-
"use strict";
|
|
96496
96489
|
}
|
|
96497
96490
|
});
|
|
96498
96491
|
|
|
@@ -311872,7 +311865,6 @@ async function dispatchShaped(key5, options) {
|
|
|
311872
311865
|
var onViolation;
|
|
311873
311866
|
var init_dispatch = __esm({
|
|
311874
311867
|
"lib/commands/dispatch.ts"() {
|
|
311875
|
-
"use strict";
|
|
311876
311868
|
init_errors();
|
|
311877
311869
|
init_registry();
|
|
311878
311870
|
init_confirm();
|
|
@@ -312934,6 +312926,7 @@ function applyTextPath(layout2, path, tp, rebase = true) {
|
|
|
312934
312926
|
var defaultCircleRadius, ownsPath, mapPoint;
|
|
312935
312927
|
var init_text_path = __esm({
|
|
312936
312928
|
"lib/engine/text/text-path.ts"() {
|
|
312929
|
+
"use strict";
|
|
312937
312930
|
init_scene_graph();
|
|
312938
312931
|
init_transform();
|
|
312939
312932
|
init_shape_to_path();
|
|
@@ -313051,6 +313044,7 @@ function areaBounds(rings) {
|
|
|
313051
313044
|
}
|
|
313052
313045
|
var init_text_area = __esm({
|
|
313053
313046
|
"lib/engine/text/text-area.ts"() {
|
|
313047
|
+
"use strict";
|
|
313054
313048
|
}
|
|
313055
313049
|
});
|
|
313056
313050
|
|
|
@@ -328483,7 +328477,7 @@ var init_package = __esm({
|
|
|
328483
328477
|
"packages/runtime/package.json"() {
|
|
328484
328478
|
package_default = {
|
|
328485
328479
|
name: "@popcraft/runtime",
|
|
328486
|
-
version: "0.
|
|
328480
|
+
version: "0.53.0",
|
|
328487
328481
|
description: "What code exported from PopCraft shares: the meaning of expressions (operators and functions) and, as it grows, the parts of a design's behaviour that are common code rather than generated React.",
|
|
328488
328482
|
license: "MIT",
|
|
328489
328483
|
homepage: "https://popcraft.app/docs/exporting/nextjs",
|
|
@@ -353149,6 +353143,7 @@ function exportsOf(source3) {
|
|
|
353149
353143
|
var CODE_LIMITS, packageOf;
|
|
353150
353144
|
var init_source2 = __esm({
|
|
353151
353145
|
"lib/code/source.ts"() {
|
|
353146
|
+
"use strict";
|
|
353152
353147
|
CODE_LIMITS = { modules: 100, sourceLength: 2e5, packages: 12 };
|
|
353153
353148
|
packageOf = (spec) => spec.split("/").slice(0, spec.startsWith("@") ? 2 : 1).join("/");
|
|
353154
353149
|
}
|
|
@@ -353191,6 +353186,7 @@ function compileModule(module2) {
|
|
|
353191
353186
|
var import_sucrase, BUILT_IN, memo4;
|
|
353192
353187
|
var init_compile2 = __esm({
|
|
353193
353188
|
"lib/code/compile.ts"() {
|
|
353189
|
+
"use strict";
|
|
353194
353190
|
import_sucrase = __toESM(require_dist2());
|
|
353195
353191
|
init_source2();
|
|
353196
353192
|
init_source2();
|
|
@@ -362233,7 +362229,6 @@ var init_delete_current_file = __esm({
|
|
|
362233
362229
|
var storeOpsSeam;
|
|
362234
362230
|
var init_seams = __esm({
|
|
362235
362231
|
"lib/commands/seams.ts"() {
|
|
362236
|
-
"use strict";
|
|
362237
362232
|
storeOpsSeam = (st) => ({
|
|
362238
362233
|
booleanOperation: (op4) => st().booleanOperation(op4),
|
|
362239
362234
|
flatten: () => st().flattenSelection(),
|
|
@@ -368595,16 +368590,16 @@ var init_api5 = __esm({
|
|
|
368595
368590
|
}
|
|
368596
368591
|
});
|
|
368597
368592
|
|
|
368598
|
-
// node_modules/.pnpm/@popcraft+plugins@1.0
|
|
368593
|
+
// node_modules/.pnpm/@popcraft+plugins@1.3.0/node_modules/@popcraft/plugins/dist/generated/runtime.js
|
|
368599
368594
|
var MAIN_RUNTIME, UI_RUNTIME;
|
|
368600
368595
|
var init_runtime6 = __esm({
|
|
368601
|
-
"node_modules/.pnpm/@popcraft+plugins@1.0
|
|
368602
|
-
MAIN_RUNTIME = '"use strict";\n(() => {\n // src/runtime/rpc.ts\n function createRpcClient() {\n let port = null;\n const queue = [];\n const pending = {};\n const listeners = {};\n let nextId = 1;\n function send(msg) {\n if (port) port.postMessage(msg);\n else queue.push(msg);\n }\n function call(method, params) {\n return new Promise((resolve, reject) => {\n const id = nextId++;\n pending[id] = { resolve, reject };\n send({ kind: "rpc", id, method, params });\n });\n }\n function emit(event, data) {\n for (const cb of (listeners[event] || []).slice()) {\n try {\n cb(data);\n } catch (e) {\n console.error(e);\n }\n }\n }\n window.addEventListener("message", (e) => {\n const data = e.data;\n if (e.source !== window.parent || !data || data.type !== "popcraft-plugin-port" || port) return;\n port = e.ports[0];\n port.onmessage = (ev) => {\n const m = ev.data || {};\n if (m.kind === "result" && m.id !== void 0 && pending[m.id]) {\n const p = pending[m.id];\n delete pending[m.id];\n if (m.error) p.reject(new Error(m.error));\n else p.resolve(m.result);\n } else if (m.kind === "event" && m.event) {\n emit(m.event, m.data);\n }\n };\n for (const msg of queue.splice(0)) port.postMessage(msg);\n });\n return {\n call,\n send,\n on(event, cb) {\n (listeners[event] = listeners[event] || []).push(cb);\n },\n off(event, cb) {\n listeners[event] = (listeners[event] || []).filter((x) => x !== cb);\n }\n };\n }\n\n // src/runtime/main.ts\n function clone(v) {\n return v === void 0 ? {} : JSON.parse(JSON.stringify(v));\n }\n function createMainApi(rpc = createRpcClient()) {\n const uiHandlers = [];\n let uiOnMessage = null;\n const uiQueue = [];\n function deliverUI(msg) {\n for (const cb of uiHandlers) {\n try {\n cb(msg);\n } catch (e) {\n console.error(e);\n }\n }\n if (typeof uiOnMessage === "function") {\n try {\n uiOnMessage(msg);\n } catch (e) {\n console.error(e);\n }\n }\n }\n function flushUI() {\n if (uiHandlers.length || typeof uiOnMessage === "function") uiQueue.splice(0).forEach(deliverUI);\n }\n rpc.on("uimessage", (msg) => {\n if (!uiHandlers.length && typeof uiOnMessage !== "function") uiQueue.push(msg);\n else deliverUI(msg);\n });\n let widgetDef = null;\n const widgetQueue = [];\n function renderWidget(state) {\n const handlers = {};\n function walk(el, path) {\n if (!el || typeof el !== "object") return el;\n const out = {};\n for (const k of Object.keys(el)) {\n const v = el[k];\n if (k === "children") {\n out.children = (Array.isArray(v) ? v : [v]).filter((c) => c !== null && c !== void 0 && c !== false).map((c, i) => walk(c, path + "." + i));\n } else if (k === "onClick" && typeof v === "function") {\n handlers[path] = v;\n out.onClick = path;\n } else {\n out[k] = v;\n }\n }\n return out;\n }\n return { tree: walk(widgetDef.render(state), "root"), handlers };\n }\n function initialWidgetState() {\n const s = widgetDef && widgetDef.initialState;\n return clone(typeof s === "function" ? s() : s);\n }\n function commitWidget(nodeId, state) {\n return rpc.call("widgetUpdate", { id: nodeId, state, tree: renderWidget(clone(state)).tree });\n }\n function handleWidgetClick(e) {\n Promise.resolve().then(() => {\n const state = clone(e.state);\n const rendered = renderWidget(state);\n const h = rendered.handlers[e.handler] || widgetDef.handlers && widgetDef.handlers[e.handler];\n if (typeof h !== "function") return;\n return Promise.resolve(h(state, { nodeId: e.nodeId })).then((ret) => commitWidget(e.nodeId, ret === void 0 ? state : ret));\n }).catch((err) => rpc.send({ kind: "error", message: String((err == null ? void 0 : err.message) || err) }));\n }\n rpc.on("widgetclick", (e) => {\n if (widgetDef) handleWidgetClick(e);\n else widgetQueue.push(e);\n });\n const popcraft = {\n /** Which menu command the user picked, or null when the plugin ran some other way. */\n command: null,\n /** Host import mode when launched as an importer, else null. */\n importMode: null,\n /** Pending import file when the host handed one over, else null. */\n importFile: null,\n /** Pending export request (File \u2192 Export \u2192 this plugin\'s format), else null. */\n exportRequest: null,\n getSelection: () => rpc.call("getSelection"),\n setSelection: (ids) => rpc.call("setSelection", { ids }),\n getNode: (id) => rpc.call("getNode", { id }),\n findNodes: (query) => rpc.call("findNodes", query || {}),\n getCurrentPage: () => rpc.call("getCurrentPage"),\n createNode: (type, props) => rpc.call("createNode", { type, props: props || {} }),\n updateNode: (id, props) => rpc.call("updateNode", { id, props }),\n deleteNode: (id) => rpc.call("deleteNode", { id }),\n setText: (id, characters) => rpc.call("setText", { id, characters }),\n /** Put TEXT layers on a path (another layer\'s outline, or their own arc, circle or wave), or tune one: brackets, alignment, placement, effect, overflow. */\n setTextPath: (opts) => rpc.call("setTextPath", opts || {}),\n /** Area type: flow a TEXT layer inside a closed shape, kept `inset` px in. */\n flowTextIntoShape: (opts) => rpc.call("flowTextIntoShape", opts || {}),\n /** Take TEXT layers off their path or out of their shape (or free every text linked to a path / shape). */\n detachText: (opts) => rpc.call("detachText", opts || {}),\n /** Auto-size TEXT layers\' type to their box, shape or path. */\n setTextFit: (opts) => rpc.call("setTextFit", opts || {}),\n createPage: (name) => rpc.call("createPage", name != null ? { name: String(name) } : {}),\n setCurrentPage: (pageId) => rpc.call("setCurrentPage", { pageId }),\n createImage: (opts) => rpc.call("createImage", opts || {}),\n createDocument: (opts) => rpc.call("createDocument", opts || {}),\n getImportMode: () => rpc.call("getImportMode"),\n getImportFile: () => rpc.call("getImportFile"),\n /**\n * The open page as a storefront design in a neutral form, for an exporter that writes its own store\'s templates:\n * each page\'s HTML with the store\'s data marked (`{{page.title}}`, `{{item.price}}`, `<!-- pc:each \u2026 -->` lists,\n * `data-pc-action` forms), and its collections with their commerce schema and sample records.\n */\n getStorefront: () => rpc.call("getStorefront"),\n /**\n * A design\'s data (docs: Collections): a collection and its fields (`schema`: what it stands for, e.g.\n * `commerce.product`, whose fields are made for it), its records, and reading them.\n */\n editCollection: (opts) => rpc.call("editCollection", opts || {}),\n editRecords: (opts) => rpc.call("editRecords", opts || {}),\n getRecords: (opts) => rpc.call("getRecords", opts || {}),\n /** A layer as a web page\'s form control (a FORM\'s `formAction`, an INPUT\'s name and value), repeated per record, a page\'s address, its semantics. */\n setControl: (opts) => rpc.call("setControl", opts || {}),\n setRepeat: (opts) => rpc.call("setRepeat", opts || {}),\n setRoute: (opts) => rpc.call("setRoute", opts || {}),\n setSemantics: (opts) => rpc.call("setSemantics", opts || {}),\n /** Which record layers are about (one product, picked from a collection), and which of its fields a layer\'s words, picture or an instance\'s properties follow. */\n setRecord: (opts) => rpc.call("setRecord", opts || {}),\n bindField: (opts) => rpc.call("bindField", opts || {}),\n /** The site\'s environment: public settings its host reads by name when it is deployed (never a secret: the file keeps them). */\n getSiteEnvironment: () => rpc.call("getSiteEnvironment"),\n setSiteEnvironment: (set) => rpc.call("setSiteEnvironment", { set }),\n /** What this plugin keeps with the open file (its settings for this design), under its own id; JSON only. */\n getFileData: (key) => rpc.call("getFileData", { key }),\n setFileData: (key, value) => rpc.call("setFileData", { key, value }),\n /** A store\'s project built from the open page, zipped (needs `export`): what an exporter saves with `saveExport`. */\n getStorefrontFiles: (target) => rpc.call("getStorefrontFiles", { target }),\n getExportRequest: () => rpc.call("getExportRequest"),\n /** Save the exporter\'s file (once per export request); the host enforces the contributed extension. */\n saveExport: (file) => rpc.call("saveExport", file || {}),\n /**\n * Presentation audio (docs/plugins/presentation-audio.md): the deck\'s slides, notes, narration and timing; the\n * soundtrack\'s settings, bed and stinger.\n */\n getPresentationAudio: (opts) => rpc.call("getPresentationAudio", opts || {}),\n /** Change the soundtrack\'s settings (voice, style, mood, loudness, beat alignment, levels) and re-time it. */\n setPresentationAudioSettings: (opts) => rpc.call("setPresentationAudioSettings", opts || {}),\n /** Put a sound in (a slide\'s narration, the bed or the stinger): bytes are normalised to the soundtrack\'s target and stored. */\n setPresentationAudioClip: (opts) => rpc.call("setPresentationAudioClip", opts || {}),\n removePresentationAudioClip: (opts) => rpc.call("removePresentationAudioClip", opts || {}),\n /** Re-time: fixed slide lengths (ms, null clears) and beat-aligned changes. */\n setPresentationTiming: (opts) => rpc.call("setPresentationTiming", opts || {}),\n /** The mix as the export carries it: loudness, true peak, and (wav: true) the 48 kHz stereo WAV. */\n getPresentationMix: (opts) => rpc.call("getPresentationMix", opts || {}),\n /** Ask the user to generate with AI (the panel opens with the request filled in; the user decides). */\n requestPresentationAudio: (opts) => rpc.call("requestPresentationAudio", opts || {}),\n /** Editor commands: each takes the arguments documented in docs/plugins/methods.md (the agent tool of the same purpose). */\n moveNodes: (opts) => rpc.call("moveNodes", opts || {}),\n resizeNodes: (opts) => rpc.call("resizeNodes", opts || {}),\n renameNodes: (opts) => rpc.call("renameNodes", opts || {}),\n reparentNodes: (opts) => rpc.call("reparentNodes", opts || {}),\n duplicateNodes: (opts) => rpc.call("duplicateNodes", opts || {}),\n groupNodes: (opts) => rpc.call("groupNodes", opts || {}),\n ungroupNodes: (opts) => rpc.call("ungroupNodes", opts || {}),\n alignNodes: (opts) => rpc.call("alignNodes", opts || {}),\n distributeNodes: (opts) => rpc.call("distributeNodes", opts || {}),\n flipNodes: (opts) => rpc.call("flipNodes", opts || {}),\n rotateNodes: (opts) => rpc.call("rotateNodes", opts || {}),\n reorderNodes: (opts) => rpc.call("reorderNodes", opts || {}),\n setLocked: (opts) => rpc.call("setLocked", opts || {}),\n setVisible: (opts) => rpc.call("setVisible", opts || {}),\n setAutoLayout: (opts) => rpc.call("setAutoLayout", opts || {}),\n importSvg: (opts) => rpc.call("importSvg", opts || {}),\n measureNodes: (opts) => rpc.call("measureNodes", opts || {}),\n setFills: (opts) => rpc.call("setFills", opts || {}),\n setStrokes: (opts) => rpc.call("setStrokes", opts || {}),\n setEffects: (opts) => rpc.call("setEffects", opts || {}),\n replaceColor: (opts) => rpc.call("replaceColor", opts || {}),\n setTypography: (opts) => rpc.call("setTypography", opts || {}),\n applyStyle: (opts) => rpc.call("applyStyle", opts || {}),\n createComponent: (opts) => rpc.call("createComponent", opts || {}),\n createInstance: (opts) => rpc.call("createInstance", opts || {}),\n renamePage: (opts) => rpc.call("renamePage", opts || {}),\n getDocumentOutline: (opts) => rpc.call("getDocumentOutline", opts || {}),\n setPageSetup: (opts) => rpc.call("setPageSetup", opts || {}),\n setShowAdvance: (opts) => rpc.call("setShowAdvance", opts || {}),\n booleanOperation: (opts) => rpc.call("booleanOperation", opts || {}),\n flattenNodes: (opts) => rpc.call("flattenNodes", opts || {}),\n outlineStroke: (opts) => rpc.call("outlineStroke", opts || {}),\n setMask: (opts) => rpc.call("setMask", opts || {}),\n setMaskType: (opts) => rpc.call("setMaskType", opts || {}),\n shapeBuilder: (opts) => rpc.call("shapeBuilder", opts || {}),\n setKeyframes: (opts) => rpc.call("setKeyframes", opts || {}),\n getAnimation: (opts) => rpc.call("getAnimation", opts || {}),\n getCompositions: (opts) => rpc.call("getCompositions", opts || {}),\n editBehaviours: (opts) => rpc.call("editBehaviours", opts || {}),\n setTimeline: (opts) => rpc.call("setTimeline", opts || {}),\n setLayerTiming: (opts) => rpc.call("setLayerTiming", opts || {}),\n editTextAnimation: (opts) => rpc.call("editTextAnimation", opts || {}),\n edit3DScene: (opts) => rpc.call("edit3DScene", opts || {}),\n setInstancePlayback: (opts) => rpc.call("setInstancePlayback", opts || {}),\n editComponentProperty: (opts) => rpc.call("editComponentProperty", opts || {}),\n setShaderFill: (opts) => rpc.call("setShaderFill", opts || {}),\n createComposition: (opts) => rpc.call("createComposition", opts || {}),\n editComposition: (opts) => rpc.call("editComposition", opts || {}),\n editStateMachine: (opts) => rpc.call("editStateMachine", opts || {}),\n getStateMachine: (opts) => rpc.call("getStateMachine", opts || {}),\n applyMotionPreset: (opts) => rpc.call("applyMotionPreset", opts || {}),\n staggerMotion: (opts) => rpc.call("staggerMotion", opts || {}),\n createMotionComponent: (opts) => rpc.call("createMotionComponent", opts || {}),\n addAudio: (opts) => rpc.call("addAudio", opts || {}),\n editFrameAudio: (opts) => rpc.call("editFrameAudio", opts || {}),\n editVideoClip: (opts) => rpc.call("editVideoClip", opts || {}),\n detectAudioOnsets: (opts) => rpc.call("detectAudioOnsets", opts || {}),\n cutToBeat: (opts) => rpc.call("cutToBeat", opts || {}),\n editPrototype: (opts) => rpc.call("editPrototype", opts || {}),\n usePresentationFallbackAudio: (opts) => rpc.call("usePresentationFallbackAudio", opts || {}),\n /** Bring a Lottie, PDF or PopCraft file into the open document (the `importFile` field is the file an importer was handed). */\n importDocumentFile: (opts) => rpc.call("importDocumentFile", opts || {}),\n getStyles: () => rpc.call("getStyles"),\n createPaintStyle: (name, paints) => rpc.call("createPaintStyle", { name, paints }),\n getVariables: () => rpc.call("getVariables"),\n setVariableValue: (variableId, modeId, value) => rpc.call("setVariableValue", { variableId, modeId, value }),\n exportNode: (id, options) => rpc.call("exportNode", { id, options: options || {} }),\n openExternal: (url) => rpc.call("openExternal", { url }),\n notify: (message, options) => rpc.call("notify", { message: String(message), error: !!(options && options.error) }),\n showUI: (options) => rpc.call("showUI", options || {}),\n hideUI: () => rpc.call("hideUI"),\n /** Ends the run. The optional message is shown as a notification. */\n closePlugin: (message) => rpc.call("closePlugin", { message }),\n storage: {\n get: (key) => rpc.call("storageGet", { key }),\n set: (key, value) => rpc.call("storageSet", { key, value })\n },\n ui: {\n get onmessage() {\n return uiOnMessage;\n },\n set onmessage(cb) {\n uiOnMessage = cb;\n flushUI();\n },\n postMessage: (msg) => rpc.send({ kind: "toUI", data: msg }),\n on: (cb) => {\n uiHandlers.push(cb);\n flushUI();\n }\n },\n widget: {\n register(def) {\n if (!def || typeof def.render !== "function") throw new Error("popcraft.widget.register needs a render(state) function");\n widgetDef = def;\n widgetQueue.splice(0).forEach(handleWidgetClick);\n },\n insert(options) {\n if (!widgetDef) return Promise.reject(new Error("Call popcraft.widget.register first"));\n const o = options || {};\n const state = o.state !== void 0 ? clone(o.state) : initialWidgetState();\n return rpc.call("widgetInsert", { state, tree: renderWidget(state).tree, x: o.x, y: o.y });\n },\n getState: (nodeId) => rpc.call("widgetGet", { id: nodeId }),\n setState(nodeId, state) {\n if (!widgetDef) return Promise.reject(new Error("Call popcraft.widget.register first"));\n return commitWidget(nodeId, clone(state));\n }\n },\n on: (event, cb) => rpc.on(event, cb),\n off: (event, cb) => rpc.off(event, cb)\n };\n rpc.on("init", (data) => {\n var _a, _b, _c;\n popcraft.command = data.command;\n popcraft.importMode = (_a = data.importMode) != null ? _a : null;\n popcraft.importFile = (_b = data.importFile) != null ? _b : null;\n popcraft.exportRequest = (_c = data.exportRequest) != null ? _c : null;\n });\n return popcraft;\n }\n function installMainApi() {\n const rpc = createRpcClient();\n const api = createMainApi(rpc);\n const w = window;\n w.__popcraftRpc = rpc;\n w.popcraft = api;\n w.vizpops = api;\n window.addEventListener("error", (e) => rpc.send({ kind: "error", message: String(e.message || e) }));\n window.addEventListener("unhandledrejection", (e) => rpc.send({ kind: "error", message: String(e.reason && e.reason.message || e.reason) }));\n return api;\n }\n\n // src/runtime/main.entry.ts\n installMainApi();\n})();';
|
|
368596
|
+
"node_modules/.pnpm/@popcraft+plugins@1.3.0/node_modules/@popcraft/plugins/dist/generated/runtime.js"() {
|
|
368597
|
+
MAIN_RUNTIME = '"use strict";\n(() => {\n // src/runtime/rpc.ts\n function createRpcClient() {\n let port = null;\n const queue = [];\n const pending = {};\n const listeners = {};\n let nextId = 1;\n function send(msg) {\n if (port) port.postMessage(msg);\n else queue.push(msg);\n }\n function call(method, params) {\n return new Promise((resolve, reject) => {\n const id = nextId++;\n pending[id] = { resolve, reject };\n send({ kind: "rpc", id, method, params });\n });\n }\n function emit(event, data) {\n for (const cb of (listeners[event] || []).slice()) {\n try {\n cb(data);\n } catch (e) {\n console.error(e);\n }\n }\n }\n window.addEventListener("message", (e) => {\n const data = e.data;\n if (e.source !== window.parent || !data || data.type !== "popcraft-plugin-port" || port) return;\n port = e.ports[0];\n port.onmessage = (ev) => {\n const m = ev.data || {};\n if (m.kind === "result" && m.id !== void 0 && pending[m.id]) {\n const p = pending[m.id];\n delete pending[m.id];\n if (m.error) p.reject(new Error(m.error));\n else p.resolve(m.result);\n } else if (m.kind === "event" && m.event) {\n emit(m.event, m.data);\n }\n };\n for (const msg of queue.splice(0)) port.postMessage(msg);\n });\n return {\n call,\n send,\n on(event, cb) {\n (listeners[event] = listeners[event] || []).push(cb);\n },\n off(event, cb) {\n listeners[event] = (listeners[event] || []).filter((x) => x !== cb);\n }\n };\n }\n\n // src/runtime/main.ts\n function clone(v) {\n return v === void 0 ? {} : JSON.parse(JSON.stringify(v));\n }\n function createMainApi(rpc = createRpcClient()) {\n const uiHandlers = [];\n let uiOnMessage = null;\n const uiQueue = [];\n function deliverUI(msg) {\n for (const cb of uiHandlers) {\n try {\n cb(msg);\n } catch (e) {\n console.error(e);\n }\n }\n if (typeof uiOnMessage === "function") {\n try {\n uiOnMessage(msg);\n } catch (e) {\n console.error(e);\n }\n }\n }\n function flushUI() {\n if (uiHandlers.length || typeof uiOnMessage === "function") uiQueue.splice(0).forEach(deliverUI);\n }\n rpc.on("uimessage", (msg) => {\n if (!uiHandlers.length && typeof uiOnMessage !== "function") uiQueue.push(msg);\n else deliverUI(msg);\n });\n let widgetDef = null;\n const widgetQueue = [];\n function renderWidget(state) {\n const handlers = {};\n function walk(el, path) {\n if (!el || typeof el !== "object") return el;\n const out = {};\n for (const k of Object.keys(el)) {\n const v = el[k];\n if (k === "children") {\n out.children = (Array.isArray(v) ? v : [v]).filter((c) => c !== null && c !== void 0 && c !== false).map((c, i) => walk(c, path + "." + i));\n } else if (k === "onClick" && typeof v === "function") {\n handlers[path] = v;\n out.onClick = path;\n } else {\n out[k] = v;\n }\n }\n return out;\n }\n return { tree: walk(widgetDef.render(state), "root"), handlers };\n }\n function initialWidgetState() {\n const s = widgetDef && widgetDef.initialState;\n return clone(typeof s === "function" ? s() : s);\n }\n function commitWidget(nodeId, state) {\n return rpc.call("widgetUpdate", { id: nodeId, state, tree: renderWidget(clone(state)).tree });\n }\n function handleWidgetClick(e) {\n Promise.resolve().then(() => {\n const state = clone(e.state);\n const rendered = renderWidget(state);\n const h = rendered.handlers[e.handler] || widgetDef.handlers && widgetDef.handlers[e.handler];\n if (typeof h !== "function") return;\n return Promise.resolve(h(state, { nodeId: e.nodeId })).then((ret) => commitWidget(e.nodeId, ret === void 0 ? state : ret));\n }).catch((err) => rpc.send({ kind: "error", message: String((err == null ? void 0 : err.message) || err) }));\n }\n rpc.on("widgetclick", (e) => {\n if (widgetDef) handleWidgetClick(e);\n else widgetQueue.push(e);\n });\n const popcraft = {\n /** Which menu command the user picked, or null when the plugin ran some other way. */\n command: null,\n /** Host import mode when launched as an importer, else null. */\n importMode: null,\n /** Pending import file when the host handed one over, else null. */\n importFile: null,\n /** Pending export request (File \u2192 Export \u2192 this plugin\'s format), else null. */\n exportRequest: null,\n getSelection: () => rpc.call("getSelection"),\n setSelection: (ids) => rpc.call("setSelection", { ids }),\n getNode: (id) => rpc.call("getNode", { id }),\n findNodes: (query) => rpc.call("findNodes", query || {}),\n getCurrentPage: () => rpc.call("getCurrentPage"),\n createNode: (type, props) => rpc.call("createNode", { type, props: props || {} }),\n updateNode: (id, props) => rpc.call("updateNode", { id, props }),\n deleteNode: (id) => rpc.call("deleteNode", { id }),\n setText: (id, characters) => rpc.call("setText", { id, characters }),\n /** Put TEXT layers on a path (another layer\'s outline, or their own arc, circle or wave), or tune one: brackets, alignment, placement, effect, overflow. */\n setTextPath: (opts) => rpc.call("setTextPath", opts || {}),\n /** Area type: flow a TEXT layer inside a closed shape, kept `inset` px in. */\n flowTextIntoShape: (opts) => rpc.call("flowTextIntoShape", opts || {}),\n /** Take TEXT layers off their path or out of their shape (or free every text linked to a path / shape). */\n detachText: (opts) => rpc.call("detachText", opts || {}),\n /** Auto-size TEXT layers\' type to their box, shape or path. */\n setTextFit: (opts) => rpc.call("setTextFit", opts || {}),\n createPage: (name) => rpc.call("createPage", name != null ? { name: String(name) } : {}),\n setCurrentPage: (pageId) => rpc.call("setCurrentPage", { pageId }),\n createImage: (opts) => rpc.call("createImage", opts || {}),\n createDocument: (opts) => rpc.call("createDocument", opts || {}),\n getImportMode: () => rpc.call("getImportMode"),\n getImportFile: () => rpc.call("getImportFile"),\n /**\n * The open page as a storefront design in a neutral form, for an exporter that writes its own store\'s templates:\n * each page\'s HTML with the store\'s data marked (`{{page.title}}`, `{{item.price}}`, `<!-- pc:each \u2026 -->` lists,\n * `data-pc-action` forms), and its collections with their commerce schema and sample records.\n */\n getStorefront: () => rpc.call("getStorefront"),\n /**\n * A design\'s data (docs: Collections): a collection and its fields (`schema`: what it stands for, e.g.\n * `commerce.product`, whose fields are made for it), its records, and reading them.\n */\n editCollection: (opts) => rpc.call("editCollection", opts || {}),\n editRecords: (opts) => rpc.call("editRecords", opts || {}),\n getRecords: (opts) => rpc.call("getRecords", opts || {}),\n /** A layer as a web page\'s form control (a FORM\'s `formAction`, an INPUT\'s name and value), repeated per record, a page\'s address, its semantics. */\n setControl: (opts) => rpc.call("setControl", opts || {}),\n setRepeat: (opts) => rpc.call("setRepeat", opts || {}),\n setRoute: (opts) => rpc.call("setRoute", opts || {}),\n setSemantics: (opts) => rpc.call("setSemantics", opts || {}),\n /** Which record layers are about (one product, picked from a collection), and which of its fields a layer\'s words, picture or an instance\'s properties follow. */\n setRecord: (opts) => rpc.call("setRecord", opts || {}),\n bindField: (opts) => rpc.call("bindField", opts || {}),\n /** The site\'s environment: public settings its host reads by name when it is deployed (never a secret: the file keeps them). */\n getSiteEnvironment: () => rpc.call("getSiteEnvironment"),\n setSiteEnvironment: (set) => rpc.call("setSiteEnvironment", { set }),\n /** What this plugin keeps with the open file (its settings for this design), under its own id; JSON only. */\n getFileData: (key) => rpc.call("getFileData", { key }),\n setFileData: (key, value) => rpc.call("setFileData", { key, value }),\n /** A store\'s project built from the open page, zipped (needs `export`): what an exporter saves with `saveExport`. */\n getStorefrontFiles: (target) => rpc.call("getStorefrontFiles", { target }),\n getExportRequest: () => rpc.call("getExportRequest"),\n /** Save the exporter\'s file (once per export request); the host enforces the contributed extension. */\n saveExport: (file) => rpc.call("saveExport", file || {}),\n /**\n * Presentation audio (docs/plugins/presentation-audio.md): the deck\'s slides, notes, narration and timing; the\n * soundtrack\'s settings, bed and stinger.\n */\n getPresentationAudio: (opts) => rpc.call("getPresentationAudio", opts || {}),\n /** Change the soundtrack\'s settings (voice, style, mood, loudness, beat alignment, levels) and re-time it. */\n setPresentationAudioSettings: (opts) => rpc.call("setPresentationAudioSettings", opts || {}),\n /** Put a sound in (a slide\'s narration, the bed or the stinger): bytes are normalised to the soundtrack\'s target and stored. */\n setPresentationAudioClip: (opts) => rpc.call("setPresentationAudioClip", opts || {}),\n removePresentationAudioClip: (opts) => rpc.call("removePresentationAudioClip", opts || {}),\n /** Re-time: fixed slide lengths (ms, null clears) and beat-aligned changes. */\n setPresentationTiming: (opts) => rpc.call("setPresentationTiming", opts || {}),\n /** The mix as the export carries it: loudness, true peak, and (wav: true) the 48 kHz stereo WAV. */\n getPresentationMix: (opts) => rpc.call("getPresentationMix", opts || {}),\n /** Ask the user to generate with AI (the panel opens with the request filled in; the user decides). */\n requestPresentationAudio: (opts) => rpc.call("requestPresentationAudio", opts || {}),\n /** Editor commands: each takes the arguments documented in docs/plugins/methods.md (the agent tool of the same purpose). */\n moveNodes: (opts) => rpc.call("moveNodes", opts || {}),\n resizeNodes: (opts) => rpc.call("resizeNodes", opts || {}),\n renameNodes: (opts) => rpc.call("renameNodes", opts || {}),\n reparentNodes: (opts) => rpc.call("reparentNodes", opts || {}),\n duplicateNodes: (opts) => rpc.call("duplicateNodes", opts || {}),\n groupNodes: (opts) => rpc.call("groupNodes", opts || {}),\n ungroupNodes: (opts) => rpc.call("ungroupNodes", opts || {}),\n alignNodes: (opts) => rpc.call("alignNodes", opts || {}),\n distributeNodes: (opts) => rpc.call("distributeNodes", opts || {}),\n flipNodes: (opts) => rpc.call("flipNodes", opts || {}),\n rotateNodes: (opts) => rpc.call("rotateNodes", opts || {}),\n reorderNodes: (opts) => rpc.call("reorderNodes", opts || {}),\n setLocked: (opts) => rpc.call("setLocked", opts || {}),\n setVisible: (opts) => rpc.call("setVisible", opts || {}),\n setAutoLayout: (opts) => rpc.call("setAutoLayout", opts || {}),\n importSvg: (opts) => rpc.call("importSvg", opts || {}),\n measureNodes: (opts) => rpc.call("measureNodes", opts || {}),\n setFills: (opts) => rpc.call("setFills", opts || {}),\n setStrokes: (opts) => rpc.call("setStrokes", opts || {}),\n setEffects: (opts) => rpc.call("setEffects", opts || {}),\n replaceColor: (opts) => rpc.call("replaceColor", opts || {}),\n setTypography: (opts) => rpc.call("setTypography", opts || {}),\n applyStyle: (opts) => rpc.call("applyStyle", opts || {}),\n createComponent: (opts) => rpc.call("createComponent", opts || {}),\n createInstance: (opts) => rpc.call("createInstance", opts || {}),\n renamePage: (opts) => rpc.call("renamePage", opts || {}),\n getDocumentOutline: (opts) => rpc.call("getDocumentOutline", opts || {}),\n setPageSetup: (opts) => rpc.call("setPageSetup", opts || {}),\n setShowAdvance: (opts) => rpc.call("setShowAdvance", opts || {}),\n booleanOperation: (opts) => rpc.call("booleanOperation", opts || {}),\n flattenNodes: (opts) => rpc.call("flattenNodes", opts || {}),\n outlineStroke: (opts) => rpc.call("outlineStroke", opts || {}),\n setMask: (opts) => rpc.call("setMask", opts || {}),\n setMaskType: (opts) => rpc.call("setMaskType", opts || {}),\n shapeBuilder: (opts) => rpc.call("shapeBuilder", opts || {}),\n setKeyframes: (opts) => rpc.call("setKeyframes", opts || {}),\n getAnimation: (opts) => rpc.call("getAnimation", opts || {}),\n getCompositions: (opts) => rpc.call("getCompositions", opts || {}),\n editBehaviours: (opts) => rpc.call("editBehaviours", opts || {}),\n setTimeline: (opts) => rpc.call("setTimeline", opts || {}),\n setLayerTiming: (opts) => rpc.call("setLayerTiming", opts || {}),\n editTextAnimation: (opts) => rpc.call("editTextAnimation", opts || {}),\n edit3DScene: (opts) => rpc.call("edit3DScene", opts || {}),\n setInstancePlayback: (opts) => rpc.call("setInstancePlayback", opts || {}),\n editComponentProperty: (opts) => rpc.call("editComponentProperty", opts || {}),\n setShaderFill: (opts) => rpc.call("setShaderFill", opts || {}),\n createComposition: (opts) => rpc.call("createComposition", opts || {}),\n editComposition: (opts) => rpc.call("editComposition", opts || {}),\n editStateMachine: (opts) => rpc.call("editStateMachine", opts || {}),\n getStateMachine: (opts) => rpc.call("getStateMachine", opts || {}),\n applyMotionPreset: (opts) => rpc.call("applyMotionPreset", opts || {}),\n staggerMotion: (opts) => rpc.call("staggerMotion", opts || {}),\n createMotionComponent: (opts) => rpc.call("createMotionComponent", opts || {}),\n addAudio: (opts) => rpc.call("addAudio", opts || {}),\n editFrameAudio: (opts) => rpc.call("editFrameAudio", opts || {}),\n editVideoClip: (opts) => rpc.call("editVideoClip", opts || {}),\n detectAudioOnsets: (opts) => rpc.call("detectAudioOnsets", opts || {}),\n cutToBeat: (opts) => rpc.call("cutToBeat", opts || {}),\n editPrototype: (opts) => rpc.call("editPrototype", opts || {}),\n usePresentationFallbackAudio: (opts) => rpc.call("usePresentationFallbackAudio", opts || {}),\n /** Bring a Lottie, PDF or PopCraft file into the open document (the `importFile` field is the file an importer was handed). */\n importDocumentFile: (opts) => rpc.call("importDocumentFile", opts || {}),\n getStyles: () => rpc.call("getStyles"),\n createPaintStyle: (name, paints) => rpc.call("createPaintStyle", { name, paints }),\n getVariables: () => rpc.call("getVariables"),\n setVariableValue: (variableId, modeId, value) => rpc.call("setVariableValue", { variableId, modeId, value }),\n exportNode: (id, options) => rpc.call("exportNode", { id, options: options || {} }),\n openExternal: (url) => rpc.call("openExternal", { url }),\n /**\n * Send a file to an https URL. PopCraft makes the request, not the sandbox, so it works for files of\n * any size the server accepts, including straight to a presigned storage URL. Needs `network`.\n */\n upload: (url, options) => {\n const body = options.body instanceof ArrayBuffer ? new Uint8Array(options.body) : options.body;\n return rpc.call("upload", {\n url,\n body,\n method: options.method,\n contentType: options.contentType,\n headers: options.headers\n });\n },\n notify: (message, options) => rpc.call("notify", { message: String(message), error: !!(options && options.error) }),\n showUI: (options) => rpc.call("showUI", options || {}),\n hideUI: () => rpc.call("hideUI"),\n /** Ends the run. The optional message is shown as a notification. */\n closePlugin: (message) => rpc.call("closePlugin", { message }),\n storage: {\n get: (key) => rpc.call("storageGet", { key }),\n set: (key, value) => rpc.call("storageSet", { key, value })\n },\n ui: {\n get onmessage() {\n return uiOnMessage;\n },\n set onmessage(cb) {\n uiOnMessage = cb;\n flushUI();\n },\n postMessage: (msg) => rpc.send({ kind: "toUI", data: msg }),\n on: (cb) => {\n uiHandlers.push(cb);\n flushUI();\n }\n },\n widget: {\n register(def) {\n if (!def || typeof def.render !== "function") throw new Error("popcraft.widget.register needs a render(state) function");\n widgetDef = def;\n widgetQueue.splice(0).forEach(handleWidgetClick);\n },\n insert(options) {\n if (!widgetDef) return Promise.reject(new Error("Call popcraft.widget.register first"));\n const o = options || {};\n const state = o.state !== void 0 ? clone(o.state) : initialWidgetState();\n return rpc.call("widgetInsert", { state, tree: renderWidget(state).tree, x: o.x, y: o.y });\n },\n getState: (nodeId) => rpc.call("widgetGet", { id: nodeId }),\n setState(nodeId, state) {\n if (!widgetDef) return Promise.reject(new Error("Call popcraft.widget.register first"));\n return commitWidget(nodeId, clone(state));\n }\n },\n on: (event, cb) => rpc.on(event, cb),\n off: (event, cb) => rpc.off(event, cb)\n };\n rpc.on("init", (data) => {\n var _a, _b, _c;\n popcraft.command = data.command;\n popcraft.importMode = (_a = data.importMode) != null ? _a : null;\n popcraft.importFile = (_b = data.importFile) != null ? _b : null;\n popcraft.exportRequest = (_c = data.exportRequest) != null ? _c : null;\n });\n return popcraft;\n }\n function installMainApi() {\n const rpc = createRpcClient();\n const api = createMainApi(rpc);\n const w = window;\n w.__popcraftRpc = rpc;\n w.popcraft = api;\n w.vizpops = api;\n window.addEventListener("error", (e) => rpc.send({ kind: "error", message: String(e.message || e) }));\n window.addEventListener("unhandledrejection", (e) => rpc.send({ kind: "error", message: String(e.reason && e.reason.message || e.reason) }));\n return api;\n }\n\n // src/runtime/main.entry.ts\n installMainApi();\n})();';
|
|
368603
368598
|
UI_RUNTIME = '"use strict";\n(() => {\n // src/runtime/rpc.ts\n function createRpcClient() {\n let port = null;\n const queue = [];\n const pending = {};\n const listeners = {};\n let nextId = 1;\n function send(msg) {\n if (port) port.postMessage(msg);\n else queue.push(msg);\n }\n function call(method, params) {\n return new Promise((resolve, reject) => {\n const id = nextId++;\n pending[id] = { resolve, reject };\n send({ kind: "rpc", id, method, params });\n });\n }\n function emit(event, data) {\n for (const cb of (listeners[event] || []).slice()) {\n try {\n cb(data);\n } catch (e) {\n console.error(e);\n }\n }\n }\n window.addEventListener("message", (e) => {\n const data = e.data;\n if (e.source !== window.parent || !data || data.type !== "popcraft-plugin-port" || port) return;\n port = e.ports[0];\n port.onmessage = (ev) => {\n const m = ev.data || {};\n if (m.kind === "result" && m.id !== void 0 && pending[m.id]) {\n const p = pending[m.id];\n delete pending[m.id];\n if (m.error) p.reject(new Error(m.error));\n else p.resolve(m.result);\n } else if (m.kind === "event" && m.event) {\n emit(m.event, m.data);\n }\n };\n for (const msg of queue.splice(0)) port.postMessage(msg);\n });\n return {\n call,\n send,\n on(event, cb) {\n (listeners[event] = listeners[event] || []).push(cb);\n },\n off(event, cb) {\n listeners[event] = (listeners[event] || []).filter((x) => x !== cb);\n }\n };\n }\n\n // src/runtime/ui.ts\n function createUiApi(rpc = createRpcClient()) {\n const popcraft = {\n onmessage: null,\n postMessage: (msg) => rpc.send({ kind: "fromUI", data: msg }),\n close: () => rpc.send({ kind: "closeUI" })\n };\n rpc.on("message", (msg) => {\n if (typeof popcraft.onmessage === "function") popcraft.onmessage(msg);\n window.dispatchEvent(new MessageEvent("message", { data: { pluginMessage: msg } }));\n });\n return popcraft;\n }\n function installUiApi() {\n const rpc = createRpcClient();\n const api = createUiApi(rpc);\n const w = window;\n w.__popcraftRpc = rpc;\n w.popcraft = api;\n w.vizpops = api;\n return api;\n }\n\n // src/runtime/ui.entry.ts\n installUiApi();\n})();';
|
|
368604
368599
|
}
|
|
368605
368600
|
});
|
|
368606
368601
|
|
|
368607
|
-
// node_modules/.pnpm/@popcraft+plugins@1.0
|
|
368602
|
+
// node_modules/.pnpm/@popcraft+plugins@1.3.0/node_modules/@popcraft/plugins/dist/host.js
|
|
368608
368603
|
function csp(network) {
|
|
368609
368604
|
const connect2 = network ? "connect-src * data: blob:;" : "connect-src 'none';";
|
|
368610
368605
|
const img = network ? "img-src * data: blob:;" : "img-src data: blob:;";
|
|
@@ -368632,40 +368627,40 @@ function buildUIDocument(uiHtml, network) {
|
|
|
368632
368627
|
}
|
|
368633
368628
|
var escapeScript;
|
|
368634
368629
|
var init_host2 = __esm({
|
|
368635
|
-
"node_modules/.pnpm/@popcraft+plugins@1.0
|
|
368630
|
+
"node_modules/.pnpm/@popcraft+plugins@1.3.0/node_modules/@popcraft/plugins/dist/host.js"() {
|
|
368636
368631
|
init_runtime6();
|
|
368637
368632
|
escapeScript = (code) => code.replace(/<\/script/gi, "<\\/script");
|
|
368638
368633
|
}
|
|
368639
368634
|
});
|
|
368640
368635
|
|
|
368641
|
-
// node_modules/.pnpm/@popcraft+plugins@1.0
|
|
368636
|
+
// node_modules/.pnpm/@popcraft+plugins@1.3.0/node_modules/@popcraft/plugins/dist/runtime/rpc.js
|
|
368642
368637
|
var init_rpc = __esm({
|
|
368643
|
-
"node_modules/.pnpm/@popcraft+plugins@1.0
|
|
368638
|
+
"node_modules/.pnpm/@popcraft+plugins@1.3.0/node_modules/@popcraft/plugins/dist/runtime/rpc.js"() {
|
|
368644
368639
|
}
|
|
368645
368640
|
});
|
|
368646
368641
|
|
|
368647
|
-
// node_modules/.pnpm/@popcraft+plugins@1.0
|
|
368642
|
+
// node_modules/.pnpm/@popcraft+plugins@1.3.0/node_modules/@popcraft/plugins/dist/runtime/main.js
|
|
368648
368643
|
var init_main = __esm({
|
|
368649
|
-
"node_modules/.pnpm/@popcraft+plugins@1.0
|
|
368644
|
+
"node_modules/.pnpm/@popcraft+plugins@1.3.0/node_modules/@popcraft/plugins/dist/runtime/main.js"() {
|
|
368650
368645
|
init_rpc();
|
|
368651
368646
|
}
|
|
368652
368647
|
});
|
|
368653
368648
|
|
|
368654
|
-
// node_modules/.pnpm/@popcraft+plugins@1.0
|
|
368649
|
+
// node_modules/.pnpm/@popcraft+plugins@1.3.0/node_modules/@popcraft/plugins/dist/types.js
|
|
368655
368650
|
var init_types10 = __esm({
|
|
368656
|
-
"node_modules/.pnpm/@popcraft+plugins@1.0
|
|
368651
|
+
"node_modules/.pnpm/@popcraft+plugins@1.3.0/node_modules/@popcraft/plugins/dist/types.js"() {
|
|
368657
368652
|
}
|
|
368658
368653
|
});
|
|
368659
368654
|
|
|
368660
|
-
// node_modules/.pnpm/@popcraft+plugins@1.0
|
|
368655
|
+
// node_modules/.pnpm/@popcraft+plugins@1.3.0/node_modules/@popcraft/plugins/dist/widget.js
|
|
368661
368656
|
var init_widget = __esm({
|
|
368662
|
-
"node_modules/.pnpm/@popcraft+plugins@1.0
|
|
368657
|
+
"node_modules/.pnpm/@popcraft+plugins@1.3.0/node_modules/@popcraft/plugins/dist/widget.js"() {
|
|
368663
368658
|
}
|
|
368664
368659
|
});
|
|
368665
368660
|
|
|
368666
|
-
// node_modules/.pnpm/@popcraft+plugins@1.0
|
|
368661
|
+
// node_modules/.pnpm/@popcraft+plugins@1.3.0/node_modules/@popcraft/plugins/dist/index.js
|
|
368667
368662
|
var init_dist = __esm({
|
|
368668
|
-
"node_modules/.pnpm/@popcraft+plugins@1.0
|
|
368663
|
+
"node_modules/.pnpm/@popcraft+plugins@1.3.0/node_modules/@popcraft/plugins/dist/index.js"() {
|
|
368669
368664
|
init_host2();
|
|
368670
368665
|
init_main();
|
|
368671
368666
|
init_runtime6();
|
|
@@ -399253,7 +399248,7 @@ function dispatchPluginCall(env, method, params2 = {}) {
|
|
|
399253
399248
|
}
|
|
399254
399249
|
});
|
|
399255
399250
|
}
|
|
399256
|
-
var PLUGIN_CAPABILITIES, pluginCommandId, empty, commands, pluginRun, registered;
|
|
399251
|
+
var PLUGIN_CAPABILITIES, pluginCommandId, empty, MAX_UPLOAD_BYTES, MAX_UPLOAD_REPLY_CHARS, commands, pluginRun, registered;
|
|
399257
399252
|
var init_plugin = __esm({
|
|
399258
399253
|
"lib/commands/plugin.ts"() {
|
|
399259
399254
|
init_zod();
|
|
@@ -399269,6 +399264,8 @@ var init_plugin = __esm({
|
|
|
399269
399264
|
PLUGIN_CAPABILITIES = ["render", "storage", "panel"];
|
|
399270
399265
|
pluginCommandId = (method) => `plugin.${method}`;
|
|
399271
399266
|
empty = external_exports.object({});
|
|
399267
|
+
MAX_UPLOAD_BYTES = 500 * 1024 * 1024;
|
|
399268
|
+
MAX_UPLOAD_REPLY_CHARS = 1024 * 1024;
|
|
399272
399269
|
commands = [
|
|
399273
399270
|
defineCommand({
|
|
399274
399271
|
id: pluginCommandId("getVariables"),
|
|
@@ -399348,6 +399345,46 @@ var init_plugin = __esm({
|
|
|
399348
399345
|
return { summary: "Opened link" };
|
|
399349
399346
|
}
|
|
399350
399347
|
}),
|
|
399348
|
+
defineCommand({
|
|
399349
|
+
id: pluginCommandId("upload"),
|
|
399350
|
+
title: "Upload a file",
|
|
399351
|
+
domain: "ui",
|
|
399352
|
+
// The sandbox's own fetch is fine for small requests; a book-sized export goes through here so it can be
|
|
399353
|
+
// PUT straight onto a presigned storage URL rather than through a server that caps its request body.
|
|
399354
|
+
params: external_exports.object({
|
|
399355
|
+
url: external_exports.string().refine(isOpenableUrl, { error: "url must be https, or http on localhost" }),
|
|
399356
|
+
body: external_exports.union([external_exports.instanceof(Uint8Array), external_exports.string()]),
|
|
399357
|
+
method: external_exports.enum(["PUT", "POST"]).optional(),
|
|
399358
|
+
contentType: external_exports.string().max(200).optional(),
|
|
399359
|
+
headers: external_exports.record(external_exports.string(), external_exports.string()).optional()
|
|
399360
|
+
}),
|
|
399361
|
+
effect: "none",
|
|
399362
|
+
permission: "network",
|
|
399363
|
+
expose: { plugin: { method: "upload", shape: (r) => r.data } },
|
|
399364
|
+
run: async (p2) => {
|
|
399365
|
+
const size6 = typeof p2.body === "string" ? p2.body.length : p2.body.byteLength;
|
|
399366
|
+
if (size6 > MAX_UPLOAD_BYTES) throw new PluginApiError(`upload is limited to ${MAX_UPLOAD_BYTES / 1024 / 1024} MB`, "invalid_params");
|
|
399367
|
+
if (typeof location !== "undefined" && new URL(p2.url).origin === location.origin) {
|
|
399368
|
+
throw new PluginApiError("upload cannot send to PopCraft itself", "invalid_params");
|
|
399369
|
+
}
|
|
399370
|
+
const headers = new Headers(p2.headers ?? {});
|
|
399371
|
+
if (p2.contentType) headers.set("content-type", p2.contentType);
|
|
399372
|
+
let res;
|
|
399373
|
+
try {
|
|
399374
|
+
res = await fetch(p2.url, { method: p2.method ?? "PUT", body: p2.body, headers, credentials: "omit", mode: "cors" });
|
|
399375
|
+
} catch (err2) {
|
|
399376
|
+
throw new PluginApiError(`Could not reach ${new URL(p2.url).origin}: ${err2 instanceof Error ? err2.message : String(err2)}`, "unsupported");
|
|
399377
|
+
}
|
|
399378
|
+
const text = await res.text();
|
|
399379
|
+
const data = {
|
|
399380
|
+
ok: res.ok,
|
|
399381
|
+
status: res.status,
|
|
399382
|
+
headers: Object.fromEntries(res.headers.entries()),
|
|
399383
|
+
body: text.length > MAX_UPLOAD_REPLY_CHARS ? text.slice(0, MAX_UPLOAD_REPLY_CHARS) : text
|
|
399384
|
+
};
|
|
399385
|
+
return { summary: `Uploaded ${size6} bytes (${res.status})`, data };
|
|
399386
|
+
}
|
|
399387
|
+
}),
|
|
399351
399388
|
defineCommand({
|
|
399352
399389
|
id: pluginCommandId("showUI"),
|
|
399353
399390
|
title: "Show plugin UI",
|
|
@@ -406459,7 +406496,6 @@ function registerBuiltinCommands() {
|
|
|
406459
406496
|
var builtinCommands, uiOnlyCommands;
|
|
406460
406497
|
var init_builtin4 = __esm({
|
|
406461
406498
|
"lib/commands/builtin.ts"() {
|
|
406462
|
-
"use strict";
|
|
406463
406499
|
init_registry();
|
|
406464
406500
|
init_node();
|
|
406465
406501
|
init_node();
|
|
@@ -414064,7 +414100,7 @@ init_resources();
|
|
|
414064
414100
|
init_desktop();
|
|
414065
414101
|
init_hypery();
|
|
414066
414102
|
import { createInterface } from "node:readline";
|
|
414067
|
-
var VERSION2 = "0.
|
|
414103
|
+
var VERSION2 = "0.53.0";
|
|
414068
414104
|
var HELP = `popcraft ${VERSION2} \u2014 the PopCraft command line
|
|
414069
414105
|
|
|
414070
414106
|
Files (headless, on .popcraft files):
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@popcraft/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.53.0",
|
|
4
4
|
"description": "The PopCraft command line: edit .popcraft files headlessly, call the REST API, publish to the marketplace and manage the desktop app's local plugins, themes, fonts, skills and agents.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"homepage": "https://popcraft.app/docs/api/cli",
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
"esbuild": "0.28.2"
|
|
35
35
|
},
|
|
36
36
|
"dependencies": {
|
|
37
|
-
"@popcraft/kit": "0.
|
|
37
|
+
"@popcraft/kit": "0.53.0"
|
|
38
38
|
},
|
|
39
39
|
"scripts": {
|
|
40
40
|
"build": "node build.mjs",
|