@wordrhyme/plugin 0.1.0-alpha.5
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/dist/admin/index.d.ts +19 -0
- package/dist/admin/index.js +42 -0
- package/dist/admin/index.js.map +1 -0
- package/dist/artifact.d.ts +17 -0
- package/dist/artifact.js +96 -0
- package/dist/artifact.js.map +1 -0
- package/dist/chunk-46KUIGB6.js +230 -0
- package/dist/chunk-46KUIGB6.js.map +1 -0
- package/dist/chunk-6GDCFR67.js +218 -0
- package/dist/chunk-6GDCFR67.js.map +1 -0
- package/dist/chunk-DY44Q4CK.js +188 -0
- package/dist/chunk-DY44Q4CK.js.map +1 -0
- package/dist/chunk-MZOLSLJ7.js +65 -0
- package/dist/chunk-MZOLSLJ7.js.map +1 -0
- package/dist/chunk-QNCOGISF.js +694 -0
- package/dist/chunk-QNCOGISF.js.map +1 -0
- package/dist/chunk-UGMYO6AU.js +37 -0
- package/dist/chunk-UGMYO6AU.js.map +1 -0
- package/dist/chunk-YQDKOEUI.js +242 -0
- package/dist/chunk-YQDKOEUI.js.map +1 -0
- package/dist/chunk-ZUBFLOKU.js +153 -0
- package/dist/chunk-ZUBFLOKU.js.map +1 -0
- package/dist/client-WXWbuuvd.d.ts +100 -0
- package/dist/client.d.ts +3 -0
- package/dist/client.js +29 -0
- package/dist/client.js.map +1 -0
- package/dist/dev-utils.d.ts +68 -0
- package/dist/dev-utils.js +21 -0
- package/dist/dev-utils.js.map +1 -0
- package/dist/entity-extensions-B5BbZH-m.d.ts +56 -0
- package/dist/globalization.d.ts +80 -0
- package/dist/globalization.js +43 -0
- package/dist/globalization.js.map +1 -0
- package/dist/index.d.ts +316 -0
- package/dist/index.js +354 -0
- package/dist/index.js.map +1 -0
- package/dist/manifest-CPSCN_Ft.d.ts +1471 -0
- package/dist/react.d.ts +145 -0
- package/dist/react.js +94 -0
- package/dist/react.js.map +1 -0
- package/dist/release-CyapqJ3z.d.ts +230 -0
- package/dist/server.d.ts +114 -0
- package/dist/server.js +194 -0
- package/dist/server.js.map +1 -0
- package/dist/time.d.ts +34 -0
- package/dist/time.js +31 -0
- package/dist/time.js.map +1 -0
- package/dist/trpc.d.ts +43 -0
- package/dist/trpc.js +11 -0
- package/dist/trpc.js.map +1 -0
- package/dist/types-8P7XyoyQ.d.ts +1599 -0
- package/package.json +83 -0
package/dist/server.js
ADDED
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
import {
|
|
2
|
+
createPluginContext,
|
|
3
|
+
pluginProcedure,
|
|
4
|
+
pluginRouter
|
|
5
|
+
} from "./chunk-ZUBFLOKU.js";
|
|
6
|
+
import {
|
|
7
|
+
ENTITY_EXTENSION_VALUES_SAVE_HOOK_ID,
|
|
8
|
+
EXTENSION_PROJECT_SAVE_HOOK_ID,
|
|
9
|
+
entityExtensions,
|
|
10
|
+
registerEntityExtensionValueSaver
|
|
11
|
+
} from "./chunk-UGMYO6AU.js";
|
|
12
|
+
|
|
13
|
+
// src/runtime.ts
|
|
14
|
+
var runtimeBridge;
|
|
15
|
+
function setPluginRuntimeBridge(bridge) {
|
|
16
|
+
runtimeBridge = bridge;
|
|
17
|
+
}
|
|
18
|
+
function getPluginRuntimeBridge() {
|
|
19
|
+
if (!runtimeBridge) {
|
|
20
|
+
throw new Error("Plugin runtime bridge is not available");
|
|
21
|
+
}
|
|
22
|
+
return runtimeBridge;
|
|
23
|
+
}
|
|
24
|
+
function createPluginRuntimeRequestContext(input) {
|
|
25
|
+
return getPluginRuntimeBridge().createRequestContext(input);
|
|
26
|
+
}
|
|
27
|
+
function createPluginRuntimeContext(input) {
|
|
28
|
+
return getPluginRuntimeBridge().createContext(input);
|
|
29
|
+
}
|
|
30
|
+
function runWithPluginRuntimeContext(requestContext, callback) {
|
|
31
|
+
return getPluginRuntimeBridge().runWithContext(requestContext, callback);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// src/oauth.ts
|
|
35
|
+
import crypto from "crypto";
|
|
36
|
+
function buildOAuthCallbackPath(providerId) {
|
|
37
|
+
const normalized = providerId.trim();
|
|
38
|
+
if (!/^[a-z0-9-]+$/i.test(normalized)) {
|
|
39
|
+
throw new Error(`Invalid OAuth provider id: ${providerId}`);
|
|
40
|
+
}
|
|
41
|
+
return `/api/oauth/${normalized}/callback`;
|
|
42
|
+
}
|
|
43
|
+
function buildOAuthCallbackUrl(providerId, baseUrl) {
|
|
44
|
+
return new URL(buildOAuthCallbackPath(providerId), baseUrl).toString();
|
|
45
|
+
}
|
|
46
|
+
function buildOAuthResultRedirect(path, params) {
|
|
47
|
+
const url = new URL(path, "https://wordrhyme.local");
|
|
48
|
+
for (const [key, value] of Object.entries(params)) {
|
|
49
|
+
if (value !== null && value !== void 0) {
|
|
50
|
+
url.searchParams.set(key, String(value));
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
if (/^https?:\/\//i.test(path)) {
|
|
54
|
+
return url.toString();
|
|
55
|
+
}
|
|
56
|
+
return `${url.pathname}${url.search}${url.hash}`;
|
|
57
|
+
}
|
|
58
|
+
function buildOAuthStateKey(keyPrefix, state) {
|
|
59
|
+
const prefix = keyPrefix.trim().replace(/\.+$/, "");
|
|
60
|
+
if (!prefix) throw new Error("OAuth state keyPrefix is required");
|
|
61
|
+
if (!state) throw new Error("OAuth state is required");
|
|
62
|
+
return `${prefix}.${state}`;
|
|
63
|
+
}
|
|
64
|
+
function maskOAuthSecret(value) {
|
|
65
|
+
if (value.length <= 8) return "********";
|
|
66
|
+
return `${value.slice(0, 4)}****${value.slice(-4)}`;
|
|
67
|
+
}
|
|
68
|
+
async function createOAuthState(ctx, options) {
|
|
69
|
+
if (!ctx.settings) throw new Error("Settings not available");
|
|
70
|
+
const state = crypto.randomBytes(options.bytes ?? 24).toString("hex");
|
|
71
|
+
const key = buildOAuthStateKey(options.keyPrefix, state);
|
|
72
|
+
const now = options.now ?? /* @__PURE__ */ new Date();
|
|
73
|
+
const payload = {
|
|
74
|
+
...options.payload,
|
|
75
|
+
createdAt: now.toISOString()
|
|
76
|
+
};
|
|
77
|
+
if (options.ttlSeconds && options.ttlSeconds > 0) {
|
|
78
|
+
payload.expiresAt = new Date(now.getTime() + options.ttlSeconds * 1e3).toISOString();
|
|
79
|
+
}
|
|
80
|
+
if (options.includeContext !== false) {
|
|
81
|
+
if (ctx.userId) payload.userId = ctx.userId;
|
|
82
|
+
if (ctx.organizationId) payload.organizationId = ctx.organizationId;
|
|
83
|
+
}
|
|
84
|
+
await ctx.settings.set(key, payload, {
|
|
85
|
+
encrypted: options.encrypted ?? true,
|
|
86
|
+
...options.global !== void 0 ? { global: options.global } : {}
|
|
87
|
+
});
|
|
88
|
+
return { state, key, payload };
|
|
89
|
+
}
|
|
90
|
+
async function consumeOAuthState(ctx, options) {
|
|
91
|
+
if (!ctx.settings) throw new Error("Settings not available");
|
|
92
|
+
const key = buildOAuthStateKey(options.keyPrefix, options.state);
|
|
93
|
+
const raw = await ctx.settings.get(key);
|
|
94
|
+
const record = parseStateRecord(raw);
|
|
95
|
+
if (!record) {
|
|
96
|
+
throw new Error("Invalid or expired OAuth state");
|
|
97
|
+
}
|
|
98
|
+
const now = options.now ?? /* @__PURE__ */ new Date();
|
|
99
|
+
if (record.expiresAt && Date.parse(record.expiresAt) <= now.getTime()) {
|
|
100
|
+
await ctx.settings.delete(key, scopeOptions(options)).catch(() => false);
|
|
101
|
+
throw new Error("Invalid or expired OAuth state");
|
|
102
|
+
}
|
|
103
|
+
if (options.deleteOnConsume !== false) {
|
|
104
|
+
await ctx.settings.delete(key, scopeOptions(options)).catch(() => false);
|
|
105
|
+
}
|
|
106
|
+
return record;
|
|
107
|
+
}
|
|
108
|
+
function buildCanonicalQueryString(params, excludeKeys = []) {
|
|
109
|
+
const exclude = new Set(excludeKeys);
|
|
110
|
+
const entries = [];
|
|
111
|
+
for (const [key, value] of Object.entries(params)) {
|
|
112
|
+
if (exclude.has(key)) continue;
|
|
113
|
+
const values = Array.isArray(value) ? value : [value];
|
|
114
|
+
for (const item of values) {
|
|
115
|
+
if (item !== null && item !== void 0) {
|
|
116
|
+
entries.push([key, String(item)]);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
return entries.sort(([a], [b]) => a.localeCompare(b)).map(([key, value]) => `${key}=${value}`).join("&");
|
|
121
|
+
}
|
|
122
|
+
function verifyQueryHmacSha256(params, secret, options = {}) {
|
|
123
|
+
if (!secret) return false;
|
|
124
|
+
const signatureKey = options.signatureKey ?? "hmac";
|
|
125
|
+
const signature = firstQueryValue(params[signatureKey]);
|
|
126
|
+
if (!signature) return false;
|
|
127
|
+
const excludeKeys = options.excludeKeys ?? [signatureKey];
|
|
128
|
+
const digest = options.digest ?? "hex";
|
|
129
|
+
const message = buildCanonicalQueryString(params, excludeKeys);
|
|
130
|
+
const computed = crypto.createHmac("sha256", secret).update(message).digest(digest);
|
|
131
|
+
return timingSafeEqualString(computed, signature);
|
|
132
|
+
}
|
|
133
|
+
function timingSafeEqualString(a, b) {
|
|
134
|
+
const left = Buffer.from(a, "utf8");
|
|
135
|
+
const right = Buffer.from(b, "utf8");
|
|
136
|
+
if (left.length !== right.length) return false;
|
|
137
|
+
return crypto.timingSafeEqual(left, right);
|
|
138
|
+
}
|
|
139
|
+
function parseStateRecord(value) {
|
|
140
|
+
let parsed = value;
|
|
141
|
+
if (typeof value === "string") {
|
|
142
|
+
try {
|
|
143
|
+
parsed = JSON.parse(value);
|
|
144
|
+
} catch {
|
|
145
|
+
return null;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
149
|
+
return null;
|
|
150
|
+
}
|
|
151
|
+
const record = parsed;
|
|
152
|
+
if (typeof record["createdAt"] !== "string") {
|
|
153
|
+
return null;
|
|
154
|
+
}
|
|
155
|
+
if ("expiresAt" in record && typeof record["expiresAt"] !== "string") {
|
|
156
|
+
return null;
|
|
157
|
+
}
|
|
158
|
+
return record;
|
|
159
|
+
}
|
|
160
|
+
function firstQueryValue(value) {
|
|
161
|
+
const candidate = Array.isArray(value) ? value.find((item) => item !== null && item !== void 0) : value;
|
|
162
|
+
return candidate === null || candidate === void 0 ? null : String(candidate);
|
|
163
|
+
}
|
|
164
|
+
function scopeOptions(options) {
|
|
165
|
+
return options.global !== void 0 ? { global: options.global } : void 0;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// src/public-service.ts
|
|
169
|
+
function definePublicService(service) {
|
|
170
|
+
return service;
|
|
171
|
+
}
|
|
172
|
+
export {
|
|
173
|
+
ENTITY_EXTENSION_VALUES_SAVE_HOOK_ID,
|
|
174
|
+
EXTENSION_PROJECT_SAVE_HOOK_ID,
|
|
175
|
+
buildOAuthCallbackPath,
|
|
176
|
+
buildOAuthCallbackUrl,
|
|
177
|
+
buildOAuthResultRedirect,
|
|
178
|
+
buildOAuthStateKey,
|
|
179
|
+
consumeOAuthState,
|
|
180
|
+
createOAuthState,
|
|
181
|
+
createPluginContext,
|
|
182
|
+
createPluginRuntimeContext,
|
|
183
|
+
createPluginRuntimeRequestContext,
|
|
184
|
+
definePublicService,
|
|
185
|
+
entityExtensions,
|
|
186
|
+
maskOAuthSecret,
|
|
187
|
+
pluginProcedure,
|
|
188
|
+
pluginRouter,
|
|
189
|
+
registerEntityExtensionValueSaver,
|
|
190
|
+
runWithPluginRuntimeContext,
|
|
191
|
+
setPluginRuntimeBridge,
|
|
192
|
+
verifyQueryHmacSha256
|
|
193
|
+
};
|
|
194
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/runtime.ts","../src/oauth.ts","../src/public-service.ts"],"sourcesContent":["import type { PluginContext } from './types';\nimport type { DateRangeResolver } from './time';\n\nexport interface PluginRuntimeRequestContext {\n requestId?: string | undefined;\n organizationId?: string | undefined;\n originalOrganizationId?: string | undefined;\n userId?: string | undefined;\n user?: PluginContext['user'];\n userRole?: string | undefined;\n userRoles?: string[] | undefined;\n currentTeamId?: string | undefined;\n locale?: string | undefined;\n currency?: string | undefined;\n timezone?: string | undefined;\n clientTimeZone?: string | undefined;\n resolveDateRange?: DateRangeResolver | undefined;\n actorType?: PluginContext['actorType'] | 'api-token';\n isSystemContext?: boolean | undefined;\n principal?: PluginContext['principal'];\n invoker?: string | undefined;\n apiTokenId?: string | undefined;\n apiTokenScopes?: string[] | undefined;\n}\n\nexport interface CreatePluginRuntimeContextInput {\n pluginId: string;\n request?: unknown;\n response?: unknown;\n requestContext?: PluginRuntimeRequestContext | undefined;\n}\n\nexport interface PluginRuntimeBridge {\n createRequestContext(input: PluginRuntimeRequestContext): PluginRuntimeRequestContext;\n createContext(input: CreatePluginRuntimeContextInput): Promise<PluginContext>;\n runWithContext<T>(requestContext: PluginRuntimeRequestContext, callback: () => Promise<T> | T): Promise<T>;\n}\n\nlet runtimeBridge: PluginRuntimeBridge | undefined;\n\nexport function setPluginRuntimeBridge(bridge: PluginRuntimeBridge): void {\n runtimeBridge = bridge;\n}\n\nfunction getPluginRuntimeBridge(): PluginRuntimeBridge {\n if (!runtimeBridge) {\n throw new Error('Plugin runtime bridge is not available');\n }\n return runtimeBridge;\n}\n\nexport function createPluginRuntimeRequestContext(\n input: PluginRuntimeRequestContext,\n): PluginRuntimeRequestContext {\n return getPluginRuntimeBridge().createRequestContext(input);\n}\n\nexport function createPluginRuntimeContext(\n input: CreatePluginRuntimeContextInput,\n): Promise<PluginContext> {\n return getPluginRuntimeBridge().createContext(input);\n}\n\nexport function runWithPluginRuntimeContext<T>(\n requestContext: PluginRuntimeRequestContext,\n callback: () => Promise<T> | T,\n): Promise<T> {\n return getPluginRuntimeBridge().runWithContext(requestContext, callback);\n}\n","import crypto from 'node:crypto';\nimport type { PluginContext } from './types';\n\ntype OAuthSettingScope = {\n global?: boolean;\n};\n\ntype OAuthSettings = Pick<PluginContext, 'settings' | 'organizationId' | 'userId'>;\n\nexport type OAuthQueryValue =\n | string\n | number\n | boolean\n | null\n | undefined\n | readonly (string | number | boolean | null | undefined)[];\n\nexport type OAuthQueryParams = Record<string, OAuthQueryValue>;\n\nexport type OAuthStateRecord<TPayload extends Record<string, unknown> = Record<string, unknown>> =\n TPayload & {\n createdAt: string;\n expiresAt?: string;\n userId?: string;\n organizationId?: string;\n };\n\nexport interface CreateOAuthStateOptions<TPayload extends Record<string, unknown>> extends OAuthSettingScope {\n keyPrefix: string;\n payload: TPayload;\n bytes?: number;\n ttlSeconds?: number;\n encrypted?: boolean;\n includeContext?: boolean;\n now?: Date;\n}\n\nexport interface ConsumeOAuthStateOptions extends OAuthSettingScope {\n keyPrefix: string;\n state: string;\n deleteOnConsume?: boolean;\n now?: Date;\n}\n\nexport interface VerifyQueryHmacSha256Options {\n signatureKey?: string;\n excludeKeys?: string[];\n digest?: 'hex' | 'base64';\n}\n\nexport function buildOAuthCallbackPath(providerId: string): string {\n const normalized = providerId.trim();\n if (!/^[a-z0-9-]+$/i.test(normalized)) {\n throw new Error(`Invalid OAuth provider id: ${providerId}`);\n }\n return `/api/oauth/${normalized}/callback`;\n}\n\nexport function buildOAuthCallbackUrl(providerId: string, baseUrl: string): string {\n return new URL(buildOAuthCallbackPath(providerId), baseUrl).toString();\n}\n\nexport function buildOAuthResultRedirect(\n path: string,\n params: Record<string, string | number | boolean | null | undefined>,\n): string {\n const url = new URL(path, 'https://wordrhyme.local');\n for (const [key, value] of Object.entries(params)) {\n if (value !== null && value !== undefined) {\n url.searchParams.set(key, String(value));\n }\n }\n\n if (/^https?:\\/\\//i.test(path)) {\n return url.toString();\n }\n return `${url.pathname}${url.search}${url.hash}`;\n}\n\nexport function buildOAuthStateKey(keyPrefix: string, state: string): string {\n const prefix = keyPrefix.trim().replace(/\\.+$/, '');\n if (!prefix) throw new Error('OAuth state keyPrefix is required');\n if (!state) throw new Error('OAuth state is required');\n return `${prefix}.${state}`;\n}\n\nexport function maskOAuthSecret(value: string): string {\n if (value.length <= 8) return '********';\n return `${value.slice(0, 4)}****${value.slice(-4)}`;\n}\n\nexport async function createOAuthState<TPayload extends Record<string, unknown>>(\n ctx: OAuthSettings,\n options: CreateOAuthStateOptions<TPayload>,\n): Promise<{ state: string; key: string; payload: OAuthStateRecord<TPayload> }> {\n if (!ctx.settings) throw new Error('Settings not available');\n\n const state = crypto.randomBytes(options.bytes ?? 24).toString('hex');\n const key = buildOAuthStateKey(options.keyPrefix, state);\n const now = options.now ?? new Date();\n const payload = {\n ...options.payload,\n createdAt: now.toISOString(),\n } as OAuthStateRecord<TPayload>;\n\n if (options.ttlSeconds && options.ttlSeconds > 0) {\n payload.expiresAt = new Date(now.getTime() + options.ttlSeconds * 1000).toISOString();\n }\n\n if (options.includeContext !== false) {\n if (ctx.userId) payload.userId = ctx.userId;\n if (ctx.organizationId) payload.organizationId = ctx.organizationId;\n }\n\n await ctx.settings.set(key, payload, {\n encrypted: options.encrypted ?? true,\n ...(options.global !== undefined ? { global: options.global } : {}),\n });\n\n return { state, key, payload };\n}\n\nexport async function consumeOAuthState<TPayload extends Record<string, unknown> = Record<string, unknown>>(\n ctx: OAuthSettings,\n options: ConsumeOAuthStateOptions,\n): Promise<OAuthStateRecord<TPayload>> {\n if (!ctx.settings) throw new Error('Settings not available');\n\n const key = buildOAuthStateKey(options.keyPrefix, options.state);\n const raw = await ctx.settings.get<unknown>(key);\n const record = parseStateRecord<TPayload>(raw);\n if (!record) {\n throw new Error('Invalid or expired OAuth state');\n }\n\n const now = options.now ?? new Date();\n if (record.expiresAt && Date.parse(record.expiresAt) <= now.getTime()) {\n await ctx.settings.delete(key, scopeOptions(options)).catch(() => false);\n throw new Error('Invalid or expired OAuth state');\n }\n\n if (options.deleteOnConsume !== false) {\n await ctx.settings.delete(key, scopeOptions(options)).catch(() => false);\n }\n\n return record;\n}\n\nexport function createPkcePair(): {\n codeVerifier: string;\n codeChallenge: string;\n method: 'S256';\n} {\n const codeVerifier = base64Url(crypto.randomBytes(32));\n const codeChallenge = base64Url(crypto.createHash('sha256').update(codeVerifier).digest());\n return { codeVerifier, codeChallenge, method: 'S256' };\n}\n\nexport function buildCanonicalQueryString(\n params: OAuthQueryParams,\n excludeKeys: string[] = [],\n): string {\n const exclude = new Set(excludeKeys);\n const entries: Array<[string, string]> = [];\n\n for (const [key, value] of Object.entries(params)) {\n if (exclude.has(key)) continue;\n const values = Array.isArray(value) ? value : [value];\n for (const item of values) {\n if (item !== null && item !== undefined) {\n entries.push([key, String(item)]);\n }\n }\n }\n\n return entries\n .sort(([a], [b]) => a.localeCompare(b))\n .map(([key, value]) => `${key}=${value}`)\n .join('&');\n}\n\nexport function verifyQueryHmacSha256(\n params: OAuthQueryParams,\n secret: string,\n options: VerifyQueryHmacSha256Options = {},\n): boolean {\n if (!secret) return false;\n\n const signatureKey = options.signatureKey ?? 'hmac';\n const signature = firstQueryValue(params[signatureKey]);\n if (!signature) return false;\n\n const excludeKeys = options.excludeKeys ?? [signatureKey];\n const digest = options.digest ?? 'hex';\n const message = buildCanonicalQueryString(params, excludeKeys);\n const computed = crypto.createHmac('sha256', secret).update(message).digest(digest);\n\n return timingSafeEqualString(computed, signature);\n}\n\nexport function timingSafeEqualString(a: string, b: string): boolean {\n const left = Buffer.from(a, 'utf8');\n const right = Buffer.from(b, 'utf8');\n if (left.length !== right.length) return false;\n return crypto.timingSafeEqual(left, right);\n}\n\nfunction parseStateRecord<TPayload extends Record<string, unknown>>(\n value: unknown,\n): OAuthStateRecord<TPayload> | null {\n let parsed = value;\n if (typeof value === 'string') {\n try {\n parsed = JSON.parse(value) as unknown;\n } catch {\n return null;\n }\n }\n\n if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {\n return null;\n }\n\n const record = parsed as Record<string, unknown>;\n if (typeof record['createdAt'] !== 'string') {\n return null;\n }\n if ('expiresAt' in record && typeof record['expiresAt'] !== 'string') {\n return null;\n }\n\n return record as OAuthStateRecord<TPayload>;\n}\n\nfunction firstQueryValue(value: OAuthQueryValue): string | null {\n const candidate = Array.isArray(value) ? value.find((item) => item !== null && item !== undefined) : value;\n return candidate === null || candidate === undefined ? null : String(candidate);\n}\n\nfunction base64Url(input: Buffer): string {\n return input\n .toString('base64')\n .replace(/\\+/g, '-')\n .replace(/\\//g, '_')\n .replace(/=+$/g, '');\n}\n\nfunction scopeOptions(options: OAuthSettingScope): OAuthSettingScope | undefined {\n return options.global !== undefined ? { global: options.global } : undefined;\n}\n","import type { PluginContext } from \"./types\";\n\nexport interface PluginPublicServiceRequest {\n method: string;\n path: string;\n query: Record<string, string | string[]>;\n headers: Record<string, string | undefined>;\n body: unknown;\n requestId: string;\n}\n\nexport interface PluginPublicServiceResponse {\n status?: number;\n headers?: Record<string, string>;\n body?: unknown;\n}\n\nexport interface PluginPublicService {\n name: string;\n handle(request: PluginPublicServiceRequest, context: PluginContext): Promise<PluginPublicServiceResponse>;\n}\n\nexport function definePublicService(service: PluginPublicService): PluginPublicService {\n return service;\n}\n"],"mappings":";;;;;;;;;;;;;AAsCA,IAAI;AAEG,SAAS,uBAAuB,QAAmC;AACtE,kBAAgB;AACpB;AAEA,SAAS,yBAA8C;AACnD,MAAI,CAAC,eAAe;AAChB,UAAM,IAAI,MAAM,wCAAwC;AAAA,EAC5D;AACA,SAAO;AACX;AAEO,SAAS,kCACZ,OAC2B;AAC3B,SAAO,uBAAuB,EAAE,qBAAqB,KAAK;AAC9D;AAEO,SAAS,2BACZ,OACsB;AACtB,SAAO,uBAAuB,EAAE,cAAc,KAAK;AACvD;AAEO,SAAS,4BACZ,gBACA,UACU;AACV,SAAO,uBAAuB,EAAE,eAAe,gBAAgB,QAAQ;AAC3E;;;ACpEA,OAAO,YAAY;AAkDZ,SAAS,uBAAuB,YAA4B;AAC/D,QAAM,aAAa,WAAW,KAAK;AACnC,MAAI,CAAC,gBAAgB,KAAK,UAAU,GAAG;AACnC,UAAM,IAAI,MAAM,8BAA8B,UAAU,EAAE;AAAA,EAC9D;AACA,SAAO,cAAc,UAAU;AACnC;AAEO,SAAS,sBAAsB,YAAoB,SAAyB;AAC/E,SAAO,IAAI,IAAI,uBAAuB,UAAU,GAAG,OAAO,EAAE,SAAS;AACzE;AAEO,SAAS,yBACZ,MACA,QACM;AACN,QAAM,MAAM,IAAI,IAAI,MAAM,yBAAyB;AACnD,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,MAAM,GAAG;AAC/C,QAAI,UAAU,QAAQ,UAAU,QAAW;AACvC,UAAI,aAAa,IAAI,KAAK,OAAO,KAAK,CAAC;AAAA,IAC3C;AAAA,EACJ;AAEA,MAAI,gBAAgB,KAAK,IAAI,GAAG;AAC5B,WAAO,IAAI,SAAS;AAAA,EACxB;AACA,SAAO,GAAG,IAAI,QAAQ,GAAG,IAAI,MAAM,GAAG,IAAI,IAAI;AAClD;AAEO,SAAS,mBAAmB,WAAmB,OAAuB;AACzE,QAAM,SAAS,UAAU,KAAK,EAAE,QAAQ,QAAQ,EAAE;AAClD,MAAI,CAAC,OAAQ,OAAM,IAAI,MAAM,mCAAmC;AAChE,MAAI,CAAC,MAAO,OAAM,IAAI,MAAM,yBAAyB;AACrD,SAAO,GAAG,MAAM,IAAI,KAAK;AAC7B;AAEO,SAAS,gBAAgB,OAAuB;AACnD,MAAI,MAAM,UAAU,EAAG,QAAO;AAC9B,SAAO,GAAG,MAAM,MAAM,GAAG,CAAC,CAAC,OAAO,MAAM,MAAM,EAAE,CAAC;AACrD;AAEA,eAAsB,iBAClB,KACA,SAC4E;AAC5E,MAAI,CAAC,IAAI,SAAU,OAAM,IAAI,MAAM,wBAAwB;AAE3D,QAAM,QAAQ,OAAO,YAAY,QAAQ,SAAS,EAAE,EAAE,SAAS,KAAK;AACpE,QAAM,MAAM,mBAAmB,QAAQ,WAAW,KAAK;AACvD,QAAM,MAAM,QAAQ,OAAO,oBAAI,KAAK;AACpC,QAAM,UAAU;AAAA,IACZ,GAAG,QAAQ;AAAA,IACX,WAAW,IAAI,YAAY;AAAA,EAC/B;AAEA,MAAI,QAAQ,cAAc,QAAQ,aAAa,GAAG;AAC9C,YAAQ,YAAY,IAAI,KAAK,IAAI,QAAQ,IAAI,QAAQ,aAAa,GAAI,EAAE,YAAY;AAAA,EACxF;AAEA,MAAI,QAAQ,mBAAmB,OAAO;AAClC,QAAI,IAAI,OAAQ,SAAQ,SAAS,IAAI;AACrC,QAAI,IAAI,eAAgB,SAAQ,iBAAiB,IAAI;AAAA,EACzD;AAEA,QAAM,IAAI,SAAS,IAAI,KAAK,SAAS;AAAA,IACjC,WAAW,QAAQ,aAAa;AAAA,IAChC,GAAI,QAAQ,WAAW,SAAY,EAAE,QAAQ,QAAQ,OAAO,IAAI,CAAC;AAAA,EACrE,CAAC;AAED,SAAO,EAAE,OAAO,KAAK,QAAQ;AACjC;AAEA,eAAsB,kBAClB,KACA,SACmC;AACnC,MAAI,CAAC,IAAI,SAAU,OAAM,IAAI,MAAM,wBAAwB;AAE3D,QAAM,MAAM,mBAAmB,QAAQ,WAAW,QAAQ,KAAK;AAC/D,QAAM,MAAM,MAAM,IAAI,SAAS,IAAa,GAAG;AAC/C,QAAM,SAAS,iBAA2B,GAAG;AAC7C,MAAI,CAAC,QAAQ;AACT,UAAM,IAAI,MAAM,gCAAgC;AAAA,EACpD;AAEA,QAAM,MAAM,QAAQ,OAAO,oBAAI,KAAK;AACpC,MAAI,OAAO,aAAa,KAAK,MAAM,OAAO,SAAS,KAAK,IAAI,QAAQ,GAAG;AACnE,UAAM,IAAI,SAAS,OAAO,KAAK,aAAa,OAAO,CAAC,EAAE,MAAM,MAAM,KAAK;AACvE,UAAM,IAAI,MAAM,gCAAgC;AAAA,EACpD;AAEA,MAAI,QAAQ,oBAAoB,OAAO;AACnC,UAAM,IAAI,SAAS,OAAO,KAAK,aAAa,OAAO,CAAC,EAAE,MAAM,MAAM,KAAK;AAAA,EAC3E;AAEA,SAAO;AACX;AAYO,SAAS,0BACZ,QACA,cAAwB,CAAC,GACnB;AACN,QAAM,UAAU,IAAI,IAAI,WAAW;AACnC,QAAM,UAAmC,CAAC;AAE1C,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,MAAM,GAAG;AAC/C,QAAI,QAAQ,IAAI,GAAG,EAAG;AACtB,UAAM,SAAS,MAAM,QAAQ,KAAK,IAAI,QAAQ,CAAC,KAAK;AACpD,eAAW,QAAQ,QAAQ;AACvB,UAAI,SAAS,QAAQ,SAAS,QAAW;AACrC,gBAAQ,KAAK,CAAC,KAAK,OAAO,IAAI,CAAC,CAAC;AAAA,MACpC;AAAA,IACJ;AAAA,EACJ;AAEA,SAAO,QACF,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC,EACrC,IAAI,CAAC,CAAC,KAAK,KAAK,MAAM,GAAG,GAAG,IAAI,KAAK,EAAE,EACvC,KAAK,GAAG;AACjB;AAEO,SAAS,sBACZ,QACA,QACA,UAAwC,CAAC,GAClC;AACP,MAAI,CAAC,OAAQ,QAAO;AAEpB,QAAM,eAAe,QAAQ,gBAAgB;AAC7C,QAAM,YAAY,gBAAgB,OAAO,YAAY,CAAC;AACtD,MAAI,CAAC,UAAW,QAAO;AAEvB,QAAM,cAAc,QAAQ,eAAe,CAAC,YAAY;AACxD,QAAM,SAAS,QAAQ,UAAU;AACjC,QAAM,UAAU,0BAA0B,QAAQ,WAAW;AAC7D,QAAM,WAAW,OAAO,WAAW,UAAU,MAAM,EAAE,OAAO,OAAO,EAAE,OAAO,MAAM;AAElF,SAAO,sBAAsB,UAAU,SAAS;AACpD;AAEO,SAAS,sBAAsB,GAAW,GAAoB;AACjE,QAAM,OAAO,OAAO,KAAK,GAAG,MAAM;AAClC,QAAM,QAAQ,OAAO,KAAK,GAAG,MAAM;AACnC,MAAI,KAAK,WAAW,MAAM,OAAQ,QAAO;AACzC,SAAO,OAAO,gBAAgB,MAAM,KAAK;AAC7C;AAEA,SAAS,iBACL,OACiC;AACjC,MAAI,SAAS;AACb,MAAI,OAAO,UAAU,UAAU;AAC3B,QAAI;AACA,eAAS,KAAK,MAAM,KAAK;AAAA,IAC7B,QAAQ;AACJ,aAAO;AAAA,IACX;AAAA,EACJ;AAEA,MAAI,CAAC,UAAU,OAAO,WAAW,YAAY,MAAM,QAAQ,MAAM,GAAG;AAChE,WAAO;AAAA,EACX;AAEA,QAAM,SAAS;AACf,MAAI,OAAO,OAAO,WAAW,MAAM,UAAU;AACzC,WAAO;AAAA,EACX;AACA,MAAI,eAAe,UAAU,OAAO,OAAO,WAAW,MAAM,UAAU;AAClE,WAAO;AAAA,EACX;AAEA,SAAO;AACX;AAEA,SAAS,gBAAgB,OAAuC;AAC5D,QAAM,YAAY,MAAM,QAAQ,KAAK,IAAI,MAAM,KAAK,CAAC,SAAS,SAAS,QAAQ,SAAS,MAAS,IAAI;AACrG,SAAO,cAAc,QAAQ,cAAc,SAAY,OAAO,OAAO,SAAS;AAClF;AAUA,SAAS,aAAa,SAA2D;AAC7E,SAAO,QAAQ,WAAW,SAAY,EAAE,QAAQ,QAAQ,OAAO,IAAI;AACvE;;;ACnOO,SAAS,oBAAoB,SAAmD;AACnF,SAAO;AACX;","names":[]}
|
package/dist/time.d.ts
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
declare const DEFAULT_TIME_ZONE = "UTC";
|
|
2
|
+
declare const CLIENT_TIME_ZONE_HEADER = "x-time-zone";
|
|
3
|
+
declare const CLIENT_TIME_ZONE_COOKIE = "wr_time_zone";
|
|
4
|
+
interface DateFilterInput {
|
|
5
|
+
value: unknown;
|
|
6
|
+
variant: string;
|
|
7
|
+
operator: string;
|
|
8
|
+
}
|
|
9
|
+
interface DateFilterRange {
|
|
10
|
+
start?: Date;
|
|
11
|
+
endExclusive?: Date;
|
|
12
|
+
}
|
|
13
|
+
type DateRangeResolver = (filter: DateFilterInput) => DateFilterRange | undefined;
|
|
14
|
+
interface FormatDateTimeOptions extends Intl.DateTimeFormatOptions {
|
|
15
|
+
locale?: string;
|
|
16
|
+
timeZone?: string;
|
|
17
|
+
}
|
|
18
|
+
declare function canonicalizeTimeZone(value: unknown): string | undefined;
|
|
19
|
+
declare function isValidTimeZone(value: unknown): value is string;
|
|
20
|
+
declare function normalizeTimeZone(value: unknown, fallback?: string): string;
|
|
21
|
+
declare function getClientTimeZone(): string | undefined;
|
|
22
|
+
declare function getSupportedTimeZones(): string[];
|
|
23
|
+
declare function toUtcDayRange(dateOnly: string, timeZone: string): DateFilterRange | undefined;
|
|
24
|
+
declare function resolveDateFilterRange(filter: DateFilterInput, options: {
|
|
25
|
+
timeZone: string;
|
|
26
|
+
clientTimeZone?: string;
|
|
27
|
+
legacyClientTimeZone?: string;
|
|
28
|
+
now?: Date;
|
|
29
|
+
}): DateFilterRange | undefined;
|
|
30
|
+
declare function toUtcDateTime(localValue: string, timeZone: string): Date | undefined;
|
|
31
|
+
declare function toDateTimeLocal(value: Date | string | number, timeZone: string): string;
|
|
32
|
+
declare function formatDateTime(value: Date | string | number, options?: FormatDateTimeOptions): string;
|
|
33
|
+
|
|
34
|
+
export { CLIENT_TIME_ZONE_COOKIE, CLIENT_TIME_ZONE_HEADER, DEFAULT_TIME_ZONE, type DateFilterInput, type DateFilterRange, type DateRangeResolver, type FormatDateTimeOptions, canonicalizeTimeZone, formatDateTime, getClientTimeZone, getSupportedTimeZones, isValidTimeZone, normalizeTimeZone, resolveDateFilterRange, toDateTimeLocal, toUtcDateTime, toUtcDayRange };
|
package/dist/time.js
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import {
|
|
2
|
+
CLIENT_TIME_ZONE_COOKIE,
|
|
3
|
+
CLIENT_TIME_ZONE_HEADER,
|
|
4
|
+
DEFAULT_TIME_ZONE,
|
|
5
|
+
canonicalizeTimeZone,
|
|
6
|
+
formatDateTime,
|
|
7
|
+
getClientTimeZone,
|
|
8
|
+
getSupportedTimeZones,
|
|
9
|
+
isValidTimeZone,
|
|
10
|
+
normalizeTimeZone,
|
|
11
|
+
resolveDateFilterRange,
|
|
12
|
+
toDateTimeLocal,
|
|
13
|
+
toUtcDateTime,
|
|
14
|
+
toUtcDayRange
|
|
15
|
+
} from "./chunk-6GDCFR67.js";
|
|
16
|
+
export {
|
|
17
|
+
CLIENT_TIME_ZONE_COOKIE,
|
|
18
|
+
CLIENT_TIME_ZONE_HEADER,
|
|
19
|
+
DEFAULT_TIME_ZONE,
|
|
20
|
+
canonicalizeTimeZone,
|
|
21
|
+
formatDateTime,
|
|
22
|
+
getClientTimeZone,
|
|
23
|
+
getSupportedTimeZones,
|
|
24
|
+
isValidTimeZone,
|
|
25
|
+
normalizeTimeZone,
|
|
26
|
+
resolveDateFilterRange,
|
|
27
|
+
toDateTimeLocal,
|
|
28
|
+
toUtcDateTime,
|
|
29
|
+
toUtcDayRange
|
|
30
|
+
};
|
|
31
|
+
//# sourceMappingURL=time.js.map
|
package/dist/time.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
package/dist/trpc.d.ts
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import * as _trpc_server from '@trpc/server';
|
|
2
|
+
export { inferRouterInputs, inferRouterOutputs } from '@trpc/server';
|
|
3
|
+
import { a as PluginContext } from './types-8P7XyoyQ.js';
|
|
4
|
+
import './globalization.js';
|
|
5
|
+
import 'decimal.js';
|
|
6
|
+
import './release-CyapqJ3z.js';
|
|
7
|
+
import 'zod';
|
|
8
|
+
import './time.js';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Plugin router builder
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```ts
|
|
15
|
+
* import { pluginRouter, pluginProcedure } from '@wordrhyme/plugin';
|
|
16
|
+
*
|
|
17
|
+
* export const router = pluginRouter({
|
|
18
|
+
* hello: pluginProcedure.query(() => 'Hello from plugin!'),
|
|
19
|
+
* });
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
declare const pluginRouter: _trpc_server.TRPCRouterBuilder<{
|
|
23
|
+
ctx: PluginContext;
|
|
24
|
+
meta: Record<string, unknown>;
|
|
25
|
+
errorShape: _trpc_server.TRPCDefaultErrorShape;
|
|
26
|
+
transformer: false;
|
|
27
|
+
}>;
|
|
28
|
+
/**
|
|
29
|
+
* Plugin procedure builder (with context)
|
|
30
|
+
*
|
|
31
|
+
* Use this to define procedures that have access to PluginContext.
|
|
32
|
+
*/
|
|
33
|
+
declare const pluginProcedure: _trpc_server.TRPCProcedureBuilder<PluginContext, Record<string, unknown>, {}, _trpc_server.TRPCUnsetMarker, _trpc_server.TRPCUnsetMarker, _trpc_server.TRPCUnsetMarker, _trpc_server.TRPCUnsetMarker, false>;
|
|
34
|
+
/**
|
|
35
|
+
* Create plugin context (used by Core to inject context)
|
|
36
|
+
*
|
|
37
|
+
* This is called by PluginManager when invoking plugin handlers.
|
|
38
|
+
*/
|
|
39
|
+
declare function createPluginContext(partial: Partial<PluginContext> & {
|
|
40
|
+
pluginId: string;
|
|
41
|
+
}): PluginContext;
|
|
42
|
+
|
|
43
|
+
export { createPluginContext, pluginProcedure, pluginRouter };
|
package/dist/trpc.js
ADDED
package/dist/trpc.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|