Conversation
requiring json throw error...
|
|
Currenlty, Transform of textlint don't work. import compileModule from '../../../utils/compileModule';
import pkg from 'textlint/package.json';
const ID = 'textlint';
export default {
id: ID,
displayName: ID,
version: pkg.version,
homepage: pkg.homepage,
defaultParserID: 'textlint:markdown-to-ast',
loadTransformer(callback) {
require(['textlint/lib/textlint-core', 'babel-core'], (TextLintCore, babel) => {
callback({ TextLintCore, babel });
})
},
transform({TextLintCore, babel}, transformCode, code) {
console.log(TextLintCore);
const textlintCore = new TextLintCore();
let rule = compileModule( // eslint-disable-line no-shadow
babel.transform(transformCode).code
);
textlintCore.setupRules({
'astExplorerRule': rule
});
return textlintCore.lintText(code, ".md").then(result => {
return JSON.stringify(result);
});
}
};Error |
|
Add promise support tot
|
Update with changes from fkling/astexplorer
feat: support textlint 13 and html plugin
fix(deps): update textlint to v15.0.1
fix(deps): update textlint to v15.2.1
* Add protobuf parser * feat: add protocol buffers parser * doc: add pbkit to README * remove an unused babel plugin * remove verdored parser * chore: up pbkit (#1) it resolves some parse error cases Co-authored-by: JongChan Choi <disjukr@naver.com>
- webpack.config.jsにnode:assertのaliasとnode設定を追加 - PR用のCIワークフロー(test.yml)を追加してビルドテストを実行 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
fix(build): webpackのnode:assertモジュール解決エラーを修正
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
chore(deps): update textlint to v15.3.0
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
chore(deps): update textlint to v15.5.1
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
| } | ||
|
|
||
| getPath() { | ||
| return `/snippet/${this.hash}}`; |
There was a problem hiding this comment.
🔴 Extra closing brace } in getPath() corrupts the URL hash
The getPath() method returns /snippet/${this.hash}} with a stray } after the template literal interpolation. This extra brace is appended to the URL hash via storage/index.js:20 (global.location.hash = revision.getPath()). When a user later navigates back to this URL, getIDAndRevisionFromHash() at urlStore.js:7 will capture the hash including the trailing }, and codec.decompress() will attempt to decode a corrupted string, likely throwing an error or producing garbage output.
| return `/snippet/${this.hash}}`; | |
| return `/snippet/${this.hash}`; |
Was this helpful? React with 👍 or 👎 to provide feedback.
| }, | ||
|
|
||
| transform({ TextlintKernel, plugin }, transformCode, code) { | ||
| const kernel = new Kernel(); |
There was a problem hiding this comment.
🔴 new Kernel() references undefined variable instead of TextlintKernel
In the transform method, the code uses new Kernel() but the parameter is destructured as { TextlintKernel, plugin }. Kernel is never defined, so this will throw a ReferenceError at runtime whenever the textlint-txt transformer is executed. The other transformers (markdown at textlint-md/transformers/textlint-markdown-to-ast/index.js:40 and HTML at textlint-html/transformers/textlint-plugin-html/index.js:41) correctly use new TextlintKernel().
| const kernel = new Kernel(); | |
| const kernel = new TextlintKernel(); |
Was this helpful? React with 👍 or 👎 to provide feedback.
| require(['@textlint/kernel'], ({ TextlintKernel }, { default: plugin }) => { | ||
| callback({ TextlintKernel, plugin }); | ||
| }) |
There was a problem hiding this comment.
🔴 loadTransformer for textlint-txt only requires one module but destructures two callback arguments
The require call passes only ['@textlint/kernel'] (one module), but the callback destructures two arguments: ({ TextlintKernel }, { default: plugin }). The second argument will be undefined, and destructuring undefined throws TypeError: Cannot destructure property 'default' of 'undefined'. Compare with the markdown transformer at textlint-md/transformers/textlint-markdown-to-ast/index.js:34 which correctly requires both modules: ['@textlint/kernel', '@textlint/textlint-plugin-markdown']. The txt transformer should similarly require @textlint/textlint-plugin-text.
| require(['@textlint/kernel'], ({ TextlintKernel }, { default: plugin }) => { | |
| callback({ TextlintKernel, plugin }); | |
| }) | |
| require(['@textlint/kernel', '@textlint/textlint-plugin-text'], ({ TextlintKernel }, { default: plugin }) => { | |
| callback({ TextlintKernel, plugin }); | |
| }) |
Was this helpful? React with 👍 or 👎 to provide feedback.
| export default { | ||
| ...defaultParserInterface, | ||
| id: ID, | ||
| displayName: "@textlint/text-to-ast", |
There was a problem hiding this comment.
🟡 Markdown parser displayName incorrectly shows @textlint/text-to-ast instead of @textlint/markdown-to-ast
The markdown parser at textlint-md/textlint-markdown-to-ast.js has displayName: "@textlint/text-to-ast" but the id is textlint:markdown-to-ast and it loads @textlint/markdown-to-ast. This appears to be a copy-paste error from the text parser. Users will see the wrong parser name in the UI.
| displayName: "@textlint/text-to-ast", | |
| displayName: "@textlint/markdown-to-ast", |
Was this helpful? React with 👍 or 👎 to provide feedback.
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
| getParserSettings() { | ||
| return this.data.settings[this.data.parserID]; | ||
| } |
There was a problem hiding this comment.
🔴 getParserSettings() crashes when this.data.settings is undefined
In website/src/storage/urlStore.js:103-104, getParserSettings() directly accesses this.data.settings[this.data.parserID] without checking if settings exists. If a decompressed snippet has no settings field, this throws a TypeError. The existing parse.js implementation (website/src/storage/parse.js:139-143) handles this correctly with a null check before accessing the property. The caller at website/src/store/reducers.js:214 uses revision.getParserSettings() || ..., which would handle null/undefined returns, but cannot catch the thrown exception.
| getParserSettings() { | |
| return this.data.settings[this.data.parserID]; | |
| } | |
| getParserSettings() { | |
| const settings = this.data.settings; | |
| if (!settings) { | |
| return null; | |
| } | |
| return settings[this.data.parserID]; | |
| } |
Was this helpful? React with 👍 or 👎 to provide feedback.
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
| getTransformCode() { | ||
| return ""; | ||
| } |
There was a problem hiding this comment.
🟡 Custom rule code is lost when a snippet is shared or reopened
The rule code stored inside a shared snippet is always reported as empty (return "" at website/src/storage/urlStore.js:88-90) even though it was saved with the snippet, so anyone opening the link gets a blank rule editor.
Impact: Users who share a link that includes a custom rule lose that rule; the recipient sees an empty editor.
Saved transform payload is never read back
saveSnippet in website/src/store/snippetMiddleware.js:88-92 stores data.transform = transformCode alongside toolID, and the reducer initialises the transform editor from activeRevision.getTransformCode() (website/src/store/reducers.js:181). The gist backend returns the stored file (website/src/storage/gist.js:155-158), but the new URL backend hardcodes an empty string despite having this.data.transform available.
| getTransformCode() { | |
| return ""; | |
| } | |
| getTransformCode() { | |
| return this.data.transform || ""; | |
| } |
Was this helpful? React with 👍 or 👎 to provide feedback.
There was a problem hiding this comment.
🟡 Not ready to approve
There are runtime-breaking issues in the new URL storage and textlint TXT transformer (broken URL path + transformer loader/kernel instantiation) that must be fixed before this can be safely merged.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
This review doesn't count toward merge requirements. Sign up for the private preview to control whether Copilot approvals count.
Pull request overview
This PR turns the project into a textlint-focused fork of AST Explorer, adding Markdown/plain-text/HTML parsing + linting via textlint packages, and switching snippet persistence to a URL-encoded format suitable for GitHub Pages hosting.
Changes:
- Add textlint-based parsers/transformers for Markdown, plain text, and HTML.
- Replace server-backed snippet storage with a URL-based
json-urlcodec. - Add CI workflows and deployment tooling for the
textlintbranch / GitHub Pages.
File summaries
| File | Description |
|---|---|
| website/yarn.lock | Locks new dependencies for textlint + URL storage and related transitive deps. |
| website/webpack.config.js | Adds resolution tweaks for node:assert / node module shims. |
| website/src/utils/logger.js | Disables Google Analytics event/exception sending. |
| website/src/storage/urlStore.js | New URL-based snippet backend using json-url compression. |
| website/src/parsers/textlint-txt/transformers/textlint-txt-to-ast/index.js | New transformer that runs textlint rules on .txt input. |
| website/src/parsers/textlint-txt/transformers/textlint-txt-to-ast/codeExample.txt | Example textlint rule for plain text transformer. |
| website/src/parsers/textlint-txt/textlint-txt-to-ast.js | New parser wrapper for @textlint/text-to-ast. |
| website/src/parsers/textlint-txt/index.js | Registers the “Plain text” category. |
| website/src/parsers/textlint-txt/codeExample.txt | Plain-text sample input. |
| website/src/parsers/textlint-md/transformers/textlint-markdown-to-ast/index.js | New transformer that runs textlint rules on .md input. |
| website/src/parsers/textlint-md/transformers/textlint-markdown-to-ast/codeExample.txt | Example textlint rule for Markdown transformer. |
| website/src/parsers/textlint-md/textlint-markdown-to-ast.js | New parser wrapper for @textlint/markdown-to-ast. |
| website/src/parsers/textlint-md/index.js | Registers the “Markdown” category. |
| website/src/parsers/textlint-md/codeExample.txt | Markdown sample input. |
| website/src/parsers/textlint-html/transformers/textlint-plugin-html/index.js | New transformer that runs textlint rules on HTML input via textlint-plugin-html. |
| website/src/parsers/textlint-html/transformers/textlint-plugin-html/codeExample.txt | Example textlint rule for HTML transformer. |
| website/src/parsers/textlint-html/textlint-plugin-html.js | New parser wrapper for HTML-to-AST module shipped by textlint-plugin-html. |
| website/src/parsers/textlint-html/index.js | Registers the “HTML” category. |
| website/src/parsers/textlint-html/codeExample.txt | HTML sample input. |
| website/src/parsers/index.js | Restricts parser discovery to textlint-* directories and changes the default category. |
| website/src/parsers/html/transformers/textlint-markdown-to-ast/index.js | Adds a textlint transformer under the legacy html category directory. |
| website/src/parsers/html/transformers/textlint-markdown-to-ast/codeExample.txt | Example rule for the legacy html directory transformer. |
| website/src/parsers/html/textlint-plugin-html.js | Adds an HTML textlint parser under the legacy html category directory. |
| website/src/parsers/html/index.js | Changes the legacy html category registration. |
| website/src/parsers/html/codeExample.txt | Updates the legacy html sample input. |
| website/src/app.js | Switches storage adapters from gist/parse to URL storage only. |
| website/package.json | Adds textlint/json-url deps, deploy script, and Node build flags. |
| website/index.ejs | Updates branding/repo link and removes GA script in favor of a no-op. |
| server/yarn.lock | Updates lockfile metadata (registry URLs + integrity fields). |
| scripts/inject-rev.sh | Updates injected commit link to the new GitHub repo. |
| renovate.json | Adds Renovate configuration for dependency management (textlint-focused). |
| README.md | Documents this repository as a textlint-specific fork and deployment notes. |
| .github/workflows/test.yml | Adds a GitHub Actions workflow to install/build the website on textlint branch PRs/pushes. |
| .github/workflows/deploy.yml | Adds a GitHub Actions workflow to deploy out/ to GitHub Pages on textlint branch pushes. |
Review details
Suppressed comments (1)
website/src/parsers/textlint-html/transformers/textlint-plugin-html/index.js:42
transform()currently has aconsole.log({ TextlintKernel, plugin }), which will spam the console and can expose internal objects in production. This should be removed.
transform({ TextlintKernel, plugin }, transformCode, code) {
console.log({ TextlintKernel, plugin })
const kernel = new TextlintKernel();
const rule = compileModule( // eslint-disable-line no-shadow
- Files reviewed: 32/34 changed files
- Comments generated: 14
- Review effort level: Lite
We're testing this review assessment. Please use 👍 or 👎 to tell us if it's correct.
| import React from 'react'; | ||
| import json_url from "json-url"; | ||
|
|
||
| const codec = json_url('lzw'); |
| constructor({ data, hash }) { | ||
| console.log({data, hash}) | ||
| this.data = data; | ||
| this.hash = hash; | ||
| } |
| getPath() { | ||
| return `/snippet/${this.hash}}`; | ||
| } |
| export function fork(revision, data) { | ||
| return Promise.resolve(null); | ||
| } |
| getTransformCode() { | ||
| return ""; | ||
| } |
| export default { | ||
| ...defaultParserInterface, | ||
| id: ID, | ||
| displayName: "@textlint/text-to-ast", | ||
| version: pkg.version, | ||
| homepage: pkg.homepage, |
| export const id = 'markdown'; | ||
| export const displayName = 'Markdown'; | ||
| export const mimeTypes = ['text/markdown']; |
| export const id = 'txt'; | ||
| export const displayName = 'Plain text'; | ||
| export const mimeTypes = ['text/plain']; |
| export const id = 'html'; | ||
| export const displayName = 'HTML'; | ||
| export const mimeTypes = ['text/html']; |
| node: { | ||
| assert: 'empty', | ||
| child_process: 'empty', |


Add Markdown and plain texts support.
Would We created a fork of astexplorer?
It is specific usage of textlint and textlint is a minor tool.
Pros
Re:Viewhttps://github.com/orangain/textlint-plugin-review ).Would the user of astexplorer need textlint support?
Cons
Ref: textlint/textlint#176