@squadbase/vite-server 0.1.19-dev.6ec878e → 0.1.19-dev.907a033

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.
@@ -622,6 +622,7 @@ import devServer from "@hono/vite-dev-server";
622
622
  import nodeAdapter from "@hono/vite-dev-server/node";
623
623
  import { fileURLToPath } from "url";
624
624
  import path3 from "path";
625
+ import fs from "fs";
625
626
 
626
627
  // src/registry.ts
627
628
  import { readdir, readFile as readFile2, mkdir } from "fs/promises";
@@ -10506,11 +10507,11 @@ var googleAnalyticsOauthOnboarding = new ConnectorOnboarding({
10506
10507
  - \u30A2\u30AB\u30A6\u30F3\u30C8\u304C **1\u4EF6\u306E\u307F**: \`askUserQuestion\` \u306F\u30B9\u30AD\u30C3\u30D7\u3057\u3001\u305D\u306E\u30A2\u30AB\u30A6\u30F3\u30C8\u3092\u9078\u629E\u6E08\u307F\u3068\u3057\u3066\u6B21\u3078\u9032\u3080
10507
10508
  - \u30A2\u30AB\u30A6\u30F3\u30C8\u304C **0\u4EF6**: \u30BB\u30C3\u30C8\u30A2\u30C3\u30D7\u3092\u4E2D\u65AD\u3057\u3001\u30E6\u30FC\u30B6\u30FC\u306B\u30A2\u30AF\u30BB\u30B9\u53EF\u80FD\u306A\u30A2\u30AB\u30A6\u30F3\u30C8\u304C\u306A\u3044\u65E8\u3092\u4F1D\u3048\u308B
10508
10509
  3. \`${listPropertiesToolName}\` \u3092\u547C\u3073\u51FA\u3057\u3066\u3001\u9078\u629E\u3055\u308C\u305F\u30A2\u30AB\u30A6\u30F3\u30C8\u306E\u30D7\u30ED\u30D1\u30C6\u30A3\u4E00\u89A7\u3092\u53D6\u5F97\u3059\u308B
10509
- 4. \`updateConnectionParameters\` \u3092\u547C\u3073\u51FA\u3059:
10510
- - \`parameterSlug\`: \`"property-id"\`
10511
- - \`options\`: \u30D7\u30ED\u30D1\u30C6\u30A3\u4E00\u89A7\u3002\u5404 option \u306E \`label\` \u306F \`\u8868\u793A\u540D (id: \u30D7\u30ED\u30D1\u30C6\u30A3ID)\` \u306E\u5F62\u5F0F\u3001\`value\` \u306F\u30D7\u30ED\u30D1\u30C6\u30A3ID
10512
- - \u30D7\u30ED\u30D1\u30C6\u30A3\u304C **0\u4EF6** \u306E\u5834\u5408\u306F\u30BB\u30C3\u30C8\u30A2\u30C3\u30D7\u3092\u4E2D\u65AD\u3057\u3001\u30E6\u30FC\u30B6\u30FC\u306B\u30A2\u30AF\u30BB\u30B9\u53EF\u80FD\u306A\u30D7\u30ED\u30D1\u30C6\u30A3\u304C\u306A\u3044\u65E8\u3092\u4F1D\u3048\u308B
10513
- 5. \u30E6\u30FC\u30B6\u30FC\u304C\u9078\u629E\u3057\u305F\u30D7\u30ED\u30D1\u30C6\u30A3\u306E \`label\` \u304C\u30E1\u30C3\u30BB\u30FC\u30B8\u3068\u3057\u3066\u5C4A\u304F\u306E\u3067\u3001\u6B21\u306E\u30B9\u30C6\u30C3\u30D7\u306B\u9032\u3080
10510
+ 4. \u30D7\u30ED\u30D1\u30C6\u30A3\u306E\u9078\u629E:
10511
+ - \u30D7\u30ED\u30D1\u30C6\u30A3\u304C **2\u4EF6\u4EE5\u4E0A**: \u300C\u4F7F\u7528\u3059\u308B\u30D7\u30ED\u30D1\u30C6\u30A3\u3092\u9078\u629E\u3057\u3066\u304F\u3060\u3055\u3044\u3002\u300D\u3068\u30E6\u30FC\u30B6\u30FC\u306B\u4F1D\u3048\u305F\u4E0A\u3067\u3001\`askUserQuestion\` \u3092\u547C\u3073\u51FA\u3059\uFF08\`options\`: \u5404 option \u306E \`label\` \u306F \`\u8868\u793A\u540D (id: \u30D7\u30ED\u30D1\u30C6\u30A3ID)\` \u306E\u5F62\u5F0F\u3001\`value\` \u306F\u30D7\u30ED\u30D1\u30C6\u30A3ID\uFF09
10512
+ - \u30D7\u30ED\u30D1\u30C6\u30A3\u304C **1\u4EF6\u306E\u307F**: \`askUserQuestion\` \u306F\u30B9\u30AD\u30C3\u30D7\u3057\u3001\u305D\u306E\u30D7\u30ED\u30D1\u30C6\u30A3\u3092\u9078\u629E\u6E08\u307F\u3068\u3057\u3066\u6B21\u3078\u9032\u3080
10513
+ - \u30D7\u30ED\u30D1\u30C6\u30A3\u304C **0\u4EF6**: \u30BB\u30C3\u30C8\u30A2\u30C3\u30D7\u3092\u4E2D\u65AD\u3057\u3001\u30E6\u30FC\u30B6\u30FC\u306B\u30A2\u30AF\u30BB\u30B9\u53EF\u80FD\u306A\u30D7\u30ED\u30D1\u30C6\u30A3\u304C\u306A\u3044\u65E8\u3092\u4F1D\u3048\u308B
10514
+ 5. \u9078\u629E\u3055\u308C\u305F\u30D7\u30ED\u30D1\u30C6\u30A3ID\uFF08\u6570\u5024\uFF09\u306F\u4EE5\u964D\u306E\u30EA\u30AF\u30A8\u30B9\u30C8\u3067\u30D1\u30B9\u306B\u76F4\u63A5\u6307\u5B9A\u3059\u308B\uFF08\u30B3\u30CD\u30AF\u30B7\u30E7\u30F3\u306B\u306F\u4FDD\u5B58\u3055\u308C\u306A\u3044\uFF09\u3002\u6B21\u306E\u30B9\u30C6\u30C3\u30D7\u306B\u9032\u3080
10514
10515
 
10515
10516
  #### \u5236\u7D04
10516
10517
  - **\u30BB\u30C3\u30C8\u30A2\u30C3\u30D7\u4E2D\u306B\u30EC\u30DD\u30FC\u30C8\u30C7\u30FC\u30BF\u3092\u53D6\u5F97\u3057\u306A\u3044\u3053\u3068**\u3002\u5B9F\u884C\u3057\u3066\u3088\u3044\u306E\u306F\u4E0A\u8A18\u624B\u9806\u3067\u6307\u5B9A\u3055\u308C\u305F\u30E1\u30BF\u30C7\u30FC\u30BF\u53D6\u5F97\u306E\u307F
@@ -10524,11 +10525,11 @@ var googleAnalyticsOauthOnboarding = new ConnectorOnboarding({
10524
10525
  - **Only 1 account**: Skip \`askUserQuestion\` and proceed using that account as the selection
10525
10526
  - **0 accounts**: Abort setup and inform the user that no accessible accounts are available
10526
10527
  3. Call \`${listPropertiesToolName}\` to get the list of properties for the selected account
10527
- 4. Call \`updateConnectionParameters\`:
10528
- - \`parameterSlug\`: \`"property-id"\`
10529
- - \`options\`: The property list. Each option's \`label\` should be \`Display Name (id: propertyId)\`, \`value\` should be the property ID
10530
- - If **0 properties** are returned, abort setup and inform the user that no accessible properties are available
10531
- 5. The \`label\` of the user's selected property will arrive as a message. Proceed to the next step
10528
+ 4. Select a property:
10529
+ - **2 or more properties**: Tell the user "Please select a property.", then call \`askUserQuestion\` (\`options\`: each option's \`label\` should be \`Display Name (id: propertyId)\`, \`value\` should be the property ID)
10530
+ - **Only 1 property**: Skip \`askUserQuestion\` and proceed using that property as the selection
10531
+ - **0 properties**: Abort setup and inform the user that no accessible properties are available
10532
+ 5. Write the selected numeric property id directly into the request path (it is not stored on the connection). Proceed to the next step
10532
10533
 
10533
10534
  #### Constraints
10534
10535
  - **Do NOT fetch report data during setup**. Only the metadata requests specified in the steps above are allowed
@@ -10536,26 +10537,17 @@ var googleAnalyticsOauthOnboarding = new ConnectorOnboarding({
10536
10537
  - Write only 1 sentence between tool calls, then immediately call the next tool. Skip unnecessary explanations and proceed efficiently`
10537
10538
  },
10538
10539
  dataOverviewInstructions: {
10539
- en: `1. Call connector_google-analytics-oauth_request with GET properties/{propertyId}/metadata to list available dimensions and metrics
10540
- 2. Call connector_google-analytics-oauth_request with POST properties/{propertyId}:runReport using a small date range and basic metrics to verify data availability`,
10541
- ja: `1. connector_google-analytics-oauth_request \u3067 GET properties/{propertyId}/metadata \u3092\u547C\u3073\u51FA\u3057\u3001\u5229\u7528\u53EF\u80FD\u306A\u30C7\u30A3\u30E1\u30F3\u30B7\u30E7\u30F3\u3068\u30E1\u30C8\u30EA\u30AF\u30B9\u306E\u4E00\u89A7\u3092\u53D6\u5F97
10542
- 2. connector_google-analytics-oauth_request \u3067 POST properties/{propertyId}:runReport \u3092\u77ED\u3044\u671F\u9593\u3068\u57FA\u672C\u30E1\u30C8\u30EA\u30AF\u30B9\u3067\u547C\u3073\u51FA\u3057\u3001\u30C7\u30FC\u30BF\u306E\u53EF\u7528\u6027\u3092\u78BA\u8A8D`
10540
+ en: `Use the selected numeric property id in the path (write it directly, e.g. properties/123456789).
10541
+ 1. Call connector_google-analytics-oauth_request with GET properties/<propertyId>/metadata to list available dimensions and metrics
10542
+ 2. Call connector_google-analytics-oauth_request with POST properties/<propertyId>:runReport using a small date range and basic metrics to verify data availability`,
10543
+ ja: `\u9078\u629E\u3057\u305F\u6570\u5024\u306E\u30D7\u30ED\u30D1\u30C6\u30A3ID\u3092\u30D1\u30B9\u306B\u76F4\u63A5\u8A18\u8FF0\u3057\u3066\u304F\u3060\u3055\u3044\uFF08\u4F8B: properties/123456789\uFF09\u3002
10544
+ 1. connector_google-analytics-oauth_request \u3067 GET properties/<propertyId>/metadata \u3092\u547C\u3073\u51FA\u3057\u3001\u5229\u7528\u53EF\u80FD\u306A\u30C7\u30A3\u30E1\u30F3\u30B7\u30E7\u30F3\u3068\u30E1\u30C8\u30EA\u30AF\u30B9\u306E\u4E00\u89A7\u3092\u53D6\u5F97
10545
+ 2. connector_google-analytics-oauth_request \u3067 POST properties/<propertyId>:runReport \u3092\u77ED\u3044\u671F\u9593\u3068\u57FA\u672C\u30E1\u30C8\u30EA\u30AF\u30B9\u3067\u547C\u3073\u51FA\u3057\u3001\u30C7\u30FC\u30BF\u306E\u53EF\u7528\u6027\u3092\u78BA\u8A8D`
10543
10546
  }
10544
10547
  });
