diff --git a/bin/looker-resources-index/.gitignore b/bin/looker-resources-index/.gitignore new file mode 100644 index 000000000..79eb78346 --- /dev/null +++ b/bin/looker-resources-index/.gitignore @@ -0,0 +1,2 @@ +node_modules +tmp \ No newline at end of file diff --git a/bin/looker-resources-index/README.md b/bin/looker-resources-index/README.md new file mode 100644 index 000000000..a42b6c9c2 --- /dev/null +++ b/bin/looker-resources-index/README.md @@ -0,0 +1,18 @@ +# Looker Resources Index + +This folder contains data (in code) about Looker-related resources and scripts to maintain and repackage that data for publication. + +The main location that the data is maintained is in `src/resource-data/resources.ts` + +The main output of these scripts is a JSON file in `../../docs/resources` intended to be checked in to git and consumed via CDN. You may also import the typescript exports from this folder, for example to benefit from type declarations. + +* Before use, install dependencies with `yarn install` +* To run tests & reports about the resources data, `yarn run analyze` +* To build the distributable JSON file, run `yarn run build` + +## Sample Use Cases + +- Create a "resource explorer" UI (for developer portal or hackathons) +- Generate a "home"/"index" page for the developer portal +- Generate an "Overview" page for each platform feature page (e.g. Actions, API, etc.) +- Find and embed "related resources" into specific articles and content \ No newline at end of file diff --git a/bin/looker-resources-index/package.json b/bin/looker-resources-index/package.json new file mode 100644 index 000000000..72833582d --- /dev/null +++ b/bin/looker-resources-index/package.json @@ -0,0 +1,21 @@ +{ + "name": "looker-resources-index", + "description": "A listing of Looker-related resources, and some automation for publishing the listing in consumable formats", + "main": "src/resource-data/resources.ts", + "private": true, + "engines": { + "node": ">=12.0.0" + }, + "scripts": { + "start": "echo \"No 'start' command available. Did you want to 'build'?\"", + "build": "node_modules/.bin/tsc --project . && node tmp/compiled-typescript/scripts/build.js", + "analyze": "node_modules/.bin/tsc --project . && node tmp/compiled-typescript/scripts/analyze/cli.js", + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "Looker", + "license": "MIT", + "devDependencies": { + "@types/node": "^16.11.13", + "typescript": "^4.5.4" + } +} diff --git a/bin/looker-resources-index/src/resource-data/definitions.ts b/bin/looker-resources-index/src/resource-data/definitions.ts new file mode 100644 index 000000000..108f670cd --- /dev/null +++ b/bin/looker-resources-index/src/resource-data/definitions.ts @@ -0,0 +1,42 @@ +/* + + MIT License + + Copyright (c) 2021 Looker Data Sciences, Inc. + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + + */ +import type { LocaleString } from '../types' +import { ContentType } from '../types' + +export const contentType: Record = { + [ContentType.demo]: + 'Demo content demonstrates a use case and/or business value without the need for coding, configuration, or installation.', + [ContentType.sandbox]: + 'Sandbox content allows interactive testing, coding, and simulation, without the need for setup or installation.', + [ContentType.sampleCode]: + 'Sample code refers to illustrative code, usually simplified, that is representative of code that would be written by an application or service that integrates with one of our platform features.', + [ContentType.sourceCode]: + 'Source code refers to the underlying code that defines our integrations. It is available for our open-source platform features, such as the Action API. It can often play a similar role to reference material, and can be much more complex than sample code.', + [ContentType.library]: + 'Code that can be consumed as a dependency of other code, usually via a package/module manager', + [ContentType.installableCode]: + 'Installable code is template or sample code that can also be directly deployed and then modified, often through existing automation such as the Looker Marketplace, without the need to first adapt it.', +} diff --git a/bin/looker-resources-index/src/resource-data/resources.ts b/bin/looker-resources-index/src/resource-data/resources.ts new file mode 100644 index 000000000..9e4230002 --- /dev/null +++ b/bin/looker-resources-index/src/resource-data/resources.ts @@ -0,0 +1,638 @@ +/* + + MIT License + + Copyright (c) 2021 Looker Data Sciences, Inc. + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + + */ +import type { Resource } from '../types' +import { ContentType, Language, Persona, PlatformFeature } from '../types' + +// Common, unambiguous values for conciseness +const { + tutorial, + demo, + sandbox, + tool, + library, + sampleCode, + reference, + sourceCode, + video, +} = ContentType +const { javascript, typescript, python } = Language +const { + admin, + developer, + frontendDeveloper, + backendDeveloper, + modeler, + analyst, + investigator, +} = Persona +const { + actions, + api, + components, + embed, + extensions, + git, + customVisualization, +} = PlatformFeature + +export const resources: Resource[] = [ + { + id: '//atomfashion.io', + title: 'Embed Demo', + description: "A comprehensive demo of Looker's embedding capabilities", + url: 'https://atomfashion.io/', + isGoogleResource: true, + contentTypes: [demo], + platformFeatures: [embed, api], + personas: [developer, frontendDeveloper], + }, + { + id: '//community.looker.com/looker-api-77/creating-a-development-environment-for-custom-visualizations-8470', + title: 'Custom Viz Dev Environment Setup', + description: 'A tutorial to build a custom viz development environment', + url: 'https://community.looker.com/looker-api-77/creating-a-development-environment-for-custom-visualizations-8470', + contentTypes: [tutorial, sampleCode], + platformFeatures: [customVisualization], + languages: [typescript], + personas: [developer, frontendDeveloper, analyst], + }, + { + id: '//community.looker.com/lookml-5/automating-frequently-changing-schemas-with-aws-lambda-10196', + title: 'Automate Schema Changes', + description: + 'Learn how to set up your Looker instance to poll and make changes to your LookML model with an AWS Lambda function.', + url: 'https://community.looker.com/lookml-5/automating-frequently-changing-schemas-with-aws-lambda-10196', + contentTypes: [tutorial, sampleCode], + platformFeatures: [git, PlatformFeature.lookml], + languages: [python], + personas: [developer, backendDeveloper, modeler], + }, + { + id: '//community.looker.com/open-source-projects-78/export-the-results-of-a-looker-query-to-bigquery-9720', + title: 'BigQuery Writeback Action', + description: + 'Learn how to write an action that exports the results of a Looker Query to BigQuery.', + url: 'https://community.looker.com/open-source-projects-78/export-the-results-of-a-looker-query-to-bigquery-9720', + contentTypes: [tutorial, sampleCode], + platformFeatures: [actions], + languages: [python, Language.lookml], + personas: [developer, backendDeveloper, analyst], + }, + { + id: '//components.looker.com', + title: 'Looker Components', + description: + 'Looker Components are a collection of tools for building Looker data experiences.', + url: 'https://components.looker.com/', + isGoogleResource: true, + contentTypes: [reference], + platformFeatures: [components], + personas: [developer, frontendDeveloper], + }, + { + id: '//components.looker.com/storybook', + title: 'Components Examples Storybook', + description: 'Looker Components Storybook contains component examples', + url: 'https://components.looker.com/storybook', + isGoogleResource: true, + contentTypes: [reference, demo, sandbox], + platformFeatures: [components], + personas: [developer, frontendDeveloper], + }, + { + id: '//covid19response.cloud.looker.com/embed/dashboards-next/51', + title: 'COVID-19 Dashboards', + description: 'Prebuilt dashboards for immediate access to COVID-19 data.', + url: 'https://covid19response.cloud.looker.com/embed/dashboards-next/51', + contentTypes: [demo], + platformFeatures: [], + personas: [modeler, analyst, investigator], + }, + { + id: '//developers.looker.com/components/visualization-components', + title: 'Visualization Components Playground', + description: + "An interactive demonstration of Looker's new Visualization Components", + url: 'https://developers.looker.com/components/visualization-components', + contentTypes: [sandbox], + platformFeatures: [components], + personas: [developer, frontendDeveloper], + }, + { + id: '//fabio-looker.github.io/looker_sso_tool', + title: 'SSO Embed Tool', + description: + 'This tool helps you troubleshoot SSO embed URLs generated by your scripts.', + url: 'https://fabio-looker.github.io/looker_sso_tool/', + contentTypes: [tool, sandbox], + platformFeatures: [embed], + personas: [developer], + }, + { + id: '//github.com/brechtv/looker_google_sheets', + title: 'Looker API for Google Sheets', + description: + 'This Google Apps Script uses Looker API to load Looks, get data dictionaries, etc.', + url: 'https://github.com/brechtv/looker_google_sheets', + contentTypes: [sampleCode], + platformFeatures: [api], + languages: [javascript], + personas: [developer, analyst], + }, + { + id: '//github.com/bryan-at-looker/looker-feed', + title: 'Looker Feed Extension Mockup', + description: 'An early-stage mockup of a Twitter-style Looker Extension.', + url: 'https://github.com/bryan-at-looker/looker-feed', + contentTypes: [sampleCode], + platformFeatures: [extensions], + languages: [typescript], + personas: [developer], + }, + { + id: '//github.com/fabio-looker/eav-builder', + title: 'EAV Builder', + description: 'An automated EAV builder for EAV schemas.', + url: 'https://github.com/fabio-looker/eav-builder', + contentTypes: [tool], + platformFeatures: [PlatformFeature.lookml], + personas: [developer, modeler], + }, + { + id: '//github.com/fabio-looker/looker_sso_tool', + title: 'SSO Embed Tool Source', + description: + 'The source code for the SSO embed tool for you to extend or run locally.', + url: 'https://github.com/fabio-looker/looker_sso_tool', + contentTypes: [tool], + platformFeatures: [embed], + languages: [javascript], + personas: [developer], + }, + { + id: '//github.com/fabio-looker/sample-cloud-function-action', + title: 'Sample Action for Google Cloud Functions', + description: + 'Sample code for an Action & ActionHub, for use on Google Cloud Functions (serverless)', + url: 'https://github.com/fabio-looker/sample-cloud-function-action', + contentTypes: [sampleCode], + platformFeatures: [actions], + languages: [javascript], + personas: [developer, backendDeveloper], + }, + { + id: '//github.com/fishtown-analytics/dbtdocs-to-lookml', + title: 'DBTdocs To LookML', + description: + 'A tool to persist descriptions from your dbt project to your lookml project.', + url: 'https://github.com/fishtown-analytics/dbtdocs-to-lookml', + isGoogleResource: false, + contentTypes: [tool], + platformFeatures: [PlatformFeature.lookml], + personas: [developer, modeler], + }, + { + id: '//github.com/Headset/looker-environment', + title: 'Custom Vis Dev Environment Example', + description: + 'An example custom viz development environment developed by Headset. (may be out of date)', + url: 'https://github.com/Headset/looker-environment', + isGoogleResource: false, + contentTypes: [sampleCode], + platformFeatures: [customVisualization], + languages: [typescript], + personas: [developer, frontendDeveloper], + }, + { + id: '//github.com/joshtemple/lkml', + title: 'LookML parser', + description: 'A LookML parser and serializer implemented in Python.', + url: 'https://github.com/joshtemple/lkml', + isGoogleResource: false, + contentTypes: [tool, library], + platformFeatures: [PlatformFeature.lookml], + languages: [python], + personas: [developer, backendDeveloper, modeler], + }, + { + id: '//github.com/Ladvien/vscode-looker', + title: 'LookML VSCode Syntax', + description: 'VSCode syntax for LookML. (may be out of date)', + url: 'https://github.com/Ladvien/vscode-looker', + isGoogleResource: false, + contentTypes: [tool], + platformFeatures: [PlatformFeature.lookml], + personas: [developer, modeler], + }, + { + id: '//github.com/leighajarett/JSON_to_LookML', + title: 'JSON To LookML', + description: + 'This script was designed for data tables with JSON objects. It creates a LookML view file with a dimension for each JSON object field. (may be out of date)', + url: 'https://github.com/leighajarett/JSON_to_LookML', + contentTypes: [tool], + platformFeatures: [PlatformFeature.lookml], + personas: [developer, modeler], + }, + { + id: '//github.com/looker-open-source/app-data-dictionary', + title: 'Data Dictionary Extension', + description: + 'This is the official Looker Data Dictionary, fully open source and available as an example.', + url: 'https://github.com/looker-open-source/app-data-dictionary', + isGoogleResource: true, + contentTypes: [sampleCode], + platformFeatures: [extensions], + languages: [typescript], + personas: [developer, modeler, analyst, investigator], + }, + { + id: '//github.com/looker-open-source/chatty', + title: 'Chatty - Iframe Msg Manager', + description: + 'Chatty is a simple web browser iframe host/client channel message manager. We use it for iframe communication.', + url: 'https://github.com/looker-open-source/chatty', + isGoogleResource: true, + contentTypes: [library, sourceCode], + platformFeatures: [embed], + languages: [typescript], + personas: [developer, frontendDeveloper], + }, + { + id: '//github.com/looker-open-source/create-looker-extension', + title: 'Extension Creation Utility', + description: + 'Create extensions with zero manual configuration with the create-looker-extension utility.', + url: 'https://github.com/looker-open-source/create-looker-extension', + contentTypes: [tool, ContentType.template], + platformFeatures: [extensions], + languages: [typescript, javascript], + personas: [developer, frontendDeveloper], + }, + { + id: '//github.com/looker-open-source/embed-sdk', + title: 'Embed SDK', + description: + 'The Looker JavaScript Embed SDK makes embedding Looker content in your web application easy!', + url: 'https://github.com/looker-open-source/embed-sdk', + isGoogleResource: true, + contentTypes: [library, sourceCode], + platformFeatures: [embed], + languages: [javascript, typescript], + personas: [developer], + }, + { + id: '//github.com/looker-open-source/extension-examples', + title: 'Extension Framework Examples', + description: + 'A repository with multiple Extension Framework examples using Typescript, Javascript, React, and Redux', + url: 'https://github.com/looker-open-source/extension-examples', + isGoogleResource: true, + contentTypes: [sampleCode], + platformFeatures: [extensions], + languages: [javascript, typescript], + personas: [developer, frontendDeveloper], + }, + { + id: '//github.com/looker-open-source/extension-examples/tree/main/react/typescript/access-key-demo', + title: 'Extension Example: Access Key', + description: + 'This example demonstrates how to write a Looker extension that needs an access key to run.', + url: 'https://github.com/looker-open-source/extension-examples/tree/main/react/typescript/access-key-demo', + isGoogleResource: true, + contentTypes: [sampleCode], + platformFeatures: [extensions], + languages: [typescript], + personas: [developer, frontendDeveloper], + }, + { + id: '//github.com/looker-open-source/extension-examples/tree/main/react/typescript/kitchensink', + title: 'Extension Example: Kitchensink', + description: + "This example demonstrates most of Extension SDK's functionality and is a great starting point.", + url: 'https://github.com/looker-open-source/extension-examples/tree/main/react/typescript/kitchensink', + isGoogleResource: true, + contentTypes: [sampleCode], + platformFeatures: [extensions], + languages: [typescript], + personas: [developer, frontendDeveloper], + }, + { + id: '//github.com/looker-open-source/gzr', + title: 'Gzr', + description: 'Gzr is a Looker Content Utility developer tool', + url: 'https://github.com/looker-open-source/gzr', + isGoogleResource: true, + contentTypes: [tool, sourceCode], + platformFeatures: [api], + languages: [Language.ruby], + personas: [developer, backendDeveloper, admin], + }, + { + id: '//github.com/looker-open-source/healthcare_demo', + title: 'Sample LookML: Healthcare', + description: + 'A BigQuery-based LookML project that demonstrates Looker’s value in the healthcare landscape.', + url: 'https://github.com/looker-open-source/healthcare_demo', + contentTypes: [sampleCode], + languages: [Language.lookml], + platformFeatures: [PlatformFeature.lookml], + personas: [modeler], + }, + { + id: '//github.com/looker-open-source/henry', + title: 'Henry', + description: + 'Henry is a command line tool that finds model bloat in your Looker instance and identifies unused content in models and explores.', + url: 'https://github.com/looker-open-source/henry', + isGoogleResource: true, + contentTypes: [tool, sourceCode], + languages: [python], + platformFeatures: [api, PlatformFeature.lookml], + personas: [modeler, admin], + }, + { + id: '//github.com/looker-open-source/look-at-me-sideways', + title: 'LookML Style Guide & Linter', + description: + 'Look At Me Sideways (LAMS) is the official LookML style guide and linter to help you create maintainable LookML projects.', + url: 'https://github.com/looker-open-source/look-at-me-sideways', + isGoogleResource: true, + contentTypes: [tool, sourceCode], + platformFeatures: [PlatformFeature.lookml], + personas: [modeler, admin], + languages: [javascript], + }, + { + id: '//github.com/looker-open-source/lookr', + title: 'Looker R SDK 3.0', + description: 'Looker 3.0 SDK for R', + url: 'https://github.com/looker-open-source/lookr', + contentTypes: [library, sourceCode], + languages: [Language.r], + platformFeatures: [api, PlatformFeature.sdk], + personas: [developer], + }, + { + id: '//github.com/looker-open-source/marketing_demo', + title: 'Sample LookML: Digital Marketing', + description: + 'A Snowflake-based LookML project that demonstrates Looker’s value in the digital marketing landscape.', + url: 'https://github.com/looker-open-source/marketing_demo', + contentTypes: [sampleCode], + languages: [Language.lookml], + platformFeatures: [PlatformFeature.lookml], + personas: [modeler], + }, + { + id: '//github.com/looker-open-source/sdk-codegen', + title: 'SDK Codegen', + description: + 'The SDK Codegen is the source of truth for all SDKs and lets you create them for any language', + url: 'https://github.com/looker-open-source/sdk-codegen', + contentTypes: [library], + platformFeatures: [api, PlatformFeature.sdk], + languages: [ + Language.cSharp, + Language.go, + Language.kotlin, + python, + Language.r, + Language.ruby, + Language.swift, + typescript, + ], + personas: [developer], + }, + { + id: '//github.com/looker-open-source/sdk-codegen/tree/main/examples', + title: 'SDK Examples', + description: + 'Our collection of SDK examples currently in: C#, Java, Kotlin, Python, R, Ruby, Swift, and TypeScript.', + url: 'https://github.com/looker-open-source/sdk-codegen/tree/main/examples', + contentTypes: [sampleCode], + languages: [ + Language.cSharp, + Language.go, + Language.kotlin, + python, + Language.r, + Language.ruby, + Language.swift, + typescript, + ], + platformFeatures: [api, PlatformFeature.sdk], + personas: [developer], + }, + { + id: '//github.com/looker/actions', + title: 'Action Hub Source', + description: + 'The official Looker Action Hub repository for all your action requirements and examples.', + url: 'https://github.com/looker/actions', + contentTypes: [sourceCode, reference], + platformFeatures: [actions], + languages: [typescript], + personas: [developer, backendDeveloper], + }, + { + id: '//github.com/looker/actions/tree/master/src/actions', + title: 'Actions Source', + description: + 'Direct link to the directory of all complete Actions in the official action hub.', + url: 'https://github.com/looker/actions/tree/master/src/actions', + contentTypes: [sourceCode, sampleCode], + platformFeatures: [actions], + languages: [typescript], + personas: [developer, backendDeveloper], + }, + { + id: '//github.com/looker/covid19', + title: 'COVID-19 Data Block', + description: + 'This COVID-19 Block consists of LookML models, pre-built dashboards, and explores. The underlying data is only available in BigQuery.', + url: 'https://github.com/looker/covid19', + contentTypes: [sampleCode], + platformFeatures: [PlatformFeature.lookml], + personas: [modeler], + languages: [Language.lookml], + }, + { + id: '//github.com/looker/custom_visualizations_v2', + title: 'Custom Visualizations v2', + description: + 'The official repository of Looker Custom Visualizations API and examples', + url: 'https://github.com/looker/custom_visualizations_v2', + contentTypes: [reference, sampleCode], + platformFeatures: [customVisualization], + personas: [developer, Persona.frontendDeveloper], + languages: [typescript], + }, + { + id: '//github.com/looker/looker_embed_sso_examples', + title: 'Looker Embed SSO Examples', + description: + "Examples of performing Looker's SSO Embed URL signing in various server-side languages", + url: 'https://github.com/looker/looker_embed_sso_examples', + contentTypes: [sampleCode], + platformFeatures: [embed], + languages: [ + Language.cSharp, + Language.go, + javascript, + Language.php, + python, + Language.ruby, + ], + personas: [developer, backendDeveloper], + }, + { + id: '//github.com/thalesmello/lkml.vim', + title: 'LookML Vim Syntax', + description: 'Vim syntax for LookML. (may be out of date)', + url: 'https://github.com/thalesmello/lkml.vim', + contentTypes: [tool], + platformFeatures: [PlatformFeature.lookml], + personas: [modeler], + }, + { + id: '//github.com/ww-tech/lookml-tools', + title: "WW's LookML Tools", + description: + 'Developed by WW, this repository contains tools to handle best practices with developing LookML files.', + url: 'https://github.com/ww-tech/lookml-tools', + contentTypes: [tool, sampleCode], + platformFeatures: [PlatformFeature.lookml], + personas: [modeler], + languages: [python], + }, + { + id: '//gitlab.com/alison985/awesome-looker', + title: 'Awesome Looker Projects', + description: 'An awesome list of awesome Looker projects.', + url: 'https://gitlab.com/alison985/awesome-looker/-/tree/main', + contentTypes: [ContentType.other], + personas: [Persona.other], + }, + { + id: '//hack.looker.com/dashboards/16', + title: 'BQ Public Datasets on hack.looker.com', + description: 'BigQuery PublicHackathon', + url: 'https://hack.looker.com/dashboards/16', + isHackathonSpecific: true, + contentTypes: [ContentType.data], + personas: [modeler, analyst, investigator], + }, + { + id: '//hack.looker.com/extensions/marketplace_extension_api_explorer::api-explorer', + title: 'API Explorer on hack.looker.com', + description: + 'The API Explorer lets you learn and interact with the Looker API.', + url: 'https://hack.looker.com/extensions/marketplace_extension_api_explorer::api-explorer', + isHackathonSpecific: true, + contentTypes: [tool], + platformFeatures: [api], + personas: [developer], + }, + { + id: '//lookervisbuilder.com', + title: 'Custom Viz Builder', + description: + 'A Web IDE/sandbox to help develop Looker Custom Visualizations.', + url: 'https://lookervisbuilder.com/', + contentTypes: [sandbox], + platformFeatures: [customVisualization], + personas: [developer, frontendDeveloper, analyst], + }, + { + id: '//www.npmjs.com/package/@looker/extension-sdk-react', + title: 'Extension SDK: React', + description: + 'The React Extension SDK npm package. This lets you build a Looker extension — See the Extension Framework Examples for examples.', + url: 'https://www.npmjs.com/package/@looker/extension-sdk-react', + contentTypes: [library], + platformFeatures: [extensions], + languages: [javascript], + personas: [developer, frontendDeveloper], + }, + { + id: '//www.youtube.com/watch?v=3lbq5w7kcLs', + title: 'Extension Framework Tutorial Video', + description: + 'A JOIN 2021 tutorial video on developing with the Extension Framework.', + url: 'https://www.youtube.com/watch?v=3lbq5w7kcLs', + contentTypes: [tutorial, video], + platformFeatures: [extensions], + personas: [developer, frontendDeveloper], + }, + { + id: '//www.youtube.com/watch?v=DnIG0pD3UNA', + title: 'Actions Tutorial Video', + description: 'A JOIN 2021 tutorial video on creating actions.', + url: 'https://www.youtube.com/watch?v=DnIG0pD3UNA', + contentTypes: [tutorial, video], + platformFeatures: [actions], + personas: [developer, backendDeveloper], + }, + { + id: '//www.youtube.com/watch?v=ixwWGKyG3wA', + title: 'Custom Viz Demo Video', + description: 'An older demo of Lookers custom viz capabilities', + url: 'https://www.youtube.com/watch?v=ixwWGKyG3wA', + contentTypes: [tutorial, video], + platformFeatures: [customVisualization], + personas: [developer, frontendDeveloper, analyst], + }, + { + id: '//www.youtube.com/watch?v=kOanUnTMDpg', + title: 'API Explorer & API Tutorial Video', + description: + 'A JOIN 2021 tutorial video on using API Explorer and Looker API.', + url: 'https://www.youtube.com/watch?v=kOanUnTMDpg', + contentTypes: [tutorial, video], + platformFeatures: [api], + personas: [developer], + }, + { + id: '//www.youtube.com/watch?v=rSWX6oAOtMs', + title: 'Visualization Components Demo Video', + description: + 'A JOIN 2021 intro and demo video of the new visualization components.', + url: 'https://www.youtube.com/watch?v=rSWX6oAOtMs', + contentTypes: [demo, video], + platformFeatures: [actions], + personas: [developer, frontendDeveloper], + }, + { + id: '//www.youtube.com/watch?v=XTvJjCeAT74', + title: 'Embed Tutorial Video', + description: 'A JOIN 2021 tutorial video on Iframe and SSO Embedding.', + url: 'https://www.youtube.com/watch?v=XTvJjCeAT74', + contentTypes: [tutorial, video], + platformFeatures: [embed], + personas: [developer], + }, +] diff --git a/bin/looker-resources-index/src/scripts/analyze/cli.ts b/bin/looker-resources-index/src/scripts/analyze/cli.ts new file mode 100644 index 000000000..7070b311c --- /dev/null +++ b/bin/looker-resources-index/src/scripts/analyze/cli.ts @@ -0,0 +1,59 @@ +/* + + MIT License + + Copyright (c) 2021 Looker Data Sciences, Inc. + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + + */ + +/* eslint no-console: "off" */ + +import { resources } from '../../resource-data/resources' + +import * as analyze from './index' + +report() + +function report() { + const results: Record = {} + + results.missingLanguages = analyze.missingLanguages(resources) + if (results.missingLanguages.actionItems.length > 0) { + console.log('\n### Missing Languages ###\n') + console.log(results.missingLanguages.actionItems.join('\n')) + } + + results.missingPersonas = analyze.missingPersonas(resources) + if (results.missingPersonas.actionItems.length > 0) { + console.log('\n### Missing Personas ###\n') + console.log(results.missingPersonas.actionItems.join('\n')) + } + + console.log('\n### Platform Feature x Content Type Coverage Matrix ###\n') + results.platformFeatureXContentType = + analyze.platformFeatureXContentType(resources) + console.table(results.platformFeatureXContentType.table) + + console.log('\n### Summary ###\n') + Object.values(results) + .filter((r) => r.summary) + .forEach((r) => console.log(r.summary)) +} diff --git a/bin/looker-resources-index/src/scripts/analyze/index.ts b/bin/looker-resources-index/src/scripts/analyze/index.ts new file mode 100644 index 000000000..ec2650744 --- /dev/null +++ b/bin/looker-resources-index/src/scripts/analyze/index.ts @@ -0,0 +1,28 @@ +/* + + MIT License + + Copyright (c) 2021 Looker Data Sciences, Inc. + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + + */ +export * from './missing-languages' +export * from './missing-personas' +export * from './platform-feature-x-content-type' diff --git a/bin/looker-resources-index/src/scripts/analyze/missing-languages.ts b/bin/looker-resources-index/src/scripts/analyze/missing-languages.ts new file mode 100644 index 000000000..02a164a5d --- /dev/null +++ b/bin/looker-resources-index/src/scripts/analyze/missing-languages.ts @@ -0,0 +1,58 @@ +/* + + MIT License + + Copyright (c) 2021 Looker Data Sciences, Inc. + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + + */ +import type { Resource } from '../../types' +import { ContentType } from '../../types' + +export function missingLanguages(resources: Resource[]) { + const isTargetContentType = (c: ContentType) => + [ + ContentType.sampleCode, + ContentType.sourceCode, + ContentType.template, + ContentType.library, + ].includes(c) + + const resourcesRequiringLanguages = resources.filter((r) => + r.contentTypes?.some(isTargetContentType) + ) + + const resourcesMissingLanguages = resourcesRequiringLanguages.filter( + (r) => !r.languages || r.languages.length === 0 + ) + + return { + summary: + resourcesMissingLanguages.length === 0 + ? `✅\tAll ${resourcesRequiringLanguages.length} resources that should have a language have one` + : `⚠️\t${resourcesMissingLanguages.length} of ${resourcesRequiringLanguages.length} resources that should have a language are missing them`, + actionItems: resourcesMissingLanguages.map( + (r) => + `No languages declared, with a contentType '${r.contentTypes.find( + isTargetContentType + )}'\tResource ID: ${r.id}` + ), + } +} diff --git a/bin/looker-resources-index/src/scripts/analyze/missing-personas.ts b/bin/looker-resources-index/src/scripts/analyze/missing-personas.ts new file mode 100644 index 000000000..1ed66f71f --- /dev/null +++ b/bin/looker-resources-index/src/scripts/analyze/missing-personas.ts @@ -0,0 +1,42 @@ +/* + + MIT License + + Copyright (c) 2021 Looker Data Sciences, Inc. + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + + */ +import type { Resource } from '../../types' + +export function missingPersonas(resources: Resource[]) { + const resourcesMissingPersonas = resources.filter( + (r) => !r.personas || r.personas.length === 0 + ) + + return { + summary: + resourcesMissingPersonas.length === 0 + ? `✅\tAll ${resources.length} resources have personas defined` + : `⚠️\t${resourcesMissingPersonas.length} of ${resources.length} resources are missing personas`, + actionItems: resourcesMissingPersonas.map( + (r) => `No personas defined. \tResource ID: ${r.id}` + ), + } +} diff --git a/bin/looker-resources-index/src/scripts/analyze/platform-feature-x-content-type.ts b/bin/looker-resources-index/src/scripts/analyze/platform-feature-x-content-type.ts new file mode 100644 index 000000000..c8149d893 --- /dev/null +++ b/bin/looker-resources-index/src/scripts/analyze/platform-feature-x-content-type.ts @@ -0,0 +1,61 @@ +/* + + MIT License + + Copyright (c) 2021 Looker Data Sciences, Inc. + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + + */ +import type { Resource } from '../../types' +import { PlatformFeature, ContentType } from '../../types' + +export function platformFeatureXContentType(resources: Resource[]) { + const rows = Object.keys(PlatformFeature) as PlatformFeature[] + const rowField = 'platformFeatures' + const cols = [ + ContentType.demo, + ContentType.sandbox, + ContentType.sampleCode, + ContentType.reference, + ] + const colField = 'contentTypes' + + const table = Object.fromEntries( + rows.map((row) => { + const resourcesForRow = resources.filter((rsc) => + rsc[rowField]?.includes(row) + ) + return [ + row, + Object.fromEntries( + cols.map((col) => [ + col, + resourcesForRow.filter((rsc) => rsc[colField]?.includes(col)) + .length || null, + ]) + ), + ] + }) + ) + + return { + table, + } +} diff --git a/bin/looker-resources-index/src/scripts/build.ts b/bin/looker-resources-index/src/scripts/build.ts new file mode 100644 index 000000000..c706b1ce4 --- /dev/null +++ b/bin/looker-resources-index/src/scripts/build.ts @@ -0,0 +1,122 @@ +/* + + MIT License + + Copyright (c) 2021 Looker Data Sciences, Inc. + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + + */ + +/* eslint no-console: "off" */ + +import * as fs from 'fs' +import * as path from 'path' +import * as crypto from 'crypto' +import { resources } from '../resource-data/resources' +import type { Resource } from '../types' + +main() + +async function main() { + // File paths are relative to built JS folder (/tmp/compiled-typesript) + const resourcesPath = '../../../../../docs/resources/resources.json' + const resourceLockPath = '../../../../../docs/resources/resource-lock.json' + + const priorResourcesBundle = tryJsonParse(await readFile(resourcesPath), {}) + const priorResources = (priorResourcesBundle.resources || []) as Resource[] + const priorResourceLock = tryJsonParse( + await readFile(resourceLockPath), + undefined + ) + + if (priorResourceLock) { + const modifiedResources = priorResources.filter( + (r) => priorResourceLock[r.id] !== resourceDigest(r) + ) + if (modifiedResources.length) { + console.error( + "The output resources.json file seems to have been manually edited. The following id's have unexpected values:" + ) + modifiedResources.forEach((r) => console.error(' > ' + r.id)) + console.error( + 'After ensuring that all manually modified data is reflected in the resource source data, delete the resource-lock.json file and re-build' + ) + process.exit(1) + } + } + + const resourcesLock = Object.fromEntries( + resources.map((r) => [r.id, resourceDigest(r)]) + ) + + console.log('Writing resources.json') + await writeFile(resourcesPath, format(resources)) + console.log('Writing lockfile') + await writeFile(resourceLockPath, JSON.stringify(resourcesLock, undefined, 2)) + console.log('Done!') +} + +function writeFile(fp: string, contents: string) { + return new Promise((resolve, reject) => { + fs.writeFile( + path.resolve(__dirname, fp), + contents, + { encoding: 'utf-8' }, + (err) => { + err ? reject(err) : resolve() + } + ) + }) +} +function readFile(fp: string) { + return new Promise((resolve, reject) => { + fs.readFile( + path.resolve(__dirname, fp), + { encoding: 'utf-8' }, + (err, str) => { + err ? reject(err) : resolve(str) + } + ) + }) +} + +function format(resources: Resource[]): string { + const sortedResources = resources.sort((a, b) => a.id.localeCompare(b.id)) // Sort by id + return `{ + "resources":[ + ${sortedResources.map(resourceToJson).join(',\n\t\t')} + ] +}` +} + +function resourceToJson(r: Resource) { + const { id, ...rest } = r + return JSON.stringify({ id, ...rest }) +} +function resourceDigest(r: Resource) { + return crypto.createHash('sha1').update(resourceToJson(r)).digest('hex') +} +function tryJsonParse(str: string, dft: any) { + try { + return JSON.parse(str) + } catch (e) { + return dft + } +} diff --git a/bin/looker-resources-index/src/types.ts b/bin/looker-resources-index/src/types.ts new file mode 100644 index 000000000..8dd829141 --- /dev/null +++ b/bin/looker-resources-index/src/types.ts @@ -0,0 +1,120 @@ +/* + + MIT License + + Copyright (c) 2021 Looker Data Sciences, Inc. + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + + */ + +export interface Resource { + id: ResourceId + title: LocaleString + description: LocaleString + url: LocaleString + + // Optional + isGoogleResource?: boolean + isHackathonSpecific?: boolean + thumbnailImageUrl?: LocaleString + // publishDate + // lastUpdate + // authorNames + // authorAvatars + // some form of rating or quality metric? + + // Optional "tags" + contentTypes?: ContentType[] + platformFeatures?: PlatformFeature[] + languages?: Language[] + licenses?: License[] + relatedResources?: ResourceId[] + personas?: Persona[] + tags?: string[] +} + +export enum ContentType { + article = 'article', + tutorial = 'tutorial', + course = 'course', + workshop = 'workshop', + demo = 'demo', + sandbox = 'sandbox', + tool = 'tool', + library = 'library', + reference = 'reference', + sampleCode = 'sampleCode', + sourceCode = 'sourceCode', + template = 'template', + installableCode = 'installableCode', + data = 'data', + video = 'video', + other = 'other', +} + +export enum PlatformFeature { + actions = 'actions', + api = 'api', + components = 'components', + embed = 'embed', + extensions = 'extensions', + git = 'git', + lookml = 'lookml', + oauth = 'oauth', + sdk = 'sdk', + customVisualization = 'customVisualization', + other = 'other', +} + +export enum Language { + javascript = 'javascript', + typescript = 'typescript', + python = 'python', + ruby = 'ruby', + cSharp = 'cSharp', + kotlin = 'kotlin', + swift = 'swift', + go = 'go', + r = 'r', + php = 'php', + lookml = 'lookml', + other = 'other', +} + +export enum License { + mit = 'mit', + unlicensed = 'unlicensed', + other = 'other', + unknown = 'unknown', +} + +export enum Persona { + developer = 'developer', + frontendDeveloper = 'developer/frontend', + backendDeveloper = 'developer/backend', + modeler = 'modeler', + admin = 'admin', + analyst = 'analyst', + investigator = 'viewer', + other = 'other', +} + +export type ResourceId = string +export type LocaleString = string | Record diff --git a/bin/looker-resources-index/tsconfig.json b/bin/looker-resources-index/tsconfig.json new file mode 100644 index 000000000..5706fb933 --- /dev/null +++ b/bin/looker-resources-index/tsconfig.json @@ -0,0 +1,21 @@ +{ + "compilerOptions": { + "module": "commonjs", + "target": "es6", + "noImplicitAny": true, + "moduleResolution": "node", + "sourceMap": true, + "outDir": "tmp/compiled-typescript", + "baseUrl": ".", + "types": ["node"], + "lib":["es2019"], + "paths": { + "*": [ + "node_modules/*" + ] + } + }, + "include": [ + "src/**/*" + ] + } diff --git a/bin/looker-resources-index/yarn.lock b/bin/looker-resources-index/yarn.lock new file mode 100644 index 000000000..a0c137dc9 --- /dev/null +++ b/bin/looker-resources-index/yarn.lock @@ -0,0 +1,13 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@types/node@^16.11.13": + version "16.11.15" + resolved "https://registry.yarnpkg.com/@types/node/-/node-16.11.15.tgz#724da13bc1ba99fe8190d0f5cd35cb53c67db942" + integrity sha512-LMGR7iUjwZRxoYnfc9+YELxwqkaLmkJlo4/HUvOMyGvw9DaHO0gtAbH2FUdoFE6PXBTYZIT7x610r7kdo8o1fQ== + +typescript@^4.5.4: + version "4.5.4" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.5.4.tgz#a17d3a0263bf5c8723b9c52f43c5084edf13c2e8" + integrity sha512-VgYs2A2QIRuGphtzFV7aQJduJ2gyfTljngLzjpfW9FoYZF6xuw1W0vW9ghCKLfcWrCFxK81CSGRAvS1pn4fIUg== diff --git a/docs/resources/README.md b/docs/resources/README.md new file mode 100644 index 000000000..41a9eb7ba --- /dev/null +++ b/docs/resources/README.md @@ -0,0 +1,7 @@ +# Looker Resources Index + +The `resources.json` file contained in this directory provides an index of Looker-related resources, primarily aimed at developers and hackathon attendees. + +**The JSON file is generated. Do not modify it directly, as any direct modifications will be overwritten** + +To modify the contents of the JSON file, edit the source code/data in [`/bin/looker-resources-index`](../../bin/looker-resources-index) and then `yarn install && yarn run build` in that directory. diff --git a/docs/resources/resource-lock.json b/docs/resources/resource-lock.json new file mode 100644 index 000000000..aa2c07179 --- /dev/null +++ b/docs/resources/resource-lock.json @@ -0,0 +1,54 @@ +{ + "//atomfashion.io": "87007cabb29f4fc842722d7e3aed874efeb6a548", + "//community.looker.com/looker-api-77/creating-a-development-environment-for-custom-visualizations-8470": "8befb72b1e55f34148718172476b5fddf69673a0", + "//community.looker.com/lookml-5/automating-frequently-changing-schemas-with-aws-lambda-10196": "1db0bf513f02a4d0d52e2d3910cfc766c700a74b", + "//community.looker.com/open-source-projects-78/export-the-results-of-a-looker-query-to-bigquery-9720": "b9ece0d7f18d588d92367d30e68a6b3a4f05df37", + "//components.looker.com": "8c797dee5da61d122de953896a9d58bc68b4b12c", + "//components.looker.com/storybook": "95c00003b7a575dc39bae080bab47d621bcf96fc", + "//covid19response.cloud.looker.com/embed/dashboards-next/51": "ad20438c40079d1a78146370ef611fd5bbd9ac0b", + "//developers.looker.com/components/visualization-components": "55782fe46c179bb3f0afb12257caad9ca15e954c", + "//fabio-looker.github.io/looker_sso_tool": "1a57aa95e3ed78b6c99e150c3164b87965418db1", + "//github.com/brechtv/looker_google_sheets": "0f3cee1b54657cadf29138c968768cee01579a2e", + "//github.com/bryan-at-looker/looker-feed": "8082fed5376319d818267ea33a27c7a08e55a3ef", + "//github.com/fabio-looker/eav-builder": "b8a9c939e2ba9f59a8c1f49a46c978b6a0014bf2", + "//github.com/fabio-looker/looker_sso_tool": "2b474f7bf2c2067588565fd41869eabb49f9ac80", + "//github.com/fabio-looker/sample-cloud-function-action": "55c67d2af0cacfbc8f0c9f7fa4cc02d5369d1bd9", + "//github.com/fishtown-analytics/dbtdocs-to-lookml": "d0edf4c42031a9d04f5bb6ed79ab436c0bfbf13f", + "//github.com/Headset/looker-environment": "50ad7786205c542f6afc190389c7cf6f00650bd2", + "//github.com/joshtemple/lkml": "f33ec53f57db04ad79105650f94e89620186f9cf", + "//github.com/Ladvien/vscode-looker": "f078cac5d6b9ceda6feee3d2c3cd67ab6de6cafb", + "//github.com/leighajarett/JSON_to_LookML": "3ecd7aaf2d401dc16a47ea86fc6fa72d49219e57", + "//github.com/looker-open-source/app-data-dictionary": "8291c14083d5470addbff0c5a141d288ac8bd021", + "//github.com/looker-open-source/chatty": "c4635d36de084f469de5bd28ce3ef10511fb4318", + "//github.com/looker-open-source/create-looker-extension": "1594db51c86fdc37fa3b2810cc8074b3117ec50e", + "//github.com/looker-open-source/embed-sdk": "237b02d898cf77423156fca032cb9b5c5da9befd", + "//github.com/looker-open-source/extension-examples": "9169a61b4e03af314ccd7bd7d2fa18bb647a0693", + "//github.com/looker-open-source/extension-examples/tree/main/react/typescript/access-key-demo": "1d3b0ca4b549190c81f6ae2f7e5b13dd1a5457f5", + "//github.com/looker-open-source/extension-examples/tree/main/react/typescript/kitchensink": "b01959aeb50b64642306069f9a6c26136bb1f92e", + "//github.com/looker-open-source/gzr": "4e75f2538bdbb392499e330da5f54accfd2f69dc", + "//github.com/looker-open-source/healthcare_demo": "d8b200073ca4c02ed84b78fd7eb912795c13221c", + "//github.com/looker-open-source/henry": "3bdad003c121838e7ed54c7c28e1119cc55bc978", + "//github.com/looker-open-source/look-at-me-sideways": "aace9499a5595efad4d6f250614e537a9520631a", + "//github.com/looker-open-source/lookr": "c71205386cf4d87abf1f16ba6f5c03b0aafdffa9", + "//github.com/looker-open-source/marketing_demo": "d046079b5a92cfdaa15afd2ad31905b1d5f43fe0", + "//github.com/looker-open-source/sdk-codegen": "aadba42a72fccb18ecc3d0bd1d6a18c7a2c2fffb", + "//github.com/looker-open-source/sdk-codegen/tree/main/examples": "3bdcb80a3a678450f205a31e88042ab5985eecd7", + "//github.com/looker/actions": "6a53e788412cbdea65f9f3134269638612175a11", + "//github.com/looker/actions/tree/master/src/actions": "9baed3d2b6f655b82c369233deb90d82842c5889", + "//github.com/looker/covid19": "b2c24412494a84894c72e9d772dd7708f92f13b8", + "//github.com/looker/custom_visualizations_v2": "82049c0f67afb046bce752ed95d3ffbdd2a015f2", + "//github.com/looker/looker_embed_sso_examples": "363508bacd6993633a513a0ccba2816fb2f28b40", + "//github.com/thalesmello/lkml.vim": "0766f29998d12c4ff33bf9063c0e1aeddbf526af", + "//github.com/ww-tech/lookml-tools": "4d1b1bdb04752765cf750628d97c729eb88ac4cf", + "//gitlab.com/alison985/awesome-looker": "383678a45475a2bc538444d764b8fb0bfaa2bff3", + "//hack.looker.com/dashboards/16": "ec72c7602cddc830d94d2784f11bb644639649a5", + "//hack.looker.com/extensions/marketplace_extension_api_explorer::api-explorer": "77d3f83064c41ab0346ab2336e92521520bb7418", + "//lookervisbuilder.com": "80f8bf8773c214914c03f41c31f0a59d64e14510", + "//www.npmjs.com/package/@looker/extension-sdk-react": "cea4a63a97b5ac140ae2330c520c1c26bf6d290e", + "//www.youtube.com/watch?v=3lbq5w7kcLs": "62fafda0ed587142a949af10e1c0d8e1aa9c4735", + "//www.youtube.com/watch?v=DnIG0pD3UNA": "5196e0897b976d26d1bf841fd627163175ced7a0", + "//www.youtube.com/watch?v=ixwWGKyG3wA": "7f97721ab7d45616a0b0a67084ec4a9d18993450", + "//www.youtube.com/watch?v=kOanUnTMDpg": "51cd19921e99ff9065a9edc4ec2e7b58c69660ce", + "//www.youtube.com/watch?v=rSWX6oAOtMs": "89abb980cb9a2ae918e16b3972e2d7ea00478d43", + "//www.youtube.com/watch?v=XTvJjCeAT74": "4eb245b17fe7b8d140c0eed3a08dac175559d409" +} \ No newline at end of file diff --git a/docs/resources/resources.json b/docs/resources/resources.json new file mode 100644 index 000000000..f9b6f27b3 --- /dev/null +++ b/docs/resources/resources.json @@ -0,0 +1,56 @@ +{ + "resources":[ + {"id":"//atomfashion.io","title":"Embed Demo","description":"A comprehensive demo of Looker's embedding capabilities","url":"https://atomfashion.io/","isGoogleResource":true,"contentTypes":["demo"],"platformFeatures":["embed","api"],"personas":["developer","developer/frontend"]}, + {"id":"//community.looker.com/looker-api-77/creating-a-development-environment-for-custom-visualizations-8470","title":"Custom Viz Dev Environment Setup","description":"A tutorial to build a custom viz development environment","url":"https://community.looker.com/looker-api-77/creating-a-development-environment-for-custom-visualizations-8470","contentTypes":["tutorial","sampleCode"],"platformFeatures":["customVisualization"],"languages":["typescript"],"personas":["developer","developer/frontend","analyst"]}, + {"id":"//community.looker.com/lookml-5/automating-frequently-changing-schemas-with-aws-lambda-10196","title":"Automate Schema Changes","description":"Learn how to set up your Looker instance to poll and make changes to your LookML model with an AWS Lambda function.","url":"https://community.looker.com/lookml-5/automating-frequently-changing-schemas-with-aws-lambda-10196","contentTypes":["tutorial","sampleCode"],"platformFeatures":["git","lookml"],"languages":["python"],"personas":["developer","developer/backend","modeler"]}, + {"id":"//community.looker.com/open-source-projects-78/export-the-results-of-a-looker-query-to-bigquery-9720","title":"BigQuery Writeback Action","description":"Learn how to write an action that exports the results of a Looker Query to BigQuery.","url":"https://community.looker.com/open-source-projects-78/export-the-results-of-a-looker-query-to-bigquery-9720","contentTypes":["tutorial","sampleCode"],"platformFeatures":["actions"],"languages":["python","lookml"],"personas":["developer","developer/backend","analyst"]}, + {"id":"//components.looker.com","title":"Looker Components","description":"Looker Components are a collection of tools for building Looker data experiences.","url":"https://components.looker.com/","isGoogleResource":true,"contentTypes":["reference"],"platformFeatures":["components"],"personas":["developer","developer/frontend"]}, + {"id":"//components.looker.com/storybook","title":"Components Examples Storybook","description":"Looker Components Storybook contains component examples","url":"https://components.looker.com/storybook","isGoogleResource":true,"contentTypes":["reference","demo","sandbox"],"platformFeatures":["components"],"personas":["developer","developer/frontend"]}, + {"id":"//covid19response.cloud.looker.com/embed/dashboards-next/51","title":"COVID-19 Dashboards","description":"Prebuilt dashboards for immediate access to COVID-19 data.","url":"https://covid19response.cloud.looker.com/embed/dashboards-next/51","contentTypes":["demo"],"platformFeatures":[],"personas":["modeler","analyst","viewer"]}, + {"id":"//developers.looker.com/components/visualization-components","title":"Visualization Components Playground","description":"An interactive demonstration of Looker's new Visualization Components","url":"https://developers.looker.com/components/visualization-components","contentTypes":["sandbox"],"platformFeatures":["components"],"personas":["developer","developer/frontend"]}, + {"id":"//fabio-looker.github.io/looker_sso_tool","title":"SSO Embed Tool","description":"This tool helps you troubleshoot SSO embed URLs generated by your scripts.","url":"https://fabio-looker.github.io/looker_sso_tool/","contentTypes":["tool","sandbox"],"platformFeatures":["embed"],"personas":["developer"]}, + {"id":"//github.com/brechtv/looker_google_sheets","title":"Looker API for Google Sheets","description":"This Google Apps Script uses Looker API to load Looks, get data dictionaries, etc.","url":"https://github.com/brechtv/looker_google_sheets","contentTypes":["sampleCode"],"platformFeatures":["api"],"languages":["javascript"],"personas":["developer","analyst"]}, + {"id":"//github.com/bryan-at-looker/looker-feed","title":"Looker Feed Extension Mockup","description":"An early-stage mockup of a Twitter-style Looker Extension.","url":"https://github.com/bryan-at-looker/looker-feed","contentTypes":["sampleCode"],"platformFeatures":["extensions"],"languages":["typescript"],"personas":["developer"]}, + {"id":"//github.com/fabio-looker/eav-builder","title":"EAV Builder","description":"An automated EAV builder for EAV schemas.","url":"https://github.com/fabio-looker/eav-builder","contentTypes":["tool"],"platformFeatures":["lookml"],"personas":["developer","modeler"]}, + {"id":"//github.com/fabio-looker/looker_sso_tool","title":"SSO Embed Tool Source","description":"The source code for the SSO embed tool for you to extend or run locally.","url":"https://github.com/fabio-looker/looker_sso_tool","contentTypes":["tool"],"platformFeatures":["embed"],"languages":["javascript"],"personas":["developer"]}, + {"id":"//github.com/fabio-looker/sample-cloud-function-action","title":"Sample Action for Google Cloud Functions","description":"Sample code for an Action & ActionHub, for use on Google Cloud Functions (serverless)","url":"https://github.com/fabio-looker/sample-cloud-function-action","contentTypes":["sampleCode"],"platformFeatures":["actions"],"languages":["javascript"],"personas":["developer","developer/backend"]}, + {"id":"//github.com/fishtown-analytics/dbtdocs-to-lookml","title":"DBTdocs To LookML","description":"A tool to persist descriptions from your dbt project to your lookml project.","url":"https://github.com/fishtown-analytics/dbtdocs-to-lookml","isGoogleResource":false,"contentTypes":["tool"],"platformFeatures":["lookml"],"personas":["developer","modeler"]}, + {"id":"//github.com/Headset/looker-environment","title":"Custom Vis Dev Environment Example","description":"An example custom viz development environment developed by Headset. (may be out of date)","url":"https://github.com/Headset/looker-environment","isGoogleResource":false,"contentTypes":["sampleCode"],"platformFeatures":["customVisualization"],"languages":["typescript"],"personas":["developer","developer/frontend"]}, + {"id":"//github.com/joshtemple/lkml","title":"LookML parser","description":"A LookML parser and serializer implemented in Python.","url":"https://github.com/joshtemple/lkml","isGoogleResource":false,"contentTypes":["tool","library"],"platformFeatures":["lookml"],"languages":["python"],"personas":["developer","developer/backend","modeler"]}, + {"id":"//github.com/Ladvien/vscode-looker","title":"LookML VSCode Syntax","description":"VSCode syntax for LookML. (may be out of date)","url":"https://github.com/Ladvien/vscode-looker","isGoogleResource":false,"contentTypes":["tool"],"platformFeatures":["lookml"],"personas":["developer","modeler"]}, + {"id":"//github.com/leighajarett/JSON_to_LookML","title":"JSON To LookML","description":"This script was designed for data tables with JSON objects. It creates a LookML view file with a dimension for each JSON object field. (may be out of date)","url":"https://github.com/leighajarett/JSON_to_LookML","contentTypes":["tool"],"platformFeatures":["lookml"],"personas":["developer","modeler"]}, + {"id":"//github.com/looker-open-source/app-data-dictionary","title":"Data Dictionary Extension","description":"This is the official Looker Data Dictionary, fully open source and available as an example.","url":"https://github.com/looker-open-source/app-data-dictionary","isGoogleResource":true,"contentTypes":["sampleCode"],"platformFeatures":["extensions"],"languages":["typescript"],"personas":["developer","modeler","analyst","viewer"]}, + {"id":"//github.com/looker-open-source/chatty","title":"Chatty - Iframe Msg Manager","description":"Chatty is a simple web browser iframe host/client channel message manager. We use it for iframe communication.","url":"https://github.com/looker-open-source/chatty","isGoogleResource":true,"contentTypes":["library","sourceCode"],"platformFeatures":["embed"],"languages":["typescript"],"personas":["developer","developer/frontend"]}, + {"id":"//github.com/looker-open-source/create-looker-extension","title":"Extension Creation Utility","description":"Create extensions with zero manual configuration with the create-looker-extension utility.","url":"https://github.com/looker-open-source/create-looker-extension","contentTypes":["tool","template"],"platformFeatures":["extensions"],"languages":["typescript","javascript"],"personas":["developer","developer/frontend"]}, + {"id":"//github.com/looker-open-source/embed-sdk","title":"Embed SDK","description":"The Looker JavaScript Embed SDK makes embedding Looker content in your web application easy!","url":"https://github.com/looker-open-source/embed-sdk","isGoogleResource":true,"contentTypes":["library","sourceCode"],"platformFeatures":["embed"],"languages":["javascript","typescript"],"personas":["developer"]}, + {"id":"//github.com/looker-open-source/extension-examples","title":"Extension Framework Examples","description":"A repository with multiple Extension Framework examples using Typescript, Javascript, React, and Redux","url":"https://github.com/looker-open-source/extension-examples","isGoogleResource":true,"contentTypes":["sampleCode"],"platformFeatures":["extensions"],"languages":["javascript","typescript"],"personas":["developer","developer/frontend"]}, + {"id":"//github.com/looker-open-source/extension-examples/tree/main/react/typescript/access-key-demo","title":"Extension Example: Access Key","description":"This example demonstrates how to write a Looker extension that needs an access key to run.","url":"https://github.com/looker-open-source/extension-examples/tree/main/react/typescript/access-key-demo","isGoogleResource":true,"contentTypes":["sampleCode"],"platformFeatures":["extensions"],"languages":["typescript"],"personas":["developer","developer/frontend"]}, + {"id":"//github.com/looker-open-source/extension-examples/tree/main/react/typescript/kitchensink","title":"Extension Example: Kitchensink","description":"This example demonstrates most of Extension SDK's functionality and is a great starting point.","url":"https://github.com/looker-open-source/extension-examples/tree/main/react/typescript/kitchensink","isGoogleResource":true,"contentTypes":["sampleCode"],"platformFeatures":["extensions"],"languages":["typescript"],"personas":["developer","developer/frontend"]}, + {"id":"//github.com/looker-open-source/gzr","title":"Gzr","description":"Gzr is a Looker Content Utility developer tool","url":"https://github.com/looker-open-source/gzr","isGoogleResource":true,"contentTypes":["tool","sourceCode"],"platformFeatures":["api"],"languages":["ruby"],"personas":["developer","developer/backend","admin"]}, + {"id":"//github.com/looker-open-source/healthcare_demo","title":"Sample LookML: Healthcare","description":"A BigQuery-based LookML project that demonstrates Looker’s value in the healthcare landscape.","url":"https://github.com/looker-open-source/healthcare_demo","contentTypes":["sampleCode"],"languages":["lookml"],"platformFeatures":["lookml"],"personas":["modeler"]}, + {"id":"//github.com/looker-open-source/henry","title":"Henry","description":"Henry is a command line tool that finds model bloat in your Looker instance and identifies unused content in models and explores.","url":"https://github.com/looker-open-source/henry","isGoogleResource":true,"contentTypes":["tool","sourceCode"],"languages":["python"],"platformFeatures":["api","lookml"],"personas":["modeler","admin"]}, + {"id":"//github.com/looker-open-source/look-at-me-sideways","title":"LookML Style Guide & Linter","description":"Look At Me Sideways (LAMS) is the official LookML style guide and linter to help you create maintainable LookML projects.","url":"https://github.com/looker-open-source/look-at-me-sideways","isGoogleResource":true,"contentTypes":["tool","sourceCode"],"platformFeatures":["lookml"],"personas":["modeler","admin"],"languages":["javascript"]}, + {"id":"//github.com/looker-open-source/lookr","title":"Looker R SDK 3.0","description":"Looker 3.0 SDK for R","url":"https://github.com/looker-open-source/lookr","contentTypes":["library","sourceCode"],"languages":["r"],"platformFeatures":["api","sdk"],"personas":["developer"]}, + {"id":"//github.com/looker-open-source/marketing_demo","title":"Sample LookML: Digital Marketing","description":"A Snowflake-based LookML project that demonstrates Looker’s value in the digital marketing landscape.","url":"https://github.com/looker-open-source/marketing_demo","contentTypes":["sampleCode"],"languages":["lookml"],"platformFeatures":["lookml"],"personas":["modeler"]}, + {"id":"//github.com/looker-open-source/sdk-codegen","title":"SDK Codegen","description":"The SDK Codegen is the source of truth for all SDKs and lets you create them for any language","url":"https://github.com/looker-open-source/sdk-codegen","contentTypes":["library"],"platformFeatures":["api","sdk"],"languages":["cSharp","go","kotlin","python","r","ruby","swift","typescript"],"personas":["developer"]}, + {"id":"//github.com/looker-open-source/sdk-codegen/tree/main/examples","title":"SDK Examples","description":"Our collection of SDK examples currently in: C#, Java, Kotlin, Python, R, Ruby, Swift, and TypeScript.","url":"https://github.com/looker-open-source/sdk-codegen/tree/main/examples","contentTypes":["sampleCode"],"languages":["cSharp","go","kotlin","python","r","ruby","swift","typescript"],"platformFeatures":["api","sdk"],"personas":["developer"]}, + {"id":"//github.com/looker/actions","title":"Action Hub Source","description":"The official Looker Action Hub repository for all your action requirements and examples.","url":"https://github.com/looker/actions","contentTypes":["sourceCode","reference"],"platformFeatures":["actions"],"languages":["typescript"],"personas":["developer","developer/backend"]}, + {"id":"//github.com/looker/actions/tree/master/src/actions","title":"Actions Source","description":"Direct link to the directory of all complete Actions in the official action hub.","url":"https://github.com/looker/actions/tree/master/src/actions","contentTypes":["sourceCode","sampleCode"],"platformFeatures":["actions"],"languages":["typescript"],"personas":["developer","developer/backend"]}, + {"id":"//github.com/looker/covid19","title":"COVID-19 Data Block","description":"This COVID-19 Block consists of LookML models, pre-built dashboards, and explores. The underlying data is only available in BigQuery.","url":"https://github.com/looker/covid19","contentTypes":["sampleCode"],"platformFeatures":["lookml"],"personas":["modeler"],"languages":["lookml"]}, + {"id":"//github.com/looker/custom_visualizations_v2","title":"Custom Visualizations v2","description":"The official repository of Looker Custom Visualizations API and examples","url":"https://github.com/looker/custom_visualizations_v2","contentTypes":["reference","sampleCode"],"platformFeatures":["customVisualization"],"personas":["developer","developer/frontend"],"languages":["typescript"]}, + {"id":"//github.com/looker/looker_embed_sso_examples","title":"Looker Embed SSO Examples","description":"Examples of performing Looker's SSO Embed URL signing in various server-side languages","url":"https://github.com/looker/looker_embed_sso_examples","contentTypes":["sampleCode"],"platformFeatures":["embed"],"languages":["cSharp","go","javascript","php","python","ruby"],"personas":["developer","developer/backend"]}, + {"id":"//github.com/thalesmello/lkml.vim","title":"LookML Vim Syntax","description":"Vim syntax for LookML. (may be out of date)","url":"https://github.com/thalesmello/lkml.vim","contentTypes":["tool"],"platformFeatures":["lookml"],"personas":["modeler"]}, + {"id":"//github.com/ww-tech/lookml-tools","title":"WW's LookML Tools","description":"Developed by WW, this repository contains tools to handle best practices with developing LookML files.","url":"https://github.com/ww-tech/lookml-tools","contentTypes":["tool","sampleCode"],"platformFeatures":["lookml"],"personas":["modeler"],"languages":["python"]}, + {"id":"//gitlab.com/alison985/awesome-looker","title":"Awesome Looker Projects","description":"An awesome list of awesome Looker projects.","url":"https://gitlab.com/alison985/awesome-looker/-/tree/main","contentTypes":["other"],"personas":["other"]}, + {"id":"//hack.looker.com/dashboards/16","title":"BQ Public Datasets on hack.looker.com","description":"BigQuery PublicHackathon","url":"https://hack.looker.com/dashboards/16","isHackathonSpecific":true,"contentTypes":["data"],"personas":["modeler","analyst","viewer"]}, + {"id":"//hack.looker.com/extensions/marketplace_extension_api_explorer::api-explorer","title":"API Explorer on hack.looker.com","description":"The API Explorer lets you learn and interact with the Looker API.","url":"https://hack.looker.com/extensions/marketplace_extension_api_explorer::api-explorer","isHackathonSpecific":true,"contentTypes":["tool"],"platformFeatures":["api"],"personas":["developer"]}, + {"id":"//lookervisbuilder.com","title":"Custom Viz Builder","description":"A Web IDE/sandbox to help develop Looker Custom Visualizations.","url":"https://lookervisbuilder.com/","contentTypes":["sandbox"],"platformFeatures":["customVisualization"],"personas":["developer","developer/frontend","analyst"]}, + {"id":"//www.npmjs.com/package/@looker/extension-sdk-react","title":"Extension SDK: React","description":"The React Extension SDK npm package. This lets you build a Looker extension — See the Extension Framework Examples for examples.","url":"https://www.npmjs.com/package/@looker/extension-sdk-react","contentTypes":["library"],"platformFeatures":["extensions"],"languages":["javascript"],"personas":["developer","developer/frontend"]}, + {"id":"//www.youtube.com/watch?v=3lbq5w7kcLs","title":"Extension Framework Tutorial Video","description":"A JOIN 2021 tutorial video on developing with the Extension Framework.","url":"https://www.youtube.com/watch?v=3lbq5w7kcLs","contentTypes":["tutorial","video"],"platformFeatures":["extensions"],"personas":["developer","developer/frontend"]}, + {"id":"//www.youtube.com/watch?v=DnIG0pD3UNA","title":"Actions Tutorial Video","description":"A JOIN 2021 tutorial video on creating actions.","url":"https://www.youtube.com/watch?v=DnIG0pD3UNA","contentTypes":["tutorial","video"],"platformFeatures":["actions"],"personas":["developer","developer/backend"]}, + {"id":"//www.youtube.com/watch?v=ixwWGKyG3wA","title":"Custom Viz Demo Video","description":"An older demo of Lookers custom viz capabilities","url":"https://www.youtube.com/watch?v=ixwWGKyG3wA","contentTypes":["tutorial","video"],"platformFeatures":["customVisualization"],"personas":["developer","developer/frontend","analyst"]}, + {"id":"//www.youtube.com/watch?v=kOanUnTMDpg","title":"API Explorer & API Tutorial Video","description":"A JOIN 2021 tutorial video on using API Explorer and Looker API.","url":"https://www.youtube.com/watch?v=kOanUnTMDpg","contentTypes":["tutorial","video"],"platformFeatures":["api"],"personas":["developer"]}, + {"id":"//www.youtube.com/watch?v=rSWX6oAOtMs","title":"Visualization Components Demo Video","description":"A JOIN 2021 intro and demo video of the new visualization components.","url":"https://www.youtube.com/watch?v=rSWX6oAOtMs","contentTypes":["demo","video"],"platformFeatures":["actions"],"personas":["developer","developer/frontend"]}, + {"id":"//www.youtube.com/watch?v=XTvJjCeAT74","title":"Embed Tutorial Video","description":"A JOIN 2021 tutorial video on Iframe and SSO Embedding.","url":"https://www.youtube.com/watch?v=XTvJjCeAT74","contentTypes":["tutorial","video"],"platformFeatures":["embed"],"personas":["developer"]} + ] +} \ No newline at end of file diff --git a/package.json b/package.json index aa2df53f3..33d455727 100644 --- a/package.json +++ b/package.json @@ -246,6 +246,7 @@ } ] }, + "eslintignore": ["bin/looker-resources-index/tmp/compiled-typescript/**/*.js"], "keywords": [], "resolutions": { "set-value": "^2.0.1",