tryghost / sdk Goto Github PK
View Code? Open in Web Editor NEWTools for working with Ghost's APIs
License: MIT License
Tools for working with Ghost's APIs
License: MIT License
The Admin SDK accepts data.author
and data.authors
. This design was not discussed and needs to be decided whether we want to keep or not. IMO we have dropped single author usage, it's is more confusing than helpful? Ghost now supports attaching relations as array of strings, which makes it already easy to attach relations.
Furthermore, the Admin SDK currently requires you to send author ids.
e.g.
data.authors = [{id: id}]
Ghost accepts id, slug or email for authors.
Ghost accepts slug, name or id for tags.
Tags are not handled at all.
data.author
design with @peterzimon @ErisDS ~ just removed for now because of time. people can use api.posts.add({authors: ['email']})
When an invalid url
value is provided we show the following error message:
GhostAdminAPI Config Invalid: @tryghost/admin-api requires a "url" without a trailing slash like "https://site.com" or "https://site.com/blog"
It would be useful if we included the url
value that was passed in so that it's faster to debug problems such as an environment variable not being set.
Should create an iframe element, append it to the page, and make sure it is not visible.
Should use the layer0 SDK to interact with the iframe.
Should emit events
I'm trying to use the @tryghost/admin-api
on a React and webpack application. I'm having the following error:
ERROR in ./node_modules/@tryghost/admin-api/lib/index.js
Module not found: Error: Can't resolve 'fs' in
I'm aware that react doesn't allow me to have the fs module as pointed out in this answer: https://stackoverflow.com/a/48359480/7537918. However I wanna know if there's any work around on this.
I'm having the following error: Error?(@tryghost/content-api/lib/index) error Expected identifier
on IE 11, when using the content api. I see that the lib is very well maintained so I'm opening this issue.
@tryghost/content-api
import GhostContentAPI from '@tryghost/content-api';
Any other info e.g. Why do you consider this to be a bug? What did you expect to happen instead?
Hello,
When i request a list of posts, the client API return an array of posts objects with a meta object at the root of this array. As i use Typescript with "@types/tryghost__content-api", this array is not strongly typed and i can not work with this type of array.
Example :
[
{
id: '5e4a9fa6b5eeed1d57bc400f',
uuid: 'acaaa168-bf1a-4193-9ae9-90ff1b452d2a',
title: 'my first article'
},
{
id: '5e46c4b0bb3f2813da132685',
uuid: '3e208441-8f24-43bc-bc02-20f0d3db9e1e',
title: 'my second article',
},
meta: {
pagination: { page: 1, limit: 4, pages: 1, total: 2, next: null, prev: null }
}
]
As coded in "@types/tryghost__content-api", i was waiting an object like :
posts:
[
{
id: '5e4a9fa6b5eeed1d57bc400f',
uuid: 'acaaa168-bf1a-4193-9ae9-90ff1b452d2a',
title: 'my first article'
},
{
id: '5e46c4b0bb3f2813da132685',
uuid: '3e208441-8f24-43bc-bc02-20f0d3db9e1e',
title: 'my second article',
},
],
meta: {
pagination: { page: 1, limit: 4, pages: 1, total: 2, next: null, prev: null }
}
Call the posts API with a Tag filter
BlogApi.posts .browse({ limit: 4, include: ['tags', 'authors'], filter: 'tag:' + category, }) .catch(err => { console.error(err); throw err; });
Use the result API
I run this code:
const api = new GhostContentAPI({
url: CONFIG.GHOST.URL,
key: CONFIG.GHOST.API_KEY.CONTENT,
version: 'v3'
})
export async function getPost (postSlug, { include='tags,authors' } ) {
const post = await api.posts
.read({
slug: postSlug,
include: include,
})
.catch((err) => {
logError(`getPost(${postSlug})`, err)
return { statusCode: 404, message: 'getPost() failed' }
})
return post
}
But the api only returns an array with posts, there is not meta object appended.
I see the json response itself from the server does include the meta field. Is it a bug that it is lost in the sdk ?
I try to create a new post on my blog using node.js
Here is my code it works, but request gives and error
const GhostAdminAPI = require('@tryghost/admin-api');
const path = require('path');
// Your API config
const api = new GhostAdminAPI({
url: 'https://citvy.com/blog',
version: "v3",
key: 'ADMIN API KEY FROM GHOST PANEL'
});
// Your content
let html = '<p>My test post content.</p><figure><img src="https://static.ghost.org/v3.0.0/images/welcome-to-ghost.png" /><figcaption>My awesome photo</figcaption></figure>';
return api.posts
.add(
{ title: 'My Test Post', html },
{ source: 'html' },
{ excerpt: "π Welcome, it's great to have you here." },
{ feature_image: "https://static.ghost.org/v3.0.0/images/welcome-to-ghost.png" }
)
.then(res => console.log(JSON.stringify(res)))
.catch(err => console.log(err));
The example I took exactly from here: https://ghost.org/docs/api/v2/javascript/admin/#publishing-example
There's a new settings endpoint: TryGhost/Ghost#10328
It only supports browse, not read π¬
Welcome to Ghost's GitHub repo! ππ
We use GitHub only for bug reports π
Anything else should be posted to https://forum.ghost.org π«
π¨For support, help & questions use https://forum.ghost.org/c/help
π‘For feature requests & ideas you can post and vote on https://forum.ghost.org/c/Ideas
If your issue is with Ghost CLI, please report it on the CLI repo β‘οΈΒ https://github.com/TryGhost/Ghost-CLI/issues/new.
I have a auto CD using admin-api to upload themes. After upgrade to 1.1.1, it failed with
Error: Must be of FormData or include path
at Object.upload (/home/leo/projects/libra_casper/node_modules/@tryghost/admin-api/lib/index.js:214:39)
at main (/home/leo/projects/libra_casper/.github/workflows/deploy-theme.js:12:26)
at Object.<anonymous> (/home/leo/projects/libra_casper/.github/workflows/deploy-theme.js:20:2)
at Module._compile (internal/modules/cjs/loader.js:1156:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1176:10)
at Module.load (internal/modules/cjs/loader.js:1000:32)
at Function.Module._load (internal/modules/cjs/loader.js:899:14)
at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:74:12)
at internal/main/run_main_module.js:18:47
I think it is related to #186 . He misunderstood the meaning of the parameter.
The parameter should able to accept a object containing file path OR a file stream of the theme pack.
This should be added once we're ready for people to start using it.
This is just a warning, but we should probably look to resolving it anyway.
Using the tags helper in gatsby results in a warning. I've used it like:
<Tags post={post} limit={1}>
and also
<Tags post={post} limit={1} autolink={false}>
Both generate the same warning:
Warning: Each child in an array or iterator should have a unique "key" prop. See https://fb.me/react-warning-keys for more information.
This is not solved by doing e.g.
<Tags key={hit.slug} post={post} limit={1} autolink={false}>
@tryghost/html-to-mobiledoc
has a dependency to jsdom
(13.2.0).
jsdom
dropped support for Node v6.
The problem is that no tests are executed for Node v6, because the installation fails. Is that fixable? Have not looked into it.
π
In our @tryghost/admin-api
package we only expose direct methods for calling specific endpoints. The auth, url building, data processing, etc aspects all exist but are hidden as internal implementation details.
We'd like to expose as many primitives as possible for SDK users to build their own implementations around in case the provided all-in-one wrapper is insufficient.
The first real-world use-case that's been identified is when using the package inside of Zapier. Zapier provides its own request library which comes with benefits like logging of all requests for easier external debugging.
TODO:
Currently the separator
option of tags helper cannot be set as empty since helper sets an initial default value for separator in case it finds it to be empty in options here.
This essentially turns the separator condition here always truthy and always adds a separator to the final array even when its not intended. So filtering an array of tags based on visibility will always return an array with extra ,
values in array based on separator.
It seems the default value of ,
is only useful for string list of tags and so a simple fix is to use the default value only here for string output.
When uploading a large theme zip, the admin-api package will throw an error Error: Request body larger than maxBodyLength limit
.
Reviewing some related issues (axios/axios#1985, yakovkhalinsky/backblaze-b2#45), it would appear that although axios
has a default maxContentLimit
of -1
which should be "limitless" that does not work for PUT/POST requests which pick up a default limit of 10MB from the underlying follow-request
dependency.
From the responses in yakovkhalinsky/backblaze-b2#45 it sounds like we could try setting the axios default maxContentLength
to Infinity
.
Currently the content/admin api SDKs format the response that is received from the API.
We'd like to add a "format response" boolean option to the SDKs so that consumers have the option to skip formatting and receive the raw data that is returned from the API.
Our initial use-case for this is a tool that can automatically generate request/response documentation for our API.
See: jsdom/jsdom@0cba358
Is it possible to pin jsdom to 12.0.0?
Currently there is no handling for errors in setup and no fall backs
Case 1: let api = new GhostContentAPI();
results in:
content-api.umd.js:1 Uncaught TypeError: Cannot destructure property `host` of 'undefined' or 'null'.
at new e (content-api.umd.js:1)
at example.html:9
Case 2:
let api = new GhostContentAPI({});
api.settings.browse().then((settings) => {
console.log(settings);
});
Results in
example.html:18 Error: Network Error
at u (VM76 content-api.umd.js:1)
at XMLHttpRequest.i.onerror (VM76 content-api.umd.js:1)
at VM76 content-api.umd.js:1
at new Promise (<anonymous>)
at g (VM76 content-api.umd.js:1)
at B (VM76 content-api.umd.js:1)
etc (I can update with more info if helpful)
We should always lean towards failing with helpful error messages wherever possible, rather than using fallbacks.
E.g. if the version is set to 2
-> "invalid version"
E.g. if the version is missing -> "version missing"
The configuration object for GhostContentAPI should look like this:
{
host: 'https://mysubdomain.ghost.io',
ghostPath: 'ghost',
key: '26hexcharsgohere',
version: 'v2'
}
The ghostPath
key should not be required, and should fallback to being ghost
.
This means that most people don't have to specify this, and if in future we do make it configurable we are covered.
Attach members token to the Authorization
header, using the GhostMembers
scheme.
Related: TryGhost/Ghost#10110
We should not put code into index.js. Node uses the index.js file to look up files in a folder.
The "index.js" file has the purpose to expose & prepare an interface for a folder/unit.
Furthermore, all the code lives mostly in one file (in the index.js). Would be great to split up little units.
Both enhancements will help other (SDK) developers to follow & understand the code.
This has lower priority for now, but this is a perfect post cleanup task π
We have added:
These are still missing:
Reference: https://github.com/TryGhost/Ghost/blob/master/core/server/web/api/v2/admin/middleware.js
needs #495
I am unable to update a post using Admin API. I get UPDATE_COLLISION
error.
I run
await api.posts.edit({"id": "5c8051da2a25b600c01ff9ee", "mobiledoc": JSON.stringify(md), "updated_at": "2019-05-09T11:39:37.000Z"})
and get
{ UpdateCollisionError: Saving failed! Someone else is editing this post.
at makeRequest.catch (/tmp/node_modules/@tryghost/admin-api/lib/index.js:292:33)
at process._tickCallback (internal/process/next_tick.js:68:7)
name: 'UpdateCollisionError',
context: 'Saving failed! Someone else is editing this post.',
type: 'UpdateCollisionError',
details:
{ clientUpdatedAt: '2019-05-09T11:39:37.000Z',
serverUpdatedAt: '2019-05-08T15:40:57.000Z' },
property: null,
help: null,
code: 'UPDATE_COLLISION',
id: '36069d20-723f-11e9-9b05-d55f47be1c26' }
I guarantee that nobody else is editing that post. I don't have it open in a web browser, and nobody else knows that the post I am editing even exists.
JS API docs suck. I mean, really suck. Typos ("api.pages.edit" instead of "api.posts.edit"), "updated_at" is not included, there is only one example (to publish). It's a miracle that I ever found how to use it all.
Axios library returns err.response
, err.request
and err.config
, which are very fat and make stdout impossible to read. Need to figure out if we have to return some of these values to the user or not. And if so, we have to define the output + design.
The v2 JSON API returns this on error:
errors: [{id: ..., help: ...., code: ...., details:...}]
SDK deserializes these fields into:
{ ValidationError: Validation error, cannot save post.
at makeRequest.catch (ghost/ghost-sdk/packages/admin-api/lib/index.js:290:33)
at process._tickCallback (internal/process/next_tick.js:68:7)
name: 'ValidationError',
context: 'Validation failed for \'posts[0]\'',
type: 'ValidationError',
details:
[ { keyword: 'required',
dataPath: '.posts[0]',
schemaPath: '#/properties/posts/items/required',
params: [Object],
message: 'should have required property \'title\'' } ],
help: null,
code: null,
id: '2f5ebe00-3917-11e9-8a93-53537def9b36' }
This is cool. But if you get a library error, the error looks like:
{ Error: connect ECONNREFUSED 127.0.0.1:2368
at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1104:14)
errno: 'ECONNREFUSED',
code: 'ECONNREFUSED',
syscall: 'connect',
address: '127.0.0.1',
port: 2368 }
Error is different. This is hard to document & hard to work with.
Need to figure out what todo.
Browse requests for posts and pages do not return reading_time
when using fields
parameter.
curl 'https://GHOST_URL/ghost/api/v3/content/posts/?key=API_KEY&fields=id%2Cslug%2Ctitle%2Creading_time' \
-H 'Accept: application/json'
The response does not include reading_time
, although the same request without the fields
parameter returns the reading_time
.
Create the initial members sdk - this will be a fairly low level one.
The api it should expose will be like
const Members = require('@ghost/members-sdk');
const members = Members(options); // options can be undefined, for now...
// returns Promise.resolve(token|null) if they are logged in or not
members.getToken();
// returns Promise.resolve(true|false) on whether it worked or not
members.logout();
// returns Promise.resolve(true|false) on whether it worked or not
members.login();
thoughts?
I noticed a couple issues in the test cases for slugify -
γγ¦γγ γγ
-- should transliterate as shitekudasai instead of sitekudasai
control:\x07notcontrol:\xB5
-- the code point \xB5 is invalid, should be \xC2\xB5 or \u00B5
If an invalid admin api key is provided then it can result in an unhandled error cannot read property 'split' of undefined
Create SDK allowing to communicate with Admin API using api keys with a similar design to Content API SDK. The initial version should allow CRUD operations on post
resource.
admin-api-schema's get()
method returns raw json schemas without resolving definitions used in $ref
. This makes get method hardly usable if somebody needs to see whole schema (for example when used in documentation). More on this read this comment.
One of possible solutions could be adding $ref resolution through package like ref-parser. But more research should be done into use-cases and other solutions first
The admin SDK doesn't export these stable /themes/
methods:
Found while working on documentation for TryGhost/Team/issues/421.
The admin and content API SDKs look almost the same, but they don't work consistently.
contentAPI.posts.read({ slug: 'welcome', fields: 'title' })
adminAPI.posts.read({ slug: 'welcome', fields: 'title' })
adminAPI.posts.read({ slug: 'welcome'}, {fields: 'title' })
The functions are the same, but one requires options to be passed as a second object and the other doesn't.
The behaviour between the two SDKs should be consistent where possible. The admin API has more options because it is able to edit as well as fetch data. Still, there's no reason for this not to work for read requests!
I've added the code for a gatsby (react, but uses gatbsy-link, not react-link) version of the Tag helper here:
https://github.com/TryGhost/Ghost-SDK/tree/master/packages/helpers-gatsby/src
This needs to be packaged and built into helpers-gatsby/Tags.js so that it's possible to do
import Tags from @tryghost/helpers-gatsby
This will be used in our docs and other gatsby projects e.g. here.
I think a good package to model this on might be https://github.com/nfl/react-helmet, but I'm not 100%.
url-utils
package has too many intermingled functions in a single index.js
file.
Have package build from a set of smaller functions which would be as pure as possible.
After extracting url-utils
package from Ghost core (#114) it was hard to break up a package into smaller pieces right away. The main reason is calls between the functions are to dependent on one another. For example, the getSubdir
method is being called almost from every function and sometimes is even nested as a call from deduplicateSubDir
. Another pain point is urlJoin
method, which operates on arguments
directly and adding any parameters to it would need some more thinking (because it possibly could change existing API).
To decouple methods from getSubdir
it could be extracted into function parameters instead.
The urlJoin
method could be wrapped to keep accepting no parameters. The wrapper would call internal urlJoinInternal
method with first parameter as an options object containing subdir value: urlJoinInternal({subdir: getSubdir()}, ...arguments)
.
Possible approaches section needs more research and discussion.
I wonder if it's necessary to have the strict requirements of a host
with no trailing slash and a ghostPath
with no leading/trailing slash when creating a new GhostAdminAPI instance?
In Zapier we've always asked the user for their "Admin URL" as it's easy to explain and they only need to copy/paste the URL after loading their admin screen (they should know where this is π). However, that results in some ugly code to work around the strict initialiser argument requirements:
const {URL} = require('url');
const GhostAdminApi = require('@tryghost/admin-api');
// Convenience method for creating a GhostAdminAPI instance from the bundle data
const initAdminApi = ({adminUrl, adminApiKey: key}) => {
// we get the "Admin URL" from the user as it's less error prone and easier
// to explain but GhostAdminAPI requires a specific host/path combination
const url = new URL(adminUrl);
const host = url.origin.replace(/\/$/, '');
const ghostPath = url.pathname.replace(/^\/|\/$/g, '');
return new GhostAdminApi({
host,
ghostPath,
key,
version: 'v2'
});
};
Perhaps we can make the initialiser more forgiving so that we only need to pass in a URL?
Data validation cashes schema definition from single API which leads to incorrect validation results. In other words, valid data for v3 API is getting validated against v2 schema.
post
resource data against v2
schemaawait jsonSchema.validate({
data: {
posts: [{updated_at: '2020-10-02', title: 'whatever'}]
},
schema: `posts-edit`,
version: 'v2'
});
posts
which is only valid in v3 API (add email_subject field)await jsonSchema.validate({
data: {
posts: [{updated_at: '2020-10-02', email_subject: 'only available in canary}]
},
schema: `posts-edit`,
version: 'canary'
});
email_subject
is a valid field for canary/v3 schemas.Expected behavior is - validation should always match schema definition and not throw errors for valid data.
The cause for a bug is schema caching which done on validator/ajv level.
create react app disallows compiling code from outside the source directory, so it relies on modules to provide their code transpiled to es5 or whatever. for some reason this isn't working with your package for @tryghost/content-api
. i am looking for a work around to get my build working again. i don't know much about this, if you can offer any insight i would appreciate it.
for now i am working around it by copying lib/index.js
directly to my project src, so it can be compiled.
If an attribute/value pair is used in plain text, eg. inside a <code>
element and there are actual html tags with the same attribute/value pair then the url replacements can get out of sync, replacing the plain text pair rather than the html pair.
1) utils: htmlRelativeToAbsolute()
skips any matching attribute/url pairs in plain text:
AssertionError: expected '<p>You can use <code>href="http://my-ghost-blog.com/relative"</code> to make relative links like <a href="/relative">this</a></p>' to equal '<p>You can use <code>href="/relative"</code> to make relative links like <a href="http://my-ghost-blog.com/relative">this</a></p>'
+ expected - actual
-<p>You can use <code>href="http://my-ghost-blog.com/relative"</code> to make relative links like <a href="/relative">this</a></p>
+<p>You can use <code>href="/relative"</code> to make relative links like <a href="http://my-ghost-blog.com/relative">this</a></p>
Successfully run Typescript compiler and run from complied files
Error when trying to run with a Webpack build. The error is:
TypeError: r is not a constructor
at e.getArticleBySlug (/home/david/strataV2/strata-cms.api/dist/bundle.js:1:3078)
...........
I am using Ghost Content API within a service that is
Node 10.15.2
"typescript": "^2.9.2",
"ts-loader": "^5.3.3",
"webpack": "^4.29.6",
"webpack-cli": "^3.2.3"
import { Request, Response } from "express";
import * as GhostContentAPI from '@tryghost/content-api';
export getPosts = (req: Request, res: Response) => {
const api = new GhostContentAPI({
url: "http://.............................azure.com",
key: "a405..................dbb1",
version: "v2",
});
api.posts
.browse({limit: 5, include: 'tags,authors'})
.then((posts: any) => {
posts.forEach((post: any) => {
console.log(post.title);
});
res.status(200).json(posts);
})
.catch((err: any) => {
console.error(err);
res.statusMessage = err.message;
res.status(404).end();
});
}
Running either:
ts-node src/server.ts
or
tsc
node dist/server.js
Works as expected.
Running
webpack -p
Complies without errors, starts without issues. Hitting the endpoint that calls the method above results in the error
TypeError: r is not a constructor
at e.getArticleBySlug (/home/david/strataV2/strata-cms.api/dist/bundle.js:1:3078)
at Layer.handle [as handle_request] (/home/david/strataV2/strata-cms.api/node_modules/express/lib/router/layer.js:95:5)
at next (/home/david/strataV2/strata-cms.api/node_modules/express/lib/router/route.js:137:13)
at Route.dispatch (/home/david/strataV2/strata-cms.api/node_modules/express/lib/router/route.js:112:3)
at Layer.handle [as handle_request] (/home/david/strataV2/strata-cms.api/node_modules/express/lib/router/layer.js:95:5)
at /home/david/strataV2/strata-cms.api/node_modules/express/lib/router/index.js:281:22
at param (/home/david/strataV2/strata-cms.api/node_modules/express/lib/router/index.js:354:14)
at param (/home/david/strataV2/strata-cms.api/node_modules/express/lib/router/index.js:365:14)
at Function.process_params (/home/david/strataV2/strata-cms.api/node_modules/express/lib/router/index.js:410:3)
at next (/home/david/strataV2/strata-cms.api/node_modules/express/lib/router/index.js:275:10)
If I import GhostContentAPI like
import GhostContentAPI from '@tryghost/content-api';
results in the following
TypeError: content_api_1.default is not a constructor
at exports.getArticleBySlug (/home/david/strataV2/strata-cms.api/src/controllers/Article.controller.ts:6:15)
at Layer.handle [as handle_request] (/home/david/strataV2/strata-cms.api/node_modules/express/lib/router/layer.js:95:5)
at next (/home/david/strataV2/strata-cms.api/node_modules/express/lib/router/route.js:137:13)
at Route.dispatch (/home/david/strataV2/strata-cms.api/node_modules/express/lib/router/route.js:112:3)
at Layer.handle [as handle_request] (/home/david/strataV2/strata-cms.api/node_modules/express/lib/router/layer.js:95:5)
at /home/david/strataV2/strata-cms.api/node_modules/express/lib/router/index.js:281:22
at param (/home/david/strataV2/strata-cms.api/node_modules/express/lib/router/index.js:354:14)
at param (/home/david/strataV2/strata-cms.api/node_modules/express/lib/router/index.js:365:14)
at Function.process_params (/home/david/strataV2/strata-cms.api/node_modules/express/lib/router/index.js:410:3)
at next (/home/david/strataV2/strata-cms.api/node_modules/express/lib/router/index.js:275:10)
declare module '@tryghost/content-api';
Our API SDKs moved from initial spike to production release without going through much cleanup or refactoring. We'd like to review the code to make it easier to follow, easier to customise for additional resources, and better match patterns in our other codebases.
index.js
and split up as necessaryemail
, that shouldn't leak into all other resource's allowed params and error message textsThe @tryghost/admin-api
library should not be used in a client-side app as there is no way to protect the Admin API Key. Using it in a client-side app means any user of that app gets full write access to the Admin API.
Should we discourage that practice by removing the explicitly-client-side UMD bundle?
This is the lowest layer of the sdk - it will interact with the iframe directly
requirements:
function listen(iframe, fn) {
iframe.addEventListener('message', function (event) {
if (event.data.type === 'event') fn(event.data);
});
}
https://travis-ci.org/github/weareopensource/Vue/builds/717478799
core-js/modules/es6.array.iterator in ./node_modules/@tryghost/content-api/es/content-api.js
262* core-js/modules/es6.function.name in ./node_modules/@tryghost/content-api/es/content-api.js
263* core-js/modules/es6.object.assign in ./node_modules/@tryghost/content-api/es/content-api.js
264* core-js/modules/es6.object.keys in ./node_modules/@tryghost/content-api/es/content-api.js
265* core-js/modules/es6.object.to-string in ./node_modules/@tryghost/content-api/es/content-api.js
266* core-js/modules/es6.promise in ./node_modules/@tryghost/content-api/es/content-api.js
267* core-js/modules/es6.string.ends-with in ./node_modules/@tryghost/content-api/es/content-api.js
268* core-js/modules/es6.string.starts-with in ./node_modules/@tryghost/content-api/es/content-api.js
269* core-js/modules/es7.array.includes in ./node_modules/@tryghost/content-api/es/content-api.js
270* core-js/modules/web.dom.iterable in ./node_modules/@tryghost/content-api/es/content-api.js
probably linked to Babel and core-js: gatsbyjs/gatsby#7862
I tried to clear the cache relaunched several times, checked that it was not linked to another dependency upgrade ...
without success, I trace the bug, if that can help
Really no idea, just add content-API as a dependency of a Vue project, npm run build will fail.
downgrade to 1.4.2 : "@tryghost/content-api": "1.4.2"
https://travis-ci.org/github/weareopensource/Vue/builds/717319344
We currently do not handle the Admin API errors well.
If I receive a 422, I am getting an error object back like:
{ Error: Request failed with status code 422
config:
request:
response:
data: {errors: [{ message: 'MESSAGE: Validation failed for 'posts[0]'', ....}]}
"Request failed with status code 422" comes from the library we are using. We are not receiving the Ghost error message.
We could use Ignition to deserialize the error to receive a proper error instance.
Furthermore, it is helpful to have access to the response. Most packages offer the access to the response through the error object (e.g. supertest or got)
api.posts.add(...)
.catch((err) => {
err.message
err.statusCode
err.response
})
In Axios 19.2 they fixed a bug where if the URL had the word javascript
anywhere on it, then it would be deemed as a XSS attempt and the request would fail. I found this because my blog's front-end is a Vue application that fetches content using the Content API and was getting a weird "post not found" error whenever I tried to access a post of mine which the slug contains javascript
on it.
javascript
on the slugHi, im trying to use the ghost API to add a post on the websiteβ¦
const GHOST_API = new GhostAdminAPI({
url: END_POINT,
version: "v3",
key: GHOST_KEY
});
GHOST_API.posts.add({
title: 'My first draft API post',
mobiledoc: '{\"version\":\"0.3.1\",\"atoms\":[],\"cards\":[],\"markups\":[],\"sections\":[[1,\"p\",[[0,[],0,\"My post content. Work in progress...\"]]]]}'
}).then(result => {
res.send(JSON.stringify(result) + " - SUCCESS!")
}).catch(err => {
res.send(JSON.stringify(err) + " - ERROR!")
});
The result
being the Array of posts i already have, but it does not add the new one.
Ive used this guide: https://ghost.org/docs/api/v3/javascript/admin/
Thanks for suggestions
This should be a simple drop in script - it will rely on the Layer 1 SDK
<button data-members-signin>Beam me up scotty</button>
<button data-members-signout>Get me outta here</button>
<script src="/members-sdk-layer-2.js"></script>
This will hide the buttons depending on if you're logged in, and initiate signin/signout flows when they are clicked
After looking into this issue TryGhost/Ghost#10793 I've narrowed down the quote switching to the urlUtils.makeAbsoluteUrls
function.
HTML allows "
or '
to indicate value boundaries, this is useful when putting JSON into data attributes but the quotes need to be kept correct. Our absolute URLs function is automatically switching them which then creates invalid HTML (although browsers do a reasonable job of interpreting it as far as layout goes) and breaks any javascript that was using the data attributes.
This:
<div data-options='{"strings": ["item1", "item2"]}'>
Becomes:
<div data-options="{"strings": ["item1"], ["item2"]}">
A declarative, efficient, and flexible JavaScript library for building user interfaces.
π Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. πππ
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google β€οΈ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.