10545
10548
 
10546
10549
  // ../connectors/src/connectors/google-analytics-oauth/parameters.ts
10547
- init_parameter_definition();
10548
- var parameters16 = {
10549
- propertyId: new ParameterDefinition({
10550
- slug: "property-id",
10551
- name: "Google Analytics Property ID",
10552
- description: "The Google Analytics 4 property ID (e.g., 123456789). Can be found in GA4 Admin > Property Settings.",
10553
- envVarBaseKey: "GA_OAUTH_PROPERTY_ID",
10554
- type: "text",
10555
- secret: false,
10556
- required: false
10557
- })
10558
- };
10550
+ var parameters16 = {};
10559
10551
 
10560
10552
  // ../connectors/src/connectors/google-analytics-oauth/setup-flow.ts
10561
10553
  var ADMIN_BASE_URL4 = "https://analyticsadmin.googleapis.com/v1beta";
@@ -10862,7 +10854,7 @@ var inputSchema25 = z25.object({
10862
10854
  connectionId: z25.string().describe("ID of the Google Analytics OAuth connection to use"),
10863
10855
  method: z25.enum(["GET", "POST"]).describe("HTTP method"),
10864
10856
  path: z25.string().describe(
10865
- "API path appended to https://analyticsdata.googleapis.com/v1beta/ (e.g., 'properties/{propertyId}:runReport'). {propertyId} is automatically replaced."
10857
+ "API path appended to https://analyticsdata.googleapis.com/v1beta/ (e.g., 'properties/123456789:runReport'). Write the numeric property id directly into the path."
10866
10858
  ),
10867
10859
  body: z25.record(z25.string(), z25.unknown()).optional().describe("POST request body (JSON)")
10868
10860
  });
