@pinagent/react-native 0.1.2 → 0.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/babel.cjs +1 -1
- package/dist/babel.cjs.map +1 -1
- package/dist/babel.js +1 -1
- package/dist/babel.js.map +1 -1
- package/drizzle/0000_fast_swarm.sql +46 -0
- package/drizzle/0001_lazy_jimmy_woo.sql +1 -0
- package/drizzle/0002_cool_thena.sql +13 -0
- package/drizzle/0003_flowery_zodiak.sql +13 -0
- package/drizzle/0004_abandoned_toro.sql +8 -0
- package/drizzle/0005_quick_ozymandias.sql +2 -0
- package/drizzle/0006_inline_resolved_backfill.sql +7 -0
- package/drizzle/0007_brief_the_santerians.sql +1 -0
- package/drizzle/0008_curved_ricochet.sql +5 -0
- package/drizzle/meta/0000_snapshot.json +328 -0
- package/drizzle/meta/0001_snapshot.json +335 -0
- package/drizzle/meta/0002_snapshot.json +343 -0
- package/drizzle/meta/0003_snapshot.json +435 -0
- package/drizzle/meta/0004_snapshot.json +489 -0
- package/drizzle/meta/0005_snapshot.json +504 -0
- package/drizzle/meta/0006_snapshot.json +504 -0
- package/drizzle/meta/0007_snapshot.json +511 -0
- package/drizzle/meta/0008_snapshot.json +546 -0
- package/drizzle/meta/_journal.json +69 -0
- package/package.json +7 -4
package/dist/babel.cjs
CHANGED
|
@@ -120,7 +120,7 @@ function pinagentSource(babel) {
|
|
|
120
120
|
const attrs = [t.jsxAttribute(t.jsxIdentifier(ATTR), t.stringLiteral(value))];
|
|
121
121
|
const comp = enclosingComponentName(path, t);
|
|
122
122
|
if (comp) attrs.push(t.jsxAttribute(t.jsxIdentifier(COMP_ATTR), t.stringLiteral(comp)));
|
|
123
|
-
node.attributes.
|
|
123
|
+
node.attributes.unshift(...attrs);
|
|
124
124
|
} }
|
|
125
125
|
};
|
|
126
126
|
}
|
package/dist/babel.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"babel.cjs","names":["sep"],"sources":["../src/babel.ts"],"sourcesContent":["// SPDX-License-Identifier: Apache-2.0\n/**\n * Metro/Babel source-tagging plugin — the React Native analog of the web\n * `@pinagent/babel-plugin`.\n *\n * It splices a `data-pa-loc=\"<file>:<line>:<col>\"` prop (plus a\n * `data-pa-comp=\"<EnclosingComponent>\"` companion) onto every authored JSX\n * element, exactly mirroring what the web babel plugin emits as a DOM\n * attribute. On React Native that prop survives onto the host fiber's\n * `memoizedProps`, so {@link resolvePick} can read it back at tap time.\n *\n * ## Why this exists (and didn't used to)\n *\n * The original RN design leaned on each fiber's `_debugSource`, populated in\n * dev by `@babel/plugin-transform-react-jsx-source` — \"reuse RN's, no custom\n * plugin needed\". **React 19 removed `_debugSource`** (the `ReactElement`\n * constructor no longer takes a `source` arg; the `__source` prop is consumed\n * by `jsxDEV` and never reaches `memoizedProps`), and **RN 0.81+ dropped the\n * `source` field from `getInspectorDataForViewAtPoint`**. So the runtime no\n * longer carries any source location — we have to inject our own, at build\n * time, the same way web does.\n *\n * Wire it into `babel.config.js` (dev only) BEFORE `babel-preset-expo`'s JSX\n * transform so the attribute is present when JSX lowers to `jsxDEV`:\n *\n * const pinagentSource = require('@pinagent/react-native/babel').default;\n * module.exports = (api) => {\n * api.cache(true);\n * const dev = process.env.NODE_ENV !== 'production';\n * return {\n * presets: ['babel-preset-expo'],\n * plugins: dev ? [pinagentSource] : [],\n * };\n * };\n *\n * Typed loosely (no `@babel/*` type deps) on purpose — like {@link inspector},\n * this is a thin, version-tolerant shim over an external toolchain that this\n * otherwise web-only monorepo doesn't carry types for.\n */\nimport { isAbsolute, relative, sep } from 'node:path';\n\n/** The attribute the web plugin emits — reused verbatim so reads match. */\nconst ATTR = 'data-pa-loc';\n/** Companion attribute carrying the enclosing component name. */\nconst COMP_ATTR = 'data-pa-comp';\n\n// Minimal structural typing for the slice of Babel we touch. Babel hands the\n// plugin a `types` namespace and node paths; we lean on duck-typing rather\n// than pulling in @types/babel__core.\n// biome-ignore lint/suspicious/noExplicitAny: external babel AST, typed loosely\ntype Any = any;\n\ninterface PluginState {\n filename?: string;\n cwd?: string;\n opts?: { projectRoot?: string };\n file?: { opts?: { filename?: string; cwd?: string; root?: string } };\n}\n\nfunction toPosix(p: string): string {\n return sep === '/' ? p : p.split(sep).join('/');\n}\n\n/**\n * Walk up to the nearest enclosing React component — the closest\n * function/class ancestor with a PascalCase name. Lowercase callbacks\n * (`items.map(x => <Row/>)`) are skipped, so list items report the component\n * that owns the list. Mirrors `@pinagent/babel-plugin`'s `transform.ts`.\n */\nfunction enclosingComponentName(path: Any, t: Any): string | null {\n let fn = path.getFunctionParent?.();\n while (fn) {\n const name = inferFunctionName(fn, t);\n if (name && /^[A-Z]/.test(name)) return name;\n fn = fn.getFunctionParent?.();\n }\n return null;\n}\n\nfunction inferFunctionName(fnPath: Any, t: Any): string | null {\n const node = fnPath.node;\n if (t.isFunctionDeclaration(node) && node.id) return node.id.name;\n if (t.isClassMethod(node) || t.isClassPrivateMethod(node)) {\n const cls = fnPath.findParent((p: Any) => p.isClassDeclaration() || p.isClassExpression());\n if (cls) {\n const clsNode = cls.node;\n if ((t.isClassDeclaration(clsNode) || t.isClassExpression(clsNode)) && clsNode.id) {\n return clsNode.id.name;\n }\n return nameFromBinding(cls, t);\n }\n return null;\n }\n return nameFromBinding(fnPath, t);\n}\n\nfunction nameFromBinding(p: Any, t: Any): string | null {\n const pn = p.parentPath?.node;\n if (!pn) return null;\n if (t.isVariableDeclarator(pn) && t.isIdentifier(pn.id)) return pn.id.name;\n if ((t.isObjectProperty(pn) || t.isObjectMethod(pn)) && t.isIdentifier(pn.key))\n return pn.key.name;\n if ((t.isClassProperty(pn) || t.isClassMethod(pn)) && t.isIdentifier(pn.key)) return pn.key.name;\n if (t.isAssignmentExpression(pn) && t.isIdentifier(pn.left)) return pn.left.name;\n return null;\n}\n\nfunction isFragment(name: Any, t: Any): boolean {\n if (t.isJSXIdentifier(name)) return name.name === 'Fragment';\n if (t.isJSXMemberExpression(name)) {\n return t.isJSXIdentifier(name.property) && name.property.name === 'Fragment';\n }\n return t.isJSXNamespacedName(name);\n}\n\n/** Resolve the project root used to make paths relative. */\nfunction rootFor(state: PluginState): string | undefined {\n return state.opts?.projectRoot ?? state.file?.opts?.root ?? state.cwd ?? state.file?.opts?.cwd;\n}\n\n/** Resolve the file being transformed. */\nfunction filenameFor(state: PluginState): string | undefined {\n return state.filename ?? state.file?.opts?.filename;\n}\n\nexport interface PinagentBabelOptions {\n /** Project root for project-relative paths. Defaults to Babel's cwd/root. */\n projectRoot?: string;\n}\n\n/**\n * The Babel plugin. Default export so a `babel.config.js` can `require()` it\n * and drop the function straight into `plugins`.\n */\nexport default function pinagentSource(babel: { types: Any }): Any {\n const t = babel.types;\n return {\n name: 'pinagent-source',\n visitor: {\n JSXOpeningElement(path: Any, state: PluginState) {\n const node = path.node;\n if (isFragment(node.name, t)) return;\n\n // Already tagged? Idempotent — re-running is a no-op.\n const tagged = node.attributes.some(\n (a: Any) => t.isJSXAttribute(a) && t.isJSXIdentifier(a.name) && a.name.name === ATTR,\n );\n if (tagged) return;\n\n const loc = node.loc?.start;\n if (!loc) return;\n\n const filename = filenameFor(state);\n if (!filename || filename.includes(`${sep}node_modules${sep}`)) return;\n\n const root = rootFor(state);\n let rel = root && isAbsolute(filename) ? relative(root, filename) : filename;\n rel = toPosix(rel);\n // Only tag files inside the project root — skip anything resolved\n // outside it (e.g. the in-tree widget source under an out-of-root\n // package, which the developer never taps on).\n if (rel.startsWith('../')) return;\n\n const value = `${rel}:${loc.line}:${loc.column + 1}`;\n const attrs = [t.jsxAttribute(t.jsxIdentifier(ATTR), t.stringLiteral(value))];\n const comp = enclosingComponentName(path, t);\n if (comp) {\n attrs.push(t.jsxAttribute(t.jsxIdentifier(COMP_ATTR), t.stringLiteral(comp)));\n }\n node.attributes.push(...attrs);\n },\n },\n };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"babel.cjs","names":["sep"],"sources":["../src/babel.ts"],"sourcesContent":["// SPDX-License-Identifier: Apache-2.0\n/**\n * Metro/Babel source-tagging plugin — the React Native analog of the web\n * `@pinagent/babel-plugin`.\n *\n * It splices a `data-pa-loc=\"<file>:<line>:<col>\"` prop (plus a\n * `data-pa-comp=\"<EnclosingComponent>\"` companion) onto every authored JSX\n * element, exactly mirroring what the web babel plugin emits as a DOM\n * attribute. On React Native that prop survives onto the host fiber's\n * `memoizedProps`, so {@link resolvePick} can read it back at tap time.\n *\n * ## Why this exists (and didn't used to)\n *\n * The original RN design leaned on each fiber's `_debugSource`, populated in\n * dev by `@babel/plugin-transform-react-jsx-source` — \"reuse RN's, no custom\n * plugin needed\". **React 19 removed `_debugSource`** (the `ReactElement`\n * constructor no longer takes a `source` arg; the `__source` prop is consumed\n * by `jsxDEV` and never reaches `memoizedProps`), and **RN 0.81+ dropped the\n * `source` field from `getInspectorDataForViewAtPoint`**. So the runtime no\n * longer carries any source location — we have to inject our own, at build\n * time, the same way web does.\n *\n * Wire it into `babel.config.js` (dev only) BEFORE `babel-preset-expo`'s JSX\n * transform so the attribute is present when JSX lowers to `jsxDEV`:\n *\n * const pinagentSource = require('@pinagent/react-native/babel').default;\n * module.exports = (api) => {\n * api.cache(true);\n * const dev = process.env.NODE_ENV !== 'production';\n * return {\n * presets: ['babel-preset-expo'],\n * plugins: dev ? [pinagentSource] : [],\n * };\n * };\n *\n * Typed loosely (no `@babel/*` type deps) on purpose — like {@link inspector},\n * this is a thin, version-tolerant shim over an external toolchain that this\n * otherwise web-only monorepo doesn't carry types for.\n */\nimport { isAbsolute, relative, sep } from 'node:path';\n\n/** The attribute the web plugin emits — reused verbatim so reads match. */\nconst ATTR = 'data-pa-loc';\n/** Companion attribute carrying the enclosing component name. */\nconst COMP_ATTR = 'data-pa-comp';\n\n// Minimal structural typing for the slice of Babel we touch. Babel hands the\n// plugin a `types` namespace and node paths; we lean on duck-typing rather\n// than pulling in @types/babel__core.\n// biome-ignore lint/suspicious/noExplicitAny: external babel AST, typed loosely\ntype Any = any;\n\ninterface PluginState {\n filename?: string;\n cwd?: string;\n opts?: { projectRoot?: string };\n file?: { opts?: { filename?: string; cwd?: string; root?: string } };\n}\n\nfunction toPosix(p: string): string {\n return sep === '/' ? p : p.split(sep).join('/');\n}\n\n/**\n * Walk up to the nearest enclosing React component — the closest\n * function/class ancestor with a PascalCase name. Lowercase callbacks\n * (`items.map(x => <Row/>)`) are skipped, so list items report the component\n * that owns the list. Mirrors `@pinagent/babel-plugin`'s `transform.ts`.\n */\nfunction enclosingComponentName(path: Any, t: Any): string | null {\n let fn = path.getFunctionParent?.();\n while (fn) {\n const name = inferFunctionName(fn, t);\n if (name && /^[A-Z]/.test(name)) return name;\n fn = fn.getFunctionParent?.();\n }\n return null;\n}\n\nfunction inferFunctionName(fnPath: Any, t: Any): string | null {\n const node = fnPath.node;\n if (t.isFunctionDeclaration(node) && node.id) return node.id.name;\n if (t.isClassMethod(node) || t.isClassPrivateMethod(node)) {\n const cls = fnPath.findParent((p: Any) => p.isClassDeclaration() || p.isClassExpression());\n if (cls) {\n const clsNode = cls.node;\n if ((t.isClassDeclaration(clsNode) || t.isClassExpression(clsNode)) && clsNode.id) {\n return clsNode.id.name;\n }\n return nameFromBinding(cls, t);\n }\n return null;\n }\n return nameFromBinding(fnPath, t);\n}\n\nfunction nameFromBinding(p: Any, t: Any): string | null {\n const pn = p.parentPath?.node;\n if (!pn) return null;\n if (t.isVariableDeclarator(pn) && t.isIdentifier(pn.id)) return pn.id.name;\n if ((t.isObjectProperty(pn) || t.isObjectMethod(pn)) && t.isIdentifier(pn.key))\n return pn.key.name;\n if ((t.isClassProperty(pn) || t.isClassMethod(pn)) && t.isIdentifier(pn.key)) return pn.key.name;\n if (t.isAssignmentExpression(pn) && t.isIdentifier(pn.left)) return pn.left.name;\n return null;\n}\n\nfunction isFragment(name: Any, t: Any): boolean {\n if (t.isJSXIdentifier(name)) return name.name === 'Fragment';\n if (t.isJSXMemberExpression(name)) {\n return t.isJSXIdentifier(name.property) && name.property.name === 'Fragment';\n }\n return t.isJSXNamespacedName(name);\n}\n\n/** Resolve the project root used to make paths relative. */\nfunction rootFor(state: PluginState): string | undefined {\n return state.opts?.projectRoot ?? state.file?.opts?.root ?? state.cwd ?? state.file?.opts?.cwd;\n}\n\n/** Resolve the file being transformed. */\nfunction filenameFor(state: PluginState): string | undefined {\n return state.filename ?? state.file?.opts?.filename;\n}\n\nexport interface PinagentBabelOptions {\n /** Project root for project-relative paths. Defaults to Babel's cwd/root. */\n projectRoot?: string;\n}\n\n/**\n * The Babel plugin. Default export so a `babel.config.js` can `require()` it\n * and drop the function straight into `plugins`.\n */\nexport default function pinagentSource(babel: { types: Any }): Any {\n const t = babel.types;\n return {\n name: 'pinagent-source',\n visitor: {\n JSXOpeningElement(path: Any, state: PluginState) {\n const node = path.node;\n if (isFragment(node.name, t)) return;\n\n // Already tagged? Idempotent — re-running is a no-op.\n const tagged = node.attributes.some(\n (a: Any) => t.isJSXAttribute(a) && t.isJSXIdentifier(a.name) && a.name.name === ATTR,\n );\n if (tagged) return;\n\n const loc = node.loc?.start;\n if (!loc) return;\n\n const filename = filenameFor(state);\n if (!filename || filename.includes(`${sep}node_modules${sep}`)) return;\n\n const root = rootFor(state);\n let rel = root && isAbsolute(filename) ? relative(root, filename) : filename;\n rel = toPosix(rel);\n // Only tag files inside the project root — skip anything resolved\n // outside it (e.g. the in-tree widget source under an out-of-root\n // package, which the developer never taps on).\n if (rel.startsWith('../')) return;\n\n const value = `${rel}:${loc.line}:${loc.column + 1}`;\n const attrs = [t.jsxAttribute(t.jsxIdentifier(ATTR), t.stringLiteral(value))];\n const comp = enclosingComponentName(path, t);\n if (comp) {\n attrs.push(t.jsxAttribute(t.jsxIdentifier(COMP_ATTR), t.stringLiteral(comp)));\n }\n // Prepend, NOT append — this is load-bearing for generic wrapper\n // components. A wrapper like `<ViewRn {...rest} />` forwards the\n // call site's own `data-pa-loc` (which arrives via `rest`) onto the\n // host view. JSX props resolve last-wins, so our spliced attribute\n // must come BEFORE `{...rest}` to let the forwarded call-site location\n // override the wrapper's own definition line. Append it after the\n // spread and every element rendered through the wrapper collapses to\n // the wrapper's `file:line`, and the tapped child becomes unreachable.\n // The web `@pinagent/babel-plugin` gets this for free by inserting at\n // `name.end` (before all attributes); we mirror that here.\n node.attributes.unshift(...attrs);\n },\n },\n };\n}\n"],"mappings":"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"}
|
package/dist/babel.js
CHANGED
|
@@ -120,7 +120,7 @@ function pinagentSource(babel) {
|
|
|
120
120
|
const attrs = [t.jsxAttribute(t.jsxIdentifier(ATTR), t.stringLiteral(value))];
|
|
121
121
|
const comp = enclosingComponentName(path, t);
|
|
122
122
|
if (comp) attrs.push(t.jsxAttribute(t.jsxIdentifier(COMP_ATTR), t.stringLiteral(comp)));
|
|
123
|
-
node.attributes.
|
|
123
|
+
node.attributes.unshift(...attrs);
|
|
124
124
|
} }
|
|
125
125
|
};
|
|
126
126
|
}
|
package/dist/babel.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"babel.js","names":[],"sources":["../src/babel.ts"],"sourcesContent":["// SPDX-License-Identifier: Apache-2.0\n/**\n * Metro/Babel source-tagging plugin — the React Native analog of the web\n * `@pinagent/babel-plugin`.\n *\n * It splices a `data-pa-loc=\"<file>:<line>:<col>\"` prop (plus a\n * `data-pa-comp=\"<EnclosingComponent>\"` companion) onto every authored JSX\n * element, exactly mirroring what the web babel plugin emits as a DOM\n * attribute. On React Native that prop survives onto the host fiber's\n * `memoizedProps`, so {@link resolvePick} can read it back at tap time.\n *\n * ## Why this exists (and didn't used to)\n *\n * The original RN design leaned on each fiber's `_debugSource`, populated in\n * dev by `@babel/plugin-transform-react-jsx-source` — \"reuse RN's, no custom\n * plugin needed\". **React 19 removed `_debugSource`** (the `ReactElement`\n * constructor no longer takes a `source` arg; the `__source` prop is consumed\n * by `jsxDEV` and never reaches `memoizedProps`), and **RN 0.81+ dropped the\n * `source` field from `getInspectorDataForViewAtPoint`**. So the runtime no\n * longer carries any source location — we have to inject our own, at build\n * time, the same way web does.\n *\n * Wire it into `babel.config.js` (dev only) BEFORE `babel-preset-expo`'s JSX\n * transform so the attribute is present when JSX lowers to `jsxDEV`:\n *\n * const pinagentSource = require('@pinagent/react-native/babel').default;\n * module.exports = (api) => {\n * api.cache(true);\n * const dev = process.env.NODE_ENV !== 'production';\n * return {\n * presets: ['babel-preset-expo'],\n * plugins: dev ? [pinagentSource] : [],\n * };\n * };\n *\n * Typed loosely (no `@babel/*` type deps) on purpose — like {@link inspector},\n * this is a thin, version-tolerant shim over an external toolchain that this\n * otherwise web-only monorepo doesn't carry types for.\n */\nimport { isAbsolute, relative, sep } from 'node:path';\n\n/** The attribute the web plugin emits — reused verbatim so reads match. */\nconst ATTR = 'data-pa-loc';\n/** Companion attribute carrying the enclosing component name. */\nconst COMP_ATTR = 'data-pa-comp';\n\n// Minimal structural typing for the slice of Babel we touch. Babel hands the\n// plugin a `types` namespace and node paths; we lean on duck-typing rather\n// than pulling in @types/babel__core.\n// biome-ignore lint/suspicious/noExplicitAny: external babel AST, typed loosely\ntype Any = any;\n\ninterface PluginState {\n filename?: string;\n cwd?: string;\n opts?: { projectRoot?: string };\n file?: { opts?: { filename?: string; cwd?: string; root?: string } };\n}\n\nfunction toPosix(p: string): string {\n return sep === '/' ? p : p.split(sep).join('/');\n}\n\n/**\n * Walk up to the nearest enclosing React component — the closest\n * function/class ancestor with a PascalCase name. Lowercase callbacks\n * (`items.map(x => <Row/>)`) are skipped, so list items report the component\n * that owns the list. Mirrors `@pinagent/babel-plugin`'s `transform.ts`.\n */\nfunction enclosingComponentName(path: Any, t: Any): string | null {\n let fn = path.getFunctionParent?.();\n while (fn) {\n const name = inferFunctionName(fn, t);\n if (name && /^[A-Z]/.test(name)) return name;\n fn = fn.getFunctionParent?.();\n }\n return null;\n}\n\nfunction inferFunctionName(fnPath: Any, t: Any): string | null {\n const node = fnPath.node;\n if (t.isFunctionDeclaration(node) && node.id) return node.id.name;\n if (t.isClassMethod(node) || t.isClassPrivateMethod(node)) {\n const cls = fnPath.findParent((p: Any) => p.isClassDeclaration() || p.isClassExpression());\n if (cls) {\n const clsNode = cls.node;\n if ((t.isClassDeclaration(clsNode) || t.isClassExpression(clsNode)) && clsNode.id) {\n return clsNode.id.name;\n }\n return nameFromBinding(cls, t);\n }\n return null;\n }\n return nameFromBinding(fnPath, t);\n}\n\nfunction nameFromBinding(p: Any, t: Any): string | null {\n const pn = p.parentPath?.node;\n if (!pn) return null;\n if (t.isVariableDeclarator(pn) && t.isIdentifier(pn.id)) return pn.id.name;\n if ((t.isObjectProperty(pn) || t.isObjectMethod(pn)) && t.isIdentifier(pn.key))\n return pn.key.name;\n if ((t.isClassProperty(pn) || t.isClassMethod(pn)) && t.isIdentifier(pn.key)) return pn.key.name;\n if (t.isAssignmentExpression(pn) && t.isIdentifier(pn.left)) return pn.left.name;\n return null;\n}\n\nfunction isFragment(name: Any, t: Any): boolean {\n if (t.isJSXIdentifier(name)) return name.name === 'Fragment';\n if (t.isJSXMemberExpression(name)) {\n return t.isJSXIdentifier(name.property) && name.property.name === 'Fragment';\n }\n return t.isJSXNamespacedName(name);\n}\n\n/** Resolve the project root used to make paths relative. */\nfunction rootFor(state: PluginState): string | undefined {\n return state.opts?.projectRoot ?? state.file?.opts?.root ?? state.cwd ?? state.file?.opts?.cwd;\n}\n\n/** Resolve the file being transformed. */\nfunction filenameFor(state: PluginState): string | undefined {\n return state.filename ?? state.file?.opts?.filename;\n}\n\nexport interface PinagentBabelOptions {\n /** Project root for project-relative paths. Defaults to Babel's cwd/root. */\n projectRoot?: string;\n}\n\n/**\n * The Babel plugin. Default export so a `babel.config.js` can `require()` it\n * and drop the function straight into `plugins`.\n */\nexport default function pinagentSource(babel: { types: Any }): Any {\n const t = babel.types;\n return {\n name: 'pinagent-source',\n visitor: {\n JSXOpeningElement(path: Any, state: PluginState) {\n const node = path.node;\n if (isFragment(node.name, t)) return;\n\n // Already tagged? Idempotent — re-running is a no-op.\n const tagged = node.attributes.some(\n (a: Any) => t.isJSXAttribute(a) && t.isJSXIdentifier(a.name) && a.name.name === ATTR,\n );\n if (tagged) return;\n\n const loc = node.loc?.start;\n if (!loc) return;\n\n const filename = filenameFor(state);\n if (!filename || filename.includes(`${sep}node_modules${sep}`)) return;\n\n const root = rootFor(state);\n let rel = root && isAbsolute(filename) ? relative(root, filename) : filename;\n rel = toPosix(rel);\n // Only tag files inside the project root — skip anything resolved\n // outside it (e.g. the in-tree widget source under an out-of-root\n // package, which the developer never taps on).\n if (rel.startsWith('../')) return;\n\n const value = `${rel}:${loc.line}:${loc.column + 1}`;\n const attrs = [t.jsxAttribute(t.jsxIdentifier(ATTR), t.stringLiteral(value))];\n const comp = enclosingComponentName(path, t);\n if (comp) {\n attrs.push(t.jsxAttribute(t.jsxIdentifier(COMP_ATTR), t.stringLiteral(comp)));\n }\n node.attributes.push(...attrs);\n },\n },\n };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"babel.js","names":[],"sources":["../src/babel.ts"],"sourcesContent":["// SPDX-License-Identifier: Apache-2.0\n/**\n * Metro/Babel source-tagging plugin — the React Native analog of the web\n * `@pinagent/babel-plugin`.\n *\n * It splices a `data-pa-loc=\"<file>:<line>:<col>\"` prop (plus a\n * `data-pa-comp=\"<EnclosingComponent>\"` companion) onto every authored JSX\n * element, exactly mirroring what the web babel plugin emits as a DOM\n * attribute. On React Native that prop survives onto the host fiber's\n * `memoizedProps`, so {@link resolvePick} can read it back at tap time.\n *\n * ## Why this exists (and didn't used to)\n *\n * The original RN design leaned on each fiber's `_debugSource`, populated in\n * dev by `@babel/plugin-transform-react-jsx-source` — \"reuse RN's, no custom\n * plugin needed\". **React 19 removed `_debugSource`** (the `ReactElement`\n * constructor no longer takes a `source` arg; the `__source` prop is consumed\n * by `jsxDEV` and never reaches `memoizedProps`), and **RN 0.81+ dropped the\n * `source` field from `getInspectorDataForViewAtPoint`**. So the runtime no\n * longer carries any source location — we have to inject our own, at build\n * time, the same way web does.\n *\n * Wire it into `babel.config.js` (dev only) BEFORE `babel-preset-expo`'s JSX\n * transform so the attribute is present when JSX lowers to `jsxDEV`:\n *\n * const pinagentSource = require('@pinagent/react-native/babel').default;\n * module.exports = (api) => {\n * api.cache(true);\n * const dev = process.env.NODE_ENV !== 'production';\n * return {\n * presets: ['babel-preset-expo'],\n * plugins: dev ? [pinagentSource] : [],\n * };\n * };\n *\n * Typed loosely (no `@babel/*` type deps) on purpose — like {@link inspector},\n * this is a thin, version-tolerant shim over an external toolchain that this\n * otherwise web-only monorepo doesn't carry types for.\n */\nimport { isAbsolute, relative, sep } from 'node:path';\n\n/** The attribute the web plugin emits — reused verbatim so reads match. */\nconst ATTR = 'data-pa-loc';\n/** Companion attribute carrying the enclosing component name. */\nconst COMP_ATTR = 'data-pa-comp';\n\n// Minimal structural typing for the slice of Babel we touch. Babel hands the\n// plugin a `types` namespace and node paths; we lean on duck-typing rather\n// than pulling in @types/babel__core.\n// biome-ignore lint/suspicious/noExplicitAny: external babel AST, typed loosely\ntype Any = any;\n\ninterface PluginState {\n filename?: string;\n cwd?: string;\n opts?: { projectRoot?: string };\n file?: { opts?: { filename?: string; cwd?: string; root?: string } };\n}\n\nfunction toPosix(p: string): string {\n return sep === '/' ? p : p.split(sep).join('/');\n}\n\n/**\n * Walk up to the nearest enclosing React component — the closest\n * function/class ancestor with a PascalCase name. Lowercase callbacks\n * (`items.map(x => <Row/>)`) are skipped, so list items report the component\n * that owns the list. Mirrors `@pinagent/babel-plugin`'s `transform.ts`.\n */\nfunction enclosingComponentName(path: Any, t: Any): string | null {\n let fn = path.getFunctionParent?.();\n while (fn) {\n const name = inferFunctionName(fn, t);\n if (name && /^[A-Z]/.test(name)) return name;\n fn = fn.getFunctionParent?.();\n }\n return null;\n}\n\nfunction inferFunctionName(fnPath: Any, t: Any): string | null {\n const node = fnPath.node;\n if (t.isFunctionDeclaration(node) && node.id) return node.id.name;\n if (t.isClassMethod(node) || t.isClassPrivateMethod(node)) {\n const cls = fnPath.findParent((p: Any) => p.isClassDeclaration() || p.isClassExpression());\n if (cls) {\n const clsNode = cls.node;\n if ((t.isClassDeclaration(clsNode) || t.isClassExpression(clsNode)) && clsNode.id) {\n return clsNode.id.name;\n }\n return nameFromBinding(cls, t);\n }\n return null;\n }\n return nameFromBinding(fnPath, t);\n}\n\nfunction nameFromBinding(p: Any, t: Any): string | null {\n const pn = p.parentPath?.node;\n if (!pn) return null;\n if (t.isVariableDeclarator(pn) && t.isIdentifier(pn.id)) return pn.id.name;\n if ((t.isObjectProperty(pn) || t.isObjectMethod(pn)) && t.isIdentifier(pn.key))\n return pn.key.name;\n if ((t.isClassProperty(pn) || t.isClassMethod(pn)) && t.isIdentifier(pn.key)) return pn.key.name;\n if (t.isAssignmentExpression(pn) && t.isIdentifier(pn.left)) return pn.left.name;\n return null;\n}\n\nfunction isFragment(name: Any, t: Any): boolean {\n if (t.isJSXIdentifier(name)) return name.name === 'Fragment';\n if (t.isJSXMemberExpression(name)) {\n return t.isJSXIdentifier(name.property) && name.property.name === 'Fragment';\n }\n return t.isJSXNamespacedName(name);\n}\n\n/** Resolve the project root used to make paths relative. */\nfunction rootFor(state: PluginState): string | undefined {\n return state.opts?.projectRoot ?? state.file?.opts?.root ?? state.cwd ?? state.file?.opts?.cwd;\n}\n\n/** Resolve the file being transformed. */\nfunction filenameFor(state: PluginState): string | undefined {\n return state.filename ?? state.file?.opts?.filename;\n}\n\nexport interface PinagentBabelOptions {\n /** Project root for project-relative paths. Defaults to Babel's cwd/root. */\n projectRoot?: string;\n}\n\n/**\n * The Babel plugin. Default export so a `babel.config.js` can `require()` it\n * and drop the function straight into `plugins`.\n */\nexport default function pinagentSource(babel: { types: Any }): Any {\n const t = babel.types;\n return {\n name: 'pinagent-source',\n visitor: {\n JSXOpeningElement(path: Any, state: PluginState) {\n const node = path.node;\n if (isFragment(node.name, t)) return;\n\n // Already tagged? Idempotent — re-running is a no-op.\n const tagged = node.attributes.some(\n (a: Any) => t.isJSXAttribute(a) && t.isJSXIdentifier(a.name) && a.name.name === ATTR,\n );\n if (tagged) return;\n\n const loc = node.loc?.start;\n if (!loc) return;\n\n const filename = filenameFor(state);\n if (!filename || filename.includes(`${sep}node_modules${sep}`)) return;\n\n const root = rootFor(state);\n let rel = root && isAbsolute(filename) ? relative(root, filename) : filename;\n rel = toPosix(rel);\n // Only tag files inside the project root — skip anything resolved\n // outside it (e.g. the in-tree widget source under an out-of-root\n // package, which the developer never taps on).\n if (rel.startsWith('../')) return;\n\n const value = `${rel}:${loc.line}:${loc.column + 1}`;\n const attrs = [t.jsxAttribute(t.jsxIdentifier(ATTR), t.stringLiteral(value))];\n const comp = enclosingComponentName(path, t);\n if (comp) {\n attrs.push(t.jsxAttribute(t.jsxIdentifier(COMP_ATTR), t.stringLiteral(comp)));\n }\n // Prepend, NOT append — this is load-bearing for generic wrapper\n // components. A wrapper like `<ViewRn {...rest} />` forwards the\n // call site's own `data-pa-loc` (which arrives via `rest`) onto the\n // host view. JSX props resolve last-wins, so our spliced attribute\n // must come BEFORE `{...rest}` to let the forwarded call-site location\n // override the wrapper's own definition line. Append it after the\n // spread and every element rendered through the wrapper collapses to\n // the wrapper's `file:line`, and the tapped child becomes unreachable.\n // The web `@pinagent/babel-plugin` gets this for free by inserting at\n // `name.end` (before all attributes); we mirror that here.\n node.attributes.unshift(...attrs);\n },\n },\n };\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
CREATE TABLE `active_runs` (
|
|
2
|
+
`conversation_id` text PRIMARY KEY NOT NULL,
|
|
3
|
+
`started_at` integer NOT NULL,
|
|
4
|
+
`current_turn` integer NOT NULL,
|
|
5
|
+
`awaiting_ask_id` text,
|
|
6
|
+
`last_error` text,
|
|
7
|
+
FOREIGN KEY (`conversation_id`) REFERENCES `conversations`(`id`) ON UPDATE no action ON DELETE cascade
|
|
8
|
+
);
|
|
9
|
+
--> statement-breakpoint
|
|
10
|
+
CREATE TABLE `conversations` (
|
|
11
|
+
`id` text PRIMARY KEY NOT NULL,
|
|
12
|
+
`comment` text NOT NULL,
|
|
13
|
+
`agent_session_id` text,
|
|
14
|
+
`status` text DEFAULT 'pending' NOT NULL,
|
|
15
|
+
`note` text,
|
|
16
|
+
`commit_sha` text,
|
|
17
|
+
`branch` text,
|
|
18
|
+
`worktree_path` text,
|
|
19
|
+
`created_at` integer DEFAULT (unixepoch() * 1000) NOT NULL,
|
|
20
|
+
`updated_at` integer DEFAULT (unixepoch() * 1000) NOT NULL,
|
|
21
|
+
`resolved_at` integer
|
|
22
|
+
);
|
|
23
|
+
--> statement-breakpoint
|
|
24
|
+
CREATE TABLE `messages` (
|
|
25
|
+
`id` integer PRIMARY KEY AUTOINCREMENT NOT NULL,
|
|
26
|
+
`conversation_id` text NOT NULL,
|
|
27
|
+
`turn` integer NOT NULL,
|
|
28
|
+
`role` text NOT NULL,
|
|
29
|
+
`content` text NOT NULL,
|
|
30
|
+
`created_at` integer DEFAULT (unixepoch() * 1000) NOT NULL,
|
|
31
|
+
FOREIGN KEY (`conversation_id`) REFERENCES `conversations`(`id`) ON UPDATE no action ON DELETE cascade
|
|
32
|
+
);
|
|
33
|
+
--> statement-breakpoint
|
|
34
|
+
CREATE TABLE `widget_anchors` (
|
|
35
|
+
`conversation_id` text PRIMARY KEY NOT NULL,
|
|
36
|
+
`url` text NOT NULL,
|
|
37
|
+
`file` text,
|
|
38
|
+
`line` integer,
|
|
39
|
+
`col` integer,
|
|
40
|
+
`selector` text NOT NULL,
|
|
41
|
+
`click_x` integer,
|
|
42
|
+
`click_y` integer,
|
|
43
|
+
`viewport_w` integer,
|
|
44
|
+
`viewport_h` integer,
|
|
45
|
+
FOREIGN KEY (`conversation_id`) REFERENCES `conversations`(`id`) ON UPDATE no action ON DELETE cascade
|
|
46
|
+
);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
ALTER TABLE `widget_anchors` ADD `user_agent` text;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
ALTER TABLE `conversations` ADD `worktree_state` text DEFAULT 'none' NOT NULL;
|
|
2
|
+
--> statement-breakpoint
|
|
3
|
+
-- Backfill rows that already have a worktree on disk so the UI sees them as
|
|
4
|
+
-- actionable (Land/Discard) rather than as inline-mode rows.
|
|
5
|
+
UPDATE `conversations`
|
|
6
|
+
SET `worktree_state` = 'active'
|
|
7
|
+
WHERE `worktree_path` IS NOT NULL AND `commit_sha` IS NULL;
|
|
8
|
+
--> statement-breakpoint
|
|
9
|
+
-- Older rows whose worktrees were already merged externally (commit_sha set)
|
|
10
|
+
-- are treated as `landed` so they don't reappear in the lifecycle UI.
|
|
11
|
+
UPDATE `conversations`
|
|
12
|
+
SET `worktree_state` = 'landed'
|
|
13
|
+
WHERE `worktree_path` IS NOT NULL AND `commit_sha` IS NOT NULL;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
CREATE TABLE `pull_requests` (
|
|
2
|
+
`id` integer PRIMARY KEY AUTOINCREMENT NOT NULL,
|
|
3
|
+
`number` integer NOT NULL,
|
|
4
|
+
`url` text NOT NULL,
|
|
5
|
+
`branch` text NOT NULL,
|
|
6
|
+
`base_branch` text NOT NULL,
|
|
7
|
+
`title` text NOT NULL,
|
|
8
|
+
`body` text DEFAULT '' NOT NULL,
|
|
9
|
+
`state` text DEFAULT 'open' NOT NULL,
|
|
10
|
+
`conversation_ids` text DEFAULT ('[]') NOT NULL,
|
|
11
|
+
`created_at` integer DEFAULT (unixepoch() * 1000) NOT NULL,
|
|
12
|
+
`updated_at` integer DEFAULT (unixepoch() * 1000) NOT NULL
|
|
13
|
+
);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
ALTER TABLE `widget_anchors` ADD `additional_anchors` text;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
ALTER TABLE `widget_anchors` ADD `component` text;--> statement-breakpoint
|
|
2
|
+
ALTER TABLE `widget_anchors` ADD `component_path` text;--> statement-breakpoint
|
|
3
|
+
ALTER TABLE `widget_anchors` ADD `instance_index` integer;--> statement-breakpoint
|
|
4
|
+
ALTER TABLE `widget_anchors` ADD `instance_total` integer;--> statement-breakpoint
|
|
5
|
+
ALTER TABLE `widget_anchors` ADD `instance_fingerprint` text;
|
|
@@ -0,0 +1,328 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": "6",
|
|
3
|
+
"dialect": "sqlite",
|
|
4
|
+
"id": "b40e99e7-5146-4202-abfd-1c03df81d9f5",
|
|
5
|
+
"prevId": "00000000-0000-0000-0000-000000000000",
|
|
6
|
+
"tables": {
|
|
7
|
+
"active_runs": {
|
|
8
|
+
"name": "active_runs",
|
|
9
|
+
"columns": {
|
|
10
|
+
"conversation_id": {
|
|
11
|
+
"name": "conversation_id",
|
|
12
|
+
"type": "text",
|
|
13
|
+
"primaryKey": true,
|
|
14
|
+
"notNull": true,
|
|
15
|
+
"autoincrement": false
|
|
16
|
+
},
|
|
17
|
+
"started_at": {
|
|
18
|
+
"name": "started_at",
|
|
19
|
+
"type": "integer",
|
|
20
|
+
"primaryKey": false,
|
|
21
|
+
"notNull": true,
|
|
22
|
+
"autoincrement": false
|
|
23
|
+
},
|
|
24
|
+
"current_turn": {
|
|
25
|
+
"name": "current_turn",
|
|
26
|
+
"type": "integer",
|
|
27
|
+
"primaryKey": false,
|
|
28
|
+
"notNull": true,
|
|
29
|
+
"autoincrement": false
|
|
30
|
+
},
|
|
31
|
+
"awaiting_ask_id": {
|
|
32
|
+
"name": "awaiting_ask_id",
|
|
33
|
+
"type": "text",
|
|
34
|
+
"primaryKey": false,
|
|
35
|
+
"notNull": false,
|
|
36
|
+
"autoincrement": false
|
|
37
|
+
},
|
|
38
|
+
"last_error": {
|
|
39
|
+
"name": "last_error",
|
|
40
|
+
"type": "text",
|
|
41
|
+
"primaryKey": false,
|
|
42
|
+
"notNull": false,
|
|
43
|
+
"autoincrement": false
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
"indexes": {},
|
|
47
|
+
"foreignKeys": {
|
|
48
|
+
"active_runs_conversation_id_conversations_id_fk": {
|
|
49
|
+
"name": "active_runs_conversation_id_conversations_id_fk",
|
|
50
|
+
"tableFrom": "active_runs",
|
|
51
|
+
"tableTo": "conversations",
|
|
52
|
+
"columnsFrom": [
|
|
53
|
+
"conversation_id"
|
|
54
|
+
],
|
|
55
|
+
"columnsTo": [
|
|
56
|
+
"id"
|
|
57
|
+
],
|
|
58
|
+
"onDelete": "cascade",
|
|
59
|
+
"onUpdate": "no action"
|
|
60
|
+
}
|
|
61
|
+
},
|
|
62
|
+
"compositePrimaryKeys": {},
|
|
63
|
+
"uniqueConstraints": {},
|
|
64
|
+
"checkConstraints": {}
|
|
65
|
+
},
|
|
66
|
+
"conversations": {
|
|
67
|
+
"name": "conversations",
|
|
68
|
+
"columns": {
|
|
69
|
+
"id": {
|
|
70
|
+
"name": "id",
|
|
71
|
+
"type": "text",
|
|
72
|
+
"primaryKey": true,
|
|
73
|
+
"notNull": true,
|
|
74
|
+
"autoincrement": false
|
|
75
|
+
},
|
|
76
|
+
"comment": {
|
|
77
|
+
"name": "comment",
|
|
78
|
+
"type": "text",
|
|
79
|
+
"primaryKey": false,
|
|
80
|
+
"notNull": true,
|
|
81
|
+
"autoincrement": false
|
|
82
|
+
},
|
|
83
|
+
"agent_session_id": {
|
|
84
|
+
"name": "agent_session_id",
|
|
85
|
+
"type": "text",
|
|
86
|
+
"primaryKey": false,
|
|
87
|
+
"notNull": false,
|
|
88
|
+
"autoincrement": false
|
|
89
|
+
},
|
|
90
|
+
"status": {
|
|
91
|
+
"name": "status",
|
|
92
|
+
"type": "text",
|
|
93
|
+
"primaryKey": false,
|
|
94
|
+
"notNull": true,
|
|
95
|
+
"autoincrement": false,
|
|
96
|
+
"default": "'pending'"
|
|
97
|
+
},
|
|
98
|
+
"note": {
|
|
99
|
+
"name": "note",
|
|
100
|
+
"type": "text",
|
|
101
|
+
"primaryKey": false,
|
|
102
|
+
"notNull": false,
|
|
103
|
+
"autoincrement": false
|
|
104
|
+
},
|
|
105
|
+
"commit_sha": {
|
|
106
|
+
"name": "commit_sha",
|
|
107
|
+
"type": "text",
|
|
108
|
+
"primaryKey": false,
|
|
109
|
+
"notNull": false,
|
|
110
|
+
"autoincrement": false
|
|
111
|
+
},
|
|
112
|
+
"branch": {
|
|
113
|
+
"name": "branch",
|
|
114
|
+
"type": "text",
|
|
115
|
+
"primaryKey": false,
|
|
116
|
+
"notNull": false,
|
|
117
|
+
"autoincrement": false
|
|
118
|
+
},
|
|
119
|
+
"worktree_path": {
|
|
120
|
+
"name": "worktree_path",
|
|
121
|
+
"type": "text",
|
|
122
|
+
"primaryKey": false,
|
|
123
|
+
"notNull": false,
|
|
124
|
+
"autoincrement": false
|
|
125
|
+
},
|
|
126
|
+
"created_at": {
|
|
127
|
+
"name": "created_at",
|
|
128
|
+
"type": "integer",
|
|
129
|
+
"primaryKey": false,
|
|
130
|
+
"notNull": true,
|
|
131
|
+
"autoincrement": false,
|
|
132
|
+
"default": "(unixepoch() * 1000)"
|
|
133
|
+
},
|
|
134
|
+
"updated_at": {
|
|
135
|
+
"name": "updated_at",
|
|
136
|
+
"type": "integer",
|
|
137
|
+
"primaryKey": false,
|
|
138
|
+
"notNull": true,
|
|
139
|
+
"autoincrement": false,
|
|
140
|
+
"default": "(unixepoch() * 1000)"
|
|
141
|
+
},
|
|
142
|
+
"resolved_at": {
|
|
143
|
+
"name": "resolved_at",
|
|
144
|
+
"type": "integer",
|
|
145
|
+
"primaryKey": false,
|
|
146
|
+
"notNull": false,
|
|
147
|
+
"autoincrement": false
|
|
148
|
+
}
|
|
149
|
+
},
|
|
150
|
+
"indexes": {},
|
|
151
|
+
"foreignKeys": {},
|
|
152
|
+
"compositePrimaryKeys": {},
|
|
153
|
+
"uniqueConstraints": {},
|
|
154
|
+
"checkConstraints": {}
|
|
155
|
+
},
|
|
156
|
+
"messages": {
|
|
157
|
+
"name": "messages",
|
|
158
|
+
"columns": {
|
|
159
|
+
"id": {
|
|
160
|
+
"name": "id",
|
|
161
|
+
"type": "integer",
|
|
162
|
+
"primaryKey": true,
|
|
163
|
+
"notNull": true,
|
|
164
|
+
"autoincrement": true
|
|
165
|
+
},
|
|
166
|
+
"conversation_id": {
|
|
167
|
+
"name": "conversation_id",
|
|
168
|
+
"type": "text",
|
|
169
|
+
"primaryKey": false,
|
|
170
|
+
"notNull": true,
|
|
171
|
+
"autoincrement": false
|
|
172
|
+
},
|
|
173
|
+
"turn": {
|
|
174
|
+
"name": "turn",
|
|
175
|
+
"type": "integer",
|
|
176
|
+
"primaryKey": false,
|
|
177
|
+
"notNull": true,
|
|
178
|
+
"autoincrement": false
|
|
179
|
+
},
|
|
180
|
+
"role": {
|
|
181
|
+
"name": "role",
|
|
182
|
+
"type": "text",
|
|
183
|
+
"primaryKey": false,
|
|
184
|
+
"notNull": true,
|
|
185
|
+
"autoincrement": false
|
|
186
|
+
},
|
|
187
|
+
"content": {
|
|
188
|
+
"name": "content",
|
|
189
|
+
"type": "text",
|
|
190
|
+
"primaryKey": false,
|
|
191
|
+
"notNull": true,
|
|
192
|
+
"autoincrement": false
|
|
193
|
+
},
|
|
194
|
+
"created_at": {
|
|
195
|
+
"name": "created_at",
|
|
196
|
+
"type": "integer",
|
|
197
|
+
"primaryKey": false,
|
|
198
|
+
"notNull": true,
|
|
199
|
+
"autoincrement": false,
|
|
200
|
+
"default": "(unixepoch() * 1000)"
|
|
201
|
+
}
|
|
202
|
+
},
|
|
203
|
+
"indexes": {},
|
|
204
|
+
"foreignKeys": {
|
|
205
|
+
"messages_conversation_id_conversations_id_fk": {
|
|
206
|
+
"name": "messages_conversation_id_conversations_id_fk",
|
|
207
|
+
"tableFrom": "messages",
|
|
208
|
+
"tableTo": "conversations",
|
|
209
|
+
"columnsFrom": [
|
|
210
|
+
"conversation_id"
|
|
211
|
+
],
|
|
212
|
+
"columnsTo": [
|
|
213
|
+
"id"
|
|
214
|
+
],
|
|
215
|
+
"onDelete": "cascade",
|
|
216
|
+
"onUpdate": "no action"
|
|
217
|
+
}
|
|
218
|
+
},
|
|
219
|
+
"compositePrimaryKeys": {},
|
|
220
|
+
"uniqueConstraints": {},
|
|
221
|
+
"checkConstraints": {}
|
|
222
|
+
},
|
|
223
|
+
"widget_anchors": {
|
|
224
|
+
"name": "widget_anchors",
|
|
225
|
+
"columns": {
|
|
226
|
+
"conversation_id": {
|
|
227
|
+
"name": "conversation_id",
|
|
228
|
+
"type": "text",
|
|
229
|
+
"primaryKey": true,
|
|
230
|
+
"notNull": true,
|
|
231
|
+
"autoincrement": false
|
|
232
|
+
},
|
|
233
|
+
"url": {
|
|
234
|
+
"name": "url",
|
|
235
|
+
"type": "text",
|
|
236
|
+
"primaryKey": false,
|
|
237
|
+
"notNull": true,
|
|
238
|
+
"autoincrement": false
|
|
239
|
+
},
|
|
240
|
+
"file": {
|
|
241
|
+
"name": "file",
|
|
242
|
+
"type": "text",
|
|
243
|
+
"primaryKey": false,
|
|
244
|
+
"notNull": false,
|
|
245
|
+
"autoincrement": false
|
|
246
|
+
},
|
|
247
|
+
"line": {
|
|
248
|
+
"name": "line",
|
|
249
|
+
"type": "integer",
|
|
250
|
+
"primaryKey": false,
|
|
251
|
+
"notNull": false,
|
|
252
|
+
"autoincrement": false
|
|
253
|
+
},
|
|
254
|
+
"col": {
|
|
255
|
+
"name": "col",
|
|
256
|
+
"type": "integer",
|
|
257
|
+
"primaryKey": false,
|
|
258
|
+
"notNull": false,
|
|
259
|
+
"autoincrement": false
|
|
260
|
+
},
|
|
261
|
+
"selector": {
|
|
262
|
+
"name": "selector",
|
|
263
|
+
"type": "text",
|
|
264
|
+
"primaryKey": false,
|
|
265
|
+
"notNull": true,
|
|
266
|
+
"autoincrement": false
|
|
267
|
+
},
|
|
268
|
+
"click_x": {
|
|
269
|
+
"name": "click_x",
|
|
270
|
+
"type": "integer",
|
|
271
|
+
"primaryKey": false,
|
|
272
|
+
"notNull": false,
|
|
273
|
+
"autoincrement": false
|
|
274
|
+
},
|
|
275
|
+
"click_y": {
|
|
276
|
+
"name": "click_y",
|
|
277
|
+
"type": "integer",
|
|
278
|
+
"primaryKey": false,
|
|
279
|
+
"notNull": false,
|
|
280
|
+
"autoincrement": false
|
|
281
|
+
},
|
|
282
|
+
"viewport_w": {
|
|
283
|
+
"name": "viewport_w",
|
|
284
|
+
"type": "integer",
|
|
285
|
+
"primaryKey": false,
|
|
286
|
+
"notNull": false,
|
|
287
|
+
"autoincrement": false
|
|
288
|
+
},
|
|
289
|
+
"viewport_h": {
|
|
290
|
+
"name": "viewport_h",
|
|
291
|
+
"type": "integer",
|
|
292
|
+
"primaryKey": false,
|
|
293
|
+
"notNull": false,
|
|
294
|
+
"autoincrement": false
|
|
295
|
+
}
|
|
296
|
+
},
|
|
297
|
+
"indexes": {},
|
|
298
|
+
"foreignKeys": {
|
|
299
|
+
"widget_anchors_conversation_id_conversations_id_fk": {
|
|
300
|
+
"name": "widget_anchors_conversation_id_conversations_id_fk",
|
|
301
|
+
"tableFrom": "widget_anchors",
|
|
302
|
+
"tableTo": "conversations",
|
|
303
|
+
"columnsFrom": [
|
|
304
|
+
"conversation_id"
|
|
305
|
+
],
|
|
306
|
+
"columnsTo": [
|
|
307
|
+
"id"
|
|
308
|
+
],
|
|
309
|
+
"onDelete": "cascade",
|
|
310
|
+
"onUpdate": "no action"
|
|
311
|
+
}
|
|
312
|
+
},
|
|
313
|
+
"compositePrimaryKeys": {},
|
|
314
|
+
"uniqueConstraints": {},
|
|
315
|
+
"checkConstraints": {}
|
|
316
|
+
}
|
|
317
|
+
},
|
|
318
|
+
"views": {},
|
|
319
|
+
"enums": {},
|
|
320
|
+
"_meta": {
|
|
321
|
+
"schemas": {},
|
|
322
|
+
"tables": {},
|
|
323
|
+
"columns": {}
|
|
324
|
+
},
|
|
325
|
+
"internal": {
|
|
326
|
+
"indexes": {}
|
|
327
|
+
}
|
|
328
|
+
}
|