@stacksjs/ts-analytics 0.1.6
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/CHANGELOG.md +68 -0
- package/LICENSE.md +21 -0
- package/README.md +361 -0
- package/bin/cli.ts +169 -0
- package/dist/Analytics.d.ts +558 -0
- package/dist/api.d.ts +109 -0
- package/dist/batching.d.ts +93 -0
- package/dist/chunk-2mx7fq49.js +4 -0
- package/dist/chunk-3z29508k.js +204 -0
- package/dist/chunk-deephkz6.js +56 -0
- package/dist/chunk-j261vgyp.js +305 -0
- package/dist/chunk-xga17tz7.js +207 -0
- package/dist/config.d.ts +132 -0
- package/dist/dashboard/components/index.d.ts +80 -0
- package/dist/dashboard/composables/useAnalytics.d.ts +99 -0
- package/dist/dashboard/index.d.ts +110 -0
- package/dist/dashboard/types/index.d.ts +144 -0
- package/dist/dashboard/utils/index.d.ts +81 -0
- package/dist/dynamodb.d.ts +86 -0
- package/dist/funnels.d.ts +104 -0
- package/dist/geolocation.d.ts +96 -0
- package/dist/index.d.ts +371 -0
- package/dist/index.js +10211 -0
- package/dist/infrastructure/cdk.d.ts +60 -0
- package/dist/infrastructure/cloudformation.d.ts +44 -0
- package/dist/infrastructure/index.d.ts +45 -0
- package/dist/infrastructure/setup.d.ts +133 -0
- package/dist/integrations/cloudflare.d.ts +76 -0
- package/dist/integrations/hono.d.ts +60 -0
- package/dist/integrations/index.d.ts +24 -0
- package/dist/integrations/nuxt.d.ts +7 -0
- package/dist/integrations/nuxt.js +42 -0
- package/dist/integrations/runtime/use-ts-analytics.d.ts +18 -0
- package/dist/integrations/runtime/use-ts-analytics.js +17 -0
- package/dist/integrations/stx.d.ts +88 -0
- package/dist/integrations/stx.js +18 -0
- package/dist/lib/crypto-random.d.ts +4 -0
- package/dist/lib/salt.d.ts +16 -0
- package/dist/local.d.ts +56 -0
- package/dist/model-connector.d.ts +145 -0
- package/dist/models/AggregatedStats.d.ts +9 -0
- package/dist/models/CampaignStats.d.ts +9 -0
- package/dist/models/Conversion.d.ts +11 -0
- package/dist/models/CustomEvent.d.ts +11 -0
- package/dist/models/DeviceStats.d.ts +9 -0
- package/dist/models/EventStats.d.ts +9 -0
- package/dist/models/GeoStats.d.ts +9 -0
- package/dist/models/Goal.d.ts +9 -0
- package/dist/models/GoalStats.d.ts +9 -0
- package/dist/models/PageStats.d.ts +11 -0
- package/dist/models/PageView.d.ts +13 -0
- package/dist/models/RealtimeStats.d.ts +9 -0
- package/dist/models/ReferrerStats.d.ts +9 -0
- package/dist/models/Session.d.ts +11 -0
- package/dist/models/Site.d.ts +11 -0
- package/dist/models/index.d.ts +28 -0
- package/dist/models/types.d.ts +60 -0
- package/dist/sqs-buffering.d.ts +243 -0
- package/dist/stacks-integration.d.ts +159 -0
- package/dist/tracking-script.d.ts +71 -0
- package/dist/tracking.d.ts +17 -0
- package/dist/tracking.js +26 -0
- package/dist/types.d.ts +595 -0
- package/dist/utils/geolocation.d.ts +111 -0
- package/dist/utils/user-agent.d.ts +17 -0
- package/dist/version.d.ts +7 -0
- package/package.json +119 -0
- package/src/Analytics.ts +3349 -0
- package/src/api.ts +1286 -0
- package/src/assets/crosswind.css +2220 -0
- package/src/batching.ts +452 -0
- package/src/components/dashboard/index.ts +18 -0
- package/src/config.ts +456 -0
- package/src/dashboard/Dashboard.stx +1517 -0
- package/src/dashboard/components/AlertCard.stx +177 -0
- package/src/dashboard/components/AnalyticsDashboard.stx +354 -0
- package/src/dashboard/components/AnimatedNumber.stx +86 -0
- package/src/dashboard/components/BarChart.stx +220 -0
- package/src/dashboard/components/BrowserBreakdown.stx +98 -0
- package/src/dashboard/components/BrowsersTable.stx +125 -0
- package/src/dashboard/components/CampaignBreakdown.stx +163 -0
- package/src/dashboard/components/CampaignTable.stx +238 -0
- package/src/dashboard/components/CountryList.stx +101 -0
- package/src/dashboard/components/DataTable.stx +226 -0
- package/src/dashboard/components/DateRangePicker.stx +77 -0
- package/src/dashboard/components/DeviceBreakdown.stx +94 -0
- package/src/dashboard/components/DevicesTable.stx +163 -0
- package/src/dashboard/components/DonutChart.stories.ts +55 -0
- package/src/dashboard/components/DonutChart.stx +157 -0
- package/src/dashboard/components/EmptyState.stx +90 -0
- package/src/dashboard/components/EngagementMetrics.stx +183 -0
- package/src/dashboard/components/EventsSection.stx +192 -0
- package/src/dashboard/components/FilterBar.stx +104 -0
- package/src/dashboard/components/FullAnalyticsDashboard.stx +455 -0
- package/src/dashboard/components/FunnelChart.stx +142 -0
- package/src/dashboard/components/GeoTable.stx +337 -0
- package/src/dashboard/components/GoalsPanel.stx +109 -0
- package/src/dashboard/components/Header.stx +39 -0
- package/src/dashboard/components/HeatmapChart.stx +140 -0
- package/src/dashboard/components/LiveActivityFeed.stx +172 -0
- package/src/dashboard/components/MetricComparison.stx +106 -0
- package/src/dashboard/components/MiniStats.stx +96 -0
- package/src/dashboard/components/OSBreakdown.stx +124 -0
- package/src/dashboard/components/PageDetailCard.stx +102 -0
- package/src/dashboard/components/PagesTable.stx +127 -0
- package/src/dashboard/components/ProgressRing.stx +89 -0
- package/src/dashboard/components/RealtimeCounter.stories.ts +45 -0
- package/src/dashboard/components/RealtimeCounter.stx +46 -0
- package/src/dashboard/components/ReferrersTable.stx +180 -0
- package/src/dashboard/components/SparklineChart.stx +160 -0
- package/src/dashboard/components/StatCard.stories.ts +58 -0
- package/src/dashboard/components/StatCard.stx +90 -0
- package/src/dashboard/components/SummaryStats.stx +81 -0
- package/src/dashboard/components/TabNav.stx +66 -0
- package/src/dashboard/components/ThemeSwitcher.stx +124 -0
- package/src/dashboard/components/TimeSeriesChart.stx +106 -0
- package/src/dashboard/components/TopList.stories.ts +58 -0
- package/src/dashboard/components/TopList.stx +74 -0
- package/src/dashboard/components/TrendIndicator.stx +84 -0
- package/src/dashboard/components/heatmap/ClickHeatmap.stx +264 -0
- package/src/dashboard/components/heatmap/ElementClickList.stx +125 -0
- package/src/dashboard/components/heatmap/HeatmapControls.stx +125 -0
- package/src/dashboard/components/heatmap/HeatmapLegend.stx +69 -0
- package/src/dashboard/components/heatmap/PageHeatmap.stx +264 -0
- package/src/dashboard/components/heatmap/ScrollHeatmap.stx +127 -0
- package/src/dashboard/components/heatmap/index.ts +12 -0
- package/src/dashboard/components/index.ts +86 -0
- package/src/dashboard/composables/useAnalytics.ts +465 -0
- package/src/dashboard/demo/DemoApp.stx +370 -0
- package/src/dashboard/demo/index.ts +8 -0
- package/src/dashboard/demo/mockData.ts +234 -0
- package/src/dashboard/index.ts +117 -0
- package/src/dashboard/stx-shim.d.ts +4 -0
- package/src/dashboard/types/index.ts +203 -0
- package/src/dashboard/utils/index.ts +426 -0
- package/src/dynamodb.ts +344 -0
- package/src/funnels.ts +534 -0
- package/src/geolocation.ts +515 -0
- package/src/handlers/alerts.ts +328 -0
- package/src/handlers/annotations.ts +128 -0
- package/src/handlers/api-keys.ts +240 -0
- package/src/handlers/auth.ts +1020 -0
- package/src/handlers/authz.ts +137 -0
- package/src/handlers/collect.ts +724 -0
- package/src/handlers/data.ts +625 -0
- package/src/handlers/experiments.ts +138 -0
- package/src/handlers/funnels.ts +216 -0
- package/src/handlers/goals.ts +218 -0
- package/src/handlers/heatmaps.ts +272 -0
- package/src/handlers/index.ts +56 -0
- package/src/handlers/lib/read-cache.ts +63 -0
- package/src/handlers/misc.ts +486 -0
- package/src/handlers/oauth.ts +233 -0
- package/src/handlers/performance.ts +388 -0
- package/src/handlers/sessions.ts +413 -0
- package/src/handlers/sharing.ts +198 -0
- package/src/handlers/stats.ts +1368 -0
- package/src/handlers/team.ts +161 -0
- package/src/handlers/uptime.ts +283 -0
- package/src/handlers/views.ts +390 -0
- package/src/handlers/webhooks.ts +226 -0
- package/src/heatmap/index.ts +32 -0
- package/src/heatmap/tracking-script.ts +452 -0
- package/src/heatmap/types.ts +79 -0
- package/src/index.ts +387 -0
- package/src/infrastructure/cdk.ts +496 -0
- package/src/infrastructure/cloudformation.ts +595 -0
- package/src/infrastructure/index.ts +48 -0
- package/src/infrastructure/setup.ts +611 -0
- package/src/integrations/cloudflare.ts +732 -0
- package/src/integrations/hono.ts +589 -0
- package/src/integrations/index.ts +27 -0
- package/src/integrations/nuxt.ts +78 -0
- package/src/integrations/runtime/use-ts-analytics.ts +32 -0
- package/src/integrations/stx.ts +138 -0
- package/src/jobs/index.ts +127 -0
- package/src/lib/crypto-random.ts +41 -0
- package/src/lib/ddb-errors.ts +20 -0
- package/src/lib/dynamodb.ts +216 -0
- package/src/lib/email.ts +38 -0
- package/src/lib/ga-import.ts +471 -0
- package/src/lib/ga4-api.ts +244 -0
- package/src/lib/goals.ts +205 -0
- package/src/lib/index.ts +6 -0
- package/src/lib/ingest-counters.ts +123 -0
- package/src/lib/log.ts +36 -0
- package/src/lib/membership.ts +98 -0
- package/src/lib/plans.ts +90 -0
- package/src/lib/quota.ts +46 -0
- package/src/lib/rate-limit.ts +27 -0
- package/src/lib/rollups.ts +472 -0
- package/src/lib/salt.ts +97 -0
- package/src/lib/scheduler.ts +97 -0
- package/src/lib/significance.ts +66 -0
- package/src/lib/site-retention.ts +56 -0
- package/src/local.ts +360 -0
- package/src/model-connector.ts +616 -0
- package/src/models/AggregatedStats.ts +162 -0
- package/src/models/CampaignStats.ts +141 -0
- package/src/models/Conversion.ts +135 -0
- package/src/models/CustomEvent.ts +123 -0
- package/src/models/DeviceStats.ts +105 -0
- package/src/models/EventStats.ts +108 -0
- package/src/models/GeoStats.ts +112 -0
- package/src/models/Goal.ts +105 -0
- package/src/models/GoalStats.ts +106 -0
- package/src/models/PageStats.ts +152 -0
- package/src/models/PageView.ts +277 -0
- package/src/models/RealtimeStats.ts +96 -0
- package/src/models/ReferrerStats.ts +115 -0
- package/src/models/Session.ts +235 -0
- package/src/models/Site.ts +115 -0
- package/src/models/index.ts +50 -0
- package/src/models/orm/index.ts +2043 -0
- package/src/models/types.ts +71 -0
- package/src/router.ts +521 -0
- package/src/sqs-buffering.ts +806 -0
- package/src/stacks-integration.ts +527 -0
- package/src/tracking-script.ts +944 -0
- package/src/tracking.ts +27 -0
- package/src/types/analytics.ts +219 -0
- package/src/types/api.ts +75 -0
- package/src/types/bun-router.d.ts +15 -0
- package/src/types/dashboard.ts +62 -0
- package/src/types/index.ts +66 -0
- package/src/types/stx.d.ts +27 -0
- package/src/types/window.d.ts +101 -0
- package/src/types.ts +911 -0
- package/src/utils/cache.ts +148 -0
- package/src/utils/date.ts +118 -0
- package/src/utils/filters.ts +71 -0
- package/src/utils/geolocation.ts +323 -0
- package/src/utils/index.ts +9 -0
- package/src/utils/response.ts +180 -0
- package/src/utils/timezone-country.ts +242 -0
- package/src/utils/user-agent.ts +110 -0
- package/src/version.ts +7 -0
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generate CDK TypeScript code for analytics infrastructure
|
|
3
|
+
*/
|
|
4
|
+
export declare function generateCdkCode(props?: AnalyticsApiProps): string;
|
|
5
|
+
/**
|
|
6
|
+
* Generate minimal CDK code for just the table (no API)
|
|
7
|
+
*/
|
|
8
|
+
export declare function generateCdkTableCode(props?: AnalyticsTableProps): string;
|
|
9
|
+
/**
|
|
10
|
+
* Generate CreateTableInput for AWS SDK
|
|
11
|
+
*/
|
|
12
|
+
export declare function generateCreateTableInput(props?: AnalyticsTableProps): Record<string, unknown>;
|
|
13
|
+
/**
|
|
14
|
+
* AWS CDK Construct for Analytics DynamoDB Table
|
|
15
|
+
*
|
|
16
|
+
* This module provides CDK constructs for deploying the analytics
|
|
17
|
+
* infrastructure to AWS.
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* ```typescript
|
|
21
|
+
* import { AnalyticsTable } from 'dynamodb-tooling/analytics/infrastructure/cdk'
|
|
22
|
+
*
|
|
23
|
+
* const analytics = new AnalyticsTable(this, 'Analytics', {
|
|
24
|
+
* tableName: 'my-analytics',
|
|
25
|
+
* billingMode: BillingMode.PAY_PER_REQUEST,
|
|
26
|
+
* })
|
|
27
|
+
*
|
|
28
|
+
* // Access the table
|
|
29
|
+
* analytics.table.grantReadWriteData(myLambda)
|
|
30
|
+
* ```
|
|
31
|
+
*
|
|
32
|
+
* Note: This module exports construct props and a helper function
|
|
33
|
+
* to generate the CDK code since we can't import CDK directly
|
|
34
|
+
* (it's a peer dependency).
|
|
35
|
+
*/
|
|
36
|
+
// ============================================================================
|
|
37
|
+
// CDK Props Types
|
|
38
|
+
// ============================================================================
|
|
39
|
+
export declare interface AnalyticsTableProps {
|
|
40
|
+
tableName?: string
|
|
41
|
+
billingMode?: 'PAY_PER_REQUEST' | 'PROVISIONED'
|
|
42
|
+
readCapacity?: number
|
|
43
|
+
writeCapacity?: number
|
|
44
|
+
pointInTimeRecovery?: boolean
|
|
45
|
+
stream?: 'KEYS_ONLY' | 'NEW_IMAGE' | 'OLD_IMAGE' | 'NEW_AND_OLD_IMAGES'
|
|
46
|
+
timeToLiveAttribute?: string
|
|
47
|
+
removalPolicy?: 'DESTROY' | 'RETAIN' | 'SNAPSHOT'
|
|
48
|
+
encryption?: 'AWS_MANAGED' | 'CUSTOMER_MANAGED' | 'DEFAULT'
|
|
49
|
+
encryptionKey?: string
|
|
50
|
+
deletionProtection?: boolean
|
|
51
|
+
tags?: Record<string, string>
|
|
52
|
+
}
|
|
53
|
+
export declare interface AnalyticsApiProps extends AnalyticsTableProps {
|
|
54
|
+
stageName?: string
|
|
55
|
+
corsOrigins?: string[]
|
|
56
|
+
memorySize?: number
|
|
57
|
+
timeout?: number
|
|
58
|
+
codePath?: string
|
|
59
|
+
enableAggregation?: boolean
|
|
60
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generate CloudFormation template for analytics table
|
|
3
|
+
*/
|
|
4
|
+
export declare function generateCloudFormationTemplate(userConfig?: CloudFormationConfig): Record<string, unknown>;
|
|
5
|
+
/**
|
|
6
|
+
* Generate CloudFormation template as JSON string
|
|
7
|
+
*/
|
|
8
|
+
export declare function generateCloudFormationJson(config?: CloudFormationConfig, pretty?: boolean): string;
|
|
9
|
+
/**
|
|
10
|
+
* Generate CloudFormation template as YAML string
|
|
11
|
+
*/
|
|
12
|
+
export declare function generateCloudFormationYaml(config?: CloudFormationConfig): string;
|
|
13
|
+
/**
|
|
14
|
+
* Generate SAM (Serverless Application Model) template
|
|
15
|
+
* Includes Lambda functions for API endpoints
|
|
16
|
+
*/
|
|
17
|
+
export declare function generateSamTemplate(config?: CloudFormationConfig): Record<string, unknown>;
|
|
18
|
+
/**
|
|
19
|
+
* Generate SAM template as YAML string
|
|
20
|
+
*/
|
|
21
|
+
export declare function generateSamYaml(config?: CloudFormationConfig): string;
|
|
22
|
+
/**
|
|
23
|
+
* CloudFormation Template Generator for Analytics DynamoDB Table
|
|
24
|
+
*
|
|
25
|
+
* Generates CloudFormation JSON/YAML for deploying the analytics
|
|
26
|
+
* single-table design to AWS.
|
|
27
|
+
*/
|
|
28
|
+
export declare interface CloudFormationConfig {
|
|
29
|
+
stackName?: string
|
|
30
|
+
tableName?: string
|
|
31
|
+
billingMode?: 'PAY_PER_REQUEST' | 'PROVISIONED'
|
|
32
|
+
provisionedCapacity?: {
|
|
33
|
+
readCapacityUnits: number
|
|
34
|
+
writeCapacityUnits: number
|
|
35
|
+
}
|
|
36
|
+
enablePitr?: boolean
|
|
37
|
+
enableStreams?: boolean
|
|
38
|
+
streamViewType?: 'KEYS_ONLY' | 'NEW_IMAGE' | 'OLD_IMAGE' | 'NEW_AND_OLD_IMAGES'
|
|
39
|
+
ttlAttributeName?: string
|
|
40
|
+
enableEncryption?: boolean
|
|
41
|
+
kmsKeyArn?: string
|
|
42
|
+
tags?: Record<string, string>
|
|
43
|
+
deletionProtection?: boolean
|
|
44
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Analytics Infrastructure Module
|
|
3
|
+
*
|
|
4
|
+
* Provides tools for deploying the analytics DynamoDB table:
|
|
5
|
+
* - CloudFormation templates (JSON/YAML)
|
|
6
|
+
* - SAM templates for serverless deployment
|
|
7
|
+
* - CDK code generation
|
|
8
|
+
* - AWS SDK CreateTable input
|
|
9
|
+
* - Migration utilities
|
|
10
|
+
* - Setup scripts
|
|
11
|
+
*/
|
|
12
|
+
// CDK
|
|
13
|
+
export {
|
|
14
|
+
type AnalyticsApiProps,
|
|
15
|
+
type AnalyticsTableProps,
|
|
16
|
+
generateCdkCode,
|
|
17
|
+
generateCdkTableCode,
|
|
18
|
+
generateCreateTableInput,
|
|
19
|
+
} from './cdk';
|
|
20
|
+
// CloudFormation
|
|
21
|
+
export {
|
|
22
|
+
type CloudFormationConfig,
|
|
23
|
+
generateCloudFormationJson,
|
|
24
|
+
generateCloudFormationTemplate,
|
|
25
|
+
generateCloudFormationYaml,
|
|
26
|
+
generateSamTemplate,
|
|
27
|
+
generateSamYaml,
|
|
28
|
+
} from './cloudformation';
|
|
29
|
+
// Setup & Migrations
|
|
30
|
+
export {
|
|
31
|
+
checkTableStatus,
|
|
32
|
+
createAnalyticsTable,
|
|
33
|
+
createPitrMigration,
|
|
34
|
+
createStreamsMigration,
|
|
35
|
+
createTimeBasedGsiMigration,
|
|
36
|
+
type DynamoDBClientLike,
|
|
37
|
+
enableTtl,
|
|
38
|
+
generateAwsCliCommands,
|
|
39
|
+
type MigrationResult,
|
|
40
|
+
type MigrationStep,
|
|
41
|
+
printSetupInstructions,
|
|
42
|
+
runMigrations,
|
|
43
|
+
type SetupConfig,
|
|
44
|
+
type SetupResult,
|
|
45
|
+
} from './setup';
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import type { AnalyticsTableProps } from './cdk';
|
|
2
|
+
/**
|
|
3
|
+
* Create the analytics table
|
|
4
|
+
*
|
|
5
|
+
* @example
|
|
6
|
+
* ```typescript
|
|
7
|
+
* import { DynamoDBClient, CreateTableCommand } from '@aws-sdk/client-dynamodb'
|
|
8
|
+
* import { createAnalyticsTable } from 'dynamodb-tooling/analytics/infrastructure'
|
|
9
|
+
*
|
|
10
|
+
* const client = new DynamoDBClient({ region: 'us-east-1' })
|
|
11
|
+
*
|
|
12
|
+
* const result = await createAnalyticsTable(client, {
|
|
13
|
+
* tableName: 'my-analytics',
|
|
14
|
+
* billingMode: 'PAY_PER_REQUEST',
|
|
15
|
+
* })
|
|
16
|
+
*
|
|
17
|
+
* console.log(`Created table: ${result.tableName}`)
|
|
18
|
+
* ```
|
|
19
|
+
*/
|
|
20
|
+
export declare function createAnalyticsTable(client: DynamoDBClientLike, config?: SetupConfig | undefined, commandFactories: {
|
|
21
|
+
CreateTableCommand: new (input: Record<string, unknown>) => unknown
|
|
22
|
+
DescribeTableCommand: new (input: { TableName: string }) => unknown
|
|
23
|
+
}): Promise<SetupResult>;
|
|
24
|
+
/**
|
|
25
|
+
* Enable TTL on the analytics table
|
|
26
|
+
*/
|
|
27
|
+
export declare function enableTtl(client: DynamoDBClientLike, tableName: string, attributeName: string, commandFactory: {
|
|
28
|
+
UpdateTimeToLiveCommand: new (input: {
|
|
29
|
+
TableName: string
|
|
30
|
+
TimeToLiveSpecification: { AttributeName: string, Enabled: boolean }
|
|
31
|
+
}) => unknown
|
|
32
|
+
}): Promise<SetupResult>;
|
|
33
|
+
/**
|
|
34
|
+
* Check if table exists and is active
|
|
35
|
+
*/
|
|
36
|
+
// eslint-disable-next-line pickier/no-unused-vars
|
|
37
|
+
export declare function checkTableStatus(client: DynamoDBClientLike, tableName: string, commandFactory: {
|
|
38
|
+
DescribeTableCommand: new (input: { TableName: string }) => unknown
|
|
39
|
+
}): Promise<{
|
|
40
|
+
exists: boolean
|
|
41
|
+
status?: string
|
|
42
|
+
itemCount?: number
|
|
43
|
+
sizeBytes?: number
|
|
44
|
+
gsiCount?: number
|
|
45
|
+
}>;
|
|
46
|
+
/**
|
|
47
|
+
* Run analytics migrations
|
|
48
|
+
*/
|
|
49
|
+
export declare function runMigrations(client: DynamoDBClientLike, _tableName: string, migrations: MigrationStep[]): Promise<MigrationResult>;
|
|
50
|
+
/**
|
|
51
|
+
* Migration: Add GSI for time-based queries
|
|
52
|
+
*/
|
|
53
|
+
export declare function createTimeBasedGsiMigration(tableName: string, commandFactory: {
|
|
54
|
+
UpdateTableCommand: new (input: Record<string, unknown>) => unknown
|
|
55
|
+
}): MigrationStep;
|
|
56
|
+
/**
|
|
57
|
+
* Migration: Enable Point-in-Time Recovery
|
|
58
|
+
*/
|
|
59
|
+
export declare function createPitrMigration(tableName: string, commandFactory: {
|
|
60
|
+
UpdateContinuousBackupsCommand: new (input: Record<string, unknown>) => unknown
|
|
61
|
+
}): MigrationStep;
|
|
62
|
+
/**
|
|
63
|
+
* Migration: Enable DynamoDB Streams
|
|
64
|
+
*/
|
|
65
|
+
export declare function createStreamsMigration(tableName: string, viewType: 'KEYS_ONLY' | 'NEW_IMAGE' | 'OLD_IMAGE' | 'NEW_AND_OLD_IMAGES', commandFactory: {
|
|
66
|
+
UpdateTableCommand: new (input: Record<string, unknown>) => unknown
|
|
67
|
+
}): MigrationStep;
|
|
68
|
+
/**
|
|
69
|
+
* Print setup instructions for manual deployment
|
|
70
|
+
*/
|
|
71
|
+
export declare function printSetupInstructions(config?: SetupConfig): void;
|
|
72
|
+
/**
|
|
73
|
+
* Generate AWS CLI commands for table creation
|
|
74
|
+
*/
|
|
75
|
+
export declare function generateAwsCliCommands(config?: SetupConfig): string;
|
|
76
|
+
// ============================================================================
|
|
77
|
+
// Types
|
|
78
|
+
// ============================================================================
|
|
79
|
+
export declare interface SetupConfig extends AnalyticsTableProps {
|
|
80
|
+
region?: string
|
|
81
|
+
endpoint?: string
|
|
82
|
+
waitForActive?: boolean
|
|
83
|
+
waitTimeout?: number
|
|
84
|
+
}
|
|
85
|
+
export declare interface SetupResult {
|
|
86
|
+
success: boolean
|
|
87
|
+
tableName: string
|
|
88
|
+
tableArn?: string
|
|
89
|
+
error?: string
|
|
90
|
+
}
|
|
91
|
+
export declare interface MigrationStep {
|
|
92
|
+
name: string
|
|
93
|
+
description: string
|
|
94
|
+
execute: (client: DynamoDBClientLike) => Promise<void>
|
|
95
|
+
rollback?: (client: DynamoDBClientLike) => Promise<void>
|
|
96
|
+
}
|
|
97
|
+
export declare interface MigrationResult {
|
|
98
|
+
success: boolean
|
|
99
|
+
stepsCompleted: string[]
|
|
100
|
+
error?: string
|
|
101
|
+
failedStep?: string
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Minimal DynamoDB client interface
|
|
105
|
+
* Allows using either AWS SDK v2 or v3
|
|
106
|
+
*/
|
|
107
|
+
export declare interface DynamoDBClientLike {
|
|
108
|
+
send: (command: unknown) => Promise<unknown>
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* CreateTable command interface
|
|
112
|
+
*/
|
|
113
|
+
export declare interface CreateTableCommandLike {
|
|
114
|
+
input: Record<string, unknown>
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* DescribeTable command interface
|
|
118
|
+
*/
|
|
119
|
+
export declare interface DescribeTableCommandLike {
|
|
120
|
+
input: { TableName: string }
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* UpdateTimeToLive command interface
|
|
124
|
+
*/
|
|
125
|
+
export declare interface UpdateTimeToLiveCommandLike {
|
|
126
|
+
input: {
|
|
127
|
+
TableName: string
|
|
128
|
+
TimeToLiveSpecification: {
|
|
129
|
+
AttributeName: string
|
|
130
|
+
Enabled: boolean
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Create a Cloudflare Workers fetch handler for analytics
|
|
3
|
+
*/
|
|
4
|
+
export declare function createAnalyticsHandler(options?: CloudflareHandlerOptions): (
|
|
5
|
+
request: Request,
|
|
6
|
+
env: CloudflareEnv,
|
|
7
|
+
ctx: ExecutionContext,
|
|
8
|
+
) => Promise<Response>;
|
|
9
|
+
/**
|
|
10
|
+
* Create a D1 storage adapter for SQLite-based storage
|
|
11
|
+
*/
|
|
12
|
+
export declare function createD1Adapter(db: D1Database): StorageAdapter;
|
|
13
|
+
// ============================================================================
|
|
14
|
+
// Types
|
|
15
|
+
// ============================================================================
|
|
16
|
+
export declare interface CloudflareEnv {
|
|
17
|
+
DYNAMODB_ENDPOINT?: string
|
|
18
|
+
AWS_REGION?: string
|
|
19
|
+
AWS_ACCESS_KEY_ID?: string
|
|
20
|
+
AWS_SECRET_ACCESS_KEY?: string
|
|
21
|
+
SESSIONS_KV?: KVNamespace
|
|
22
|
+
D1_DATABASE?: D1Database
|
|
23
|
+
TABLE_NAME?: string
|
|
24
|
+
}
|
|
25
|
+
declare interface KVNamespace {
|
|
26
|
+
get: (key: string, options?: { type?: string }) => Promise<string | null>
|
|
27
|
+
put: (key: string, value: string, options?: { expirationTtl?: number }) => Promise<void>
|
|
28
|
+
delete: (key: string) => Promise<void>
|
|
29
|
+
}
|
|
30
|
+
declare interface D1Database {
|
|
31
|
+
prepare: (sql: string) => D1PreparedStatement
|
|
32
|
+
exec: (sql: string) => Promise<D1ExecResult>
|
|
33
|
+
batch: <T>(statements: D1PreparedStatement[]) => Promise<D1Result<T>[]>
|
|
34
|
+
}
|
|
35
|
+
declare interface D1PreparedStatement {
|
|
36
|
+
bind: (...values: unknown[]) => D1PreparedStatement
|
|
37
|
+
first: <T>() => Promise<T | null>
|
|
38
|
+
all: <T>() => Promise<D1Result<T>>
|
|
39
|
+
run: () => Promise<D1Result<unknown>>
|
|
40
|
+
}
|
|
41
|
+
declare interface D1Result<T> {
|
|
42
|
+
results?: T[]
|
|
43
|
+
success: boolean
|
|
44
|
+
meta?: Record<string, unknown>
|
|
45
|
+
}
|
|
46
|
+
declare interface D1ExecResult {
|
|
47
|
+
count: number
|
|
48
|
+
duration: number
|
|
49
|
+
}
|
|
50
|
+
export declare interface CloudflareHandlerOptions {
|
|
51
|
+
corsOrigins?: string[]
|
|
52
|
+
basePath?: string
|
|
53
|
+
sessionTtl?: number
|
|
54
|
+
storage?: StorageAdapter
|
|
55
|
+
}
|
|
56
|
+
export declare interface StorageAdapter {
|
|
57
|
+
putItem: (tableName: string, item: Record<string, unknown>) => Promise<void>
|
|
58
|
+
query: (tableName: string, params: QueryParams) => Promise<QueryResult>
|
|
59
|
+
}
|
|
60
|
+
declare interface QueryParams {
|
|
61
|
+
pk: string
|
|
62
|
+
skPrefix?: string
|
|
63
|
+
skStart?: string
|
|
64
|
+
skEnd?: string
|
|
65
|
+
indexName?: string
|
|
66
|
+
limit?: number
|
|
67
|
+
}
|
|
68
|
+
declare interface QueryResult {
|
|
69
|
+
items: Record<string, unknown>[]
|
|
70
|
+
lastKey?: string
|
|
71
|
+
}
|
|
72
|
+
// Cloudflare Workers types
|
|
73
|
+
declare interface ExecutionContext {
|
|
74
|
+
waitUntil: (promise: Promise<unknown>) => void
|
|
75
|
+
passThroughOnException: () => void
|
|
76
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Create analytics middleware for Hono
|
|
3
|
+
*
|
|
4
|
+
* Adds analytics context to requests and handles CORS.
|
|
5
|
+
*/
|
|
6
|
+
export declare function analyticsMiddleware(options?: Partial<AnalyticsMiddlewareOptions>): HonoMiddleware;
|
|
7
|
+
/**
|
|
8
|
+
* Create analytics routes for Hono
|
|
9
|
+
*/
|
|
10
|
+
export declare function createAnalyticsRoutes(options: AnalyticsMiddlewareOptions): {
|
|
11
|
+
collect: (c: HonoContext) => Promise<Response>
|
|
12
|
+
stats: (c: HonoContext) => Promise<Response>
|
|
13
|
+
realtime: (c: HonoContext) => Promise<Response>
|
|
14
|
+
script: (c: HonoContext) => Response
|
|
15
|
+
sites: (c: HonoContext) => Promise<Response>
|
|
16
|
+
createSite: (c: HonoContext) => Promise<Response>
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* Mount analytics routes on a Hono app
|
|
20
|
+
*/
|
|
21
|
+
export declare function mountAnalyticsRoutes(app: HonoApp, basePath: string, options: AnalyticsMiddlewareOptions): void;
|
|
22
|
+
// ============================================================================
|
|
23
|
+
// Types
|
|
24
|
+
// ============================================================================
|
|
25
|
+
declare interface HonoContext {
|
|
26
|
+
req: {
|
|
27
|
+
url: string
|
|
28
|
+
method: string
|
|
29
|
+
header: (name: string) => string | undefined
|
|
30
|
+
param: (name: string) => string | undefined
|
|
31
|
+
query: (name: string) => string | undefined
|
|
32
|
+
json: <T>() => Promise<T>
|
|
33
|
+
}
|
|
34
|
+
json: (data: unknown, status?: number) => Response
|
|
35
|
+
text: (data: string, status?: number) => Response
|
|
36
|
+
body: (data: unknown, status?: number) => Response
|
|
37
|
+
set: (name: string, value: unknown) => void
|
|
38
|
+
get: (name: string) => unknown
|
|
39
|
+
}
|
|
40
|
+
declare interface HonoApp {
|
|
41
|
+
use: (path: string, ...handlers: HonoMiddleware[]) => void
|
|
42
|
+
get: (path: string, handler: (c: HonoContext) => Promise<Response> | Response) => void
|
|
43
|
+
post: (path: string, handler: (c: HonoContext) => Promise<Response> | Response) => void
|
|
44
|
+
options: (path: string, handler: (c: HonoContext) => Promise<Response> | Response) => void
|
|
45
|
+
}
|
|
46
|
+
export declare interface AnalyticsMiddlewareOptions {
|
|
47
|
+
skipPaths?: string[]
|
|
48
|
+
getVisitorId?: (c: HonoContext) => Promise<string>
|
|
49
|
+
sessionStore?: SessionStore
|
|
50
|
+
executeCommand: (cmd: DynamoCommand) => Promise<unknown>
|
|
51
|
+
}
|
|
52
|
+
declare interface SessionStore {
|
|
53
|
+
get: (key: string) => Promise<Session | null>
|
|
54
|
+
set: (key: string, session: Session, ttlSeconds?: number) => Promise<void>
|
|
55
|
+
}
|
|
56
|
+
declare interface DynamoCommand {
|
|
57
|
+
command: string
|
|
58
|
+
input: Record<string, unknown>
|
|
59
|
+
}
|
|
60
|
+
declare type HonoMiddleware = (c: HonoContext, next: () => Promise<void>) => Promise<Response | void>;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Framework Integrations
|
|
3
|
+
*
|
|
4
|
+
* Pre-built integrations for popular frameworks.
|
|
5
|
+
*/
|
|
6
|
+
export {
|
|
7
|
+
analyticsMiddleware,
|
|
8
|
+
createAnalyticsRoutes,
|
|
9
|
+
mountAnalyticsRoutes,
|
|
10
|
+
type AnalyticsMiddlewareOptions,
|
|
11
|
+
} from './hono';
|
|
12
|
+
export {
|
|
13
|
+
createAnalyticsHandler,
|
|
14
|
+
createD1Adapter,
|
|
15
|
+
type CloudflareEnv,
|
|
16
|
+
type CloudflareHandlerOptions,
|
|
17
|
+
type StorageAdapter,
|
|
18
|
+
} from './cloudflare';
|
|
19
|
+
export {
|
|
20
|
+
type StxHeadScript,
|
|
21
|
+
tsAnalytics,
|
|
22
|
+
type TsAnalyticsOptions,
|
|
23
|
+
tsAnalyticsTag,
|
|
24
|
+
} from './stx';
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { NuxtModule } from '@nuxt/schema'
|
|
2
|
+
import { type TsAnalyticsOptions } from './stx';
|
|
3
|
+
declare const tsAnalyticsNuxtModule: NuxtModule<TsAnalyticsNuxtOptions>;
|
|
4
|
+
export declare interface TsAnalyticsNuxtOptions extends TsAnalyticsOptions {
|
|
5
|
+
enabled?: boolean
|
|
6
|
+
}
|
|
7
|
+
export default tsAnalyticsNuxtModule;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
import {
|
|
3
|
+
resolveApiEndpoint,
|
|
4
|
+
tsAnalytics
|
|
5
|
+
} from "../chunk-deephkz6.js";
|
|
6
|
+
import"../chunk-2mx7fq49.js";
|
|
7
|
+
|
|
8
|
+
// src/integrations/nuxt.ts
|
|
9
|
+
import { addImports, createResolver, defineNuxtModule } from "@nuxt/kit";
|
|
10
|
+
var tsAnalyticsNuxtModule = defineNuxtModule({
|
|
11
|
+
meta: {
|
|
12
|
+
name: "@stacksjs/ts-analytics",
|
|
13
|
+
configKey: "tsAnalytics",
|
|
14
|
+
compatibility: { nuxt: ">=3.0.0" }
|
|
15
|
+
},
|
|
16
|
+
defaults: { enabled: true },
|
|
17
|
+
setup(options, nuxt) {
|
|
18
|
+
if (options.enabled === false)
|
|
19
|
+
return;
|
|
20
|
+
const scripts = tsAnalytics(options);
|
|
21
|
+
if (scripts.length === 0) {
|
|
22
|
+
console.warn("[ts-analytics] module skipped \u2014 `appId` is required in nuxt.config `tsAnalytics`.");
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
nuxt.options.app.head.script = nuxt.options.app.head.script || [];
|
|
26
|
+
nuxt.options.app.head.script.push(...scripts);
|
|
27
|
+
nuxt.options.runtimeConfig.public.tsAnalytics = {
|
|
28
|
+
appId: options.appId,
|
|
29
|
+
apiEndpoint: resolveApiEndpoint(options.apiEndpoint)
|
|
30
|
+
};
|
|
31
|
+
const resolver = createResolver(import.meta.url);
|
|
32
|
+
addImports({
|
|
33
|
+
name: "useTsAnalytics",
|
|
34
|
+
as: "useTsAnalytics",
|
|
35
|
+
from: resolver.resolve("./runtime/use-ts-analytics")
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
var nuxt_default = tsAnalyticsNuxtModule;
|
|
40
|
+
export {
|
|
41
|
+
nuxt_default as default
|
|
42
|
+
};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export declare function useTsAnalytics(): TsAnalyticsApi;
|
|
2
|
+
/**
|
|
3
|
+
* `useTsAnalytics()` — custom event tracking for the ts-analytics Nuxt module.
|
|
4
|
+
*
|
|
5
|
+
* The injected tracker exposes a Fathom-API-compatible global
|
|
6
|
+
* (`window.fathom.track(name, value)`); this composable wraps it with an
|
|
7
|
+
* SSR-safe no-op on the server. Auto-imported by `@stacksjs/ts-analytics/nuxt`.
|
|
8
|
+
*
|
|
9
|
+
* ```ts
|
|
10
|
+
* const { track } = useTsAnalytics()
|
|
11
|
+
* track('signup')
|
|
12
|
+
* track('purchase', 4200) // optional numeric value (e.g. cents)
|
|
13
|
+
* track('signup', 0, { plan: 'pro' }) // custom properties
|
|
14
|
+
* ```
|
|
15
|
+
*/
|
|
16
|
+
export declare interface TsAnalyticsApi {
|
|
17
|
+
track: (name: string, value?: number, props?: Record<string, string | number | boolean>) => void
|
|
18
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
import"../../chunk-2mx7fq49.js";
|
|
3
|
+
|
|
4
|
+
// src/integrations/runtime/use-ts-analytics.ts
|
|
5
|
+
function useTsAnalytics() {
|
|
6
|
+
return {
|
|
7
|
+
track(name, value, props) {
|
|
8
|
+
if (typeof window === "undefined")
|
|
9
|
+
return;
|
|
10
|
+
const tracker = window.fathom;
|
|
11
|
+
tracker?.track?.(name, value, props);
|
|
12
|
+
}
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
export {
|
|
16
|
+
useTsAnalytics
|
|
17
|
+
};
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/** Resolve the API origin from an explicit override, env, then the default. */
|
|
2
|
+
export declare function resolveApiEndpoint(explicit?: string): string;
|
|
3
|
+
/**
|
|
4
|
+
* Build the ts-analytics head `<script>` entry for a stx/Stacks app config.
|
|
5
|
+
*
|
|
6
|
+
* Returns an **array** (so it spreads cleanly into `app.head.script` and can
|
|
7
|
+
* grow later — e.g. an error-tracking tag — without changing call sites).
|
|
8
|
+
* Returns `[]` when `appId`/`apiEndpoint` are missing, so a half-configured
|
|
9
|
+
* environment never injects a broken tag.
|
|
10
|
+
*/
|
|
11
|
+
export declare function tsAnalytics(options: TsAnalyticsOptions): StxHeadScript[];
|
|
12
|
+
/**
|
|
13
|
+
* Raw `<script>` tag string for non-stx contexts — paste into a plain HTML
|
|
14
|
+
* `<head>`, or inject server-side. Same inputs as {@link tsAnalytics}. Returns
|
|
15
|
+
* `''` when required options are missing.
|
|
16
|
+
*/
|
|
17
|
+
export declare function tsAnalyticsTag(options: TsAnalyticsOptions): string;
|
|
18
|
+
/**
|
|
19
|
+
* Default ts-analytics API origin — where `/script.js` is served and events are
|
|
20
|
+
* collected. Baked in (Fathom-style) so host apps supply *only* an App ID.
|
|
21
|
+
*
|
|
22
|
+
* Endpoint resolution order: an explicit `apiEndpoint` option → the
|
|
23
|
+
* `TS_ANALYTICS_ENDPOINT` env var → this constant. Set this to your production
|
|
24
|
+
* ts-analytics host so deployed apps need zero endpoint config.
|
|
25
|
+
*/
|
|
26
|
+
export declare const DEFAULT_API_ENDPOINT: 'http://localhost:2027';
|
|
27
|
+
/** A stx head `<script>` entry — an item of the config `app.head.script` array. */
|
|
28
|
+
export declare interface StxHeadScript {
|
|
29
|
+
src?: string
|
|
30
|
+
content?: string
|
|
31
|
+
defer?: boolean
|
|
32
|
+
async?: boolean
|
|
33
|
+
type?: string
|
|
34
|
+
[attr: string]: unknown
|
|
35
|
+
}
|
|
36
|
+
export declare interface TsAnalyticsOptions {
|
|
37
|
+
appId: string
|
|
38
|
+
apiEndpoint?: string
|
|
39
|
+
scriptPath?: string
|
|
40
|
+
stealth?: boolean
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* stx / Stacks Config Integration
|
|
44
|
+
*
|
|
45
|
+
* Add ts-analytics to a stx (or Stacks) app the way you'd add a Nuxt analytics
|
|
46
|
+
* module — from the config file, keyed by an **App ID**.
|
|
47
|
+
*
|
|
48
|
+
* ts-analytics serves one shared, cacheable tracker at `<apiEndpoint>/script.js`
|
|
49
|
+
* (Fathom/Plausible-style). The tracker reads its App ID from the `data-site`
|
|
50
|
+
* attribute and derives the collector endpoint from its own `src` origin, so
|
|
51
|
+
* the only thing a host app supplies is the App ID + the API origin.
|
|
52
|
+
*
|
|
53
|
+
* Spread the result into your stx config's `app.head.script`:
|
|
54
|
+
*
|
|
55
|
+
* ```ts
|
|
56
|
+
* // config/stx.ts (Stacks) — or stx.config.ts
|
|
57
|
+
* import { tsAnalytics } from '@stacksjs/ts-analytics/stx'
|
|
58
|
+
*
|
|
59
|
+
* export default {
|
|
60
|
+
* app: {
|
|
61
|
+
* head: {
|
|
62
|
+
* script: [
|
|
63
|
+
* ...tsAnalytics({ appId: 'my-app' }), // endpoint is baked in
|
|
64
|
+
* ],
|
|
65
|
+
* },
|
|
66
|
+
* },
|
|
67
|
+
* }
|
|
68
|
+
* ```
|
|
69
|
+
*
|
|
70
|
+
* **Why a head helper and not a `plugins: [...]` entry?** stx's plugin render
|
|
71
|
+
* lifecycle hooks (`afterRender`) are not invoked by the dev/serve render
|
|
72
|
+
* pipeline, and a plugin's `setup()` config mutation does not propagate to
|
|
73
|
+
* rendering. The head config *is* read on every render, so this is the reliable
|
|
74
|
+
* mechanism — and it mirrors what framework analytics modules do internally
|
|
75
|
+
* (push a tag onto the document head).
|
|
76
|
+
*/
|
|
77
|
+
/**
|
|
78
|
+
* Generate a short, unguessable App ID (Fathom-style `data-site`, 8 chars). Run
|
|
79
|
+
* once per site and paste the result into your config — the backend
|
|
80
|
+
* auto-provisions the site on its first event, so nothing else is needed.
|
|
81
|
+
*
|
|
82
|
+
* ```ts
|
|
83
|
+
* import { generateAppId } from '@stacksjs/ts-analytics/stx'
|
|
84
|
+
* console.log(generateAppId()) // e.g. 'K7MN4PQR'
|
|
85
|
+
* ```
|
|
86
|
+
*/
|
|
87
|
+
export { generateAppId } from '../lib/crypto-random';
|
|
88
|
+
export default tsAnalytics;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
import {
|
|
3
|
+
DEFAULT_API_ENDPOINT,
|
|
4
|
+
generateAppId,
|
|
5
|
+
resolveApiEndpoint,
|
|
6
|
+
stx_default,
|
|
7
|
+
tsAnalytics,
|
|
8
|
+
tsAnalyticsTag
|
|
9
|
+
} from "../chunk-deephkz6.js";
|
|
10
|
+
import"../chunk-2mx7fq49.js";
|
|
11
|
+
export {
|
|
12
|
+
tsAnalyticsTag,
|
|
13
|
+
tsAnalytics,
|
|
14
|
+
resolveApiEndpoint,
|
|
15
|
+
generateAppId,
|
|
16
|
+
stx_default as default,
|
|
17
|
+
DEFAULT_API_ENDPOINT
|
|
18
|
+
};
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
/** A random string of `length` chars drawn uniformly from `chars`. */
|
|
2
|
+
export declare function randomToken(length: number, chars?: string): string;
|
|
3
|
+
/** A short, random, unguessable App ID (default 8 chars). */
|
|
4
|
+
export declare function generateAppId(length?: number): string;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/** Daily-rotating, secret-seeded salt for visitor ID hashing.
|
|
2
|
+
*
|
|
3
|
+
* NOTE: process-local — on multi-instance deployments prefer
|
|
4
|
+
* {@link getSharedDailySalt}, which persists the day's salt in DynamoDB so
|
|
5
|
+
* every instance hashes with the same value.
|
|
6
|
+
*/
|
|
7
|
+
export declare function getDailySalt(): string;
|
|
8
|
+
/**
|
|
9
|
+
* Cluster-consistent daily salt (#165). The process-local salt differs per
|
|
10
|
+
* instance when ANALYTICS_SALT_SECRET is unset (Lambda concurrency, restarts),
|
|
11
|
+
* which inflates unique-visitor counts — the same visitor hashes differently on
|
|
12
|
+
* every instance. Persist the day's salt as a SALT item via conditional put
|
|
13
|
+
* (first writer wins) so all instances converge, with the process-local value
|
|
14
|
+
* as both the candidate and the fallback when DynamoDB is unreachable.
|
|
15
|
+
*/
|
|
16
|
+
export declare function getSharedDailySalt(): Promise<string>;
|