Compare commits
25 Commits
Author | SHA1 | Date | |
---|---|---|---|
f2e96640fa | |||
72cd9f1a00 | |||
2e9394c330 | |||
f8241b49fb | |||
7adc7b9fb1 | |||
aabb8265cd | |||
b8befa85fa | |||
114cd1900b | |||
17d8cd6585 | |||
87cdc5bb5f | |||
d03b37690f | |||
35680b135d | |||
3170da0303 | |||
8a78cc6831 | |||
911c680452 | |||
0a3768a088 | |||
7ae31b4ee0 | |||
ac3d9aeb2d | |||
c312622fb1 | |||
89829b84f4 | |||
2b2111b2f1 | |||
9c82b3534f | |||
b6abfd11d2 | |||
850f20fc38 | |||
cd1e582f88 |
22691
package-lock.json
generated
22691
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
23
package.json
23
package.json
@ -1,10 +1,11 @@
|
||||
{
|
||||
"name": "@pushrocks/smartsitemap",
|
||||
"version": "1.0.3",
|
||||
"version": "2.0.0",
|
||||
"private": false,
|
||||
"description": "a sitemap module",
|
||||
"main": "dist_ts/index.js",
|
||||
"typings": "dist_ts/index.d.ts",
|
||||
"type": "module",
|
||||
"author": "Lossless GmbH",
|
||||
"license": "MIT",
|
||||
"scripts": {
|
||||
@ -12,16 +13,20 @@
|
||||
"build": "(tsbuild --web)"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@gitzone/tsbuild": "^2.1.25",
|
||||
"@gitzone/tsbundle": "^1.0.78",
|
||||
"@gitzone/tstest": "^1.0.44",
|
||||
"@pushrocks/tapbundle": "^3.2.9",
|
||||
"@types/node": "^14.11.2",
|
||||
"tslint": "^6.1.3",
|
||||
"tslint-config-prettier": "^1.15.0"
|
||||
"@gitzone/tsbuild": "^2.1.61",
|
||||
"@gitzone/tsbundle": "^1.0.101",
|
||||
"@gitzone/tstest": "^1.0.69",
|
||||
"@pushrocks/smartenv": "^5.0.0",
|
||||
"@pushrocks/tapbundle": "^5.0.3",
|
||||
"@types/node": "^17.0.23"
|
||||
},
|
||||
"dependencies": {
|
||||
"@pushrocks/smartxml": "^1.0.4"
|
||||
"@pushrocks/smartcache": "^1.0.13",
|
||||
"@pushrocks/smartfeed": "^1.0.11",
|
||||
"@pushrocks/smartxml": "^1.0.6",
|
||||
"@pushrocks/smartyaml": "^2.0.5",
|
||||
"@pushrocks/webrequest": "^3.0.3",
|
||||
"@tsclass/tsclass": "^3.0.48"
|
||||
},
|
||||
"browserslist": [
|
||||
"last 1 chrome versions"
|
||||
|
5
test/sitemap.yml
Normal file
5
test/sitemap.yml
Normal file
@ -0,0 +1,5 @@
|
||||
|
||||
daily:
|
||||
- central.eu/
|
||||
- central.eu/privacy
|
||||
- central.eu/someotherlink
|
14
test/test.ts
14
test/test.ts
@ -1,11 +1,21 @@
|
||||
import { expect, tap } from '@pushrocks/tapbundle';
|
||||
import * as smartsitemap from '../ts/index';
|
||||
import * as smartsitemap from '../ts/index.js';
|
||||
|
||||
let testSmartsitemap: smartsitemap.SmartSitemap;
|
||||
|
||||
tap.test('should create an instance of Smartsitemap', async () => {
|
||||
testSmartsitemap = new smartsitemap.SmartSitemap();
|
||||
expect(testSmartsitemap).to.be.instanceOf(smartsitemap.SmartSitemap);
|
||||
expect(testSmartsitemap).toBeInstanceOf(smartsitemap.SmartSitemap);
|
||||
});
|
||||
|
||||
tap.test('should create a sitemap from feed', async () => {
|
||||
const sitemapString = await testSmartsitemap.createSitemapNewsFromFeedUrl('https://central.eu/feed');
|
||||
console.log(sitemapString);
|
||||
});
|
||||
|
||||
tap.test('should parse a sitemap', async () => {
|
||||
const result = await testSmartsitemap.parseSitemapUrl('https://central.eu/sitemap-news');
|
||||
console.log(result.urlset.url);
|
||||
})
|
||||
|
||||
tap.start();
|
||||
|
@ -1,2 +1,3 @@
|
||||
export * from './smartsitemap.classes.smartsitemap';
|
||||
export * from './smartsitemap.classes.sitemapnews';
|
||||
export * from './smartsitemap.classes.smartsitemap.js';
|
||||
export * from './smartsitemap.classes.sitemapnews.js';
|
||||
export * from './smartsitemap.classes.sitemapwebsite.js';
|
42
ts/interfaces/index.ts
Normal file
42
ts/interfaces/index.ts
Normal file
@ -0,0 +1,42 @@
|
||||
export interface ISitemapYaml {
|
||||
daily: string[];
|
||||
}
|
||||
|
||||
export interface IRssItem {
|
||||
[key: string]: any;
|
||||
link?: string;
|
||||
guid?: string;
|
||||
title?: string;
|
||||
pubDate?: string;
|
||||
creator?: string;
|
||||
content?: string;
|
||||
isoDate?: string;
|
||||
categories?: string[];
|
||||
contentSnippet?: string;
|
||||
enclosure?: any;
|
||||
}
|
||||
|
||||
export interface IParsedSiteMap {
|
||||
urlset: {
|
||||
url:
|
||||
| {
|
||||
loc: string;
|
||||
lastmod: string;
|
||||
changefreq: string;
|
||||
}
|
||||
| {
|
||||
loc: string;
|
||||
lastmod: string;
|
||||
changefreq: string;
|
||||
}[]
|
||||
| {
|
||||
loc: string;
|
||||
'news:news': {
|
||||
'news:publication': [];
|
||||
'news:keywords': string;
|
||||
'news:publication_date': string;
|
||||
'news:title': string;
|
||||
};
|
||||
}[];
|
||||
};
|
||||
}
|
@ -1,7 +1,73 @@
|
||||
import * as plugins from './smartsitemap.plugins';
|
||||
import * as plugins from './smartsitemap.plugins.js';
|
||||
import * as interfaces from './interfaces/index.js';
|
||||
|
||||
export class SitemapNews {
|
||||
public readFromRssFeed() {
|
||||
|
||||
public rssItems: interfaces.IRssItem[] = [];
|
||||
|
||||
constructor(optionsArg: {}) {}
|
||||
|
||||
public async readAndAddFromRssFeedString(feedStringArg: string) {
|
||||
const smartfeedInstance = new plugins.smartfeed.Smartfeed();
|
||||
const parsedFeed = await smartfeedInstance.parseFeedFromString(feedStringArg);
|
||||
this.rssItems = this.rssItems.concat(parsedFeed.items);
|
||||
}
|
||||
|
||||
public async readAndAddFromRssFeedUrl(urlArg: string) {
|
||||
const smartfeedInstance = new plugins.smartfeed.Smartfeed();
|
||||
const parsedFeed = await smartfeedInstance.parseFeedFromUrl(urlArg);
|
||||
this.rssItems = this.rssItems.concat(parsedFeed.items);
|
||||
}
|
||||
|
||||
public async readAndParseArticles(articleArrayArg: plugins.tsclass.content.IArticle[]) {
|
||||
const rssItemArray = articleArrayArg.map((articleArg): interfaces.IRssItem => {
|
||||
return {
|
||||
title: articleArg.title,
|
||||
content: articleArg.content,
|
||||
isoDate: new Date(/* TODO: put article timestamp here */).toISOString(),
|
||||
link: articleArg.url
|
||||
};
|
||||
});
|
||||
|
||||
this.rssItems = this.rssItems.concat(rssItemArray);
|
||||
}
|
||||
|
||||
public exportSitemapXml() {
|
||||
const urls: {
|
||||
loc: string;
|
||||
'news:news': {
|
||||
'news:publication': {
|
||||
'news:name': string;
|
||||
'news:language': string;
|
||||
};
|
||||
'news:publication_date': string;
|
||||
'news:keywords': string;
|
||||
'news:title': string;
|
||||
};
|
||||
}[] = [];
|
||||
for (const itemArg of this.rssItems) {
|
||||
console.log(itemArg);
|
||||
urls.push({
|
||||
loc: itemArg.link,
|
||||
'news:news': {
|
||||
'news:publication': {
|
||||
'news:language': 'en',
|
||||
'news:name': 'some name',
|
||||
},
|
||||
'news:keywords': '',
|
||||
'news:publication_date': itemArg.isoDate,
|
||||
'news:title': itemArg.title,
|
||||
},
|
||||
});
|
||||
}
|
||||
const sitemapObject: any = {
|
||||
urlset: {
|
||||
'@_xmlns': 'http://www.sitemaps.org/schemas/sitemap/0.9',
|
||||
'@_xmlns:news': 'http://www.google.com/schemas/sitemap-news/0.9',
|
||||
url: urls,
|
||||
},
|
||||
};
|
||||
const smartxmlInstance = new plugins.smartxml.SmartXml();
|
||||
const sitemapString = smartxmlInstance.createXmlFromObject(sitemapObject);
|
||||
return sitemapString;
|
||||
}
|
||||
}
|
||||
|
42
ts/smartsitemap.classes.sitemapwebsite.ts
Normal file
42
ts/smartsitemap.classes.sitemapwebsite.ts
Normal file
@ -0,0 +1,42 @@
|
||||
import * as plugins from './smartsitemap.plugins.js';
|
||||
|
||||
export type TUpdateFrequency = 'never' | 'daily' | 'weekly' | 'monthly' | 'yearly';
|
||||
|
||||
export interface IUrlInfo {
|
||||
url: string;
|
||||
timestamp: number;
|
||||
frequency?: TUpdateFrequency;
|
||||
}
|
||||
|
||||
export class SitemapWebsite {
|
||||
urlInfos: IUrlInfo[] = [];
|
||||
constructor() {}
|
||||
|
||||
public addUrl(urlInfoArg: IUrlInfo) {
|
||||
this.urlInfos.push(urlInfoArg);
|
||||
}
|
||||
|
||||
public exportSitemapXml() {
|
||||
const urls: {
|
||||
loc: string;
|
||||
lastmod: string;
|
||||
changefreq: TUpdateFrequency;
|
||||
}[] = [];
|
||||
for (const urlInfoArg of this.urlInfos) {
|
||||
urls.push({
|
||||
loc: urlInfoArg.url,
|
||||
lastmod: new Date(urlInfoArg.timestamp).toISOString(),
|
||||
changefreq: urlInfoArg.frequency ? urlInfoArg.frequency : 'weekly'
|
||||
});
|
||||
}
|
||||
const sitemapObject: any = {
|
||||
urlset: {
|
||||
'@_xmlns': 'http://www.sitemaps.org/schemas/sitemap/0.9',
|
||||
url: urls,
|
||||
},
|
||||
};
|
||||
const smartxmlInstance = new plugins.smartxml.SmartXml();
|
||||
const sitemapString = smartxmlInstance.createXmlFromObject(sitemapObject);
|
||||
return sitemapString;
|
||||
}
|
||||
}
|
@ -1,14 +1,81 @@
|
||||
import { SitemapNews } from './smartsitemap.classes.sitemapnews';
|
||||
import * as plugins from './smartsitemap.plugins';
|
||||
import { SitemapNews } from './smartsitemap.classes.sitemapnews.js';
|
||||
import { IUrlInfo, SitemapWebsite } from './smartsitemap.classes.sitemapwebsite.js';
|
||||
import * as plugins from './smartsitemap.plugins.js';
|
||||
import * as interfaces from './interfaces/index.js';
|
||||
|
||||
export class SmartSitemap {
|
||||
constructor() {}
|
||||
|
||||
/**
|
||||
* creates a sitemap for news
|
||||
* creates a sitemap for news from feedurl
|
||||
*/
|
||||
public createSmartsitemapNews(): SitemapNews {
|
||||
const sitemapNewsInstance = new SitemapNews();
|
||||
return sitemapNewsInstance;
|
||||
public async createSitemapNewsFromFeedUrl(feedUrlArg: string): Promise<string> {
|
||||
const sitemapNewsInstance = new SitemapNews({});
|
||||
await sitemapNewsInstance.readAndAddFromRssFeedUrl(feedUrlArg);
|
||||
return sitemapNewsInstance.exportSitemapXml();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* creates a sitemap for news from feedxmlstring
|
||||
*/
|
||||
public async createSitemapNewsFromAFeedStringArg(feedStringArg: string): Promise<string> {
|
||||
const sitemapNewsInstance = new SitemapNews({});
|
||||
await sitemapNewsInstance.readAndAddFromRssFeedString(feedStringArg);
|
||||
return sitemapNewsInstance.exportSitemapXml();
|
||||
}
|
||||
|
||||
/**
|
||||
* creates a sitemap for news from an array of articles
|
||||
*/
|
||||
public async createSitemapNewsFromArticleArray(articleArrayArg: plugins.tsclass.content.IArticle[]): Promise<string> {
|
||||
const sitemapNewsInstance = new SitemapNews({});
|
||||
await sitemapNewsInstance.readAndParseArticles(articleArrayArg);
|
||||
return sitemapNewsInstance.exportSitemapXml();
|
||||
}
|
||||
|
||||
/**
|
||||
* creates a normal sitemap from a list of urls
|
||||
*/
|
||||
public async createSitemapFromYmlString(yamlString: string): Promise<string> {
|
||||
const yamlObject: interfaces.ISitemapYaml = await plugins.smartyaml.yamlStringToObject(yamlString);
|
||||
const sitemapWebsite = new SitemapWebsite();
|
||||
for(const urlArg of yamlObject.daily) {
|
||||
sitemapWebsite.addUrl({
|
||||
url: urlArg,
|
||||
timestamp: Date.now() - 10000,
|
||||
frequency: 'daily'
|
||||
});
|
||||
}
|
||||
return sitemapWebsite.exportSitemapXml();
|
||||
}
|
||||
|
||||
/**
|
||||
* creates a normal sitemap from a list of urls
|
||||
*/
|
||||
public async createSitemapFromUrlInfoArray(urlInfosArg: IUrlInfo[]) {
|
||||
const sitemapWebsite = new SitemapWebsite();
|
||||
for(const urlInfo of urlInfosArg) {
|
||||
sitemapWebsite.addUrl(urlInfo);
|
||||
}
|
||||
return sitemapWebsite.exportSitemapXml();
|
||||
}
|
||||
|
||||
/**
|
||||
* parses a sitemap url
|
||||
*/
|
||||
public async parseSitemapUrl(urlArg: string) {
|
||||
const sitemapXml = await (await (new plugins.webrequest.WebRequest()).request(urlArg, {
|
||||
method: 'GET'
|
||||
})).text();
|
||||
|
||||
const parsedSitemap = await this.parseSitemap(sitemapXml);
|
||||
return parsedSitemap;
|
||||
}
|
||||
|
||||
/**
|
||||
* parses a sitemap
|
||||
*/
|
||||
public async parseSitemap(sitemapXmlArg: string): Promise<interfaces.IParsedSiteMap> {
|
||||
return (new plugins.smartxml.SmartXml()).parseXmlToObject(sitemapXmlArg);
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,21 @@
|
||||
// pushrocks scope
|
||||
import * as smartcache from '@pushrocks/smartcache';
|
||||
import * as smartfeed from '@pushrocks/smartfeed';
|
||||
import * as smartxml from '@pushrocks/smartxml';
|
||||
import * as smartyaml from '@pushrocks/smartyaml';
|
||||
import * as webrequest from '@pushrocks/webrequest';
|
||||
|
||||
export {
|
||||
smartxml
|
||||
smartcache,
|
||||
smartfeed,
|
||||
smartxml,
|
||||
smartyaml,
|
||||
webrequest
|
||||
};
|
||||
|
||||
// tsclass
|
||||
import * as tsclass from '@tsclass/tsclass';
|
||||
|
||||
export {
|
||||
tsclass
|
||||
};
|
||||
|
9
tsconfig.json
Normal file
9
tsconfig.json
Normal file
@ -0,0 +1,9 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"experimentalDecorators": true,
|
||||
"useDefineForClassFields": false,
|
||||
"target": "ES2022",
|
||||
"module": "ES2022",
|
||||
"moduleResolution": "nodenext"
|
||||
}
|
||||
}
|
17
tslint.json
17
tslint.json
@ -1,17 +0,0 @@
|
||||
{
|
||||
"extends": ["tslint:latest", "tslint-config-prettier"],
|
||||
"rules": {
|
||||
"semicolon": [true, "always"],
|
||||
"no-console": false,
|
||||
"ordered-imports": false,
|
||||
"object-literal-sort-keys": false,
|
||||
"member-ordering": {
|
||||
"options":{
|
||||
"order": [
|
||||
"static-method"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"defaultSeverity": "warning"
|
||||
}
|
Reference in New Issue
Block a user