adstxt-validator 1.2.3

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.
@@ -0,0 +1,89 @@
1
+ {
2
+ "validation_errors": {
3
+ "missingFields": {
4
+ "message": "Missing required fields",
5
+ "description": "Ads.txt entries require three mandatory fields: domain, account ID, and relationship",
6
+ "helpUrl": "/help/#missing-fields"
7
+ },
8
+ "invalidFormat": {
9
+ "message": "Invalid format",
10
+ "description": "The ads.txt entry format is incorrect. Please use comma-separated format",
11
+ "helpUrl": "/help/#invalid-format"
12
+ },
13
+ "invalidRelationship": {
14
+ "message": "Invalid relationship",
15
+ "description": "Relationship must be either 'DIRECT' or 'RESELLER'",
16
+ "helpUrl": "/help/#invalid-relationship"
17
+ },
18
+ "invalidDomain": {
19
+ "message": "Invalid domain",
20
+ "description": "The specified domain '{{domain}}' is not a valid domain format",
21
+ "helpUrl": "/help/#invalid-domain"
22
+ },
23
+ "emptyAccountId": {
24
+ "message": "Account ID is empty",
25
+ "description": "Account ID is a required field",
26
+ "helpUrl": "/help/#empty-account-id"
27
+ },
28
+ "emptyFile": {
29
+ "message": "File is empty",
30
+ "description": "The ads.txt file contains no content",
31
+ "helpUrl": "/help/#empty-file"
32
+ },
33
+ "invalidCharacters": {
34
+ "message": "Contains invalid characters",
35
+ "description": "The ads.txt file contains non-printable or control characters",
36
+ "helpUrl": "/help/#invalid-characters"
37
+ },
38
+ "noSellersJson": {
39
+ "message": "sellers.json file not found for {{domain}}",
40
+ "description": "The specified advertising system does not have a sellers.json file",
41
+ "helpUrl": "/help/#no-sellers-json"
42
+ },
43
+ "directAccountIdNotInSellersJson": {
44
+ "message": "DIRECT entry account ID '{{accountId}}' not found in sellers.json",
45
+ "description": "DIRECT relationship entries must have their account ID registered in the corresponding sellers.json file",
46
+ "helpUrl": "/help/#direct-account-id-not-in-sellers-json"
47
+ },
48
+ "resellerAccountIdNotInSellersJson": {
49
+ "message": "RESELLER entry account ID '{{accountId}}' not found in sellers.json",
50
+ "description": "RESELLER relationship entries must have their account ID registered in the corresponding sellers.json file",
51
+ "helpUrl": "/help/#reseller-account-id-not-in-sellers-json"
52
+ },
53
+ "domainMismatch": {
54
+ "message": "Domain mismatch: {{sellerDomain}}",
55
+ "description": "The domain in sellers.json does not match the OWNERDOMAIN/MANAGERDOMAIN in ads.txt",
56
+ "helpUrl": "/help/#domain-mismatch"
57
+ },
58
+ "directNotPublisher": {
59
+ "message": "DIRECT entry seller_type is not 'PUBLISHER'",
60
+ "description": "DIRECT relationship entries should have seller_type as 'PUBLISHER' or 'BOTH' in sellers.json",
61
+ "helpUrl": "/help/#direct-not-publisher"
62
+ },
63
+ "sellerIdNotUnique": {
64
+ "message": "Account ID '{{accountId}}' is duplicated",
65
+ "description": "The same account ID is used in multiple entries",
66
+ "helpUrl": "/help/#seller-id-not-unique"
67
+ },
68
+ "resellerNotIntermediary": {
69
+ "message": "RESELLER entry seller_type is not 'INTERMEDIARY'",
70
+ "description": "RESELLER relationship entries should have seller_type as 'INTERMEDIARY' or 'BOTH' in sellers.json",
71
+ "helpUrl": "/help/#reseller-not-intermediary"
72
+ },
73
+ "implimentedEntry": {
74
+ "message": "Duplicate entry",
75
+ "description": "Multiple ads.txt entries with the same content exist",
76
+ "helpUrl": "/help/#implimented-entry"
77
+ },
78
+ "noValidRecords": {
79
+ "message": "No valid records found",
80
+ "description": "The uploaded file or provided data does not contain any valid ads.txt records",
81
+ "helpUrl": "/help/#no-valid-records"
82
+ },
83
+ "parsingError": {
84
+ "message": "Parsing error: {{message}}",
85
+ "description": "An error occurred while parsing the file or data",
86
+ "helpUrl": "/help/#parsing-error"
87
+ }
88
+ }
89
+ }
@@ -0,0 +1,89 @@
1
+ {
2
+ "validation_errors": {
3
+ "missingFields": {
4
+ "message": "必須フィールドが不足しています",
5
+ "description": "ads.txtエントリには、ドメイン、アカウントID、関係性の3つの必須フィールドが必要です",
6
+ "helpUrl": "/help/#missing-fields"
7
+ },
8
+ "invalidFormat": {
9
+ "message": "無効なフォーマットです",
10
+ "description": "ads.txtエントリの形式が正しくありません。カンマで区切られた形式で入力してください",
11
+ "helpUrl": "/help/#invalid-format"
12
+ },
13
+ "invalidRelationship": {
14
+ "message": "無効な関係性です",
15
+ "description": "関係性は「DIRECT」または「RESELLER」である必要があります",
16
+ "helpUrl": "/help/#invalid-relationship"
17
+ },
18
+ "invalidDomain": {
19
+ "message": "無効なドメインです",
20
+ "description": "指定されたドメイン「{{domain}}」は有効なドメイン形式ではありません",
21
+ "helpUrl": "/help/#invalid-domain"
22
+ },
23
+ "emptyAccountId": {
24
+ "message": "アカウントIDが空です",
25
+ "description": "アカウントIDは必須フィールドです",
26
+ "helpUrl": "/help/#empty-account-id"
27
+ },
28
+ "emptyFile": {
29
+ "message": "ファイルが空です",
30
+ "description": "ads.txtファイルにコンテンツがありません",
31
+ "helpUrl": "/help/#empty-file"
32
+ },
33
+ "invalidCharacters": {
34
+ "message": "無効な文字が含まれています",
35
+ "description": "ads.txtファイルに印刷できない文字や制御文字が含まれています",
36
+ "helpUrl": "/help/#invalid-characters"
37
+ },
38
+ "noSellersJson": {
39
+ "message": "{{domain}}のsellers.jsonファイルが見つかりません",
40
+ "description": "指定された広告システムにsellers.jsonファイルが存在しません",
41
+ "helpUrl": "/help/#no-sellers-json"
42
+ },
43
+ "directAccountIdNotInSellersJson": {
44
+ "message": "DIRECTエントリのアカウントID「{{accountId}}」がsellers.jsonに見つかりません",
45
+ "description": "DIRECT関係のエントリは、対応するsellers.jsonファイルにアカウントIDが登録されている必要があります",
46
+ "helpUrl": "/help/#direct-account-id-not-in-sellers-json"
47
+ },
48
+ "resellerAccountIdNotInSellersJson": {
49
+ "message": "RESELLERエントリのアカウントID「{{accountId}}」がsellers.jsonに見つかりません",
50
+ "description": "RESELLER関係のエントリは、対応するsellers.jsonファイルにアカウントIDが登録されている必要があります",
51
+ "helpUrl": "/help/#reseller-account-id-not-in-sellers-json"
52
+ },
53
+ "domainMismatch": {
54
+ "message": "ドメインの不一致: {{sellerDomain}}",
55
+ "description": "sellers.jsonのドメインとads.txtのOWNERDOMAIN/MANAGERDOMAINが一致しません",
56
+ "helpUrl": "/help/#domain-mismatch"
57
+ },
58
+ "directNotPublisher": {
59
+ "message": "DIRECTエントリのseller_typeが「PUBLISHER」ではありません",
60
+ "description": "DIRECT関係のエントリは、sellers.jsonでseller_typeが「PUBLISHER」または「BOTH」である必要があります",
61
+ "helpUrl": "/help/#direct-not-publisher"
62
+ },
63
+ "sellerIdNotUnique": {
64
+ "message": "アカウントID「{{accountId}}」が重複しています",
65
+ "description": "同じアカウントIDが複数のエントリで使用されています",
66
+ "helpUrl": "/help/#seller-id-not-unique"
67
+ },
68
+ "resellerNotIntermediary": {
69
+ "message": "RESELLERエントリのseller_typeが「INTERMEDIARY」ではありません",
70
+ "description": "RESELLER関係のエントリは、sellers.jsonでseller_typeが「INTERMEDIARY」または「BOTH」である必要があります",
71
+ "helpUrl": "/help/#reseller-not-intermediary"
72
+ },
73
+ "implimentedEntry": {
74
+ "message": "重複したエントリです",
75
+ "description": "同じ内容のads.txtエントリが複数存在します",
76
+ "helpUrl": "/help/#implimented-entry"
77
+ },
78
+ "noValidRecords": {
79
+ "message": "有効なレコードがありません",
80
+ "description": "アップロードされたファイルまたは提供されたデータに有効なads.txtレコードが含まれていません",
81
+ "helpUrl": "/help/#no-valid-records"
82
+ },
83
+ "parsingError": {
84
+ "message": "解析エラー: {{message}}",
85
+ "description": "ファイルまたはデータの解析中にエラーが発生しました",
86
+ "helpUrl": "/help/#parsing-error"
87
+ }
88
+ }
89
+ }
@@ -0,0 +1,263 @@
1
+ /**
2
+ * Message system for ads-txt-validator
3
+ * Provides internationalized messages and help links for validation results
4
+ */
5
+ export interface ValidationMessage {
6
+ key: string;
7
+ severity: Severity;
8
+ message: string;
9
+ description?: string;
10
+ helpUrl?: string;
11
+ placeholders: string[];
12
+ }
13
+ export interface MessageData {
14
+ message: string;
15
+ description?: string;
16
+ helpUrl?: string;
17
+ }
18
+ export interface MessageProvider {
19
+ getMessage(key: string, locale?: string): MessageData | null;
20
+ formatMessage(key: string, placeholders: string[], locale?: string): ValidationMessage | null;
21
+ }
22
+ import { Severity } from './index';
23
+ declare const messages: {
24
+ readonly ja: {
25
+ validation_errors: {
26
+ missingFields: {
27
+ message: string;
28
+ description: string;
29
+ helpUrl: string;
30
+ };
31
+ invalidFormat: {
32
+ message: string;
33
+ description: string;
34
+ helpUrl: string;
35
+ };
36
+ invalidRelationship: {
37
+ message: string;
38
+ description: string;
39
+ helpUrl: string;
40
+ };
41
+ invalidDomain: {
42
+ message: string;
43
+ description: string;
44
+ helpUrl: string;
45
+ };
46
+ emptyAccountId: {
47
+ message: string;
48
+ description: string;
49
+ helpUrl: string;
50
+ };
51
+ emptyFile: {
52
+ message: string;
53
+ description: string;
54
+ helpUrl: string;
55
+ };
56
+ invalidCharacters: {
57
+ message: string;
58
+ description: string;
59
+ helpUrl: string;
60
+ };
61
+ noSellersJson: {
62
+ message: string;
63
+ description: string;
64
+ helpUrl: string;
65
+ };
66
+ directAccountIdNotInSellersJson: {
67
+ message: string;
68
+ description: string;
69
+ helpUrl: string;
70
+ };
71
+ resellerAccountIdNotInSellersJson: {
72
+ message: string;
73
+ description: string;
74
+ helpUrl: string;
75
+ };
76
+ domainMismatch: {
77
+ message: string;
78
+ description: string;
79
+ helpUrl: string;
80
+ };
81
+ directNotPublisher: {
82
+ message: string;
83
+ description: string;
84
+ helpUrl: string;
85
+ };
86
+ sellerIdNotUnique: {
87
+ message: string;
88
+ description: string;
89
+ helpUrl: string;
90
+ };
91
+ resellerNotIntermediary: {
92
+ message: string;
93
+ description: string;
94
+ helpUrl: string;
95
+ };
96
+ implimentedEntry: {
97
+ message: string;
98
+ description: string;
99
+ helpUrl: string;
100
+ };
101
+ noValidRecords: {
102
+ message: string;
103
+ description: string;
104
+ helpUrl: string;
105
+ };
106
+ parsingError: {
107
+ message: string;
108
+ description: string;
109
+ helpUrl: string;
110
+ };
111
+ };
112
+ };
113
+ readonly en: {
114
+ validation_errors: {
115
+ missingFields: {
116
+ message: string;
117
+ description: string;
118
+ helpUrl: string;
119
+ };
120
+ invalidFormat: {
121
+ message: string;
122
+ description: string;
123
+ helpUrl: string;
124
+ };
125
+ invalidRelationship: {
126
+ message: string;
127
+ description: string;
128
+ helpUrl: string;
129
+ };
130
+ invalidDomain: {
131
+ message: string;
132
+ description: string;
133
+ helpUrl: string;
134
+ };
135
+ emptyAccountId: {
136
+ message: string;
137
+ description: string;
138
+ helpUrl: string;
139
+ };
140
+ emptyFile: {
141
+ message: string;
142
+ description: string;
143
+ helpUrl: string;
144
+ };
145
+ invalidCharacters: {
146
+ message: string;
147
+ description: string;
148
+ helpUrl: string;
149
+ };
150
+ noSellersJson: {
151
+ message: string;
152
+ description: string;
153
+ helpUrl: string;
154
+ };
155
+ directAccountIdNotInSellersJson: {
156
+ message: string;
157
+ description: string;
158
+ helpUrl: string;
159
+ };
160
+ resellerAccountIdNotInSellersJson: {
161
+ message: string;
162
+ description: string;
163
+ helpUrl: string;
164
+ };
165
+ domainMismatch: {
166
+ message: string;
167
+ description: string;
168
+ helpUrl: string;
169
+ };
170
+ directNotPublisher: {
171
+ message: string;
172
+ description: string;
173
+ helpUrl: string;
174
+ };
175
+ sellerIdNotUnique: {
176
+ message: string;
177
+ description: string;
178
+ helpUrl: string;
179
+ };
180
+ resellerNotIntermediary: {
181
+ message: string;
182
+ description: string;
183
+ helpUrl: string;
184
+ };
185
+ implimentedEntry: {
186
+ message: string;
187
+ description: string;
188
+ helpUrl: string;
189
+ };
190
+ noValidRecords: {
191
+ message: string;
192
+ description: string;
193
+ helpUrl: string;
194
+ };
195
+ parsingError: {
196
+ message: string;
197
+ description: string;
198
+ helpUrl: string;
199
+ };
200
+ };
201
+ };
202
+ };
203
+ export type SupportedLocale = keyof typeof messages;
204
+ /**
205
+ * Configuration for message provider
206
+ */
207
+ export interface MessageConfig {
208
+ defaultLocale?: SupportedLocale;
209
+ baseUrl?: string;
210
+ }
211
+ /**
212
+ * Default message provider implementation
213
+ */
214
+ export declare class DefaultMessageProvider implements MessageProvider {
215
+ private defaultLocale;
216
+ private baseUrl?;
217
+ constructor(defaultLocale?: SupportedLocale, config?: MessageConfig);
218
+ /**
219
+ * Get raw message data for a validation key
220
+ */
221
+ getMessage(key: string, locale?: string): MessageData | null;
222
+ /**
223
+ * Format help URL with base URL if configured
224
+ */
225
+ private formatHelpUrl;
226
+ /**
227
+ * Format a message with placeholders and create a ValidationMessage
228
+ */
229
+ formatMessage(key: string, placeholders?: string[], locale?: string): ValidationMessage | null;
230
+ /**
231
+ * Replace {{placeholder}} and {{0}}, {{1}} style placeholders
232
+ */
233
+ private replacePlaceholders;
234
+ /**
235
+ * Determine severity from validation key
236
+ */
237
+ private getSeverityFromKey;
238
+ }
239
+ /**
240
+ * Set the global message provider
241
+ */
242
+ export declare function setMessageProvider(provider: MessageProvider): void;
243
+ /**
244
+ * Configure the global message provider with baseUrl
245
+ */
246
+ export declare function configureMessages(config: MessageConfig): void;
247
+ /**
248
+ * Get the current message provider
249
+ */
250
+ export declare function getMessageProvider(): MessageProvider;
251
+ /**
252
+ * Convenience function to create a validation message
253
+ */
254
+ export declare function createValidationMessage(key: string, placeholders?: string[], locale?: string): ValidationMessage | null;
255
+ /**
256
+ * Check if a locale is supported
257
+ */
258
+ export declare function isSupportedLocale(locale: string): locale is SupportedLocale;
259
+ /**
260
+ * Get list of supported locales
261
+ */
262
+ export declare function getSupportedLocales(): SupportedLocale[];
263
+ export {};
@@ -0,0 +1,189 @@
1
+ "use strict";
2
+ /**
3
+ * Message system for ads-txt-validator
4
+ * Provides internationalized messages and help links for validation results
5
+ */
6
+ var __importDefault = (this && this.__importDefault) || function (mod) {
7
+ return (mod && mod.__esModule) ? mod : { "default": mod };
8
+ };
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.DefaultMessageProvider = void 0;
11
+ exports.setMessageProvider = setMessageProvider;
12
+ exports.configureMessages = configureMessages;
13
+ exports.getMessageProvider = getMessageProvider;
14
+ exports.createValidationMessage = createValidationMessage;
15
+ exports.isSupportedLocale = isSupportedLocale;
16
+ exports.getSupportedLocales = getSupportedLocales;
17
+ const validation_json_1 = __importDefault(require("./locales/ja/validation.json"));
18
+ const validation_json_2 = __importDefault(require("./locales/en/validation.json"));
19
+ // Import severity from main index
20
+ const index_1 = require("./index");
21
+ // Message resources
22
+ const messages = {
23
+ ja: validation_json_1.default,
24
+ en: validation_json_2.default,
25
+ };
26
+ /**
27
+ * Default message provider implementation
28
+ */
29
+ class DefaultMessageProvider {
30
+ constructor(defaultLocale = 'ja', config) {
31
+ this.defaultLocale = 'ja';
32
+ this.defaultLocale = config?.defaultLocale || defaultLocale;
33
+ this.baseUrl = config?.baseUrl;
34
+ }
35
+ /**
36
+ * Get raw message data for a validation key
37
+ */
38
+ getMessage(key, locale) {
39
+ const targetLocale = locale || this.defaultLocale;
40
+ const messageBundle = messages[targetLocale] || messages[this.defaultLocale];
41
+ const messageData = messageBundle.validation_errors[key];
42
+ if (!messageData) {
43
+ return null;
44
+ }
45
+ return {
46
+ message: messageData.message,
47
+ description: messageData.description,
48
+ helpUrl: this.formatHelpUrl(messageData.helpUrl),
49
+ };
50
+ }
51
+ /**
52
+ * Format help URL with base URL if configured
53
+ */
54
+ formatHelpUrl(helpUrl) {
55
+ if (!helpUrl) {
56
+ return undefined;
57
+ }
58
+ // If helpUrl is already a full URL (starts with http/https), return as-is
59
+ if (helpUrl.startsWith('http://') || helpUrl.startsWith('https://')) {
60
+ return helpUrl;
61
+ }
62
+ // If baseUrl is configured and helpUrl is relative, combine them
63
+ if (this.baseUrl && helpUrl.startsWith('/')) {
64
+ return `${this.baseUrl.replace(/\/$/, '')}${helpUrl}`;
65
+ }
66
+ // Return helpUrl as-is for other cases
67
+ return helpUrl;
68
+ }
69
+ /**
70
+ * Format a message with placeholders and create a ValidationMessage
71
+ */
72
+ formatMessage(key, placeholders = [], locale) {
73
+ const messageData = this.getMessage(key, locale);
74
+ if (!messageData) {
75
+ return null;
76
+ }
77
+ // Replace placeholders in the message
78
+ const formattedMessage = this.replacePlaceholders(messageData.message, placeholders);
79
+ const formattedDescription = messageData.description
80
+ ? this.replacePlaceholders(messageData.description, placeholders)
81
+ : undefined;
82
+ // Determine severity based on key
83
+ const severity = this.getSeverityFromKey(key);
84
+ return {
85
+ key,
86
+ severity,
87
+ message: formattedMessage,
88
+ description: formattedDescription,
89
+ helpUrl: messageData.helpUrl,
90
+ placeholders,
91
+ };
92
+ }
93
+ /**
94
+ * Replace {{placeholder}} and {{0}}, {{1}} style placeholders
95
+ */
96
+ replacePlaceholders(template, placeholders) {
97
+ let result = template;
98
+ // Replace numbered placeholders like {{0}}, {{1}}
99
+ result = result.replace(/\{\{(\d+)\}\}/g, (match, index) => {
100
+ const placeholderIndex = parseInt(index, 10);
101
+ return placeholders[placeholderIndex] || match;
102
+ });
103
+ // Replace named placeholders
104
+ if (placeholders.length > 0) {
105
+ // Common placeholder names
106
+ const placeholderNames = ['domain', 'accountId', 'sellerDomain', 'accountType'];
107
+ placeholderNames.forEach((name, index) => {
108
+ if (index < placeholders.length) {
109
+ result = result.replace(new RegExp(`\\{\\{${name}\\}\\}`, 'g'), placeholders[index]);
110
+ }
111
+ });
112
+ }
113
+ return result;
114
+ }
115
+ /**
116
+ * Determine severity from validation key
117
+ */
118
+ getSeverityFromKey(key) {
119
+ // Keys that should be errors
120
+ const errorKeys = [
121
+ 'missingFields',
122
+ 'invalidFormat',
123
+ 'invalidRelationship',
124
+ 'invalidDomain',
125
+ 'emptyAccountId',
126
+ 'emptyFile',
127
+ 'invalidCharacters',
128
+ 'directAccountIdNotInSellersJson',
129
+ 'resellerAccountIdNotInSellersJson',
130
+ ];
131
+ if (errorKeys.includes(key)) {
132
+ return index_1.Severity.ERROR;
133
+ }
134
+ // Keys that should be warnings
135
+ const warningKeys = [
136
+ 'noSellersJson',
137
+ 'domainMismatch',
138
+ 'directNotPublisher',
139
+ 'resellerNotIntermediary',
140
+ 'sellerIdNotUnique',
141
+ ];
142
+ if (warningKeys.includes(key)) {
143
+ return index_1.Severity.WARNING;
144
+ }
145
+ // Default to info
146
+ return index_1.Severity.INFO;
147
+ }
148
+ }
149
+ exports.DefaultMessageProvider = DefaultMessageProvider;
150
+ /**
151
+ * Global message provider instance
152
+ */
153
+ let globalMessageProvider = new DefaultMessageProvider();
154
+ /**
155
+ * Set the global message provider
156
+ */
157
+ function setMessageProvider(provider) {
158
+ globalMessageProvider = provider;
159
+ }
160
+ /**
161
+ * Configure the global message provider with baseUrl
162
+ */
163
+ function configureMessages(config) {
164
+ globalMessageProvider = new DefaultMessageProvider(config.defaultLocale, config);
165
+ }
166
+ /**
167
+ * Get the current message provider
168
+ */
169
+ function getMessageProvider() {
170
+ return globalMessageProvider;
171
+ }
172
+ /**
173
+ * Convenience function to create a validation message
174
+ */
175
+ function createValidationMessage(key, placeholders = [], locale) {
176
+ return globalMessageProvider.formatMessage(key, placeholders, locale);
177
+ }
178
+ /**
179
+ * Check if a locale is supported
180
+ */
181
+ function isSupportedLocale(locale) {
182
+ return locale in messages;
183
+ }
184
+ /**
185
+ * Get list of supported locales
186
+ */
187
+ function getSupportedLocales() {
188
+ return Object.keys(messages);
189
+ }
package/package.json ADDED
@@ -0,0 +1,55 @@
1
+ {
2
+ "name": "adstxt-validator",
3
+ "version": "1.2.3",
4
+ "description": "A TypeScript library for validating ads.txt files and sellers.json files",
5
+ "type": "module",
6
+ "main": "dist/index.js",
7
+ "types": "dist/index.d.ts",
8
+ "files": [
9
+ "dist/**/*",
10
+ "src/locales/**/*.json",
11
+ "README.md",
12
+ "LICENSE"
13
+ ],
14
+ "scripts": {
15
+ "build": "tsc",
16
+ "lint": "eslint src --ext .ts",
17
+ "lint:fix": "eslint src --ext .ts --fix",
18
+ "format": "prettier --write \"src/**/*.ts\"",
19
+ "format:check": "prettier --check \"src/**/*.ts\"",
20
+ "prepublishOnly": "npm run build",
21
+ "test": "echo \"Tests will be implemented in future versions\" && exit 0"
22
+ },
23
+ "keywords": [
24
+ "ads.txt",
25
+ "sellers.json",
26
+ "advertising",
27
+ "validation",
28
+ "typescript"
29
+ ],
30
+ "author": "Yoshihiko Miyaichi",
31
+ "license": "MIT",
32
+ "repository": {
33
+ "type": "git",
34
+ "url": "https://github.com/miyaichi/adstxt-validator.git"
35
+ },
36
+ "publishConfig": {
37
+ "access": "public"
38
+ },
39
+ "dependencies": {
40
+ "psl": "^1.9.0"
41
+ },
42
+ "devDependencies": {
43
+ "@eslint/js": "^9.39.2",
44
+ "@types/node": "^20.0.0",
45
+ "@types/psl": "^1.1.3",
46
+ "@typescript-eslint/eslint-plugin": "^8.49.0",
47
+ "@typescript-eslint/parser": "^8.49.0",
48
+ "eslint": "^9.39.2",
49
+ "eslint-config-prettier": "^10.1.8",
50
+ "eslint-plugin-prettier": "^5.5.4",
51
+ "prettier": "^3.7.4",
52
+ "typescript": "^5.0.4",
53
+ "typescript-eslint": "^8.49.0"
54
+ }
55
+ }