@chronicle.app/foursquare 0.3.0
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/LICENSE +21 -0
- package/README.md +86 -0
- package/dist/auth/FoursquareOAuthProvider.d.ts +9 -0
- package/dist/auth/FoursquareOAuthProvider.js +8 -0
- package/dist/connectors/FoursquareExtractor.d.ts +35 -0
- package/dist/connectors/FoursquareExtractor.js +54 -0
- package/dist/connectors/FoursquareTransformer.d.ts +10 -0
- package/dist/connectors/FoursquareTransformer.js +78 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +7 -0
- package/dist/utils/FoursquareProxy.d.ts +48 -0
- package/dist/utils/FoursquareProxy.js +54 -0
- package/package.json +75 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Andrew Louis
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
# @chronicle.app/foursquare
|
|
2
|
+
|
|
3
|
+
Chronicle plugin that imports your Foursquare/Swarm check-in history.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @chronicle.app/foursquare
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Authentication
|
|
12
|
+
|
|
13
|
+
Check-ins come from the authenticated user (`users/self/checkins`), so the
|
|
14
|
+
plugin needs a user OAuth access token. Register a Foursquare developer app to
|
|
15
|
+
get a client ID/secret, set its redirect URI to `http://127.0.0.1:7463/callback`,
|
|
16
|
+
then run:
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
chronicle auth login foursquare --client-id YOUR_ID --client-secret YOUR_SECRET
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
This stores the access token; the extractor picks it up automatically. You can
|
|
23
|
+
also pass a token directly with `--access-token`.
|
|
24
|
+
|
|
25
|
+
## Usage
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
# Uses the stored token from `auth login`
|
|
29
|
+
chronicle extract foursquare
|
|
30
|
+
|
|
31
|
+
# With a token and date/size filters
|
|
32
|
+
chronicle extract foursquare --strategy api \
|
|
33
|
+
--access-token YOUR_TOKEN \
|
|
34
|
+
--since 2024-01-01 \
|
|
35
|
+
--limit 1000
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Configuration
|
|
39
|
+
|
|
40
|
+
The extractor supports the following options:
|
|
41
|
+
|
|
42
|
+
- `--access-token`: Foursquare user OAuth token (auto-retrieved from stored
|
|
43
|
+
credentials if omitted)
|
|
44
|
+
- `--since`: Only check-ins on or after this date
|
|
45
|
+
- `--limit`: Maximum number of check-ins to extract
|
|
46
|
+
|
|
47
|
+
## Development
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
# Install dependencies
|
|
51
|
+
npm install
|
|
52
|
+
|
|
53
|
+
# Build the plugin
|
|
54
|
+
npm run build -w @chronicle.app/foursquare
|
|
55
|
+
|
|
56
|
+
# Run the tests
|
|
57
|
+
npm test -w @chronicle.app/foursquare
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## API Endpoints
|
|
61
|
+
|
|
62
|
+
- `users/self`: the authenticated user (actor), for the check-in agent
|
|
63
|
+
- `users/self/checkins`: check-in history, paged (50/page) with `afterTimestamp`
|
|
64
|
+
for `--since`
|
|
65
|
+
|
|
66
|
+
## Chronicle schema output
|
|
67
|
+
|
|
68
|
+
Each check-in becomes a `CheckInAction` (keyed on the check-in id, timestamped at
|
|
69
|
+
`createdAt`) whose:
|
|
70
|
+
|
|
71
|
+
- `agent` is an `Agent` keyed on your Foursquare user id, with name, profile
|
|
72
|
+
`url`, and avatar `image`
|
|
73
|
+
- `object` is a `Venue` keyed on the Foursquare venue id, with `category` (the
|
|
74
|
+
venue's Foursquare categories) and a nested keyless `Location` (lat/long +
|
|
75
|
+
formatted address)
|
|
76
|
+
|
|
77
|
+
Because the `Venue` is keyed on `[@type, source: foursquare, sourceId]`, it
|
|
78
|
+
collapses onto the same entity as an Arc Timeline place that carries a `sameAs`
|
|
79
|
+
edge to the same Foursquare venue id.
|
|
80
|
+
|
|
81
|
+
## Tests
|
|
82
|
+
|
|
83
|
+
The tests serve synthetic `users/self` and check-in responses from a local HTTP
|
|
84
|
+
server on 127.0.0.1, pass a fake access token in config, and point Chronicle's
|
|
85
|
+
credential store at an empty temporary directory, so they never call Foursquare
|
|
86
|
+
or read the host's stored credentials or accounts.
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { OAuthProvider } from '@chronicle.app/auth';
|
|
2
|
+
export declare class FoursquareOAuthProvider extends OAuthProvider {
|
|
3
|
+
static providerId: string;
|
|
4
|
+
static authorizationUrl: string;
|
|
5
|
+
static tokenUrl: string;
|
|
6
|
+
static scopes: string[];
|
|
7
|
+
static requiresClientSecret: boolean;
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=FoursquareOAuthProvider.d.ts.map
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { OAuthProvider } from '@chronicle.app/auth';
|
|
2
|
+
export class FoursquareOAuthProvider extends OAuthProvider {
|
|
3
|
+
static providerId = 'foursquare';
|
|
4
|
+
static authorizationUrl = 'https://foursquare.com/oauth2/authenticate';
|
|
5
|
+
static tokenUrl = 'https://foursquare.com/oauth2/access_token';
|
|
6
|
+
static scopes = [];
|
|
7
|
+
static requiresClientSecret = true;
|
|
8
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { Extractor, Record } from '@chronicle.app/etl';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import FoursquareTransformer from './FoursquareTransformer.js';
|
|
4
|
+
export declare class FoursquareExtractor extends Extractor<typeof FoursquareExtractor> {
|
|
5
|
+
static source: string;
|
|
6
|
+
static description: string;
|
|
7
|
+
static delivery: "api";
|
|
8
|
+
static strategy: string;
|
|
9
|
+
static recordTypes: string[];
|
|
10
|
+
static default: boolean;
|
|
11
|
+
static defaultTransformer: typeof FoursquareTransformer;
|
|
12
|
+
static schema: z.ZodObject<{
|
|
13
|
+
since: z.ZodOptional<z.ZodDate>;
|
|
14
|
+
until: z.ZodOptional<z.ZodDate>;
|
|
15
|
+
limit: z.ZodOptional<z.ZodNumber>;
|
|
16
|
+
} & {
|
|
17
|
+
'access-token': z.ZodOptional<z.ZodString>;
|
|
18
|
+
}, "strip", z.ZodTypeAny, {
|
|
19
|
+
limit?: number | undefined;
|
|
20
|
+
'access-token'?: string | undefined;
|
|
21
|
+
since?: Date | undefined;
|
|
22
|
+
until?: Date | undefined;
|
|
23
|
+
}, {
|
|
24
|
+
limit?: number | undefined;
|
|
25
|
+
'access-token'?: string | undefined;
|
|
26
|
+
since?: Date | undefined;
|
|
27
|
+
until?: Date | undefined;
|
|
28
|
+
}>;
|
|
29
|
+
private proxy;
|
|
30
|
+
private actor;
|
|
31
|
+
setup(): Promise<void>;
|
|
32
|
+
extract(): AsyncGenerator<Record>;
|
|
33
|
+
determineCount(): Promise<number | null>;
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=FoursquareExtractor.d.ts.map
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { Extractor } from '@chronicle.app/etl';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import { resolveCredentials } from '@chronicle.app/auth';
|
|
4
|
+
import FoursquareProxy from '../utils/FoursquareProxy.js';
|
|
5
|
+
import FoursquareTransformer from './FoursquareTransformer.js';
|
|
6
|
+
export class FoursquareExtractor extends Extractor {
|
|
7
|
+
static source = 'foursquare';
|
|
8
|
+
static description = 'Check-ins';
|
|
9
|
+
static delivery = 'api';
|
|
10
|
+
static strategy = 'api';
|
|
11
|
+
static recordTypes = ['checkins'];
|
|
12
|
+
static default = true;
|
|
13
|
+
static defaultTransformer = FoursquareTransformer;
|
|
14
|
+
static schema = Extractor.schema.extend({
|
|
15
|
+
'access-token': z
|
|
16
|
+
.string()
|
|
17
|
+
.optional()
|
|
18
|
+
.describe('Foursquare access token (auto-retrieved from stored credentials if not provided)'),
|
|
19
|
+
});
|
|
20
|
+
proxy;
|
|
21
|
+
actor;
|
|
22
|
+
async setup() {
|
|
23
|
+
const config = this.config;
|
|
24
|
+
// Use the token from the flag, else the one stored by `auth login foursquare`.
|
|
25
|
+
const { accessToken } = await resolveCredentials('foursquare', {
|
|
26
|
+
accessToken: { from: ['accessToken'] },
|
|
27
|
+
}, {
|
|
28
|
+
overrides: { accessToken: config['access-token'] },
|
|
29
|
+
errorMessage: 'Foursquare access token is required. Either pass --access-token or authenticate with: chronicle auth login foursquare --client-id YOUR_ID --client-secret YOUR_SECRET',
|
|
30
|
+
});
|
|
31
|
+
this.proxy = new FoursquareProxy(accessToken);
|
|
32
|
+
this.actor = await this.proxy.loadSelf();
|
|
33
|
+
}
|
|
34
|
+
async *extract() {
|
|
35
|
+
const config = this.config;
|
|
36
|
+
try {
|
|
37
|
+
const checkins = await this.proxy.loadCheckins({
|
|
38
|
+
since: config.since,
|
|
39
|
+
limit: config.limit,
|
|
40
|
+
});
|
|
41
|
+
this.logger.info(`Retrieved ${checkins.length} checkins from Foursquare`);
|
|
42
|
+
for (const checkin of checkins) {
|
|
43
|
+
yield this.createRecord(checkin, { actor: this.actor });
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
catch (error) {
|
|
47
|
+
this.logger.error('Error fetching Foursquare checkins');
|
|
48
|
+
throw error;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
async determineCount() {
|
|
52
|
+
return null;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { ChronicleTransformer, Record } from '@chronicle.app/etl';
|
|
2
|
+
import { ActionAndChildren } from '@chronicle.app/schema';
|
|
3
|
+
export default class FoursquareTransformer extends ChronicleTransformer {
|
|
4
|
+
transform(record: Record): Promise<ActionAndChildren[]>;
|
|
5
|
+
private buildCheckinActions;
|
|
6
|
+
private buildVenue;
|
|
7
|
+
private buildLocation;
|
|
8
|
+
private buildUser;
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=FoursquareTransformer.d.ts.map
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { ChronicleTransformer, createImageObject } from '@chronicle.app/etl';
|
|
2
|
+
export default class FoursquareTransformer extends ChronicleTransformer {
|
|
3
|
+
async transform(record) {
|
|
4
|
+
const actions = [];
|
|
5
|
+
if (record.extraction.recordType === 'checkins') {
|
|
6
|
+
actions.push(...this.buildCheckinActions(record));
|
|
7
|
+
}
|
|
8
|
+
return actions;
|
|
9
|
+
}
|
|
10
|
+
buildCheckinActions(record) {
|
|
11
|
+
const actions = [];
|
|
12
|
+
const checkin = record.data;
|
|
13
|
+
const actor = record.context?.actor;
|
|
14
|
+
const user = this.buildUser(actor);
|
|
15
|
+
const venue = this.buildVenue(checkin);
|
|
16
|
+
const action = {
|
|
17
|
+
'@type': 'CheckInAction',
|
|
18
|
+
'@key': ['@type', 'source', 'sourceId'],
|
|
19
|
+
timestamp: new Date(checkin.createdAt * 1000),
|
|
20
|
+
source: 'foursquare',
|
|
21
|
+
sourceId: checkin.id,
|
|
22
|
+
agent: user,
|
|
23
|
+
object: venue,
|
|
24
|
+
};
|
|
25
|
+
actions.push(action);
|
|
26
|
+
return actions;
|
|
27
|
+
}
|
|
28
|
+
// A Foursquare venue is a named point of interest → a Venue. Its
|
|
29
|
+
// coordinates/address are its own keyless Location value (content-interned),
|
|
30
|
+
// not entity properties on the Venue. Keyed [@type, source, sourceId] with
|
|
31
|
+
// source "foursquare", so an Arc place's sameAs edge to this id collapses onto
|
|
32
|
+
// the same entity.
|
|
33
|
+
buildVenue(checkin) {
|
|
34
|
+
const { venue } = checkin;
|
|
35
|
+
const { location } = venue;
|
|
36
|
+
const address = location.formattedAddress ? location.formattedAddress.join(', ') : undefined;
|
|
37
|
+
// Foursquare's category names (the primary one first), e.g. ["Park"].
|
|
38
|
+
const category = [...(venue.categories ?? [])]
|
|
39
|
+
.sort((a, b) => (b.primary ? 1 : 0) - (a.primary ? 1 : 0))
|
|
40
|
+
.map(c => c.name)
|
|
41
|
+
.filter(Boolean);
|
|
42
|
+
return {
|
|
43
|
+
'@type': 'Venue',
|
|
44
|
+
'@key': ['@type', 'source', 'sourceId'],
|
|
45
|
+
source: 'foursquare',
|
|
46
|
+
sourceId: venue.id,
|
|
47
|
+
name: venue.name,
|
|
48
|
+
location: this.buildLocation(location.lat, location.lng, address),
|
|
49
|
+
...(category.length > 0 && { category }),
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
// The geo as a `Location` value — a keyless StructuredValue that shred
|
|
53
|
+
// content-interns into location_values (deduped by payload).
|
|
54
|
+
buildLocation(latitude, longitude, address) {
|
|
55
|
+
return {
|
|
56
|
+
'@type': 'Location',
|
|
57
|
+
latitude,
|
|
58
|
+
longitude,
|
|
59
|
+
...(address && { address }),
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
buildUser(actor) {
|
|
63
|
+
// Foursquare photo URLs are assembled as `${prefix}${size}${suffix}`.
|
|
64
|
+
const avatar = actor.photo?.prefix
|
|
65
|
+
? `${actor.photo.prefix}300x300${actor.photo.suffix}`
|
|
66
|
+
: undefined;
|
|
67
|
+
return {
|
|
68
|
+
'@type': 'Agent',
|
|
69
|
+
'@key': ['@type', 'source', 'sourceId'],
|
|
70
|
+
source: 'foursquare',
|
|
71
|
+
sourceId: actor.id,
|
|
72
|
+
name: `${actor.firstName} ${actor.lastName}`,
|
|
73
|
+
url: actor.canonicalUrl,
|
|
74
|
+
sameAs: ['@me'],
|
|
75
|
+
...(avatar && { emblem: createImageObject({ url: avatar }) }),
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { FoursquareExtractor } from './connectors/FoursquareExtractor.js';
|
|
2
|
+
export { default as FoursquareTransformer } from './connectors/FoursquareTransformer.js';
|
|
3
|
+
export { FoursquareOAuthProvider } from './auth/FoursquareOAuthProvider.js';
|
|
4
|
+
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { FoursquareExtractor } from './connectors/FoursquareExtractor.js';
|
|
2
|
+
export { default as FoursquareTransformer } from './connectors/FoursquareTransformer.js';
|
|
3
|
+
export { FoursquareOAuthProvider } from './auth/FoursquareOAuthProvider.js';
|
|
4
|
+
// Register OAuth provider
|
|
5
|
+
import { OAuthProviderRegistry } from '@chronicle.app/auth';
|
|
6
|
+
import { FoursquareOAuthProvider } from './auth/FoursquareOAuthProvider.js';
|
|
7
|
+
OAuthProviderRegistry.register(FoursquareOAuthProvider);
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { ApiProxy } from '@chronicle.app/etl';
|
|
2
|
+
export interface FoursquareCategory {
|
|
3
|
+
id: string;
|
|
4
|
+
name: string;
|
|
5
|
+
primary?: boolean;
|
|
6
|
+
}
|
|
7
|
+
export interface FoursquareCheckin {
|
|
8
|
+
id: string;
|
|
9
|
+
createdAt: number;
|
|
10
|
+
venue: {
|
|
11
|
+
id: string;
|
|
12
|
+
name: string;
|
|
13
|
+
categories?: FoursquareCategory[];
|
|
14
|
+
location: {
|
|
15
|
+
lat: number;
|
|
16
|
+
lng: number;
|
|
17
|
+
formattedAddress?: string[];
|
|
18
|
+
country?: string;
|
|
19
|
+
city?: string;
|
|
20
|
+
state?: string;
|
|
21
|
+
postalCode?: string;
|
|
22
|
+
address?: string;
|
|
23
|
+
};
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
export interface FoursquareUser {
|
|
27
|
+
id: string;
|
|
28
|
+
firstName: string;
|
|
29
|
+
lastName: string;
|
|
30
|
+
canonicalUrl: string;
|
|
31
|
+
photo: {
|
|
32
|
+
prefix: string;
|
|
33
|
+
suffix: string;
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
export default class FoursquareProxy extends ApiProxy {
|
|
37
|
+
private oauthToken;
|
|
38
|
+
constructor(accessToken: string);
|
|
39
|
+
initialize(): Promise<void>;
|
|
40
|
+
loadCheckins(options?: {
|
|
41
|
+
since?: Date;
|
|
42
|
+
limit?: number;
|
|
43
|
+
}): Promise<FoursquareCheckin[]>;
|
|
44
|
+
loadSelf(): Promise<FoursquareUser>;
|
|
45
|
+
private loadCheckinPage;
|
|
46
|
+
private loadEndpoint;
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=FoursquareProxy.d.ts.map
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { ApiProxy } from '@chronicle.app/etl';
|
|
2
|
+
const API_VERSION = 20_170_310;
|
|
3
|
+
export default class FoursquareProxy extends ApiProxy {
|
|
4
|
+
// Foursquare authenticates with an `oauth_token` query parameter, not a
|
|
5
|
+
// bearer header, so the token lives here and the base's accessToken stays unset.
|
|
6
|
+
oauthToken;
|
|
7
|
+
constructor(accessToken) {
|
|
8
|
+
super({
|
|
9
|
+
baseURL: 'https://api.foursquare.com/v2/',
|
|
10
|
+
headers: {
|
|
11
|
+
'User-Agent': 'Chronicle/1.0',
|
|
12
|
+
'Content-Type': 'application/json',
|
|
13
|
+
},
|
|
14
|
+
});
|
|
15
|
+
this.oauthToken = accessToken;
|
|
16
|
+
}
|
|
17
|
+
async initialize() {
|
|
18
|
+
// The access token is resolved by the extractor's own CredentialManager
|
|
19
|
+
// lookup and handed to the constructor; nothing to load lazily here.
|
|
20
|
+
}
|
|
21
|
+
async loadCheckins(options = {}) {
|
|
22
|
+
return this.paginateOffset({
|
|
23
|
+
pageSize: 50,
|
|
24
|
+
limit: options.limit,
|
|
25
|
+
fetchPage: offset => this.loadCheckinPage({ limit: 50, offset, since: options.since }),
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
async loadSelf() {
|
|
29
|
+
const response = await this.loadEndpoint('users/self');
|
|
30
|
+
return response.response.user;
|
|
31
|
+
}
|
|
32
|
+
async loadCheckinPage(options) {
|
|
33
|
+
const params = {
|
|
34
|
+
limit: options.limit,
|
|
35
|
+
offset: options.offset,
|
|
36
|
+
};
|
|
37
|
+
if (options.since) {
|
|
38
|
+
params.afterTimestamp = Math.floor(options.since.getTime() / 1000);
|
|
39
|
+
}
|
|
40
|
+
const response = await this.loadEndpoint('users/self/checkins', params);
|
|
41
|
+
return response.response.checkins.items;
|
|
42
|
+
}
|
|
43
|
+
async loadEndpoint(endpoint, params = {}) {
|
|
44
|
+
return this.request({
|
|
45
|
+
url: endpoint,
|
|
46
|
+
method: 'GET',
|
|
47
|
+
params: {
|
|
48
|
+
...params,
|
|
49
|
+
oauth_token: this.oauthToken,
|
|
50
|
+
v: API_VERSION,
|
|
51
|
+
},
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@chronicle.app/foursquare",
|
|
3
|
+
"version": "0.3.0",
|
|
4
|
+
"main": "./dist/index.js",
|
|
5
|
+
"types": "./dist/index.d.ts",
|
|
6
|
+
"files": [
|
|
7
|
+
"dist/**/*.js",
|
|
8
|
+
"dist/**/*.d.ts"
|
|
9
|
+
],
|
|
10
|
+
"scripts": {
|
|
11
|
+
"build": "tsc -b tsconfig.lib.json",
|
|
12
|
+
"typecheck": "tsc -p tsconfig.json",
|
|
13
|
+
"lint": "eslint src --ext .ts,.js",
|
|
14
|
+
"test": "node --test src/*.test.js"
|
|
15
|
+
},
|
|
16
|
+
"keywords": [
|
|
17
|
+
"chronicle",
|
|
18
|
+
"foursquare"
|
|
19
|
+
],
|
|
20
|
+
"author": "Andrew Louis",
|
|
21
|
+
"license": "MIT",
|
|
22
|
+
"type": "module",
|
|
23
|
+
"description": "Chronicle plugin for Foursquare check-ins",
|
|
24
|
+
"devDependencies": {
|
|
25
|
+
"@chronicle.app/etl": "0.3.0",
|
|
26
|
+
"@chronicle.app/schema": "0.3.0",
|
|
27
|
+
"@chronicle.app/tsconfig": "0.3.0",
|
|
28
|
+
"@types/node": "^22.10.1",
|
|
29
|
+
"typescript": "^5.7.2"
|
|
30
|
+
},
|
|
31
|
+
"homepage": "https://chronicle.app",
|
|
32
|
+
"repository": {
|
|
33
|
+
"type": "git",
|
|
34
|
+
"url": "https://github.com/chronicle-app/chronicle.git",
|
|
35
|
+
"directory": "plugins/foursquare"
|
|
36
|
+
},
|
|
37
|
+
"publishConfig": {
|
|
38
|
+
"access": "public",
|
|
39
|
+
"registry": "https://registry.npmjs.org/"
|
|
40
|
+
},
|
|
41
|
+
"dependencies": {
|
|
42
|
+
"@chronicle.app/auth": "0.3.0",
|
|
43
|
+
"axios": "^1.7.9",
|
|
44
|
+
"zod": "^3.24.1"
|
|
45
|
+
},
|
|
46
|
+
"peerDependencies": {
|
|
47
|
+
"@chronicle.app/etl": ">=0.1.0 <1.0.0",
|
|
48
|
+
"@chronicle.app/schema": ">=0.1.0 <1.0.0"
|
|
49
|
+
},
|
|
50
|
+
"engines": {
|
|
51
|
+
"node": ">=22.13.0"
|
|
52
|
+
},
|
|
53
|
+
"exports": {
|
|
54
|
+
".": {
|
|
55
|
+
"types": "./dist/index.d.ts",
|
|
56
|
+
"import": "./dist/index.js"
|
|
57
|
+
}
|
|
58
|
+
},
|
|
59
|
+
"chronicle": {
|
|
60
|
+
"plugin": true,
|
|
61
|
+
"sources": {
|
|
62
|
+
"foursquare": {
|
|
63
|
+
"strategies": {
|
|
64
|
+
"api": {
|
|
65
|
+
"delivery": "api",
|
|
66
|
+
"recordTypes": [
|
|
67
|
+
"checkins"
|
|
68
|
+
],
|
|
69
|
+
"default": true
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|