@@ -10881,7 +10873,7 @@ var requestTool4 = new ConnectorTool({
10881
10873
  name: "request",
10882
10874
  description: `Send authenticated requests to the Google Analytics Data API v1beta.
10883
10875
  Authentication is handled automatically via OAuth proxy.
10884
- {propertyId} in the path is automatically replaced with the connection's property ID.`,
10876
+ Write the numeric property id directly into the path (e.g. properties/123456789:runReport).`,
10885
10877
  inputSchema: inputSchema25,
10886
10878
  outputSchema: outputSchema25,
10887
10879
  async execute({ connectionId, method, path: path4, body }, connections, config) {
@@ -10896,9 +10888,7 @@ Authentication is handled automatically via OAuth proxy.
10896
10888
  `[connector-request] google-analytics-oauth/${connection.name}: ${method} ${path4}`
10897
10889
  );
10898
10890
  try {
10899
- const propertyId = parameters16.propertyId.tryGetValue(connection);
10900
- const resolvedPath = propertyId ? path4.replace(/\{propertyId\}/g, propertyId) : path4;
10901
- const url = `${BASE_URL4}${resolvedPath}`;
10891
+ const url = `${BASE_URL4}${path4}`;
10902
10892
  const token = await getProxyToken8(config.oauthProxy);
10903
10893
  const proxyUrl = `https://${config.oauthProxy.sandboxId}.${config.oauthProxy.previewBaseDomain}/_sqcore/connections/${connectionId}/request`;
10904
10894
  const controller = new AbortController();
@@ -10968,7 +10958,7 @@ var googleAnalyticsOauthConnector = new ConnectorPlugin({
10968
10958
  systemPrompt: {
10969
10959
  en: `### Tools
10970
10960
 
10971
- - \`connector_google-analytics-oauth_request\`: Send authenticated requests to the GA4 Data API. Use it for running reports, getting metadata, and realtime reports. The {propertyId} placeholder in paths is automatically replaced. Authentication is configured automatically via OAuth.
10961
+ - \`connector_google-analytics-oauth_request\`: Send authenticated requests to the GA4 Data API. Use it for running reports, getting metadata, and realtime reports. Write the target property into the path as \`properties/{numericPropertyId}\`. Authentication is configured automatically via OAuth.
10972
10962
  - \`connector_google-analytics-oauth_listAccounts\`: List accessible Google Analytics accounts. Use during setup to discover available accounts.
10973
10963
  - \`connector_google-analytics-oauth_listProperties\`: List GA4 properties for a given account. Use during setup to select the target property.
10974
10964
 
@@ -11004,10 +10994,12 @@ averageSessionDuration, conversions, totalRevenue
11004
10994
  The business logic type for this connector is "typescript". Write handler code using the connector SDK shown below. Do NOT access credentials directly from environment variables and do NOT read \`INTERNAL_SQUADBASE_*\` env vars \u2014 the SDK takes care of OAuth.
11005
10995
 
11006
10996
  SDK surface (client created via \`connection(connectionId)\`):
11007
- - \`client.request(path, init?)\` \u2014 low-level authenticated fetch (\`path\` is appended to \`https://analyticsdata.googleapis.com/v1beta/\`).
11008
- - \`client.runReport(request)\` \u2014 run a GA4 report.
11009
- - \`client.runRealtimeReport(request)\` \u2014 run a realtime report.
11010
- - \`client.getMetadata()\` \u2014 fetch available dimensions and metrics.
10997
+ - \`client.runReport(request)\` \u2014 run a GA4 report and get back \`{ rows, rowCount }\` (JSON, already parsed). **This is the primary method \u2014 prefer it over \`request\`.** Pass \`propertyId\` (bare numeric id) on the request object to target a property.
10998
+ - \`client.runRealtimeReport(request)\` \u2014 run a realtime report. \`propertyId\` works the same as \`runReport\`.
10999
+ - \`client.getMetadata(propertyId)\` \u2014 fetch available dimensions and metrics for a property.
11000
+ - \`client.request(path, init?)\` \u2014 low-level authenticated fetch that returns a raw \`Response\` (\`path\` is appended to \`https://analyticsdata.googleapis.com/v1beta/\`; write the numeric property id directly into the path). Only use this for endpoints the convenience methods above do not cover, and remember to \`await res.json()\` yourself.
11001
+
11002
+ **\`propertyId\` is required on every call** \u2014 pass the numeric id from the data overview. A GA connection can span multiple properties, so there is no stored default.
11011
11003
 
11012
11004
  If a handler test fails with \`Connection proxy is not configured\`, retry \u2014 the sandbox is still initializing. Do NOT abandon the SDK and construct OAuth proxy URLs manually.
11013
11005
 
@@ -11017,30 +11009,33 @@ If a handler test fails with \`Connection proxy is not configured\`, retry \u201
11017
11009
  import { connection } from "@squadbase/vite-server/connectors/google-analytics-oauth";
11018
11010
 
11019
11011
  const ga = connection("<connectionId>");
11012
+ const propertyId = "123456789"; // numeric GA4 property id from the data overview
11020
11013
 
11021
- // Authenticated fetch (returns standard Response)
11022
- const res = await ga.request("properties/{propertyId}:runReport", {
11023
- method: "POST",
11024
- body: JSON.stringify({ dateRanges: [{ startDate: "7daysAgo", endDate: "today" }], metrics: [{ name: "activeUsers" }] }),
11025
- });
11026
- const data = await res.json();
11027
-
11028
- // Convenience methods
11014
+ // Convenience methods (pass propertyId explicitly)
11029
11015
  const { rows, rowCount } = await ga.runReport({
11016
+ propertyId,
11030
11017
  dateRanges: [{ startDate: "7daysAgo", endDate: "today" }],
11031
11018
  dimensions: [{ name: "date" }],
11032
11019
  metrics: [{ name: "activeUsers" }, { name: "sessions" }],
11033
11020
  limit: 100,
11034
11021
  });
11035
- const metadata = await ga.getMetadata();
11022
+ const metadata = await ga.getMetadata(propertyId);
11036
11023
  const realtime = await ga.runRealtimeReport({
11024
+ propertyId,
11037
11025
  metrics: [{ name: "activeUsers" }],
11038
11026
  dimensions: [{ name: "country" }],
11039
11027
  });
11028
+
11029
+ // Low-level authenticated fetch (write the numeric property id into the path)
11030
+ const res = await ga.request(\`properties/\${propertyId}:runReport\`, {
11031
+ method: "POST",
11032
+ body: JSON.stringify({ dateRanges: [{ startDate: "7daysAgo", endDate: "today" }], metrics: [{ name: "activeUsers" }] }),
11033
+ });
11034
+ const data = await res.json();
11040
11035
  \`\`\``,
11041
11036
  ja: `### \u30C4\u30FC\u30EB
11042
11037
 
11043
- - \`connector_google-analytics-oauth_request\`: GA4 Data API\u3078\u8A8D\u8A3C\u6E08\u307F\u30EA\u30AF\u30A8\u30B9\u30C8\u3092\u9001\u4FE1\u3057\u307E\u3059\u3002\u30EC\u30DD\u30FC\u30C8\u306E\u5B9F\u884C\u3001\u30E1\u30BF\u30C7\u30FC\u30BF\u306E\u53D6\u5F97\u3001\u30EA\u30A2\u30EB\u30BF\u30A4\u30E0\u30EC\u30DD\u30FC\u30C8\u306B\u4F7F\u7528\u3057\u307E\u3059\u3002\u30D1\u30B9\u5185\u306E{propertyId}\u30D7\u30EC\u30FC\u30B9\u30DB\u30EB\u30C0\u30FC\u306F\u81EA\u52D5\u7684\u306B\u7F6E\u63DB\u3055\u308C\u307E\u3059\u3002OAuth\u7D4C\u7531\u3067\u8A8D\u8A3C\u306F\u81EA\u52D5\u8A2D\u5B9A\u3055\u308C\u307E\u3059\u3002
11038
+ - \`connector_google-analytics-oauth_request\`: GA4 Data API\u3078\u8A8D\u8A3C\u6E08\u307F\u30EA\u30AF\u30A8\u30B9\u30C8\u3092\u9001\u4FE1\u3057\u307E\u3059\u3002\u30EC\u30DD\u30FC\u30C8\u306E\u5B9F\u884C\u3001\u30E1\u30BF\u30C7\u30FC\u30BF\u306E\u53D6\u5F97\u3001\u30EA\u30A2\u30EB\u30BF\u30A4\u30E0\u30EC\u30DD\u30FC\u30C8\u306B\u4F7F\u7528\u3057\u307E\u3059\u3002\u5BFE\u8C61\u30D7\u30ED\u30D1\u30C6\u30A3\u306F\u30D1\u30B9\u306B \`properties/{\u6570\u5024\u306E\u30D7\u30ED\u30D1\u30C6\u30A3ID}\` \u306E\u5F62\u3067\u76F4\u63A5\u8A18\u8FF0\u3057\u3066\u304F\u3060\u3055\u3044\u3002OAuth\u7D4C\u7531\u3067\u8A8D\u8A3C\u306F\u81EA\u52D5\u8A2D\u5B9A\u3055\u308C\u307E\u3059\u3002
11044
11039
  - \`connector_google-analytics-oauth_listAccounts\`: \u30A2\u30AF\u30BB\u30B9\u53EF\u80FD\u306AGoogle Analytics\u30A2\u30AB\u30A6\u30F3\u30C8\u306E\u4E00\u89A7\u3092\u53D6\u5F97\u3057\u307E\u3059\u3002\u30BB\u30C3\u30C8\u30A2\u30C3\u30D7\u6642\u306B\u5229\u7528\u53EF\u80FD\u306A\u30A2\u30AB\u30A6\u30F3\u30C8\u3092\u78BA\u8A8D\u3059\u308B\u305F\u3081\u306B\u4F7F\u7528\u3057\u307E\u3059\u3002
11045
11040
  - \`connector_google-analytics-oauth_listProperties\`: \u6307\u5B9A\u30A2\u30AB\u30A6\u30F3\u30C8\u306EGA4\u30D7\u30ED\u30D1\u30C6\u30A3\u4E00\u89A7\u3092\u53D6\u5F97\u3057\u307E\u3059\u3002\u30BB\u30C3\u30C8\u30A2\u30C3\u30D7\u6642\u306B\u30BF\u30FC\u30B2\u30C3\u30C8\u30D7\u30ED\u30D1\u30C6\u30A3\u3092\u9078\u629E\u3059\u308B\u305F\u3081\u306B\u4F7F\u7528\u3057\u307E\u3059\u3002
11046
11041
 
@@ -11076,10 +11071,12 @@ averageSessionDuration, conversions, totalRevenue
11076
11071
  \u3053\u306E\u30B3\u30CD\u30AF\u30BF\u306E\u30D3\u30B8\u30CD\u30B9\u30ED\u30B8\u30C3\u30AF\u30BF\u30A4\u30D7\u306F "typescript" \u3067\u3059\u3002\u4EE5\u4E0B\u306B\u793A\u3059\u30B3\u30CD\u30AF\u30BF SDK \u3092\u4F7F\u7528\u3057\u3066\u30CF\u30F3\u30C9\u30E9\u30B3\u30FC\u30C9\u3092\u8A18\u8FF0\u3057\u3066\u304F\u3060\u3055\u3044\u3002\u74B0\u5883\u5909\u6570\u304B\u3089\u76F4\u63A5\u8A8D\u8A3C\u60C5\u5831\u306B\u30A2\u30AF\u30BB\u30B9\u3057\u306A\u3044\u3067\u304F\u3060\u3055\u3044\u3002\`INTERNAL_SQUADBASE_*\` \u306E\u74B0\u5883\u5909\u6570\u3092\u4F7F\u3063\u3066\u624B\u52D5\u3067 OAuth \u30D7\u30ED\u30AD\u30B7\u3092\u53E9\u304F\u3053\u3068\u3082\u3057\u306A\u3044\u3067\u304F\u3060\u3055\u3044 \u2014 SDK \u304C OAuth \u3092\u51E6\u7406\u3057\u307E\u3059\u3002
11077
11072
 
11078
11073
  SDK\uFF08\`connection(connectionId)\` \u3067\u4F5C\u6210\u3057\u305F\u30AF\u30E9\u30A4\u30A2\u30F3\u30C8\uFF09:
11079
- - \`client.request(path, init?)\` \u2014 \u4F4E\u30EC\u30D9\u30EB\u306E\u8A8D\u8A3C\u4ED8\u304D fetch\uFF08\`path\` \u306F \`https://analyticsdata.googleapis.com/v1beta/\` \u306B\u8FFD\u52A0\u3055\u308C\u307E\u3059\uFF09\u3002
11080
- - \`client.runReport(request)\` \u2014 GA4 \u30EC\u30DD\u30FC\u30C8\u3092\u5B9F\u884C\u3002
11081
- - \`client.runRealtimeReport(request)\` \u2014 \u30EA\u30A2\u30EB\u30BF\u30A4\u30E0\u30EC\u30DD\u30FC\u30C8\u3092\u5B9F\u884C\u3002
11082
- - \`client.getMetadata()\` \u2014 \u5229\u7528\u53EF\u80FD\u306A\u30C7\u30A3\u30E1\u30F3\u30B7\u30E7\u30F3\u3068\u30E1\u30C8\u30EA\u30AF\u30B9\u3092\u53D6\u5F97\u3002
11074
+ - \`client.runReport(request)\` \u2014 GA4 \u30EC\u30DD\u30FC\u30C8\u3092\u5B9F\u884C\u3057\u3001\`{ rows, rowCount }\`\uFF08\u30D1\u30FC\u30B9\u6E08\u307F JSON\uFF09\u3092\u8FD4\u3057\u307E\u3059\u3002**\u3053\u308C\u304C\u4E3B\u8981\u30E1\u30BD\u30C3\u30C9\u3067\u3059 \u2014 \`request\` \u3088\u308A\u512A\u5148\u3057\u3066\u4F7F\u3063\u3066\u304F\u3060\u3055\u3044\u3002** \u30EA\u30AF\u30A8\u30B9\u30C8\u30AA\u30D6\u30B8\u30A7\u30AF\u30C8\u306B \`propertyId\`\uFF08\u6570\u5024\u306E\u30D7\u30ED\u30D1\u30C6\u30A3ID\uFF09\u3092\u6307\u5B9A\u3057\u3066\u5BFE\u8C61\u30D7\u30ED\u30D1\u30C6\u30A3\u3092\u6C7A\u3081\u307E\u3059\u3002
11075
+ - \`client.runRealtimeReport(request)\` \u2014 \u30EA\u30A2\u30EB\u30BF\u30A4\u30E0\u30EC\u30DD\u30FC\u30C8\u3092\u5B9F\u884C\u3002\`propertyId\` \u306E\u6271\u3044\u306F \`runReport\` \u3068\u540C\u3058\u3067\u3059\u3002
11076
+ - \`client.getMetadata(propertyId)\` \u2014 \u6307\u5B9A\u30D7\u30ED\u30D1\u30C6\u30A3\u306E\u5229\u7528\u53EF\u80FD\u306A\u30C7\u30A3\u30E1\u30F3\u30B7\u30E7\u30F3\u3068\u30E1\u30C8\u30EA\u30AF\u30B9\u3092\u53D6\u5F97\u3002
11077
+ - \`client.request(path, init?)\` \u2014 \u4F4E\u30EC\u30D9\u30EB\u306E\u8A8D\u8A3C\u4ED8\u304D fetch\u3002\u751F\u306E \`Response\` \u3092\u8FD4\u3057\u307E\u3059\uFF08\`path\` \u306F \`https://analyticsdata.googleapis.com/v1beta/\` \u306B\u8FFD\u52A0\u3055\u308C\u307E\u3059\u3002\u6570\u5024\u306E\u30D7\u30ED\u30D1\u30C6\u30A3ID\u3092\u30D1\u30B9\u306B\u76F4\u63A5\u66F8\u3044\u3066\u304F\u3060\u3055\u3044\uFF09\u3002\u4E0A\u8A18\u306E\u4FBF\u5229\u30E1\u30BD\u30C3\u30C9\u3067\u8CC4\u3048\u306A\u3044\u30A8\u30F3\u30C9\u30DD\u30A4\u30F3\u30C8\u306E\u5834\u5408\u306E\u307F\u4F7F\u7528\u3057\u3001\`await res.json()\` \u306F\u81EA\u5206\u3067\u884C\u3063\u3066\u304F\u3060\u3055\u3044\u3002
11078
+
11079
+ **\`propertyId\` \u306F\u3059\u3079\u3066\u306E\u547C\u3073\u51FA\u3057\u3067\u5FC5\u9808\u3067\u3059**\uFF08\u30C7\u30FC\u30BF\u6982\u8981\u306B\u8F09\u3063\u3066\u3044\u308B\u6570\u5024ID\uFF09\u3002GA \u306E\u30B3\u30CD\u30AF\u30B7\u30E7\u30F3\u306F\u8907\u6570\u30D7\u30ED\u30D1\u30C6\u30A3\u306B\u307E\u305F\u304C\u308B\u3053\u3068\u304C\u3042\u308B\u305F\u3081\u3001\u30C7\u30D5\u30A9\u30EB\u30C8\u306F\u4FDD\u5B58\u3055\u308C\u307E\u305B\u3093\u3002
11083
11080
 
11084
11081
  \u30CF\u30F3\u30C9\u30E9\u306E\u30C6\u30B9\u30C8\u304C \`Connection proxy is not configured\` \u3067\u5931\u6557\u3059\u308B\u5834\u5408\u306F\u518D\u8A66\u884C\u3057\u3066\u304F\u3060\u3055\u3044\u3002\u901A\u5E38\u306F\u30B5\u30F3\u30C9\u30DC\u30C3\u30AF\u30B9\u306E\u521D\u671F\u5316\u4E2D\u306B\u8D77\u304D\u307E\u3059\u3002SDK \u3092\u8AE6\u3081\u3066 OAuth \u30D7\u30ED\u30AD\u30B7\u306E URL \u3092\u81EA\u5206\u3067\u7D44\u307F\u7ACB\u3066\u308B\u3053\u3068\u306F **\u3057\u306A\u3044\u3067\u304F\u3060\u3055\u3044**\u3002
11085
11082
 
@@ -11089,37 +11086,36 @@ SDK\uFF08\`connection(connectionId)\` \u3067\u4F5C\u6210\u3057\u305F\u30AF\u30E9
11089
11086
  import { connection } from "@squadbase/vite-server/connectors/google-analytics-oauth";
11090
11087
 
11091
11088
  const ga = connection("<connectionId>");
11089
+ const propertyId = "123456789"; // \u30C7\u30FC\u30BF\u6982\u8981\u306B\u8F09\u3063\u3066\u3044\u308B\u6570\u5024\u306E GA4 \u30D7\u30ED\u30D1\u30C6\u30A3ID
11092
11090
 
11093
- // Authenticated fetch (returns standard Response)
11094
- const res = await ga.request("properties/{propertyId}:runReport", {
11095
- method: "POST",
11096
- body: JSON.stringify({ dateRanges: [{ startDate: "7daysAgo", endDate: "today" }], metrics: [{ name: "activeUsers" }] }),
11097
- });
11098
- const data = await res.json();
11099
-
11100
- // Convenience methods
11091
+ // \u4FBF\u5229\u30E1\u30BD\u30C3\u30C9\uFF08propertyId \u3092\u660E\u793A\u7684\u306B\u6E21\u3059\uFF09
11101
11092
  const { rows, rowCount } = await ga.runReport({
11093
+ propertyId,
11102
11094
  dateRanges: [{ startDate: "7daysAgo", endDate: "today" }],
11103
11095
  dimensions: [{ name: "date" }],
11104
11096
  metrics: [{ name: "activeUsers" }, { name: "sessions" }],
11105
11097
  limit: 100,
11106
11098
  });
11107
- const metadata = await ga.getMetadata();
11099
+ const metadata = await ga.getMetadata(propertyId);
11108
11100
  const realtime = await ga.runRealtimeReport({
11101
+ propertyId,
11109
11102
  metrics: [{ name: "activeUsers" }],
11110
11103
  dimensions: [{ name: "country" }],
11111
11104
  });
11105
+
11106
+ // \u4F4E\u30EC\u30D9\u30EB\u306E\u8A8D\u8A3C\u4ED8\u304D fetch\uFF08\u6570\u5024\u306E\u30D7\u30ED\u30D1\u30C6\u30A3ID\u3092\u30D1\u30B9\u306B\u76F4\u63A5\u66F8\u304F\uFF09
11107
+ const res = await ga.request(\`properties/\${propertyId}:runReport\`, {
11108
+ method: "POST",
11109
+ body: JSON.stringify({ dateRanges: [{ startDate: "7daysAgo", endDate: "today" }], metrics: [{ name: "activeUsers" }] }),
11110
+ });
11111
+ const data = await res.json();
11112
11112
  \`\`\``
11113
11113
  },
11114
11114
  tools: tools16,
11115
11115
  setup: (params, ctx, config) => runSetupFlow(googleAnalyticsOauthSetupFlow, params, ctx, config),
11116
- async checkConnection(params, config) {
11116
+ async checkConnection(_params, config) {
11117
11117
  const { proxyFetch } = config;
11118
- const propertyId = params[parameters16.propertyId.slug];
11119
- if (!propertyId) {
11120
- return { success: true };
11121
- }
11122
- const url = `https://analyticsdata.googleapis.com/v1beta/properties/${propertyId}/metadata`;
11118
+ const url = "https://analyticsadmin.googleapis.com/v1beta/accountSummaries";
11123
11119
  try {
11124
11120
  const res = await proxyFetch(url, { method: "GET" });
11125
11121
  if (!res.ok) {
@@ -47421,6 +47417,23 @@ var viteServer = null;
47421
47417
  function setViteServer(server) {
47422
47418
  viteServer = server;
47423
47419
  }
47420
+ function validateHandlerPath(dirPath, handlerPath) {
47421
+ const normalizedDir = path2.resolve(dirPath);
47422
+ const dirBase = path2.basename(normalizedDir);
47423
+ let normalized = handlerPath.replace(/^\.?[/\\]/, "");
47424
+ const prefix = dirBase + "/";
47425
+ if (normalized.startsWith(prefix)) {
47426
+ normalized = normalized.slice(prefix.length);
47427
+ }
47428
+ const absolute = path2.resolve(dirPath, normalized);
47429
+ if (!absolute.startsWith(normalizedDir + path2.sep)) {
47430
+ throw new Error(`Handler path escapes server-logic directory: ${handlerPath}`);
47431
+ }
47432
+ if (!absolute.endsWith(".ts")) {
47433
+ throw new Error(`Handler must be a .ts file: ${handlerPath}`);
47434
+ }
47435
+ return absolute;
47436
+ }
47424
47437
  var defaultServerLogicDir = path2.join(process.cwd(), "server-logic");
47425
47438
 
47426
47439
  // src/vite-plugin.ts
@@ -47435,20 +47448,17 @@ var DEFAULT_EXCLUDE = [
47435
47448
  /^\/node_modules\/.*/,
47436
47449
  /^(?!\/api)/
47437
47450
  ];
47438
- function resolveEntry(entry) {
47439
- if (entry.startsWith(".") || entry.startsWith("/")) return entry;
47440
- try {
47441
- const resolvedUrl = import.meta.resolve(entry);
47442
- const absolutePath = fileURLToPath(resolvedUrl);
47443
- const relativePath = path3.relative(process.cwd(), absolutePath).replace(/\\/g, "/");
47444
- return "./" + relativePath;
47445
- } catch {
47446
- return entry;
47447
- }
47451
+ var SERVER_LOGICS_VIRTUAL = "virtual:squadbase-server-logics";
47452
+ var SERVER_LOGICS_RESOLVED = "\0" + SERVER_LOGICS_VIRTUAL;
47453
+ function resolveServerBuildEntry() {
47454
+ const absolute = fileURLToPath(new URL("../build-entry/server-entry.mjs", import.meta.url));
47455
+ return "./" + path3.relative(process.cwd(), absolute).replace(/\\/g, "/");
47456
+ }
47457
+ function resolveServerLogicDir() {
47458
+ return process.env.SERVER_LOGIC_DIR || process.env.DATA_SOURCE_DIR || path3.resolve(process.cwd(), "server-logic");
47448
47459
  }
47449
47460
  function squadbasePlugin(options = {}) {
47450
47461
  const {
47451
- buildEntry = "@squadbase/vite-server/main",
47452
47462
  devEntry = "@squadbase/vite-server",
47453
47463
  external = [
47454
47464
  "pg",
@@ -47460,16 +47470,68 @@ function squadbasePlugin(options = {}) {
47460
47470
  "@aws-sdk/client-cost-explorer",
47461
47471
  "@aws-sdk/client-redshift-data",
47462
47472
  "@google-analytics/data",
47463
- "@kintone/rest-api-client",
47464
- // jiti はランタイムで server-logic/*.ts をトランスパイルするため、
47465
- // @hono/vite-build がサーバービルドにバンドルしないよう external にする。
47466
- "jiti"
47473
+ "@kintone/rest-api-client"
47467
47474
  ],
47468
47475
  exclude = DEFAULT_EXCLUDE
47469
47476
  } = options;
47470
47477
  const isServerBuild = (_, { command, mode }) => command === "build" && mode !== "client";
47478
+ const serverLogicBarrelPlugin = {
47479
+ name: "squadbase-server-logic-barrel",
47480
+ apply: isServerBuild,
47481
+ resolveId(id) {
47482
+ if (id === SERVER_LOGICS_VIRTUAL) return SERVER_LOGICS_RESOLVED;
47483
+ return null;
47484
+ },
47485
+ load(id) {
47486
+ if (id !== SERVER_LOGICS_RESOLVED) return null;
47487
+ const dir = resolveServerLogicDir();
47488
+ let jsonFiles = [];
47489
+ try {
47490
+ jsonFiles = fs.readdirSync(dir).filter((f) => f.endsWith(".json"));
47491
+ } catch {
47492
+ }
47493
+ let imports = "";
47494
+ let entries = "";
47495
+ jsonFiles.forEach((file, i) => {
47496
+ const slug = file.replace(/\.json$/, "");
47497
+ let raw;
47498
+ try {
47499
+ raw = JSON.parse(fs.readFileSync(path3.join(dir, file), "utf-8"));
47500
+ } catch {
47501
+ console.warn(`[squadbase] skipping ${file}: invalid JSON`);
47502
+ return;
47503
+ }
47504
+ const parsed = anyJsonServerLogicSchema.safeParse(raw);
47505
+ if (!parsed.success) return;
47506
+ const def = parsed.data;
47507
+ if (def.type !== "typescript") return;
47508
+ let handlerAbs;
47509
+ try {
47510
+ handlerAbs = validateHandlerPath(dir, def.handlerPath);
47511
+ } catch (e) {
47512
+ console.warn(
47513
+ `[squadbase] skipping server logic '${slug}': ${e.message}`
47514
+ );
47515
+ return;
47516
+ }
47517
+ if (!fs.existsSync(handlerAbs)) {
47518
+ console.warn(
47519
+ `[squadbase] skipping server logic '${slug}': handler file not found (${def.handlerPath})`
47520
+ );
47521
+ return;
47522
+ }
47523
+ imports += `import h${i} from ${JSON.stringify(handlerAbs)};
47524
+ `;
47525
+ entries += ` ${JSON.stringify(slug)}: h${i},
47526
+ `;
47527
+ });
47528
+ return `${imports}export const HANDLERS = {
47529
+ ${entries}};
47530
+ `;
47531
+ }
47532
+ };
47471
47533
  const rawBuildPlugin = buildPlugin({
47472
- entry: resolveEntry(buildEntry),
47534
+ entry: resolveServerBuildEntry(),
47473
47535
  outputDir: "./dist/server",
47474
47536
  output: "index.js",
47475
47537
  external
@@ -47492,7 +47554,7 @@ function squadbasePlugin(options = {}) {
47492
47554
  setViteServer(server);
47493
47555
  }
47494
47556
  };
47495
- return [...buildPlugins, ...devPlugins, viteServerInjectionPlugin];
47557
+ return [serverLogicBarrelPlugin, ...buildPlugins, ...devPlugins, viteServerInjectionPlugin];
47496
47558
  }
47497
47559
  export {
47498
47560
  squadbasePlugin
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@squadbase/vite-server",
3
- "version": "0.1.19-dev.6ec878e",
3
+ "version": "0.1.19-dev.907a033",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": {
@@ -325,7 +325,8 @@
325
325
  }
326
326
  },
327
327
  "files": [
328
- "dist"
328
+ "dist",
329
+ "build-entry"
329
330
  ],
330
331
  "publishConfig": {
331
332
  "access": "public",
@@ -355,7 +356,6 @@
355
356
  "@kintone/rest-api-client": "^5.5.0",
356
357
  "google-auth-library": "^9.15.1",
357
358
  "hono": "^4.12.25",
358
- "jiti": "^2.7.0",
359
359
  "mongodb": "^7.1.1",
360
360
  "mssql": "^11.0.1",
361
361
  "mysql2": "^3.11.0",