@linktr.ee/create-link-app 1.5.1 → 1.7.1

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.
@@ -19,6 +19,7 @@ class Build extends base_1.default {
19
19
  allowAnyOrigin: flags['allow-any-origin'],
20
20
  });
21
21
  }
22
+ this.log('🎉 Build complete');
22
23
  }
23
24
  async webpack(options) {
24
25
  const config = await (0, webpack_config_1.default)('production', options);
@@ -33,9 +33,17 @@ const path_1 = __importDefault(require("path"));
33
33
  * Pack the Link App source files into `package.tgz`. This includes the above required/optional directories and files.
34
34
  */
35
35
  async function packProject() {
36
- const requiredDirs = ['src'];
37
- const requiredFiles = ['package.json', 'manifest.json'];
38
- const optionalFiles = ['package-lock.json', 'yarn.lock', 'tsconfig.json', 'url-match-rules.json', 'settings.json', 'icon.svg'];
36
+ const requiredFiles = ['manifest.json'];
37
+ const optionalDirs = ['src']; // For legacy LinkApp, it could have no src code.
38
+ const optionalFiles = [
39
+ 'package.json',
40
+ 'package-lock.json',
41
+ 'yarn.lock',
42
+ 'tsconfig.json',
43
+ 'url-match-rules.json',
44
+ 'settings.json',
45
+ 'icon.svg',
46
+ ];
39
47
  const packedFiles = [];
40
48
  await new Promise((resolve, reject) => {
41
49
  const outputPath = resolveProjPath('package.tgz');
@@ -71,12 +79,11 @@ async function packProject() {
71
79
  packedFiles.push(fileName);
72
80
  }
73
81
  });
74
- requiredDirs.forEach((dirName) => {
75
- if (!fs_1.default.existsSync(resolveProjPath(dirName)) || !fs_1.default.statSync(resolveProjPath(dirName)).isDirectory()) {
76
- handleFailure(new archiver_1.ArchiverError(`Directory ${dirName} does not exist`, 'ENOENT'));
82
+ optionalDirs.forEach((dirName) => {
83
+ if (fs_1.default.existsSync(resolveProjPath(dirName)) && fs_1.default.statSync(resolveProjPath(dirName)).isDirectory()) {
84
+ archive.directory(resolveProjPath(`${dirName}/`), dirName);
85
+ packedFiles.push(`${dirName}/`);
77
86
  }
78
- archive.directory(resolveProjPath(`${dirName}/`), dirName);
79
- packedFiles.push(`${dirName}/`);
80
87
  });
81
88
  archive.finalize();
82
89
  });
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.validateJSON = void 0;
7
+ const ajv_1 = __importDefault(require("ajv"));
8
+ const ajv = new ajv_1.default();
9
+ /**
10
+ * Validates a JSON object against a given schema.
11
+ * @param data - The JSON data to validate.
12
+ * @param schema - The JSON schema to validate against.
13
+ * @returns True if the data is valid, otherwise false.
14
+ */
15
+ function validateJSON(filename, data, schema) {
16
+ const validate = ajv.compile(schema);
17
+ const valid = validate(data);
18
+ if (!valid) {
19
+ console.error(`❌ Failed to validate ${filename}`);
20
+ console.error(validate.errors);
21
+ }
22
+ return valid;
23
+ }
24
+ exports.validateJSON = validateJSON;
@@ -0,0 +1,121 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-07/schema#",
3
+ "title": "Manifest",
4
+ "type": "object",
5
+ "properties": {
6
+ "name": {
7
+ "type": "string",
8
+ "description": "The name of the link type.",
9
+ "minLength": 3,
10
+ "maxLength": 50
11
+ },
12
+ "tagline": {
13
+ "type": "string",
14
+ "description": "A short tagline for the link type.",
15
+ "minLength": 3,
16
+ "maxLength": 200
17
+ },
18
+ "description": {
19
+ "type": "array",
20
+ "items": {
21
+ "type": "string"
22
+ }
23
+ },
24
+ "version": {
25
+ "type": "string",
26
+ "description": "The version of the link type.",
27
+ "pattern": "^\\d+\\.\\d+\\.\\d+$"
28
+ },
29
+ "supporting_links": {
30
+ "type": "object",
31
+ "properties": {
32
+ "terms_of_service": {
33
+ "type": "string",
34
+ "description": "The URL of the terms of service."
35
+ },
36
+ "privacy_policy": {
37
+ "type": "string",
38
+ "description": "The URL of the privacy policy."
39
+ }
40
+ }
41
+ },
42
+ "category": {
43
+ "type": "string",
44
+ "description": "The category of the link type.",
45
+ "enum": [
46
+ "grow",
47
+ "share",
48
+ "sell",
49
+ "other"
50
+ ]
51
+ },
52
+ "search_terms": {
53
+ "type": "array",
54
+ "description": "The search terms for the link type.",
55
+ "items": {
56
+ "type": "string"
57
+ }
58
+ },
59
+ "url_match_urls": {
60
+ "type": "object",
61
+ "properties": {
62
+ "hostnames": {
63
+ "type": "array",
64
+ "items": {
65
+ "type": "string"
66
+ }
67
+ },
68
+ "patterns": {
69
+ "type": "array",
70
+ "items": {
71
+ "type": "object"
72
+ }
73
+ },
74
+ "notPatterns": {
75
+ "type": "array",
76
+ "items": {
77
+ "type": "object"
78
+ }
79
+ }
80
+ }
81
+ },
82
+ "author": {
83
+ "type": "object",
84
+ "properties": {
85
+ "name": {
86
+ "type": "string",
87
+ "description": "The name of the author."
88
+ },
89
+ "accounts": {
90
+ "type": "array",
91
+ "items": {
92
+ "type": "string"
93
+ }
94
+ },
95
+ "contact": {
96
+ "type": "object",
97
+ "properties": {
98
+ "url": {
99
+ "type": "string",
100
+ "description": "The URL of the contact."
101
+ },
102
+ "email": {
103
+ "type": "string",
104
+ "description": "The email of the contact."
105
+ }
106
+ }
107
+ }
108
+ },
109
+ "required": [
110
+ "name"
111
+ ]
112
+ }
113
+ },
114
+ "required": [
115
+ "name",
116
+ "tagline",
117
+ "version",
118
+ "author"
119
+ ],
120
+ "additionalProperties": true
121
+ }
@@ -10,7 +10,7 @@ const postcss_config_1 = require("../postcss/postcss.config");
10
10
  const linkTypeSlug = 'test-id';
11
11
  const linkTypeId = 'testId';
12
12
  const config = {
13
- stories: [`${process.cwd()}/stories/*.stories.@(js|jsx|ts|tsx)`],
13
+ stories: [`${process.cwd()}/stories/**/*.stories.@(js|jsx|ts|tsx)`],
14
14
  addons: [
15
15
  '@storybook/addon-links',
16
16
  '@storybook/addon-essentials',
@@ -15,6 +15,8 @@ require("webpack-dev-server");
15
15
  const camelcase_1 = __importDefault(require("camelcase"));
16
16
  const slugify_1 = __importDefault(require("slugify"));
17
17
  const compile_1 = __importDefault(require("../lib/schema/compile"));
18
+ const validate_1 = require("../lib/schema/validate");
19
+ const manifest_schema_json_1 = __importDefault(require("../schema/manifest.schema.json"));
18
20
  const postcss_config_1 = require("../postcss/postcss.config");
19
21
  const { ModuleFederationPlugin } = webpack_1.container;
20
22
  function toVirtualModule(code) {
@@ -39,6 +41,7 @@ async function default_1(env, options) {
39
41
  const useEditorEntry = hasEntrypoint(appDir, 'Editor.tsx');
40
42
  const appEntry = useAppEntry ? path_1.default.resolve(appDir, 'src/App') : path_1.default.resolve(appDir, 'src');
41
43
  const manifestJson = JSON.parse(fs_1.default.readFileSync(path_1.default.resolve(appDir, 'manifest.json'), 'utf8'));
44
+ (0, validate_1.validateJSON)('manifest.json', manifestJson, manifest_schema_json_1.default);
42
45
  const linkTypeName = manifestJson.name.replace(/[^A-Za-z0-9 ]/g, '');
43
46
  const linkTypeSlug = (0, slugify_1.default)(linkTypeName, { lower: true });
44
47
  const linkTypeId = (0, camelcase_1.default)(linkTypeSlug, { pascalCase: true });
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "1.5.1",
2
+ "version": "1.7.1",
3
3
  "commands": {
4
4
  "build": {
5
5
  "id": "build",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@linktr.ee/create-link-app",
3
- "version": "1.5.1",
3
+ "version": "1.7.1",
4
4
  "description": "Create a Link App on Linktr.ee.",
5
5
  "license": "UNLICENSED",
6
6
  "author": "Linktree",
@@ -5,7 +5,6 @@
5
5
  "The simple greeting link is an example link type which enables a user to to show a simple greeting on their linktr.ee profile.",
6
6
  "This example code acts as a base for experimenting with link type capabilities"
7
7
  ],
8
- "manifest_version": "1.0.0",
9
8
  "version": "1.0.0",
10
9
  "supporting_links": {
11
10
  "terms_of_service": "https://example.com/terms-of-service",
@@ -1,18 +1,18 @@
1
- import { ComponentMeta, ComponentStory } from "@storybook/react";
2
- import React from "react";
3
- import fixture from "../fixtures/props-data.json";
4
- import manifest from "../manifest.json";
1
+ import { ComponentMeta, ComponentStory } from '@storybook/react'
2
+ import React from 'react'
3
+ import fixture from '../fixtures/props-data.json'
4
+ import manifest from '../manifest.json'
5
5
 
6
- import LinkApp from "../src/App";
6
+ import LinkApp from '../src/App'
7
7
 
8
- import "./tailwind.sb.css";
8
+ import './tailwind.sb.css'
9
9
 
10
10
  export default {
11
11
  title: `Link App/${manifest.name}`,
12
12
  component: LinkApp,
13
- tags: ["autodocs"],
13
+ tags: ['autodocs'],
14
14
  parameters: {
15
- layout: "fullscreen",
15
+ layout: 'fullscreen',
16
16
  },
17
17
  args: {
18
18
  ...fixture,
@@ -25,68 +25,68 @@ export default {
25
25
  },
26
26
  },
27
27
  },
28
- } as ComponentMeta<typeof LinkApp>;
28
+ } as ComponentMeta<typeof LinkApp>
29
29
 
30
30
  export const Stack: ComponentStory<typeof LinkApp> = (args) => (
31
31
  <div
32
32
  data-link-type-id={manifest.name}
33
33
  style={{
34
- margin: "0.5rem",
34
+ margin: '0.5rem',
35
35
  width: 374,
36
36
  height: 80,
37
37
  }}
38
38
  >
39
39
  <LinkApp {...args} />
40
40
  </div>
41
- );
41
+ )
42
42
  Stack.args = {
43
- __layout: "STACK",
44
- };
43
+ __layout: 'STACK',
44
+ }
45
45
 
46
46
  export const Grid: ComponentStory<typeof LinkApp> = (args) => (
47
47
  <div
48
48
  data-link-type-id={manifest.name}
49
49
  style={{
50
- margin: "0.5rem",
50
+ margin: '0.5rem',
51
51
  width: 183,
52
52
  height: 240,
53
53
  }}
54
54
  >
55
55
  <LinkApp {...args} />
56
56
  </div>
57
- );
57
+ )
58
58
  Grid.args = {
59
- __layout: "GRID",
60
- };
59
+ __layout: 'GRID',
60
+ }
61
61
 
62
62
  export const Carousel: ComponentStory<typeof LinkApp> = (args) => (
63
63
  <div
64
64
  data-link-type-id={manifest.name}
65
65
  style={{
66
- margin: "0.5rem",
66
+ margin: '0.5rem',
67
67
  width: 224,
68
68
  height: 296,
69
69
  }}
70
70
  >
71
71
  <LinkApp {...args} />
72
72
  </div>
73
- );
73
+ )
74
74
  Carousel.args = {
75
- __layout: "CAROUSEL",
76
- };
75
+ __layout: 'CAROUSEL',
76
+ }
77
77
 
78
78
  export const Featured: ComponentStory<typeof LinkApp> = (args) => (
79
79
  <div
80
80
  data-link-type-id={manifest.name}
81
81
  style={{
82
- margin: "0.5rem",
82
+ margin: '0.5rem',
83
83
  width: 374,
84
84
  height: 374,
85
85
  }}
86
86
  >
87
87
  <LinkApp {...args} />
88
88
  </div>
89
- );
89
+ )
90
90
  Featured.args = {
91
- __layout: "FEATURED",
92
- };
91
+ __layout: 'FEATURED',
92
+ }